SDIO Slave. Sending bug.

alexey91
Posts: 5
Joined: Fri Aug 17, 2018 11:31 am

SDIO Slave. Sending bug.

Postby alexey91 » Wed Aug 29, 2018 2:53 pm

Hello.

I've faced some kind of bug i can't understand whet trying to send data from SDIO Slave.
I use 4 bit bus and CLK freq is 400kHz.
As i read from docs, buffer for sending have to be 4-byte alligned and DMA accessable. I create it like that

Code: Select all

uint8_t * dataBuf = heap_caps_malloc(600, MALLOC_CAP_DMA | MALLOC_CAP_32BIT); 
Then i send to send queue some areas of this allocated buffer.

Code: Select all

ret = sdio_slave_send_queue(&(dataBuf[100]), 100, &(dataBuf[100]), 0);
if(ret != ESP_OK) {
	printf("failed to send buf 1, errcode = %d\n", ret);
}
ret = sdio_slave_send_queue(&(dataBuf[200]), 100, &(dataBuf[200]), 0);
if(ret != ESP_OK) {
	printf("failed to send buf 2, errcode = %d\n", ret);
}
ret = sdio_slave_send_queue(&(dataBuf[300]), 100, &(dataBuf[300]), 0);
if(ret != ESP_OK) {
	printf("failed to send buf 3, errcode = %d\n", ret);
}
But if my buffer area crosses with addresses 0x3FFB5A6C - 0x3FFB5ABC, then SDIO Slave driver sends rubbish. While SDIO Host clocks all (100 * 2 + 16) ticks for 100 bytes, but slave sets data for less bytes, and send some zeros. With other buffers driver works fine.

In my case 0x3FFB5A6C is address of dataBuf[200], so second buffer area fails to be sent.
dataBuf[100-199] == 0xC3
dataBuf[200-299] == 0xF0
dataBuf[300-399] == 0xA5
i attached LA file for this case, hope bookmarks will not dissapear.

Moving 100 byte sending interval in allocated buffer i've found area (0x3FFB5A6C - 0x3FFB5ABC), that caused problems. If my send buffer touches this area by any address, sendind will be corrupted.

I also tried that on my second esp32 board with same result.

So, what that can be? Is that problem of DMA or SDIO Slave driver or silicon limitations? Are there some more areas like that?

I also attached sourse file, based on standard exanple, that i used while faced that issue.

Thanks,
alexey.
Attachments
app_main.c
sourse file
(12.72 KiB) Downloaded 721 times
SDIO_Slave_bugged_Addr.zip
logic analyzer for corrupted transaction
(17.79 KiB) Downloaded 364 times

alexey91
Posts: 5
Joined: Fri Aug 17, 2018 11:31 am

Re: SDIO Slave. Sending bug.

Postby alexey91 » Thu Aug 30, 2018 7:32 am

Hello.

A little update for my problem. I tried to send other buffers and found, that this sending bug affected by content of buffer, not by addres. If my buffer filled with bytes, where one half of byte == 0xF, and another part have only one set bit or none (i meam bytes: 0x0F, 0x1F, 0x2F, 0x4F, 0x8F, 0xF0, 0xF1, 0xF2, 0xF4 and 0xF8), then SDIO Slave sendind will be corrupted.

So this problem doesnot caused by allocator or DMA access. But anyway i need to know how to understand this to avoid thi failture in my application.

Thanks,
alexey.

ESP_michael
Posts: 37
Joined: Mon Aug 28, 2017 10:25 am

Re: SDIO Slave. Sending bug.

Postby ESP_michael » Fri Aug 31, 2018 5:21 am

Hi alexey,

I think this doesn't make sure all your transactions are done:

while(ESP_ERR_TIMEOUT == sdio_slave_send_get_finished(&tst, 0)){};

The driver needs you to keep the buffer until the sending is finished, so you have to check every one of them is finished or not.

1. To check whether is caused by this issue, you can add a infinite loop (while(1){}) before the free(dataBuf) to avoid touching to the buffer.

2. If the problem is as guessed, suggest to use a counter or something to record whether all your transactions are done. (or you can use the arg parameter to tag the last transaction!) you may set the wait argument to portMAX_DELAY to wait forever.

Please let me know if there's still problems.

alexey91
Posts: 5
Joined: Fri Aug 17, 2018 11:31 am

Re: SDIO Slave. Sending bug.

Postby alexey91 » Fri Aug 31, 2018 7:20 am

Hi, xiaoxufeng.

Thanks for reply.

I moved buffer allocation to main, and never free it. And it still failed to send buffer filled with values 0x0F, 0x1F, 0x2F, 0x4F, 0x8F, 0xF0, 0xF1, 0xF2, 0xF4 or 0xF8.

I also tried to make this buffer static,

Code: Select all

DMA_ATTR static uint8_t dataBuf[1200];
but that also have no effect. So, this problem caused definitely not by early buffer memory release.

Other thing i found, that sending buffer filled with these values drops some data, here is example.

Code: Select all

DMA_ATTR static uint8_t dataBuf[20];

for(i = 0; i < 8; i++) {
    dataBuf[i] = 0x0F;
}
for(i = 8; i < 20; i++) {
    dataBuf[i] = 0x9F;
}
ret = sdio_slave_send_queue(dataBuf, 20, dataBuf, 0);
while(1) {};
but sending i see on LA is (i write half bytes by 4 SDIO lines)

Code: Select all

  0   1   2   3   4   5   6
0 F 0 F 0 F 0 F 0 F 0 F 0 F 0 9 F 9 F 9 F 9 F 9 F 9 F 9 F 9 F 9 F 9 F 9 F 9 F 
                              ^
This point somehting happened, F is dropped. Host got CRC error
If i change buffer filling with other values, it works ok.

Do you have any ideas, what can it be?

Thanks,
alexey.

Who is online

Users browsing this forum: No registered users and 274 guests