|
|
|
@ -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); |
|
|
|
|