main/task_sdcard.c

changeset 105
9e00845dc1ee
parent 92
bac0a860f5dd
child 106
191dccfe4252
equal deleted inserted replaced
104:03c38ad63e8c 105:9e00845dc1ee
25 25
26 SDCARD_State *sdcard_state; ///< SD card status 26 SDCARD_State *sdcard_state; ///< SD card status
27 JSON_log *json_log; ///< JSON log array 27 JSON_log *json_log; ///< JSON log array
28 EventGroupHandle_t xEventGroupSDcard; ///< SD card events. 28 EventGroupHandle_t xEventGroupSDcard; ///< SD card events.
29 29
30 int card_handle = -1;
30 static const char *TAG = "task_sdcard"; 31 static const char *TAG = "task_sdcard";
31 static sdmmc_card_t* s_card = NULL; 32 static sdmmc_card_t* card = NULL;
32 static uint8_t s_pdrv = 0; 33 static uint8_t s_pdrv = 0;
33 static char * s_base_path = NULL; 34 //static char * s_base_path = NULL;
34 static uint8_t pdrv = FF_DRV_NOT_USED; 35 static uint8_t pdrv = FF_DRV_NOT_USED;
35 36
36 37
37 #define SDCARD_HOST_SLOT VSPI_HOST ///< HSPI_HOST is used by the TFT 38 #define SDCARD_HOST_SLOT VSPI_HOST ///< HSPI_HOST is used by the TFT
38 #define SDCARD_PIN_NUM_MISO 2 ///< MISO pin 39 #define SDCARD_PIN_NUM_MISO 2 ///< MISO pin
212 } 213 }
213 } 214 }
214 215
215 216
216 217
218 static esp_err_t mount_prepare_mem(const char *base_path, BYTE *out_pdrv, char **out_dup_path, sdmmc_card_t** out_card)
219 {
220 esp_err_t err = ESP_OK;
221 char* dup_path = NULL;
222
223 // connect SDMMC driver to FATFS
224 BYTE pdrv = FF_DRV_NOT_USED;
225 if (ff_diskio_get_drive(&pdrv) != ESP_OK || pdrv == FF_DRV_NOT_USED) {
226 ESP_LOGD(TAG, "the maximum count of volumes is already mounted");
227 return ESP_ERR_NO_MEM;
228
229 }
230
231 // not using ff_memalloc here, as allocation in internal RAM is preferred
232 card = (sdmmc_card_t*)malloc(sizeof(sdmmc_card_t));
233 if (card == NULL) {
234 ESP_LOGD(TAG, "could not locate new sdmmc_card_t");
235 err = ESP_ERR_NO_MEM;
236 goto cleanup;
237 }
238
239 dup_path = strdup(base_path);
240 if (!dup_path){
241 ESP_LOGD(TAG, "could not copy base_path");
242 err = ESP_ERR_NO_MEM;
243 goto cleanup;
244 }
245
246 *out_card = card;
247 *out_pdrv = pdrv;
248 *out_dup_path = dup_path;
249 return ESP_OK;
250 cleanup:
251 free(card);
252 card = NULL;
253 free(dup_path);
254 return err;
255 }
256
257
258
217 static esp_err_t my_init_sdspi_host(int slot, const void *slot_config, int *out_slot) 259 static esp_err_t my_init_sdspi_host(int slot, const void *slot_config, int *out_slot)
218 { 260 {
219 esp_err_t err = sdspi_host_init_device((const sdspi_device_config_t*)slot_config, out_slot); 261 esp_err_t err = sdspi_host_init_device((const sdspi_device_config_t*)slot_config, out_slot);
220 if (err != ESP_OK) { 262 if (err != ESP_OK) {
221 ESP_LOGE(TAG, "Failed to attach sdspi device onto an SPI bus (rc=0x%x), please initialize the \ 263 ESP_LOGE(TAG, "Failed to attach sdspi device onto an SPI bus (rc=0x%x), please initialize the \
225 } 267 }
226 268
227 269
228 270
229 /** 271 /**
230 * @brief This is a local modified version of the esp_vfs_fat_sdmmc_mount() function in 272 * @brief This is a local modified version of the esp_vfs_fat_sdspi_mount() function in
231 * the FreeRTOS components library. It is here so we can better handle errors 273 * the FreeRTOS components library. It is here so we can better handle errors
232 * for our application. 274 * for our application.
233 * @param base_path The mount path 275 * @param base_path The mount path
234 * @param host_config SPI host configuration 276 * @param host_config SPI host configuration
235 * @param slot_config Slot configuration 277 * @param slot_config Slot configuration
236 * @return Error condition. 278 * @return Error condition.
237 */ 279 */
238 esp_err_t my_vfs_fat_sdmmc_init(const char* base_path, const sdmmc_host_t* host_config, const void* slot_config, int *card_handle) 280 esp_err_t my_vfs_fat_sdspi_init(const char* base_path, const sdmmc_host_t* host_config, const void* slot_config)
239 { 281 {
240 if (s_card != NULL) { 282 esp_err_t err;
283 char* dup_path = NULL;
284
285 if (card != NULL) {
286 ESP_LOGE(TAG, "card not NULL");
241 return ESP_ERR_INVALID_STATE; 287 return ESP_ERR_INVALID_STATE;
242 } 288 }
243 289
244 // connect SDMMC driver to FATFS 290 err = mount_prepare_mem(base_path, &pdrv, &dup_path, &card);
245 pdrv = FF_DRV_NOT_USED; 291 if (err != ESP_OK) {
246 if (ff_diskio_get_drive(&pdrv) != ESP_OK || pdrv == FF_DRV_NOT_USED) { 292 ESP_LOGE(TAG, "mount_prepare failed");
247 ESP_LOGE(TAG, "the maximum count of volumes is already mounted"); 293 return err;
248 return ESP_ERR_NO_MEM; 294 }
249 } 295
250 296 //the init() function is usually empty, doesn't require any deinit to revert it
251 s_base_path = strdup(base_path);
252 if (!s_base_path) {
253 ESP_LOGE(TAG, "could not copy base_path");
254 return ESP_ERR_NO_MEM;
255 }
256 esp_err_t err = ESP_OK;
257 s_card = malloc(sizeof(sdmmc_card_t));
258 if (s_card == NULL) {
259 err = ESP_ERR_NO_MEM;
260 goto fail;
261 }
262
263 err = (*host_config->init)(); 297 err = (*host_config->init)();
264 if (err != ESP_OK) { 298 if (err != ESP_OK) {
265 ESP_LOGE(TAG, "host init returned rc=0x%x", err); 299 ESP_LOGE(TAG, "host init returned rc=0x%x", err);
266 goto fail; 300 goto fail;
267 } 301 }
268 302
269 // configure SD host 303 // configure SD host
270 err = my_init_sdspi_host(host_config->slot, slot_config, &card_handle); 304 err = my_init_sdspi_host(host_config->slot, slot_config, &card_handle);
271 if (err != ESP_OK) { 305 if (err != ESP_OK) {
272 ESP_LOGE(TAG, "init_sdspi_host() rc=0x%x", err); 306 ESP_LOGE(TAG, "my_init_sdspi_host() rc=0x%x", err);
273 goto fail; 307 goto fail;
274 } 308 }
275 return ESP_OK; 309 return ESP_OK;
276 310
277 fail: 311 fail:
278 host_config->deinit(); 312 host_config->deinit();
279 free(s_card); 313 free(card);
280 s_card = NULL; 314 card = NULL;
281 return err; 315 return err;
282 } 316 }
283 317
284 318
285 319
290 * @param slot_config Slot configuration 324 * @param slot_config Slot configuration
291 * @param mount_config Mount configuration 325 * @param mount_config Mount configuration
292 * @param[out] out_card Card information 326 * @param[out] out_card Card information
293 * @return Error condition 327 * @return Error condition
294 */ 328 */
295 esp_err_t my_esp_vfs_fat_sdmmc_mount(const char* base_path, 329 esp_err_t my_esp_vfs_fat_sdspi_mount(const char* base_path,
296 const sdmmc_host_t* host_config, 330 const sdmmc_host_t* host_config_input,
297 const void* slot_config, 331 const sdspi_device_config_t* slot_config,
298 const esp_vfs_fat_mount_config_t* mount_config, 332 const esp_vfs_fat_mount_config_t* mount_config,
299 sdmmc_card_t** out_card, 333 sdmmc_card_t** out_card)
300 int card_handle) 334 {
301 { 335 const sdmmc_host_t* host_config = host_config_input;
302 FATFS* fs = NULL; 336 FATFS* fs = NULL;
303 esp_err_t err = ESP_OK; 337 esp_err_t err = ESP_OK;
304 338
305 if (s_card == NULL) { 339 if (card == NULL) {
340 ESP_LOGE(TAG, "card not NULL");
306 return ESP_ERR_INVALID_STATE; 341 return ESP_ERR_INVALID_STATE;
307 } 342 }
308 343
344 /*
345 * The `slot` argument inside host_config should be replaced by the SD SPI handled returned
346 * above. But the input pointer is const, so create a new variable.
347 */
348 sdmmc_host_t new_config;
349 if (card_handle != host_config->slot) {
350 new_config = *host_config_input;
351 host_config = &new_config;
352 new_config.slot = card_handle;
353 }
354
309 // probe and initialize card 355 // probe and initialize card
310 err = sdmmc_card_init(host_config, s_card); 356 err = sdmmc_card_init(host_config, card);
311 if (err != ESP_OK) { 357 if (err != ESP_OK) {
312 if (err != ESP_ERR_INVALID_RESPONSE) { // No card present, do not log 358 if (err != ESP_ERR_INVALID_RESPONSE) { // No card present, do not log
313 ESP_LOGI(TAG, "sdmmc_card_init failed 0x(%x)", err); 359 ESP_LOGI(TAG, "sdmmc_card_init failed 0x(%x)", err);
314 } 360 }
315 goto fail; 361 goto fail;
316 } 362 }
363
317 if (out_card != NULL) { 364 if (out_card != NULL) {
318 *out_card = s_card; 365 *out_card = card;
319 } 366 }
320 367
321 ff_diskio_register_sdmmc(pdrv, s_card); 368 /*
369 * mount to vfs fat
370 */
371 ff_diskio_register_sdmmc(pdrv, card);
322 s_pdrv = pdrv; 372 s_pdrv = pdrv;
323 ESP_LOGD(TAG, "using pdrv=%i", pdrv); 373 ESP_LOGD(TAG, "using pdrv=%i", pdrv);
324 char drv[3] = {(char)('0' + pdrv), ':', 0}; 374 char drv[3] = {(char)('0' + pdrv), ':', 0};
325 375
326 // connect FATFS to VFS 376 // connect FATFS to VFS
354 404
355 /** 405 /**
356 * @brief Unmount a mounted SD card, 406 * @brief Unmount a mounted SD card,
357 * @return Error condition 407 * @return Error condition
358 */ 408 */
359 esp_err_t my_esp_vfs_fat_sdmmc_unmount(void) 409 esp_err_t my_esp_vfs_fat_sdspi_unmount(void)
360 { 410 {
361 if (s_card == NULL) { 411 if (card == NULL) {
362 return ESP_ERR_INVALID_STATE; 412 return ESP_ERR_INVALID_STATE;
363 } 413 }
364 // unmount 414 // unmount
365 char drv[3] = {(char)('0' + s_pdrv), ':', 0}; 415 char drv[3] = {(char)('0' + s_pdrv), ':', 0};
366 f_mount(0, drv, 0); 416 f_mount(0, drv, 0);
404 { 454 {
405 sdmmc_card_t* card; 455 sdmmc_card_t* card;
406 esp_err_t ret; 456 esp_err_t ret;
407 EventBits_t uxBits; 457 EventBits_t uxBits;
408 char filename[64]; 458 char filename[64];
409 int card_handle = -1; //uninitialized
410 459
411 sdcard_state = malloc(sizeof(SDCARD_State)); 460 sdcard_state = malloc(sizeof(SDCARD_State));
412 sdcard_state->host_ok = false; 461 sdcard_state->host_ok = false;
413 sdcard_state->card_present = false; 462 sdcard_state->card_present = false;
414 sdcard_state->logfile[0] = '\0'; 463 sdcard_state->logfile[0] = '\0';
440 slot_config.host_id = host.slot; 489 slot_config.host_id = host.slot;
441 490
442 /* 491 /*
443 * No errors from the sdspi_transaction driver. 492 * No errors from the sdspi_transaction driver.
444 */ 493 */
445 esp_log_level_set("sdspi_transaction", ESP_LOG_NONE); 494 // esp_log_level_set("sdspi_transaction", ESP_LOG_NONE);
446 495
447 /* 496 /*
448 * Options for mounting the filesystem. 497 * Options for mounting the filesystem.
449 * If format_if_mount_failed is set to true, SD card will be partitioned and 498 * If format_if_mount_failed is set to true, SD card will be partitioned and
450 * formatted in case when mounting fails. 499 * formatted in case when mounting fails.
453 .format_if_mount_failed = false, 502 .format_if_mount_failed = false,
454 .max_files = 5, 503 .max_files = 5,
455 .allocation_unit_size = 16 * 1024 504 .allocation_unit_size = 16 * 1024
456 }; 505 };
457 506
458 ret = my_vfs_fat_sdmmc_init("/sdcard", &host, &slot_config, &card_handle); 507 ret = my_vfs_fat_sdspi_init("/sdcard", &host, &slot_config);
459 if (ret == ESP_OK) { 508 if (ret == ESP_OK) {
460 ESP_LOGI(TAG, "SPI card interface ready"); 509 ESP_LOGI(TAG, "SPI card interface ready");
461 sdcard_state->host_ok = true; 510 sdcard_state->host_ok = true;
462 } else { 511 } else {
463 ESP_LOGE(TAG, "SPI card interface failed, abort task"); 512 ESP_LOGE(TAG, "SPI card interface failed, abort task");
474 523
475 if (sdcard_state->card_present == false) { 524 if (sdcard_state->card_present == false) {
476 /* 525 /*
477 * If the card is not mounted, try it. 526 * If the card is not mounted, try it.
478 */ 527 */
479 ret = my_esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card, card_handle); 528 ret = my_esp_vfs_fat_sdspi_mount("/sdcard", &host, &slot_config, &mount_config, &card);
480 if (ret == ESP_OK) { 529 if (ret == ESP_OK) {
481 ESP_LOGI(TAG, "SD card mounted on /sdcard"); 530 ESP_LOGI(TAG, "SD card mounted on /sdcard");
482 sdcard_state->card_present = true; 531 sdcard_state->card_present = true;
483 532
484 DIR* dir = opendir("/sdcard/w/log"); 533 DIR* dir = opendir("/sdcard/w/log");
494 * Check if the mounted card is still in the slot. 543 * Check if the mounted card is still in the slot.
495 */ 544 */
496 DIR* dir = opendir("/sdcard/w/log"); 545 DIR* dir = opendir("/sdcard/w/log");
497 if (dir == NULL) { 546 if (dir == NULL) {
498 ESP_LOGI(TAG, "SD card missing, unmount"); 547 ESP_LOGI(TAG, "SD card missing, unmount");
499 my_esp_vfs_fat_sdmmc_unmount(); 548 my_esp_vfs_fat_sdspi_unmount();
500 sdcard_state->card_present = false; 549 sdcard_state->card_present = false;
501 esp_log_level_set("sdmmc_sd", ESP_LOG_NONE); 550 esp_log_level_set("sdmmc_sd", ESP_LOG_NONE);
502 } else { 551 } else {
503 closedir(dir); 552 closedir(dir);
504 } 553 }

mercurial