2019-07-22 06:03 AM
Hello,
I'm sorry if this is the wrong section
I'm using STM32CubeMX on custom STM32F407VG
I'm using 1-Bit mode SD card with FatFS middleware (4-Bit didn't work at all)
I'm writing 500-1000 bytes to a txt file every ~30ms
Once the file size is > 2MB I close it and open another txt file
It works fine for few minutes and creates multiple files as well, but sometimes the f_write fails giving a FR_DISK_ERR, when I try to close it it'll give the same error
When I try to write or close again after the previous error it'll give FR_INVALID_OBJECT
Once I see this error only a HW reset of the MCU will solve it
I tried deinit/init of the HAL_SD or FatFS but nothing worked
Attached the code I'm using, this function is currently called every ~100ms with these problems, but the goal is to call it every ~30ms
void PIR_to_SD(char myData[]){
uint8_t status = FR_OK;
//mount SD if it's not already mounted
if(!sd_mount){
status = f_mount(&myFATAFS, SDPath, 0);
if(status != FR_OK){
printf("SD: Failed to mount, status = %d\r\n", status);
return;
}
sd_mount = 1;
}
//create new file if the previous file is closed
if(new_file){
sprintf(fileName, "%s%d%s", myPath, f_number++, format);
printf("filename: %s\r\n", fileName);
status = f_open(&myFILE, fileName, FA_READ | FA_WRITE | FA_OPEN_APPEND);
if(status != FR_OK){
printf("SD: Failed to open file, status = %d\r\n", status);
return;
}
new_file = 0;
}
//write data if file is successfully opened
if(write_flag){
status = f_write(&myFILE, myData, strlen(myData), &testByte);
if(status != FR_OK){
printf("SD: Failed to write data, status = %d\r\n", status);
// write_flag = 0;
}
}
//close file if size>2MB OR f_write had an error
if(f_size(&myFILE) > 2000000 || status != FR_OK || !write_flag){
status = f_close(&myFILE);
if(status != FR_OK){
printf("SD: Failed to close file, status = %d\r\n", status);
}
else{
write_flag = 1;
new_file = 1;
}
}
//none of these worked to solve the problem
/*
if(status != FR_OK){
status = f_mount(0, SDPath, 0);
printf("SD: unmount, status = %d\r\n", status);
sd_mount = 0;
printf("unlink = %d\r\n", FATFS_UnLinkDriver(SDPath));
printf("SD: deinit = %d\r\n", HAL_SD_DeInit(&hsd));
//PD3 is power enable for the SD
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_3);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_3);
printf("SD: init = %d\r\n", HAL_SD_Init(&hsd));
MX_FATFS_Init();
}
*/
}
2019-07-23 10:08 PM
I'm going to write what I found in case someone in the future has the same problem
The problem happens in this function: HAL_SD_WriteBlocks that is being called by FatFS
It gets stuck in a loop till it timeout (Important notice: the default timeout of the caller (FatFs) is very long so be careful if you're using watchdog)
I still didn't know what is the cause of the problem but the way to recover from it:
If f_write returns FR_DISK_ERR call HAL_SD_InitCard function and then f_close the file. However, you'll lose the last 1-2 packets you tried to write to the file
This will make it recover from the error
I still don't know why the error happens in the first place
2021-11-05 08:51 AM
Hi,
I don't know if you solved this, but I faced a similar problem. To work in 4-bit mode you need to decrease the the SDIOCLK, normally 12MHz is ok, in my case this start to work whit 9MHz, but I still goted some errors. With 4,5Mhz I didn't have any more problems
In my case (HCLK = 72MHz and ABP2 = 72MHz) I put SDIOCLK DIV = 14:
SDIOCLK = APB2 / (SDIOCLK DIV + 2)
static void MX_SDIO_SD_Init(void)
{
/* USER CODE BEGIN SDIO_Init 0 */
DEBUG_INIT("Func %s at %s, line %dc\n\r", __FUNCTION__, __FILE__, __LINE__);
/* USER CODE END SDIO_Init 0 */
/* USER CODE BEGIN SDIO_Init 1 */
/* USER CODE END SDIO_Init 1 */
hsd.Instance = SDIO;
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
hsd.Init.ClockDiv = 13;
/* USER CODE BEGIN SDIO_Init 2 */
if(HAL_SD_Init(&hsd) != HAL_OK)
{
Error_Handler();
}
if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
{
Error_Handler();
}
/* USER CODE END SDIO_Init 2 */
}
2021-11-06 11:11 PM
Thank you for your reply
No, we didn't work it out and we've been using 1-bit mode since
I'm going to try your solution later and see if it fixes the problem