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

Closed
OtherCrashOverride opened this issue Feb 8, 2018 · 38 comments
Closed

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

OtherCrashOverride opened this issue Feb 8, 2018 · 38 comments

Comments

@OtherCrashOverride
Copy link

OtherCrashOverride 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
Copy link
Member

igrr 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
Copy link
Author

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
Copy link

@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
Copy link
Author

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
Copy link

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.

@yihua-wang
Copy link

yihua-wang 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?

@quikue
Copy link

quikue 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
Copy link

alfonsohera 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?

@satyanraj
Copy link

Hi,

Has this issue been fixed?
We are facing a similar problem, as because of the limited number of IO we decided to share same set of SPI signals with the SD card (SPI) and other SPI devices.

Thanks

@iosix
Copy link

iosix commented Nov 13, 2019 via email

@alfonsohera
Copy link

If you initialize the SD card first the bus will then be available and you can add peripherals without any IDF code changes. Robert Vogt IV CEO IOSiX, LLC 1300 Tefft Ct #1 Saline, MI 48176 P: +1-855-OBD-1939 C: +1-734-730-9690 robert@iosix.com

On Nov 13, 2019, at 2:14 AM, Satyan Raj @.***> wrote:  Hi, Has this issue been fixed? We are facing a similar problem, as because of the limited number of IO we decided to share same set of SPI signals with the SD card (SPI) and other SPI devices. Thanks — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

What IDF version are you using? Because in my previous tests (witn an oldish version (mid april) of the main branch) initializing the SD card first did not make any difference. The problem was visible when the second device started using the bus (there was no problem when the second device was added to the bus).

@amardhore
Copy link

amardhore commented Nov 21, 2019 via email

@igrr
Copy link
Member

igrr commented Feb 13, 2020

SPI bus sharing with SDSPI has been added in 067f3d2 — please see the new sdspi_host_init_device, sdspi_host_remove_device functions.

@zavovi
Copy link

zavovi commented Mar 4, 2020

Hi,
I hacked this issue with SPI_acquire functions in release v3.3 and it was working. Now, I changed to release v4.1 and my hack not working.
Please, where are the main changes in SDSPI and MMC driver?

Thank you very much.
Vilem

@igrr
Copy link
Member

igrr commented Mar 5, 2020

Hi @zavovi, there has been a number of changes between v3.3 and v4.1... Best way to browse them is to start with git log. Assuming you are in the esp-idf directory:

git log release/v4.1...v4.0-dev -- components/driver/sd*.c

@zavovi
Copy link

zavovi commented Mar 7, 2020

Hi @igrr , thank you. Do you know something more about SPI driver? I have already right used xSemaphoreTake and xSemaphoreGive for all tasks, where I call the SPI transactions. But it seems, that when I call some functions from FatFs, it seems, that it is processed outside the call.

For example, I call this:

tcs_err_t tcs_sdcard_read_from_file(const char * filename, tcs_buffer_t * buffer)
{
	tcs_err_t err = TCS_OK;
	int readsize = 0;

	if(!tcs_sdcardSem)
		return TCS_ERR_SDCARD_INIT;

	TCS_ASSERT(filename != NULL);
	TCS_ASSERT(buffer != NULL);
	TCS_ASSERT(tcs_sdcardSem != NULL);

	/* LOCK */
	_tcs_sdcard_lock();

	/* Open file */
	int f = open(tcs_sdcard_path(filename), O_RDONLY);
	if(f <= 0)
	{
		TCS_ERROR_PRINTF(LOG_CATEGORY, "Error when open file '%s': %d", filename, f);
		err = TCS_ERR_SDCARD_OPEN;
		goto ERROR;
	}

	TCS_WARNING_PRINTF(LOG_CATEGORY, "Pre-read...");

	/* Read file */
    readsize = read(f, tcs_buffer_get_tail(buffer), tcs_buffer_get_free_size(buffer));
    if(readsize < 0)
    {
    	err = TCS_ERR_SDCARD_READ;
    	goto ERROR;
    }

    buffer->used += readsize;

    TCS_WARNING_PRINTF(LOG_CATEGORY, "Post-read...");

ERROR:
	if(f > 0)
		close(f);

	/* UNLOCK */
	_tcs_sdcard_unlock();

	return err;
}

I get error code 0x107, it is timeout. But when I disable my TFT driver, it is working properly. It seems, that something is processed outside my call. Or I don't understand, where is the difference from v3.3.

Thank you.

@edouardreg
Copy link

SPI bus sharing with SDSPI has been added in 067f3d2 — please see the new sdspi_host_init_device, sdspi_host_remove_device functions.

