Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SD-SPI bus sharing. (IDFGH-160) #1597

Open
OtherCrashOverride opened this issue Feb 8, 2018 · 9 comments

Comments

@OtherCrashOverride
Copy link

commented Feb 8, 2018

Due to the limited amount of IO pins on ESP32, it is desirable to share a SPI bus used for SD cards with other SPI devices such as a LCD display. This is currently not possible with esp-idf since the sdspi_host driver assumes the SD card will be the only device on the SPI bus.

As a "workaround", I have commented out the following line:

The above allows the SD card to share the bus with another SPI device. I have tested that both devices operate correctly when properly configured (#1080).

I would like to see SD-SPI bus sharing officially supported. An API revision will likely be required. The purpose of this post is to begin a conversation towards support.

@FayeY FayeY changed the title Support SD-SPI bus sharing. [TW#18514] Support SD-SPI bus sharing. Feb 11, 2018
@igrr

This comment has been minimized.

Copy link
Member

commented Feb 13, 2018

This seems to be pretty hard because SPI protocol of SD cards requires CS to be low for the duration of SD transaction. Single SD transaction can consist of multiple SPI transactions. Because of this, SDSPI driver controls CS in software.

If the SPI bus is shared, then nothing prevents another task from sending a transaction to a different device in between two parts of SD card transaction. However, since SDSPI driver keeps CS asserted, this extra transaction will be received by the card as well.

If in your use case the SD card and another device are only used sequentially, then the workaround you mention will work. But in the general case of multiple tasks accessing multiple SPI devices on the same bus concurrently, it will likely not work.

@OtherCrashOverride

This comment has been minimized.

Copy link
Author

commented Feb 17, 2018

I would guess there are also other drivers/apps where it is desirable to have deterministic SPI bus use: guaranteeing a group of transactions complete sequentially on the bus without interruption.

As a starting point, I propose the following:

  1. Add a spi_device_aquire API call to the SPI driver. This will lock a mutex and return an opaque handle for use in future API calls.
  2. While the mutex is held, all calls to spi_device_queue_trans will block.
  3. A new API call spi_device_queue_trans_exclusive(void* handle, ...) will be used to send/receive data while the mutex is held. The handle is checked and an error is returned if it does not match what is returned in acquisition call above.
  4. After all transactions are queued, the mutex is released with spi_device_release(void* handle). If the handle does match what was returned during acquisition, an error is returned.

With the above, all current code continues to work and exclusive use of the SPI device is transparent.

@amardhore

This comment has been minimized.

Copy link

commented Apr 17, 2018

@OtherCrashOverride how does it work for you both (SD & Display) on the same bus. i tried doing it but SD card always fails. I have a display which comes with the SD card, I have been trying to make display and SD work on the same bus but so far I have no luck. @OtherCrashOverride would you mind sharing your SD card configuration please. I am curious. Thank you.

@OtherCrashOverride

This comment has been minimized.

Copy link
Author

commented Apr 17, 2018

All the "magic" required was stated in my opening post. You need to patch the sdspi_host.c as stated and ensure you have the same duplex setting (full) for LCD and SD card.

If you are using an "Arduino compatible" SPI LCD interface that includes the SD card port, you need to replace the board's SPI resistors with 0Ohm for 3.3V operation.

@Molorius

This comment has been minimized.

Copy link

commented Jul 12, 2018

Could there at least be a Kconfig option to ignore the "return" mentioned above? That way a developer can implement their own locking mechanism if they need the bus for other devices.

@WangYifa

This comment has been minimized.

Copy link

commented Oct 24, 2018

@OtherCrashOverride I have modified esp-idf according to your suggestion, but cannot properly configure LCD and SPI SD. Could you please give me your configuration method for LCD and SPI SDCard?

@projectgus projectgus changed the title [TW#18514] Support SD-SPI bus sharing. Support SD-SPI bus sharing. (IDFGH-160) Mar 12, 2019
@quikue

This comment has been minimized.

Copy link

commented Mar 18, 2019

Thank's in advance!
I'm using the Olimex ESP32 EVB board, and I have a lot of problems to use the SD_MMC and SPI simultaneously, I spent a lot of time, but when I believe that's fixed another problem appears and doesn't work.
I'm using arduino libraries and platform.

The ESP32 EVB works whit SD_MMC 1 bit protocol, and need only 3 lines, 02 DAT0, 14 CLK, 15 SD_CMD, and SPI whit default whit, 02 MISO, 14 CLK, 13 MOSI, and 17 CS. I tried to initialize before and end after every use but doesn't work. The pin MISO and MOSI are attached to the SPI or the SD and, for me, it's impossible to do.

Anyone knows how use the SD_MMC and SPI simultaneously?

@alfonsohera

This comment has been minimized.

Copy link

commented May 3, 2019

I'm facing the same problem of not being able to share the SPI bus with an SD card using the SD SPI driver.
I'm initializing the bus first with the SDSPI driver, and then I add another device (SPI/CAN controller) to the bus. The SD card is written every minute, while messages from the CAN bus are received and sent every second. I have observed the following:
The SD card is written/read with no problem until the system starts using the SPI/CAN interface. I measured the CS pin of the SD card module I'm using, and the whole SD writing operation (3 SPI commands) lasts less than 150 ms.
As soon as the SPI/CAN interface starts receiving/sending messages, all write/read operations on the SD card return the same errors:

sdspi_host: data CRC failed, got=0x1402 expected=0xff91
sdspi_host: 30 2c 30 2c 00 2c 30 2c 30 2c 30 2c 30 2c 30 2c
sdspi_host: sdspi_host_start_command: cmd=17 error=0x109
sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
sdmmc_cmd: cmd=17, sdmmc_req_run returned 0x109
diskio_sdmmc: sdmmc_read_blocks failed

I already tried using a semaphore to control the access to the SPI bus. It does not work, the writing operation fails with the same error. I have even made some small changes to the sdspi driver to use the function spi_device_acquire_bus and spi_device_release_bus along to try to guarantee that there are no pending transactions on the bus before being used again. It doesn't work either.

After @igrr 's first response to this thread I thought that a simple mutex would solve this problem but obviously it's not that easy. Is there any way to share the SPI bus with an SD card?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants
You can’t perform that action at this time.