cancel
Showing results for 
Search instead for 
Did you mean: 

f_open not working properly

Rsrma.1
Associate III

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;
		}

1 ACCEPTED SOLUTION

Accepted Solutions

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.

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

View solution in original post

6 REPLIES 6

How large is the card you're attempting to read?​ Over 32GB? Does Windows report in properties that it uses EXFAT ?

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

No, It's a 16GB sandisk SD card. I've formatted it with FAT32.

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.

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

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?

Rsrma.1
Associate III

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.

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.

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