Hello, is SPI and SDSPI sharing working in esp-idf release v4.0 ?

@zavovi
Copy link

zavovi commented Jul 27, 2020

Hi all, I am sorry for long delay, but I still not solved my issue. I am really struggling with it and I am tired. Lot of month and it looks, that it is working, but not!
I have own HW, that it have same pinout for SD and TFT on SPI as M5Stack. I have M5Stack too.
The esp-idf version is 4.2 merged yesterday.

My code:

  1. Initialized SPI in TFT driver and initialized display. - OK
    • Started different task for updating the TFT display. Before all SPI writes, I calling xSemaphoreTake and spi_device_acquire_bus. Then I call spi_device_queue_trans and spi_device_get_trans_result for all transactions (6).
  2. Initialized SD card (without SPI init). - OK
  3. Read SD card info (sdmmc_card_print_info). - OK
  4. Check, if folder exists (used stat function). - Issue on some SD cards (ADATA 8GB is ok, GoodRAM 8 GB or SanDisk 16GB is failed with timeout - 0x107)
  5. Create directory (mkdir). Issue same as 4
  6. Read file from SD (open, read, close). - OK on all SD cards
  7. Create and write into file. - OK on all SD cards
  8. Format SD (own function made from init fatfs function). - Issue same as 4

(This behavior is only, when the same semaphore is used for I2C too. When not, then BAD SD not working for all - read/write and others). I don't understand. I tried disable all others tasks.

The TFT display is still ok.
When I disable task, which is updating the TFT display, then all SDs are working properly.
It seems, that there is some timing problem. Like SPI write is still writting to display, after spi_device_get_trans_result or something like that. Maybe the SD task is stopped or something like that.

The issue LOG in point 4:

E (3422) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x107
E (3423) diskio_sdmmc: sdmmc_read_blocks failed (263)
E (4587) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x107
E (4588) diskio_sdmmc: sdmmc_read_blocks failed (263)

The BAD SD card sdmmc_card_print_info:

I (2237) sdspi_transaction: cmd=52, R1 response: command not supported
I (2284) sdspi_transaction: cmd=5, R1 response: command not supported
Name: 00000
Type: SDHC/SDXC
Speed: 20 MHz
Size: 7431MB

The GOOD SD card sdmmc_card_print_info:

I (2278) sdspi_transaction: cmd=5, R1 response: command not supported
Name: SD
Type: SDHC/SDXC
Speed: 20 MHz
Size: 7535MB

