2020-09-29 12:57 AM
Hii everyone,
I'm using stm32f4 discovery board and its header board which consist sd card interface in it. I'm using cubeIDE to generate code for 1-bit mode SDIO interfacing using DMA. But the problem is at f_open instruction while debugging step by step its working normally means it return value is zero but if I skip that and If I jump to directly new line it return value is 13. I unable to understand what causing this problem?
Below I'm including code snippet of clock configuration
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
SDIO_SD_Init
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 = 7;
DMA Init
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
/* DMA2_Stream3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
/* DMA2_Stream6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
and main code
uint8_t sd_state = BSP_SD_Init();
uint8_t file_state;
if(sd_state != MSD_OK)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
*uc_status= sd_state;
return;
}
file_state = f_mount(&SDFatFS, (TCHAR const*)SDPath, 0);
if(file_state != FR_OK)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
*uc_status=file_state;
}
// char curr_time_str[20];
// time_t curr_time = get_current_time();
// itoa(curr_time, curr_time_str, 10);
//file_state = f_open(&SDFile, strcat(curr_time_str, ".LOG"), FA_WRITE | FA_CREATE_ALWAYS);
HAL_Delay(1000);
file_state = f_open(&SDFile, "/sd20.txt", FA_WRITE | FA_CREATE_ALWAYS);
if (file_state != FR_OK)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
*uc_status=file_state;
}
HAL_Delay(1000);
file_state = fprintf(&SDFile,"%d",1234);
if(file_state == -1)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
*uc_status=file_state;
}
HAL_Delay(1000);
file_state = f_close(&SDFile);
if (file_state != FR_OK)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
*uc_status=file_state;
}
Solved! Go to Solution.
2020-09-29 11:07 PM
There are interdependencies on the AHB/APB2 vs PLLQ clocks, and the PLL needs to be running to clock the SDIO on the card side. This clock can be upto 75 MHz, although that's not viable for CRYP/USB. The Bypass mode has errata (hence ST suggesting 75 vs 48 MHz as a remedy), and Flow Control needs to be disabled. All MicroSD should be rated to 50 MHz, the 75 MHz gets a card clock of 37.5 MHz. Wiring and termination must be considered to achieve maximal rates to the card.
2020-09-29 01:05 AM
How large is the card you're attempting to read? Over 32GB? Does Windows report in properties that it uses EXFAT ?
2020-09-29 02:15 AM
No, It's a 16GB sandisk SD card. I've formatted it with FAT32.
2020-09-29 05:10 AM
The fprintf() here is probably not going to work, use sprintf() and f_write().
I would recommend instrumenting the DISKIO layer to understand if and how that fails. Validate that the read/write to the media work properly and the timing of the SDIO is correct/suitable.
2020-09-29 05:16 AM
Yeah, I changed it to f_write and it's working for 1-bit mode but in 4-bit mode f_open returning error code 1(lower level disk error). I unable to get your point, timing of SDIO is correct/suitable. Can you please tell me some more about this?
2020-09-29 10:38 PM
Hi clive,
I've figured out what exactly the problem. I've prepared a cheat sheet which is nothing but a theory which has to be read clearly.
When I'm using HSI as a clock source and and configured clock frequency 48MHz(which is maximum in this case) then clock division factor should be greater than 1
hsd.Init.ClockDiv = 2;
If you're using HSE as a clock source, and configured clock frequency 48MHz then clock division factor should be 14 till 7 it will not work.
hsd.Init.ClockDiv = 14
As per datasheet it should be at least 3 but I found this is true when your clock frequency is 24MHz.
I think this can help others, configuring these values in their code.
2020-09-29 11:07 PM
There are interdependencies on the AHB/APB2 vs PLLQ clocks, and the PLL needs to be running to clock the SDIO on the card side. This clock can be upto 75 MHz, although that's not viable for CRYP/USB. The Bypass mode has errata (hence ST suggesting 75 vs 48 MHz as a remedy), and Flow Control needs to be disabled. All MicroSD should be rated to 50 MHz, the 75 MHz gets a card clock of 37.5 MHz. Wiring and termination must be considered to achieve maximal rates to the card.