Skip to main content
Visitor II
May 27, 2024
Question

Using stm32f407 for SDIO reading/writing

  • May 27, 2024
  • 4 replies
  • 4215 views

Has anyone successfully used STM32f407 for reading and writing SD card using SDIO? I tried creating a project with SDIO using stm32f407 with a bit of code from the sample project of FatFS_uSD using (stm32F413). And I keep getting a timeout error from the function SDMMC_GetCmdResp1.

Here's my main code:

 

 

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "fatfs.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef hsd;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
FATFS SDFatFs; /* File system object for SD card logical drive */
FIL MyFile; /* File object */
//char SDPath[4]; /* SD card logical drive path */
static uint8_t buffer[_MAX_SS]; /* a work buffer for the f_mkfs() */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDIO_SD_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */
	FRESULT res; /* FatFs function common result code */
	 uint32_t byteswritten, bytesread; /* File write/read counts */
	 uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */
	 uint8_t rtext[100]; /* File read buffer */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_SDIO_SD_Init();
 /*MX_USART2_UART_Init();
 MX_FATFS_Init();*/
 /* USER CODE BEGIN 2 */
 /*##-1- Link the micro SD disk I/O driver ##################################*/
 if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0)
 {
 /*##-2- Register the file system object to the FatFs module ##############*/
 if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK)
 {
 /* FatFs Initialization Error */
 Error_Handler();
 }
 else
 {
 /*##-3- Create a FAT file system (format) on the logical drive #########*/
 /* WARNING: Formatting the uSD card will delete all content on the device */
 if(f_mkfs((TCHAR const*)SDPath, FM_ANY, 0, buffer, sizeof(buffer)) != FR_OK)
 {
 /* FatFs Format Error */
 Error_Handler();
 }
 else
 {
 /*##-4- Create and Open a new text file object with write access #####*/
 if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
 {
 /* 'STM32.TXT' file Open for write Error */
 Error_Handler();
 }
 else
 {
 /*##-5- Write data to the text file ################################*/
 res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);

 /*##-6- Close the open text file #################################*/
 if (f_close(&MyFile) != FR_OK )
 {
 Error_Handler();
 }

 if((byteswritten == 0) || (res != FR_OK))
 {
 /* 'STM32.TXT' file Write or EOF Error */
 Error_Handler();
 }
 else
 {
 /*##-7- Open the text file object with read access ###############*/
 if(f_open(&MyFile, "STM32.TXT", FA_READ) != FR_OK)
 {
 /* 'STM32.TXT' file Open for read Error */
 Error_Handler();
 }
 else
 {
 /*##-8- Read data from the text file ###########################*/
 res = f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread);

 if((bytesread == 0) || (res != FR_OK))
 {
 /* 'STM32.TXT' file Read or EOF Error */
 Error_Handler();
 }
 else
 {
 /*##-9- Close the open text file #############################*/
 f_close(&MyFile);

 /*##-10- Compare read data with the expected data ############*/
 if((bytesread != byteswritten))
 {
 /* Read data is different from the expected data */
 Error_Handler();
 }
 else
 {
 /* Success of the demo: no error occurrence */
 	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
 }
 }
 }
 }
 }
 }
 }
 }

 /*##-11- Unlink the RAM disk I/O driver ####################################*/
 FATFS_UnLinkDriver(SDPath);
 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Configure the main internal regulator output voltage
 */
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 RCC_OscInitStruct.PLL.PLLM = 16;
 RCC_OscInitStruct.PLL.PLLN = 192;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = 4;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
 {
 Error_Handler();
 }
}

/**
 * @brief SDIO Initialization Function
 * None
 * @retval None
 */
static void MX_SDIO_SD_Init(void)
{

 /* USER CODE BEGIN SDIO_Init 0 */

 /* 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 = 0;
 /* USER CODE BEGIN SDIO_Init 2 */

 /* USER CODE END SDIO_Init 2 */

}

