cancel
Showing results for 
Search instead for 
Did you mean: 

µSD FATFS mount error (FR_NOT_READY)

AAit.1
Associate

I'm actually trying to write on a µSD card with a STM32L486QGI6.

The function f_mount() returns FR_NOT_READY whether the µSD is placed or not...

I already checked dozens of tutorials and examples for CubeMX generation (Checked the pins, the SD_Detect in pull-down, Pull-Ups for the other pins except CK, global interrupts, Clock of 40MHz divided by 4, etc...)

There is my code and the CubeMX configurations :

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "fatfs.h"
#include <string.h>
 
/* USER CODE BEGIN PV */
FRESULT testing;
FRESULT res;                                 
/* USER CODE END PV */
int main(void)
{
  /* USER CODE BEGIN 1 */
    uint32_t byteswritten, bytesread;                /* File write/read counts */
    uint8_t wtext[] = "STM32 FATFS works great!";    /* File write buffer */
    uint8_t rtext[_MAX_SS];                          /* 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_DMA_Init();
  MX_SDMMC1_SD_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */ 
    res = f_mount(&SDFatFS, (const TCHAR *)SDPath, 1);
    const TCHAR tt[]="STM32.txt";
    testing = f_open(&SDFile, tt, FA_CREATE_ALWAYS | FA_WRITE);
    res = f_write(&SDFile, wtext, strlen((char *)wtext), (void *)&byteswritten);
    f_close(&SDFile);
  /* 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 SDMMC1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SDMMC1_SD_Init(void)
{
 
  /* USER CODE BEGIN SDMMC1_Init 0 */
 
  /* USER CODE END SDMMC1_Init 0 */
 
  /* USER CODE BEGIN SDMMC1_Init 1 */
 
  /* USER CODE END SDMMC1_Init 1 */
  hsd1.Instance = SDMMC1;
  hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
  hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
  hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
  hsd1.Init.ClockDiv = 4;
  /* USER CODE BEGIN SDMMC1_Init 2 */
  /* USER CODE END SDMMC1_Init 2 */
}
 
/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA2_Channel4_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Channel4_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA2_Channel4_IRQn);
  /* DMA2_Channel5_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Channel5_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA2_Channel5_IRQn);
 
}
 
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  HAL_PWREx_EnableVddIO2();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1|GPIO_PIN_0, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
 
  /*Configure GPIO pins : PE1 PE2 PE0 */
  GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
 
  /*Configure GPIO pin : SD_DETECT_Pin */
  GPIO_InitStruct.Pin = SD_DETECT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(SD_DETECT_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : PB12 */
  GPIO_InitStruct.Pin = GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
}

0693W00000BbutoQAB.png0693W00000BbutyQAB.png0693W00000BbuuwQAB.png0693W00000BbuurQAB.png0693W00000BburAQAR.png0693W00000BbuumQAB.png0693W00000BbuucQAB.png0693W00000BbuuXQAR.png0693W00000BbuuNQAR.png0693W00000BbuuIQAR.png

1 REPLY 1

Check what the state of PC13 (SD_DETECT) actually IS

Typically the sockets have this as a switch to ground, with a pull-up, so it reads high when no card is present,and low when there is.

Write that code, and have it check it prior to trying to mount. Perhaps instrument the DISKIO level routines to see where it checks and reports if it's ready or not, and that the card has actually been initialized.

Check where its physically calling the HAL_SD_Init() function, and the MSP routines below it. If the interface/peripheral is not up, none of this will work.

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