SDIO slave. How to change timings?
SDIO slave. How to change timings?
Hi,
I'm tryimg to connect ESP32 (ESP-WROOM-32 module) via SDIO to STM32F4 uC, ESP32 should be a slave. First i've tried SDIO host-slave example, included in esp-idf, using 2 identical esp32 modules, it works almost fine(get timeout error somewhere in middle of transaction cycle). Then i tried to connect to ESP from stm32 host, but no success at all. I watched SDIO lines with logic analyzer on esp32-esp32 configuration and stm32-esp32, and found, that stm32 uses timing mode sample/drive on rising CLK edge, but esp32 uses sample/drive on falling CLK edge.
As i searched stm32 reference manual, stm32 not able to change this timings to sample/drive on falling CLK edge. But i found that esp32 can do that in SDIO slave periph. In 2.4 Strapping Pins section of ESP32 datasheet it said, that i can configure sample/drive timings by pulling MTDO and GPIO5 pins. Also i found in ESP32 Tech reference 8.3.6 SDIO Bus Timing that i can configure these timings by changing some bitfields by software. After searching esp-idf source files i found that sdio_slave_timing_t enum used for that in function sdio_slave_hw_init() from sdio_slave.c file.
I've tried both these ways to set sample/drive timings to rising edge on ESP32 SDIO slave, but still no response for stm32 request.
After that i've build esp32-esp32 stand again, uploaded sdio-host and sdio-slave examples to both boards and checked if that example works with wrong timings setup in sdio-slave (sample on rising edge is wrong due to sdio-host drive cmd line on falling edge). And it looks like these changes have no effect, example continue to work as it worked before any changes.
So, my question is, how can i change sampling/driving lines to rising edge in sdio-salve? Or is it even possible?
Thanks,
alexey.
I'm tryimg to connect ESP32 (ESP-WROOM-32 module) via SDIO to STM32F4 uC, ESP32 should be a slave. First i've tried SDIO host-slave example, included in esp-idf, using 2 identical esp32 modules, it works almost fine(get timeout error somewhere in middle of transaction cycle). Then i tried to connect to ESP from stm32 host, but no success at all. I watched SDIO lines with logic analyzer on esp32-esp32 configuration and stm32-esp32, and found, that stm32 uses timing mode sample/drive on rising CLK edge, but esp32 uses sample/drive on falling CLK edge.
As i searched stm32 reference manual, stm32 not able to change this timings to sample/drive on falling CLK edge. But i found that esp32 can do that in SDIO slave periph. In 2.4 Strapping Pins section of ESP32 datasheet it said, that i can configure sample/drive timings by pulling MTDO and GPIO5 pins. Also i found in ESP32 Tech reference 8.3.6 SDIO Bus Timing that i can configure these timings by changing some bitfields by software. After searching esp-idf source files i found that sdio_slave_timing_t enum used for that in function sdio_slave_hw_init() from sdio_slave.c file.
I've tried both these ways to set sample/drive timings to rising edge on ESP32 SDIO slave, but still no response for stm32 request.
After that i've build esp32-esp32 stand again, uploaded sdio-host and sdio-slave examples to both boards and checked if that example works with wrong timings setup in sdio-slave (sample on rising edge is wrong due to sdio-host drive cmd line on falling edge). And it looks like these changes have no effect, example continue to work as it worked before any changes.
So, my question is, how can i change sampling/driving lines to rising edge in sdio-salve? Or is it even possible?
Thanks,
alexey.
- Attachments
-
- stm32 as host timings
- stm32-esp32.jpg (109.55 KiB) Viewed 12785 times
-
- esp32 as host timings
- esp32-esp32.jpg (116.33 KiB) Viewed 12785 times
-
- Posts: 37
- Joined: Mon Aug 28, 2017 10:25 am
Re: SDIO slave. How to change timings?
Hello Alexy,
1. Firstly, yes, you are right, the SD protocol requires timing of:
DS mode:
launch: negtive edge, latch: postive edge
HS mode:
launch: postive edge, latch: postive edge
If your esp32 launches data at HS mode, it's obviously wrong.
BTW, our host cannot launch data at negtive edge now, and our slave can be configured to only one of them (edge controlled by speed mode detected automatically is not available).
2. About the relations of strapping pins and the driver
When the esp32 start up, the SDIO register is automatically set according to the boot strapping pins as an initial value. This value is kept until modified manually. So the value is at least used by the bootloader.
However, the driver will configure the timing register acoording to sdio_slave_timing_t as you see. So the SDIO slave in application is using the timing configuration in sdio_slave_timing_t. Please ignore the boot strapping pins in your application.
3. We've changed the driver default value in latest version of ESP-IDF from SDIO_SLAVE_TIMING_NSEND_PSAMPLE to SDIO_SLAVE_TIMING_PSEND_PSAMPLE to match the protocol requirements. We also fix an issue for DAT3 timing. Please update the IDF and use logic analyzer to capture the data on the bus again to check if your configuration is right again. If your wiring from STM32 is not good enough (Don't forget to connect the ground!), maybe you can try SDIO_SLAVE_TIMING_PSEND_NSAMPLE.
In the latest version, more document about compabilities are added, maybe you can get more clues there.
4. Please check that all 6 lines (CMD, CLK, DAT0-3) are all pulled up even if not used (in 1-bit mode). DAT3 is used to select the SPI mode or the SD mode. Moreover, if DAT1/2 lines are not correctly pulled-up, some strange issues exist.
If you still have problem, please provide your IDF commit (SHA1) for us to help you. Better if your code and LA capture file is attached. Make sure your slave driver is configured to PSEND PSAMPLE before you do this. We can download your software so don't worry about it.
1. Firstly, yes, you are right, the SD protocol requires timing of:
DS mode:
launch: negtive edge, latch: postive edge
HS mode:
launch: postive edge, latch: postive edge
If your esp32 launches data at HS mode, it's obviously wrong.
BTW, our host cannot launch data at negtive edge now, and our slave can be configured to only one of them (edge controlled by speed mode detected automatically is not available).
2. About the relations of strapping pins and the driver
When the esp32 start up, the SDIO register is automatically set according to the boot strapping pins as an initial value. This value is kept until modified manually. So the value is at least used by the bootloader.
However, the driver will configure the timing register acoording to sdio_slave_timing_t as you see. So the SDIO slave in application is using the timing configuration in sdio_slave_timing_t. Please ignore the boot strapping pins in your application.
3. We've changed the driver default value in latest version of ESP-IDF from SDIO_SLAVE_TIMING_NSEND_PSAMPLE to SDIO_SLAVE_TIMING_PSEND_PSAMPLE to match the protocol requirements. We also fix an issue for DAT3 timing. Please update the IDF and use logic analyzer to capture the data on the bus again to check if your configuration is right again. If your wiring from STM32 is not good enough (Don't forget to connect the ground!), maybe you can try SDIO_SLAVE_TIMING_PSEND_NSAMPLE.
In the latest version, more document about compabilities are added, maybe you can get more clues there.
4. Please check that all 6 lines (CMD, CLK, DAT0-3) are all pulled up even if not used (in 1-bit mode). DAT3 is used to select the SPI mode or the SD mode. Moreover, if DAT1/2 lines are not correctly pulled-up, some strange issues exist.
If you still have problem, please provide your IDF commit (SHA1) for us to help you. Better if your code and LA capture file is attached. Make sure your slave driver is configured to PSEND PSAMPLE before you do this. We can download your software so don't worry about it.
-
- Posts: 37
- Joined: Mon Aug 28, 2017 10:25 am
Re: SDIO slave. How to change timings?
Hi Alexy,
One more thing, the delay from CLK posedge to data stable time is about 12.5ns from my test (PSEND), which is over half a clock of 50MHz (HS mode). This is possibly why you think the data is given at negedge. You can try again in DS mode or even slower.
The protocol allows 14ns after the posedge in HS mode.
If your host cannot receive the data, maybe you can try NSEND modes.
One more thing, the delay from CLK posedge to data stable time is about 12.5ns from my test (PSEND), which is over half a clock of 50MHz (HS mode). This is possibly why you think the data is given at negedge. You can try again in DS mode or even slower.
The protocol allows 14ns after the posedge in HS mode.
If your host cannot receive the data, maybe you can try NSEND modes.
Re: SDIO slave. How to change timings?
Hi xiaoxufeng.
Thanks for your reply.
I have updated esp-idf package to the latest version and sdio_slave_timing_t settings started to affect connection in default example. Default value is SDIO_SLAVE_TIMING_PSEND_PSAMPLE, i have changed it to oposite SDIO_SLAVE_TIMING_NSEND_NSAMPLE, and example continue to work. I cannot undersand how this is possible. I see on LA that slave sending timing changed to data valid on rising edge, but example works as before.
Newertheless my connection stm32 - esp32 slave by sdio started to work, after updating and setting SDIO_SLAVE_TIMING_NSEND_NSAMPLE.
Also seems i have misundersatanding about these sdio_slave_timing_t constants. *_NSEND_* sounds like it will set valid data on falling edge of clk, but it works opposite. I can't see receiving process, but i suppose, that *_NSAMPLE means that host data is valid on rising clk edge. Am i right?
Also my CLK frequency is 400 kHz for now, while test stand is made with 10cm wires for sdio, so data stabilisation time should not be a fatal problem.
Thanks,
alexey.
Thanks for your reply.
I have updated esp-idf package to the latest version and sdio_slave_timing_t settings started to affect connection in default example. Default value is SDIO_SLAVE_TIMING_PSEND_PSAMPLE, i have changed it to oposite SDIO_SLAVE_TIMING_NSEND_NSAMPLE, and example continue to work. I cannot undersand how this is possible. I see on LA that slave sending timing changed to data valid on rising edge, but example works as before.
Newertheless my connection stm32 - esp32 slave by sdio started to work, after updating and setting SDIO_SLAVE_TIMING_NSEND_NSAMPLE.
Also seems i have misundersatanding about these sdio_slave_timing_t constants. *_NSEND_* sounds like it will set valid data on falling edge of clk, but it works opposite. I can't see receiving process, but i suppose, that *_NSAMPLE means that host data is valid on rising clk edge. Am i right?
Also my CLK frequency is 400 kHz for now, while test stand is made with 10cm wires for sdio, so data stabilisation time should not be a fatal problem.
Thanks,
alexey.
-
- Posts: 37
- Joined: Mon Aug 28, 2017 10:25 am
Re: SDIO slave. How to change timings?
Hi Alexy,
I've just tested on my board again and found no problem: the slave data output right in 10-12.5ns after the launch edge set (posedge if PSEND and negedge if NSEND) at 400KHz.
Your problem may be: the hold time requirement is not meet on either side:
host->slave side,
I saw esp32 host output data right in 5ns after the launch edge, if your host is faster, or the data line is much shorter, the timing may be violated.
slave->host side,
just as I said, the slave output data in 10-12.5 ns. Does your host has a hold time requirement longer than 10ns?
To check how this comes, maybe you can provide us a LA capture file so that we can find out timeout happen on which side (host or slave) and check whether the timing is violated. The sample rate should be as high as possible so that we can have higher resolution about the delay time (I'm using 400MHz). Testing code is strongly recommended to be provided.
Or another possible reason, the command sent from STM32 host is not compatible with our slave. If this is the case, please provide LA file for us to analysis. Or you can check whether you missed any steps of the standard SDIO initialization process.
Michael
I've just tested on my board again and found no problem: the slave data output right in 10-12.5ns after the launch edge set (posedge if PSEND and negedge if NSEND) at 400KHz.
Your problem may be: the hold time requirement is not meet on either side:
host->slave side,
I saw esp32 host output data right in 5ns after the launch edge, if your host is faster, or the data line is much shorter, the timing may be violated.
slave->host side,
just as I said, the slave output data in 10-12.5 ns. Does your host has a hold time requirement longer than 10ns?
To check how this comes, maybe you can provide us a LA capture file so that we can find out timeout happen on which side (host or slave) and check whether the timing is violated. The sample rate should be as high as possible so that we can have higher resolution about the delay time (I'm using 400MHz). Testing code is strongly recommended to be provided.
Or another possible reason, the command sent from STM32 host is not compatible with our slave. If this is the case, please provide LA file for us to analysis. Or you can check whether you missed any steps of the standard SDIO initialization process.
Michael
Re: SDIO slave. How to change timings?
Hi to all.
Sdio slave->host really work abnormal. I got standart example and some modified:
My buffer
when I send 8 and 16 bytes (depend to freq 24 or 16MHz) all ok, but when I send
more than 16 bytes - data is corrupted and error is occuried.
I think that hardware or low level has error.
Sdio slave->host really work abnormal. I got standart example and some modified:
- void loop() {
- esp_err_t ret;
- //receive data and send back to host.
- size_t length_rx;
- uint8_t *ptr;
- //set_irq(0);
- const TickType_t non_blocking = 0;
- ret = sdio_slave_recv(&handle_rx, &ptr, &length_rx, non_blocking);
- if (ret == ESP_OK) {
- ///wifi_tx(ptr, length_rx); //BUF->AIR
- for (int i=0;i<length_rx;i++) Serial.print(ptr[i]);
- Serial.println();
- if (sdio_debug) Serial.println("SDIO= slave recv OK");
- /* If buffer is no longer used, call sdio_slave_recv_load_buf to return it here. Since we wants to show how
- * to share large buffers between drivers here (we share between sending and receiving), keep the buffer
- * until the buffer is sent by sending driver.
- */
- esp_err_t err;
- //err = sdio_slave_send_get_finished(NULL, portMAX_DELAY);
- //if (err == ESP_OK)
- err = sdio_slave_send_queue(bf, 32, NULL, portMAX_DELAY);
- DMA_ATTR uint8_t bf[256]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
more than 16 bytes - data is corrupted and error is occuried.
I think that hardware or low level has error.
- Attachments
-
- SNIFFER.JPG (139.31 KiB) Viewed 11901 times
-
- IAR.JPG (203.83 KiB) Viewed 11901 times
-
- Posts: 37
- Joined: Mon Aug 28, 2017 10:25 am
Re: SDIO slave. How to change timings?
Hi DiEitch,
Can you check whether your SDIO can work in 1-bit? (note, all the pullups should be left as-is, i.e. D1-D3 should be kept high if not used)
Seen from the picture, the slave may ignore one of the clocks. This is possible to be caused by the SSN when all the data lines changed from 1-0 or 0-1. This is move possible to happen in 4-bit mode.
If this is the reason, please add more grounding wires between the host chip and the slave. (slow down the frequency may not help)
Besides, can you show me the address you sent to the slave in CMD53 when you are reading 32 bytes? The slave only outputs a specified length of data according to the address.
Michael.
Can you check whether your SDIO can work in 1-bit? (note, all the pullups should be left as-is, i.e. D1-D3 should be kept high if not used)
Seen from the picture, the slave may ignore one of the clocks. This is possible to be caused by the SSN when all the data lines changed from 1-0 or 0-1. This is move possible to happen in 4-bit mode.
If this is the reason, please add more grounding wires between the host chip and the slave. (slow down the frequency may not help)
Besides, can you show me the address you sent to the slave in CMD53 when you are reading 32 bytes? The slave only outputs a specified length of data according to the address.
Michael.
Re: SDIO slave. How to change timings?
Hallo.
In 1bit mode its work ok!
With the best regards.
In 1bit mode its work ok!
With the best regards.
Re: SDIO slave. How to change timings?
About my fifo rx function:
Code: Select all
int esp32_sdio_rd_fifo(void)
{
int ret;
u16 sz;
ret = esp32_sdio_get_pktlen(&sz); //OK
if (ret<0) ud_add(uD_Halt);
if (ret<0) return ret;
ret = sdio_memcpy_fromio(&sdio0, buf81, FIFO_ADDR-sz, sz);
if (ret<0) ud_add(uD_Halt);
if (ret<0) return ret;
return ret;
}
Re: SDIO slave. How to change timings?
Hallo Michael.xiaoxufeng wrote: ↑Thu May 23, 2019 5:26 amHi DiEitch,
...
Seen from the picture, the slave may ignore one of the clocks. This is possible to be caused by the SSN when all the data lines changed from 1-0 or 0-1. This is move possible to happen in 4-bit mode.
...
Michael.
About GND, I tried to add conductors, but no changed anything...
I compared the host and the slave transaction (16 bytes 0x0...0xF).
You was right: missed 1 clock and 0xF data!
Instead byte15/tetrade2 slave begin to send CRC.
How to fix it?
With the best regards.
- Attachments
-
- stm32send16okrcverr.JPG (220.44 KiB) Viewed 11614 times
Who is online
Users browsing this forum: No registered users and 95 guests