/**
 * @brief USART2 Initialization Function
 * None
 * @retval None
 */
static void MX_USART2_UART_Init(void)
{

 /* USER CODE BEGIN USART2_Init 0 */

 /* USER CODE END USART2_Init 0 */

 /* USER CODE BEGIN USART2_Init 1 */

 /* USER CODE END USART2_Init 1 */
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART2_Init 2 */

 /* USER CODE END USART2_Init 2 */

}

/**
 * @brief GPIO Initialization Function
 * None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOE_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOC_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

 /*Configure GPIO pin : PE7 */
 GPIO_InitStruct.Pin = GPIO_PIN_7;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

 /*Configure GPIO pins : PD14 PD15 */
 GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
 * @brief Reports the name of the source file and the source line number
 * where the assert_param error has occurred.
 * file: pointer to the source file name
 * line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
 /* USER CODE BEGIN 6 */
 /* User can add his own implementation to report the file name and line number,
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

 

 

 Most of the code was generated using STM32CubeIDE, the only thing I borrowed from the sample project is between user code begin and end 2.

 

I'm getting the timeout error (4) from this function SDMMC_CmdBlockLength.

    This topic has been closed for replies.

    4 replies

    Technical Moderator
    May 29, 2024

    Hello @KL_UOA 

    You are missing to call the function HAL_SD_Init() to initialize the SD

    /**
     * @brief SDIO Initialization Function
     * @param None
     * @retval None
     */
    static void MX_SDIO_SD_Init(void)
    {
    
     /* USER CODE BEGIN SDIO_Init 0 */
    
     /* 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_4B;
     hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
     hsd.Init.ClockDiv = 0;
     if (HAL_SD_Init(&hsd) != HAL_OK)
     {
     Error_Handler();
     }
     if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN SDIO_Init 2 */
    
     /* USER CODE END SDIO_Init 2 */
    
    }

     

    KL_UOAAuthor
    Visitor II
    May 31, 2024

    Thanks, FBL, unfortunately, that didn't help, I'm still getting 4 from  errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE). I had no problem with SD_InitCard(hsd); and SD_PowerON(hsd) before that.

    Technical Moderator
    May 31, 2024

    HI @KL_UOA 

    Would you share your project to reproduce on my end?

    KL_UOAAuthor
    Visitor II
    June 5, 2024
    KL_UOAAuthor
    Visitor II
    June 7, 2024

    Hi @FBL ,

     

    Have you got a chance to try the code yet?

     

    Thanks,

    KL_UOAAuthor
    Visitor II
    June 9, 2024

    It's readable if you zoom in. Here's a description:

    The top schematic:

    CS - C11 through a 10K resistor

    D1 - D2 through a 10K resistor

    CLK - C12 through a 10K resistor

    D0 - C8 through a 10K resistor

    RSV1 - C9 through a 10K resistor

    RSV2 - C10 through a 10K resistor

    CD - E7 to 3.3V through a 4K7 resistor

    WP - E8 to 3.3V through a 4K7 resistor

    Bottom Schematic:

    Dat0 - C8 through a 10K resistor

    Dat1 - C9 through a 10K resistor

    Dat2 - C10 through a 10K resistor

    Dat3 - C11 through a 10K resistor

    CLK - C12 through a 10K resistor

    CMD - D2 through a 10K resistor

     

     

     

    Super User
    June 9, 2024

    >It's readable if you zoom in. 

    NO. Try zoom it from the pic here ... !

    +

    But now you wrote some values... ok, this cannot work.

    10k series - how you came to this idea ?? 

    Change all these series resistors to 33...51 ohm , then try again.

    +

    here example sd-card adapter (resolution as in your pic) :)

    AScha3_0-1717915536268.png

    or from STM board (in resolution, as i use on my TFT :(

    AScha3_1-1717915605778.png

    (The EMIF... you dont have, but here are your series resistors 33...51 ohm , or just without,  r=0 .)