cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 - SDIO FAT write problem

Posted on June 21, 2017 at 14:26

Hi community!

To replicate my setup you need:

- discovery (F407)

- Discover - M0 expansion 'shield'

- Sd Card

- download my test project under atollic here (cube mx project included):    

https://uloz.to/!mbYhN53eRdyf/cubemx-sdio-fat-sdkarta-rar

 

In one of my projects i am trying to achieve to save data from mems microphone to .wav on sd card using FAT. It worked, but unfortunately, from time to time, when i try to write new chunk of data into the file, f_write() return me an error (FR_DISK_ERR). 

To find the source of the issue i have made a new project, where i only setup sdio, FAT, push button and a timer that triggers writing of a new chung of dummy data into the sd card (file). (that simulates the stream of data from microphone). The issue occure sometimes on the 3rd write batch (button push), sometimes on 5th, ... It varies. With each new batch i open a new file with incremented number in its name so i can later observe with what number of file did the issie occured.

The procedure goes like this:

Program waits for blue button to be pushed

then program mouts the SD card (f_mount) 

if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK) 

then open a new file

f_open(&MyFile, FilName, FA_CREATE_ALWAYS|FA_WRITE) != FR_OK) new file

then comes the write while loop where i write new chunk of data every 2 ms or so

f_write(&MyFile, u8WriteBuffer, WR_BUFF_SIZE,(void *)&byteswritten);

and after the write of whole batch (2500 chunks of 176 B)  is done, program waits for another button push ...

Can somebody give me some feedback on that? Where could be the problem? Do anyone faced same problem?

Thank you very much

best regards

Jan 

#issue #sdio #stm32f4 #sdcard #fat-fs #sdio-write-data-problem
16 REPLIES 16
Posted on June 30, 2017 at 15:27

Thank you very much. I guess i will have questions later on when i will try to do it. So far i have working project configured using CubeMX sdio + fatfs. I will try to modify that to DMA approach. I guess it will consist only of configuring DMA + changing tohse two functions in 

sd_diskio? 

I am not sure about how to setup the DMA in the correct way. I will enclose snippet from cube mx regarding DMA setup for sdio. Maybe you can advice what options i do need to setup.

0690X00000603v9QAA.jpg

Posted on July 03, 2017 at 11:28

Your configuration is correct, but you need to change both Rx and Tx DMA priority to 'Very High'.

Bests,

Misagh

Posted on August 12, 2017 at 04:14

Hi, I'm using FatFS with microSD and facing the same problem. Here is my observation:

1. The higher SDIO_CK, the more error encounters.

2. All my writing fails happen after a TXUNDERR occur (capture in stm32f4xx_hal_sd.c).

My solution:

1. Re-initialize SDIO interface when writing fail in SD_read/write function (lowlevel of f_write).

2. Do a retry for SD_read/SD_write functions if the first read/write fail.

My test run every 1 second, config uSdHandle.Init.ClockDiv = 3: 

   - Create a file named '0:/test.bin'.

   - Write 1000 buffer, each buffer = 2345 bytes (random data). Calculate CRC32 of buffers.

   - Read file in blocks of 1024 byte each, calculate CRC32.

   - Compare CRC32 values.

I run the test for several minutes with NO error, and the speed is about 450kbyte/s.

Posted on October 23, 2017 at 10:59

Can you tell me how to modify my code to test the read and write speed to mt sd card thorugh stm32f407vg

Posted on October 23, 2017 at 11:17

Read and write large blocks to the media and time it. Use a 32 bit TIM clocking at 1 MHz to get microsecond granularity. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 23, 2017 at 12:24

Hi Clive,

I am reading the data from accelerometer and writing it to the sd card in this way. I didnt exactly understand ur answer exactly, Could you explain a lil bit more in detail??. Using a timer is fine.

uint8_t address=0, data=0;

uint8_t x_acc=0, y_acc=0, z_acc=0;

uint8_t myData[10] = 'Acc Values';

uint8_t recData[3];

DWORD time;

int main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_SDIO_SD_Init();

MX_SPI1_Init();

MX_FATFS_Init();

MX_RTC_Init();

UINT byteCount;

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

address=0x20;

HAL_SPI_Transmit(&hspi1, &address, 1, 50);

data=0x67;

HAL_SPI_Transmit(&hspi1, &data, 1, 50);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

if(f_mount(&SDFatFS, (TCHAR const *) SDPath, 1)==FR_OK)

{

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);

if(f_open(&SDFile, 'sd_acc.txt\0', FA_WRITE | FA_CREATE_ALWAYS) == FR_OK)

{

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);

f_write(&SDFile, myData, 13, &byteCount);

f_close(&SDFile);

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);

}

}

while (1)

{

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

address = 0x29 + 0x80;

HAL_SPI_Transmit(&hspi1, &address, 1, 50);

HAL_SPI_Receive(&hspi1, &x_acc, 1, 50);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

HAL_Delay(10);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

address=0x2B + 0x80;

HAL_SPI_Transmit(&hspi1, &address, 1, 50);

HAL_SPI_Receive(&hspi1, &y_acc, 1, 50);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

HAL_Delay(10);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

address=0x2D + 0x80;

HAL_SPI_Transmit(&hspi1, &address, 1, 50);

HAL_SPI_Receive(&hspi1, &z_acc, 1, 50);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

if(f_mount(&SDFatFS, (TCHAR const *) SDPath, 1)==FR_OK)

{

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);

if(f_open(&SDFile, 'sd_acc.txt\0', FA_WRITE ) == FR_OK)

{

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);

f_lseek(&SDFile,f_size(&SDFile));

time= get_fattime();

f_printf(&SDFile,'\nx axis %u\r\t', x_acc);

f_printf(&SDFile,'y axis %u\r\t', y_acc);

f_printf(&SDFile,'z axis %u\r\t', z_acc);

f_printf(&SDFile,'time %ld\r\n', time);

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);

f_close(&SDFile);

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);

}

}

HAL_Delay(50);

}

}

Posted on October 23, 2017 at 16:15

Opening, writing 13 bytes, and closing a file is not going to be rapid.

For speed you want to buffer and write multiples of 512 bytes, ideally 16 or 32kb. For throughput tests you'd want to write several MB to get a good average.

The SD cards have significant command overhead, and costs of managing 128KB erase block on small or unaligned block transfers.

Measure time as you would with a stopwatch, take the entry time and exit times and delta them.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..