From b9ee0eb88fd1c02aeb4cb1d1047e21119f8e2bf4 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 7 Oct 2022 19:00:10 +1100 Subject: Automatically acquire the CS lock when talking to the SD card --- main/storage.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'main/storage.cpp') diff --git a/main/storage.cpp b/main/storage.cpp index e1f6f386..d2f88894 100644 --- a/main/storage.cpp +++ b/main/storage.cpp @@ -28,7 +28,6 @@ SdStorage::~SdStorage() {} SdStorage::Error SdStorage::Acquire(void) { // Acquiring the bus will also flush the mux switch change. gpio_->set_pin(GpioExpander::SD_MUX_SWITCH, GpioExpander::SD_MUX_ESP); - auto lock = gpio_->AcquireSpiBus(GpioExpander::SD_CARD); // Now we can init the driver and set up the SD card into SPI mode. sdspi_host_init(); @@ -44,6 +43,18 @@ SdStorage::Error SdStorage::Acquire(void) { ESP_ERROR_CHECK(sdspi_host_init_device(&config, &handle_)); host_ = sdmmc_host_t SDSPI_HOST_DEFAULT(); + + // We manage the CS pin ourselves via the GPIO expander. To do this safely in + // a multithreaded environment, we wrap the ESP IDF do_transaction function + // with our own that acquires the CS mutex for the duration of the SPI + // transaction. + auto src = host_.do_transaction; + sdspi::do_transaction_wrapper = [=](sdspi_dev_handle_t handle, sdmmc_command_t *cmd) -> esp_err_t { + auto lock = gpio_->AcquireSpiBus(GpioExpander::SD_CARD); + return src(handle, cmd); + }; + host_.do_transaction = &sdspi::do_transaction; + host_.slot = handle_; // Will return ESP_ERR_INVALID_RESPONSE if there is no card esp_err_t err = sdmmc_card_init(&host_, &card_); @@ -66,8 +77,6 @@ SdStorage::Error SdStorage::Acquire(void) { } void SdStorage::Release(void) { - auto lock = gpio_->AcquireSpiBus(GpioExpander::SD_CARD); - // Unmount and unregister the filesystem f_unmount(""); ff_diskio_register(fs_->pdrv, NULL); -- cgit v1.2.3