cancel
Showing results for 
Search instead for 
Did you mean: 

Attempting to read/write to SD card via SDIO on STM32F

RRayb
Associate II

I'm trying to read and write to a microSD card using this reader from sparkfun https://www.sparkfun.com/products/12941 and a nucleo board with a STM32F429ZIT6U MCU via SDIO interface. I created the project through CubeMX V 4.21 (I used the most current version 5.2 at first and ran into issues then saw some forums that said 4.21 was more stable). SDIO and FatFs middle ware were enabled in CubeMx and well as LED1 and LED2 (PB0 and PB7). I got the program from and followed these series of videos for the main.c code https://www.youtube.com/watch?v=Y5UMTGQDmog and https://www.youtube.com/watch?v=0NbBem8U80Y&t=218s. Here's a snip of main.c

/* USER CODE BEGIN 0 */
//define global variables
FATFS myFATFAS;
FIL myFILE;
UINT testByte;
 
/* USER CODE END 0 */
 
int main(void)
{
 
  /* USER CODE BEGIN 1 */
 
  /* 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_FATFS_Init();
 
  /* USER CODE BEGIN 2 */
  if(f_mount(&myFATFAS, SD_Path, 1) == FR_OK){
         	  HAL_GPIO_TogglePin (GPIOB, GPIO_PIN_0); //toggle green LED
         	  char myPath[] = "WRITE2.txt\0"; //creates file
         	  f_open(&myFILE , myPath, FA_WRITE | FA_CREATE_ALWAYS);
         	  char myData[] = "HELLO WORLD\0"; //data that is writen to file
         	  f_write(&myFILE, myData, sizeof(myData), &testByte);
         	  f_close(&myFILE);
         	  HAL_Delay(1000);
         	  HAL_GPIO_TogglePin (GPIOB, GPIO_PIN_0); //toggle green LED
      }
 
   else{
  	HAL_GPIO_TogglePin (GPIOB, GPIO_PIN_7); //toggle blue LED if not mounting
  	HAL_Delay(1000);
       }

When I run my code in True studio f_mount doesn't work. More specifically res = find_volume(&fs, &path, 0) in ff.c line 2511 doesn't return FR_OK. I've attached the VCC and ground wires to 3.3V and ground on my board and DO, SCK,and DI to PC_8, PC_12, and PD_2 respectively. 0690X000008AvtzQAC.pngThe micro SD card is formatted to FAT32. No files are created on my MicroSD card and I've no idea what I'm doing wrong.

5 REPLIES 5

So going to learn nothing from top-level code.

Used these same adapters wired in 4-bit mode on NUCLEO-144 boards.

They lack pull-up resistors, so going to be more dependent on pin configurations.

Make sure library code is not trying to switch to 4-bit mode.

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

From stepping through the code for f_mount ,it eventually calls HAL_SD_ReadBlocks in stm32fxx_hal_sd.c and returns HAL_SD_ERROR_ADDR_OUT_OF_RANGE which eventually returns FR_DISK_ERR to f_mount. Here's a snip for that code from stm32fxx_hal_sd.c.

HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
{
  SDIO_DataInitTypeDef config;
  uint32_t errorstate = HAL_SD_ERROR_NONE;
  uint32_t tickstart = HAL_GetTick();
  uint32_t count = 0U, *tempbuff = (uint32_t *)pData;
  
  if(NULL == pData)
  {
    hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
    return HAL_ERROR;
  }
 
  if(hsd->State == HAL_SD_STATE_READY)
  {
    hsd->ErrorCode = HAL_DMA_ERROR_NONE;
    
    if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
    {
      hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
      return HAL_ERROR;
    }

So putting a 10k Ohm pull up resistor on all the pins will help? I'm not sure what you mean by its going to be more dependent on pin configuration. I set the SDIO pins on CubeMX to 1bit mode when generating the code. Where in the library code would it try to switch to 4 bit mode?

>>I'm not sure what you mean by its going to be more dependent on pin configuration.

Well for starters whether the code selects internal pull-ups on the pins, and the drive speed (slew rate) settings of the pins. Likely buried in the CubeMX MSP code.

>>HAL_SD_ReadBlocks in stm32fxx_hal_sd.c and returns HAL_SD_ERROR_ADDR_OUT_OF_RANGE 

What BlockAdd is being requested? Is it actually within the scope of the media, or a value FatFs has read from another structure containing some bogus data. What value is in SdCard.LogBlockNbr?

>>Where in the library code would it try to switch to 4 bit mode?

Depends on the driver versions and family, I'd look at and around the code calling HAL_SD_Init() and the HAL function itself. Frequently in BSP code.

 uSdHandle.Init.BusWide       = SDMMC_BUS_WIDE_4B;

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

>>In stm32f4xx_hal_msp.c I found the following function: by changing the .pulls to GPIO_PuPd_UP it effectively is like putting a pull up resistor on that pin correct?

void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
 
  GPIO_InitTypeDef GPIO_InitStruct;
  if(hsd->Instance==SDIO)
  {
  /* USER CODE BEGIN SDIO_MspInit 0 */
 
  /* USER CODE END SDIO_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_SDIO_CLK_ENABLE();
  
    /**SDIO GPIO Configuration    
    PC8     ------> SDIO_D0
    PC12     ------> SDIO_CK
    PD2     ------> SDIO_CMD 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
  /* USER CODE BEGIN SDIO_MspInit 1 */
 
  /* USER CODE END SDIO_MspInit 1 */
  }

>>Both BlockAdd and hsd->SdCard.LogBlockNbr are 0. It looks like HAL_SD_GetCardCSD should set LogBlockNbr but after putting a break point on this function my code never stops there and I'm not sure where it should be called.

>> hsd->SdCard.init.buswide is also 0 when I think it should be 1. It looks like the function BSP_SD_Init from from bsd_driver_sd.c should set it since there's code there to set it to 4 bit mode and is missing a 1bit mode.

uint8_t BSP_SD_Init(void)
{
  uint8_t sd_state = MSD_OK;
  /* Check if the SD card is plugged in the slot */
  if (BSP_SD_IsDetected() != SD_PRESENT)
  {
    return MSD_ERROR;
  }
  /* HAL SD initialization */
  sd_state = HAL_SD_Init(&hsd);
#ifdef BUS_4BITS
  /* Configure SD Bus width */
  if (sd_state == MSD_OK)
  {
    /* Enable wide operation */
    if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
    {
      sd_state = MSD_ERROR;
    }
  }
#endif
  return sd_state;
}

>>...effectively is like putting a pull up resistor on that pin correct?

Yes

>>...is missing a 1bit mode.

I think it's already in 1-bit mode

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