arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
VFS_SDMMC.h
1#pragma once
2#include <string.h>
3
4#include "AudioTools/Disk/VFS.h"
5#include "driver/sdmmc_host.h"
6#include "esp_vfs_fat.h"
7#include "sd_protocol_types.h"
8#include "sdmmc_cmd.h"
9
10#ifdef SOC_SDMMC_IO_POWER_EXTERNAL
11#include "sd_pwr_ctrl_by_on_chip_ldo.h"
12#endif
13
14#define SDMMC_FREQ_DEFAULT \
15 20000
16#define SDMMC_FREQ_HIGHSPEED \
17 40000
18#define SDMMC_FREQ_PROBING 400
19#define SDMMC_FREQ_52M 52000
20#define SDMMC_FREQ_26M 26000
21#define SDMMC_FREQ_DDR50 50000
22#define SDMMC_FREQ_SDR50 100000
24#define DEFAULT_CLK 14
25#define DEFAULT_CMD 15
26#define DEFAULT_D0 2
27#define DEFAULT_D1 4
28#define DEFAULT_D2 12
29#define DEFAULT_D3 13
30
31#ifndef DEFAULT_ALLOCATION_SIZE
32#define DEFAULT_ALLOCATION_SIZE 16 * 1024
33#endif
34#ifndef DEFAULT_MAX_FILES
35#define DEFAULT_MAX_FILES 5
36#endif
37
38namespace audio_tools {
39
49class VFS_SDMMC : public VFS {
50 public:
51 enum class Speed { HS, UHS_SDR, UHS_DDR };
52 enum class BusWidth { Byte1 = 1, Byte4 = 4 };
53 VFS_SDMMC(const char* mountPoint = "/sdmmc") { mount_point = mountPoint; }
54 VFS_SDMMC(int pinClk, int pinCmd, int pinD0, int pinD1, int pinD2 = -1,
55 int pinD3 = -1, const char* mountPoint = "/sdmmc")
57 setBusWidth(pinD1 != -1 && pinD2 != -1 && pinD3 != -1 ? BusWidth::Byte4
58 : BusWidth::Byte1);
59 setPins(pinClk, pinCmd, pinD0, pinD1, pinD2, pinD3);
60 }
61
62 void setPins(int pinClk, int pinCmd, int pinD0, int pinD1, int pinD2 = -1,
63 int pinD3 = -1) {
64 setClk(pinClk);
65 setCmd(pinCmd);
66 setD0(pinD0);
67 setD1(pinD1);
68 setD2(pinD2);
69 setD3(pinD3);
70 }
71 void setClk(int pin) { pin_clk = (gpio_num_t)pin; }
72 void setCmd(int pin) { pin_clk = (gpio_num_t)pin; }
73 void setD0(int pin) { pin_d0 = (gpio_num_t)pin; }
74 void setD1(int pin) { pin_d1 = (gpio_num_t)pin; }
75 void setD2(int pin) { pin_d2 = (gpio_num_t)pin; }
76 void setD3(int pin) { pin_d3 = (gpio_num_t)pin; }
77
78 void setMountPoint(const char* mp) { mount_point = mp; }
79 void setSpeed(Speed speed) { this->speed = speed; }
80 void setBusWidth(BusWidth bits) { bus_width = bits; }
81
82 bool begin() {
83 esp_err_t ret;
84
85 // Options for mounting the filesystem.
86 // If format_if_mount_failed is set to true, SD card will be partitioned and
87 // formatted in case when mounting fails.
88 esp_vfs_fat_sdmmc_mount_config_t mount_config = {
89 .format_if_mount_failed = false,
90 .max_files = max_files,
91 .allocation_unit_size = allocation_unit_size};
92 LOGI("Initializing SD card");
93
94 // Use settings defined above to initialize SD card and mount FAT
95 // filesystem. Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience
96 // functions. Please check its source code and implement error recovery when
97 // developing production applications.
98
99 LOGI("Using SDMMC peripheral");
100
101 // By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT
102 // (20MHz) For setting a specific frequency, use host.max_freq_khz (range
103 // 400kHz - 40MHz for SDMMC) Example: for fixed frequency of 10MHz, use
104 // host.max_freq_khz = 10000;
105 host = SDMMC_HOST_DEFAULT();
106
107 switch (speed) {
108 case Speed::HS:
109 host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
110 break;
111 case Speed::UHS_SDR:
112 host.slot = SDMMC_HOST_SLOT_0;
113 host.max_freq_khz = SDMMC_FREQ_SDR50;
114 host.flags &= ~SDMMC_HOST_FLAG_DDR;
115 break;
116 case Speed::UHS_DDR:
117 host.slot = SDMMC_HOST_SLOT_0;
118 host.max_freq_khz = SDMMC_FREQ_DDR50;
119 break;
120 }
121
122 // For SoCs where the SD power can be supplied both via an internal or
123 // external (e.g. on-board LDO) power supply. When using specific IO pins
124 // (which can be used for ultra high-speed SDMMC) to connect to the SD
125 // card and the internal LDO power supply, we need to initialize the power
126 // supply first.
127#ifdef CONFIG_SD_PWR_CTRL_LDO_IO_ID
128
129 sd_pwr_ctrl_ldo_config_t ldo_config = {
130 .ldo_chan_id = CONFIG_SD_PWR_CTRL_LDO_IO_ID,
131 };
132 pwr_ctrl_handle = NULL;
133
134 ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle);
135 if (ret != ESP_OK) {
136 LOGE("Failed to create a new on-chip LDO power control driver");
137 return;
138 }
139 host.pwr_ctrl_handle = pwr_ctrl_handle;
140#endif
141
142 // This initializes the slot without card detect (CD) and write protect (WP)
143 // signals. Modify slot_config.gpio_cd and slot_config.gpio_wp if your board
144 // has these signals.
145 sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
146 // #if EXAMPLE_IS_UHS1
147 // slot_config.flags |= SDMMC_SLOT_FLAG_UHS1;
148 // #endif
149
150 // Set bus width to use:
151 slot_config.width = (int)bus_width;
152
153 // On chips where the GPIOs used for SD card can be configured, set them in
154 // the slot_config structure:
155#ifdef CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
156 slot_config.clk = pin_clk;
157 slot_config.cmd = pin_cmd;
158 slot_config.d0 = pin_d0;
159 slot_config.d1 = pin_d1;
160 slot_config.d2 = pin_d2;
161 slot_config.d3 = pin_d3;
162#endif // CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
163
164 // Enable internal pullups on enabled pins. The internal pullups
165 // are insufficient however, please make sure 10k external pullups are
166 // connected on the bus. This is for debug / example purpose only.
167 slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
168
169 LOGI("Mounting filesystem");
170 ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config,
171 &mount_config, &card);
172
173 if (ret != ESP_OK) {
174 if (ret == ESP_FAIL) {
175 LOGE("Failed to mount filesystem. ");
176 } else {
177 LOGE("Failed to initialize the card (%s). ", esp_err_to_name(ret));
178 }
179 return false;
180 }
181 LOGI("Filesystem mounted");
182
183 // Card has been initialized, print its properties
184 sdmmc_card_print_info(stdout, card);
185 return true;
186 }
187
188 void end() {
189 if (card == nullptr) return;
190 // All done, unmount partition and disable SDMMC peripheral
191 esp_vfs_fat_sdcard_unmount(mount_point, card);
192 LOGI("Card unmounted");
193 card = nullptr;
194
195 // Deinitialize the power control driver if it was used
196#ifdef CONFIG_SD_PWR_CTRL_LDO_IO_ID
197
198 ret = sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle);
199 if (ret != ESP_OK) {
200 LOGE("Failed to delete the on-chip LDO power control driver");
201 return;
202 }
203#endif
204 }
205
206 protected:
207 sdmmc_card_t* card = nullptr;
208 sdmmc_host_t host;
209 sd_pwr_ctrl_handle_t pwr_ctrl_handle;
210 int max_files = DEFAULT_MAX_FILES;
211 size_t allocation_unit_size = DEFAULT_ALLOCATION_SIZE;
212 Speed speed = Speed::HS;
213 BusWidth bus_width = BusWidth::Byte4;
214 gpio_num_t pin_clk = (gpio_num_t)DEFAULT_CLK;
215 gpio_num_t pin_cmd = (gpio_num_t)DEFAULT_CMD;
216 gpio_num_t pin_d0 = (gpio_num_t)DEFAULT_D0;
217 gpio_num_t pin_d1 = (gpio_num_t)DEFAULT_D1;
218 gpio_num_t pin_d2 = (gpio_num_t)DEFAULT_D2;
219 gpio_num_t pin_d3 = (gpio_num_t)DEFAULT_D3;
220};
221
222} // namespace audio_tools
ESP32 Virtual File System for SDMMC. The default mount point is "/sdcard" DRAFT implementation: not t...
Definition VFS_SDMMC.h:49
bool begin()
mount the file systems
Definition VFS_SDMMC.h:82
void setMountPoint(const char *mp)
provide the mount point (root directory for the file system)
Definition VFS_SDMMC.h:78
void end()
unmount the file system
Definition VFS_SDMMC.h:188
Definition VFS.h:16
const char * mountPoint()
provides the actual mount point
Definition VFS.h:55
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10