Please, could you help me? I am solving this issue lot of months and I am really tired from it :-( Please help!!!

Thank you very much.
Best regards,
Vilem

@ginkgm
Copy link
Collaborator

ginkgm commented Jul 28, 2020

Hi @zavovi ,

Due to the strange behavior of SD cards over SPI bus, you need to initialize the devices on the same bus in the following sequence strictly:

  1. The CS of other devices should be hold high. Suggested way is using gpio.
  2. Initialize the SPI bus.
  3. The SD card should be initialized before all other devices to put it into SPI mode
  4. Initialize other devices

This is because, the SD card will respond to the data stream (even without CS active) of other devices when it's just powered up and not in the SPI mode. But to put SD card into SPI mode, you have to avoid conflicts from other SPI slaves first. (or you can try pullups on all CS wires).

@ginkgm
Copy link
Collaborator

ginkgm commented Jul 28, 2020

Hi @edouardreg ,
Sorry, but this is a new feature introduced in IDF v4.2 (067f3d2). This involves quite a few changes and cannot be easily backported to earlier versions..

@zavovi
Copy link

zavovi commented Jul 28, 2020

Hi @ginkgm ,
thank you for your reply.
I've tried put the SD card initialization to the first place, but no change.

Here is part of my init code:

gpio_reset_pin(APP_TFT_PIN_CS);
/* Set as output */
gpio_set_direction(APP_TFT_PIN_CS, GPIO_MODE_OUTPUT);
/* change gpio interrupt type for one pin */
gpio_set_intr_type(APP_TFT_PIN_CS, GPIO_INTR_DISABLE);
gpio_set_level(APP_TFT_PIN_CS, 1);

static sdmmc_host_t host = SDSPI_HOST_DEFAULT();
static sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();

// Options for mounting the filesystem.
	// If format_if_mount_failed is set to true, SD card will be partitioned and
	// formatted in case when mounting fails.
static esp_vfs_fat_sdmmc_mount_config_t mount_config =
{
	.format_if_mount_failed = false,
	.max_files = 5,	/* Maximum opened files in one time */
	.allocation_unit_size = 4096 * 1024
};

spi_bus_config_t buscfg={
		.miso_io_num=TCS_SDCARD_PIN_MISO,
		.mosi_io_num=TCS_SDCARD_PIN_MOSI,
		.sclk_io_num=TCS_SDCARD_PIN_CLK,
		.quadwp_io_num=-1,
		.quadhd_io_num=-1,
		.max_transfer_sz=LV_VDB_SIZE*3+8
	};

	/* Initialize SPI bus */
	ret = spi_bus_initialize(HSPI_HOST, &buscfg, 1);
	if(ret != ESP_OK)
		return TCS_ERR_SDCARD_INIT;

ret = esp_vfs_fat_sdspi_mount(TCS_SDCARD_MNT_NAME, &host, &slot_config, &mount_config, &card);
	if (ret != ESP_OK)
	{
		TCS_ERROR_PRINTF(LOG_CATEGORY, "SD card error mount : %d (%s)\n", ret, esp_err_to_name(ret));
		err = TCS_ERR_SDCARD_MOUNT;
		goto ERROR;
	}

	// Card has been initialized, print its properties
	sdmmc_card_print_info(stdout, card);

The initialization is OK for all my SD cards. The sdmmc_card_print_info is OK too.
After that, the TFT display is initialized OK and working properly.
After that, I want to create directory and I get this error:

E (3492) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x107
E (3493) diskio_sdmmc: sdmmc_read_blocks failed (263)
E (4825) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x107
E (4826) diskio_sdmmc: sdmmc_read_blocks failed (263)

Then I read the text file, and it is OK. Write is OK too.

I am handling CS line for TFT by GPIO in each transaction by gpio_set_level(APP_TFT_PIN_CS, 0/1);.

@zavovi
Copy link

zavovi commented Jul 28, 2020

Here is example of my make directory function:

tcs_err_t tcs_sdcard_create_dir(const char * filename)
{
	tcs_err_t err = TCS_OK;
	esp_err_t ret;

	if(!tcs_sdcardSem)
		return TCS_ERR_SDCARD_INIT;

	TCS_ASSERT(filename != NULL);
	TCS_ASSERT(tcs_sdcardSem != NULL);

	/* LOCK */
	_tcs_sdcard_lock();

    ret = mkdir(tcs_sdcard_path(filename), 0x777);
	if(ret != ESP_OK)
	{
		TCS_ERROR_PRINTF(LOG_CATEGORY, "Error when creating directory '%s': %d", filename, errno);
		err = TCS_ERR_SDCARD_NEWDIR;
		goto ERROR;
	}

ERROR:

	/* UNLOCK */
	_tcs_sdcard_unlock();

	return err;
}

static void _tcs_sdcard_lock(void)
{
	/* Wait for the other task done the TFT (SPI) operation */
    tcs_tft_driver_take();

	app_gpio_set_pin(APP_TFT_PIN_CS);
	gpio_hold_en(APP_TFT_PIN_CS);

    /* Wait for the other task done the SD card operation */
    xSemaphoreTake(tcs_sdcardSem, portMAX_DELAY);
}

static void _tcs_sdcard_unlock(void)
{
	/* SD card operation done -> release for the other task */
	xSemaphoreGive(tcs_sdcardSem);

	gpio_hold_dis(APP_TFT_PIN_CS);
	app_gpio_clear_pin(APP_TFT_PIN_CS);

	/* TFT (SPI) operation done -> release for the other task */
	tcs_tft_driver_give();
}

Here are transfer function for TFT (called both):

static void _tcs_tft_disp_send_addr(uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2, void *color, uint32_t len)
{
    esp_err_t ret;
    int i = 0;

    //Transaction descriptors. Declared static so they're not allocated on the stack; we need this memory even when this
    //function is finished because the SPI driver needs access to it even while we're already calculating the next line.
    static spi_transaction_t trans[6];

    //In theory, it's better to initialize trans and data only once and hang on to the initialized
	//variables. We allocate them on the stack, so we need to re-init them each call.
	for (i=0; i<6; i++)
	{
		tcs_memset(&trans[i], 0, sizeof(spi_transaction_t));
		if ((i&1)==0)
		{
			//Even transfers are commands
			trans[i].length=8;
			trans[i].user=(void*)0;
		}
		else
		{
			//Odd transfers are data
			trans[i].length=8*4;
			trans[i].user=(void*)1;
		}
		trans[i].flags=SPI_TRANS_USE_TXDATA;
	}
	/* Command */
    trans[0].tx_data[0]=TCS_TFT_CMD_CASET;           //Column Address Set

    /* Data */
    trans[1].tx_data[0]=(uint8_t)(x1>>8);
    trans[1].tx_data[1]=(uint8_t)(x1&0xff);
    trans[1].tx_data[2]=(uint8_t)(x2>>8);
    trans[1].tx_data[3]=(uint8_t)(x2&0xff);

    /* Command */
    trans[2].tx_data[0]=TCS_TFT_CMD_PASET;           //Page address set

    /* Data */
    trans[3].tx_data[0]=(uint8_t)(y1>>8);
    trans[3].tx_data[1]=(uint8_t)(y1&0xff);
    trans[3].tx_data[2]=(uint8_t)(y2>>8);
    trans[3].tx_data[3]=(uint8_t)(y2&0xff);

	/* Command */
    trans[4].tx_data[0]=TCS_TFT_CMD_RAMWR;

	/* Data */
    trans[5].tx_buffer=color;        //finally send the line data
    trans[5].length=len*8;          //Data length, in bits
    trans[5].flags=0; //not SPI_TRANS_USE_TXDATA flag


	tcs_tft_driver_take();
    spi_device_acquire_bus(tcs_tft_ctx.spi, portMAX_DELAY);
	app_gpio_clear_pin(APP_TFT_PIN_CS);
    //Queue all transactions.
	for (i=0; i<6; i++)
	{
		ret=spi_device_queue_trans(tcs_tft_ctx.spi, &trans[i], portMAX_DELAY);
		TCS_ASSERT(ret==ESP_OK);
	}

    tcs_tft_ctx.send = TCS_TRUE;
}

void tcs_tft_driver_send_finish(void)
{
    spi_transaction_t *rtrans;
    esp_err_t ret;

    if(!tcs_tft_ctx.send)
    {
    	TCS_ASSERT(0);
    	return;
    }

    //Wait for all 6 transactions to be done and get back the results.
    for (int x=0; x<6; x++)
    {
        ret=spi_device_get_trans_result(tcs_tft_ctx.spi, &rtrans, portMAX_DELAY);
        TCS_ASSERT(ret==ESP_OK);
        //We could inspect rtrans now if we received any info back. The LCD is treated as write-only, though.
    }
	app_gpio_set_pin(APP_TFT_PIN_CS);
    spi_device_release_bus(tcs_tft_ctx.spi);
	tcs_tft_driver_give();

    tcs_tft_ctx.send = TCS_FALSE;
}

@ginkgm
Copy link
Collaborator

ginkgm commented Jul 28, 2020

Hi @zavovi ,

The sdspi driver will control the CS at proper time, you don't need to manually controls it's CS. This depends on a bus acquiring feature (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html#_CPPv422spi_device_acquire_bus19spi_device_handle_t10TickType_t) introduced in IDF v.3.2. This will also forbids other devices from using that bus. (https://github.com/espressif/esp-idf/blob/master/components/driver/sdspi_host.c#L455 introduced in v4.2).

Maybe your manual control breaks the GPIO logic of SDSPI?

@zavovi
Copy link

zavovi commented Jul 28, 2020

Hi @ginkgm ,
I know, that the sdspi driver can handle the CS lines, but when I use it, then it seems, that not working nothing (read/write, mkdir, ...) with BAD SD card. When I am handling CS manually, then the read/write working.

I had the CS lines controlled from sdspi with my GOOD SD card, but now, when I am solving other my cards, I am trying all my ideas...

@zavovi
Copy link

zavovi commented Jul 28, 2020

Ok, I changed the CS handling back to the SPI driver and leave the SD init the first, it working same. Only read/write on BAD SD cards.

@zavovi
Copy link

zavovi commented Aug 2, 2020

Hello @ginkgm ,
I added HW PullUp to CS wires, but no change. Still cannot mkdir on my "BAD" SD cards. It works only when disable task, which flushing data to TFT display.

I don't understand, why it is not working, the FreeRTOS semaphore should block right, or not? It seems, that mkdir take more time than read/write.

Any other suggestions please?
Thank you.

@amardhore
Copy link

@zavovi i had the same problem and it turned out to be the dma access. Try this: assign dma channel 1 to tft and dma channel to 2 sd card and see if it make any difference. Good luck.

@zavovi
Copy link

zavovi commented Aug 4, 2020

Hello @amardhore ,
Thank you for your advice. I tried initialized HSPI for SD card with DMA 2 and VSPI for TFT with DMA 1 and then the SD card not working (cannot read/write). Only SD init is ok.
I tried VSPI for SD and HSPI for TFT and no changed. Still SD card not working.

@amardhore
Copy link

amardhore commented Aug 4, 2020

@zavovi

so sd init is working ok? how long is your file name?
Give this a try--> in the menuconfig, try selecting long names. clean and then compile. hope it helps.

--
Amar

@zavovi
Copy link

zavovi commented Aug 4, 2020

Hello @amardhore ,
my file names:
mkdir "TCS"
mkdir "TCS/trains"
mkdir "TCS/acc"
Read/write testing on config file "wifi.cfg"

I have enabled long names and maximum was increased to 60.

SD initialization is good in all my tests (shared DMA, not shared DMA, etc...). I am initializing the SD card first.
In my half-working code (read/write working, mkdir not), I can create directory, before I am refreshing the screen (TFT), when I am refreshing the screen, I cannot create directory, only read/write a file. I tried increase refresh period - no change.

Thank you,
Vilem

@yihua-wang
Copy link

Can you provide a demo code that coexists with SD card and LCD on the sharing SPI bus?

@satyanraj
Copy link

@Alvin1Zhang: Looks like people are still struggling SPI bus issue issue with SD card.

@satyanraj
Copy link

@zavovi Can you please share the sample code, for our reference.

@zavovi
Copy link

zavovi commented Oct 8, 2020

Hello @satyanraj,
I am sorry, I haven't got time for example for now. I am working on release of my device, which is at the end of this month. I used internal ESP32 memory as filesystem instead of SD card. For now, it is enough for me and the SD card will be enabled later.

Thank you.
Vilem

@satyanraj
Copy link

Hello @satyanraj,
I am sorry, I haven't got time for example for now. I am working on release of my device, which is at the end of this month. I used internal ESP32 memory as filesystem instead of SD card. For now, it is enough for me and the SD card will be enabled later.

Thank you.
Vilem

sure

@khoek
Copy link

khoek commented Jun 11, 2021

@zavovi I have used a logic analyser and found a bug which causes this error if the other device on the SPI bus is in half-duplex mode. See: #7138

Hopefully this could help you.

ducalex added a commit to ducalex/retro-go that referenced this issue Oct 13, 2021
Esp-idf 4.2 finally added shared SPI bus support to the SD card driver and it seems more stable than retro-go's lock system.

Our lock system can't easily be fixed (many others seem to have tried and failed), so I decided to drop support for it.

See: espressif/esp-idf#1597
ducalex added a commit to ducalex/retro-go that referenced this issue Oct 13, 2021
Esp-idf 4.2 finally added shared SPI bus support to the SD card driver and it seems more stable than retro-go's lock system.

Our lock system can't easily be fixed (many others seem to have tried and failed), so I decided to drop support for it.

See: espressif/esp-idf#1597
ducalex added a commit to ducalex/retro-go that referenced this issue Oct 13, 2021
Esp-idf 4.2 finally added shared SPI bus support to the SD card driver and it seems more stable than retro-go's lock system.

Our lock system can't easily be fixed (many others seem to have tried and failed), so I decided to drop support for it.

See: espressif/esp-idf#1597
ducalex added a commit to ducalex/retro-go that referenced this issue Oct 13, 2021
Esp-idf 4.2 finally added shared SPI bus support to the SD card driver and it seems more stable than retro-go's lock system.

Our lock system can't easily be fixed (many others seem to have tried and failed), so I decided to drop support for it.

See: espressif/esp-idf#1597
ducalex added a commit to ducalex/retro-go that referenced this issue Oct 13, 2021
Esp-idf 4.2 finally added shared SPI bus support to the SD card driver and it seems more stable than retro-go's lock system.

Our lock system can't easily be fixed (many others seem to have tried and failed), so I decided to drop support for it.

See: espressif/esp-idf#1597
ducalex added a commit to ducalex/retro-go that referenced this issue Oct 13, 2021
Esp-idf 4.2 finally added shared SPI bus support to the SD card driver and it seems more stable than retro-go's lock system.

Our lock system can't easily be fixed (many others seem to have tried and failed), so I decided to drop support for it.

See: espressif/esp-idf#1597
@taherrera
Copy link

I am writing this so that this does not happen to anyone else.

I was able to read and write on the SD using VFS but some CRC errors appeared when initializing other SPI devices in the same bus such as:

E (12401) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x107
E (12401) diskio_sdmmc: sdmmc_read_blocks failed (263)

I could also see that when the SD card was inserted, the SPI communications somehow collided with the other SPI devices on the same bus. It was as if the SD always answered to SPI although its #CS pin was not asserted. This happened although the SD card was previously mounted as SPI.

The issue is now solved. The problem was the SD card. I was using a random chinatown SD card, changing the SD card did the trick for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests