cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with SD Card Setup on STM32N6570-DK (FX_BOOT_ERROR on fx_media_open)

TerZer
Associate III

Hello,

I am working with an STM32N6570-DK board and facing an issue while setting up the SD card. I created a project using TouchGFX Designer, generated the code, and opened the .ioc file. In there, I enabled SDMMC2 with 4-bit Wide mode and enabled global interrupt:


image.png

After checking the schematics, I noticed that the CK pin was incorrect, so I assigned the correct pin (PC2:(
image.pngTerZer_0-1742385627511.png

I made the following additional configurations:

  • Changed all SDMMC2 pins to pull-up and set Max output speed to Very High
  • Enabled PWR_SD_EN (PQ7) as output level high with context Free
  • Changed clock from HCLK to IC4 (should not affect anything)
  • Enabled SD_DETECT (PN12) to detect when the SD card is inserted or removed
  • Enabled EXTI Line4 and EXTI Line12 for interrupts
  • Enabled FileX with mostly default settings, except for increased memory and FX driver initialization:

TerZer_1-1742386159071.png

After this setup, I attempted to initialize the SD card with the following call:

fx_media_open(&sdio_disk, "SDIO_DISK", fx_stm32_sd_driver, NULL, fx_sd_media_memory, FX_STM32_SD_DEFAULT_SECTOR_SIZE);

However, this returns error 0x01 (FX_BOOT_ERROR). Upon further debugging, I found the issue occurs in this section of fx_stm32_sd_driver.c:

  case FX_DRIVER_BOOT_READ:
    {
      /* the boot sector is the sector zero */
      status = sd_read_data(media_ptr, 0, media_ptr->fx_media_driver_sectors, unaligned_buffer);

      if (status != FX_SUCCESS)
      {
        media_ptr->fx_media_driver_status = status;
        break;
      }

      /* Check if the sector 0 is the actual boot sector, otherwise calculate the offset into it.
      Please note that this should belong to higher level of MW to do this check and it is here
      as a temporary work solution */

      partition_start =  0;

      status =  _fx_partition_offset_calculate(media_ptr -> fx_media_driver_buffer, 0,
                                               &partition_start, &partition_size);

      /* Check partition read error.  */
      if (status)
      {
        /* Unsuccessful driver request.  */
        media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
        break;
      }

      /* Now determine if there is a partition...   */
      if (partition_start)
      {

        if (check_sd_status(FX_STM32_SD_INSTANCE) != 0)
        {
          media_ptr->fx_media_driver_status =  FX_IO_ERROR;
          break;
        }

        /* Yes, now lets read the actual boot record.  */
        status = sd_read_data(media_ptr, partition_start, media_ptr->fx_media_driver_sectors, unaligned_buffer);

        if (status != FX_SUCCESS)
        {
          media_ptr->fx_media_driver_status = status;
          break;
        }
      }

      /* Successful driver request.  */
      media_ptr -> fx_media_driver_status =  FX_SUCCESS;
      break;
    }

The function sd_read_data() returns FX_SUCCESS, but when inspecting the buffer in the debugger, it is empty (no data is present).

 

Questions:

  1. What could be causing sd_read_data() to succeed but return an empty buffer?
  2. Could it be an issue with SDMMC2 configuration, clock settings, or pull-up resistors?
  3. Do I need additional initialization steps in fx_stm32_sd_driver?
1 ACCEPTED SOLUTION

Accepted Solutions
TerZer
Associate III

Hello @Saket_Om 

When I tried to make the SD card work, there was no support for FileX at the time. After updating HALs, I recreated the project with FileX, and everything worked.

View solution in original post

4 REPLIES 4
Saket_Om
ST Employee

Hello @TerZer 

Does the SDMMC work without fileX?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om
TerZer
Associate III

Hello @Saket_Om 

When I tried to make the SD card work, there was no support for FileX at the time. After updating HALs, I recreated the project with FileX, and everything worked.

Aashritha_Vuda
Associate II

Hai TerZer,

I'm currently working on the same controller and on the same peripheral (SD Card) and facing the same issue like it is returning error 0x01 (FX_BOOT_ERROR)

Did you find any Solution?

If yes, Kindly assist me with this it will be very helpful to me.

 

Thanks

Yes, I got that fixed, but I don't remember exactly what the fix was. I can provide my code for sd init, maybe you will find a solution:

/**
  * @brief SD MSP Initialization
  * This function configures the hardware resources used in this example
  * @PAram hsd: SD handle pointer
  * @retval None
  */
void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  if(hsd->Instance==SDMMC2)
  {
    /* USER CODE BEGIN SDMMC2_MspInit 0 */
	    __HAL_RCC_GPIOD_CLK_ENABLE();
    /* USER CODE END SDMMC2_MspInit 0 */

  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SDMMC2;
    PeriphClkInitStruct.Sdmmc2ClockSelection = RCC_SDMMC2CLKSOURCE_HCLK;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }

    /* Peripheral clock enable */
    __HAL_RCC_SDMMC2_CLK_ENABLE();

    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOE_CLK_ENABLE();
    /**SDMMC2 GPIO Configuration
    PC4     ------> SDMMC2_D0
    PC5     ------> SDMMC2_D1
    PC0     ------> SDMMC2_D2
    PC2     ------> SDMMC2_CK
    PE4     ------> SDMMC2_D3
    PC3     ------> SDMMC2_CMD
    */
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_0|GPIO_PIN_2
                          |GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF11_SDMMC2;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF11_SDMMC2;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

    /* SDMMC2 interrupt Init */
    HAL_NVIC_SetPriority(SDMMC2_IRQn, 14, 0);
    HAL_NVIC_EnableIRQ(SDMMC2_IRQn);
    /* USER CODE BEGIN SDMMC2_MspInit 1 */

    /* USER CODE END SDMMC2_MspInit 1 */

  }

}
/**
  * @brief SDMMC2 Initialization Function
  * @PAram None
  * @retval None
  */
void MX_SDMMC2_SD_Init(void)
{

  /* USER CODE BEGIN SDMMC2_Init 0 */

  /* USER CODE END SDMMC2_Init 0 */

  /* USER CODE BEGIN SDMMC2_Init 1 */

  /* USER CODE END SDMMC2_Init 1 */
  hsd2.Instance = SDMMC2;
  hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd2.Init.BusWide = SDMMC_BUS_WIDE_4B;
  hsd2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd2.Init.ClockDiv = 2;
  if (HAL_SD_Init(&hsd2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SDMMC2_Init 2 */

  /* USER CODE END SDMMC2_Init 2 */

}
/**
* @brief Initializes the SD IP instance
* @PAram UINT instance SD instance to initialize
* @retval 0 on success error value otherwise
*/
INT fx_stm32_sd_init(UINT instance)
{
  INT ret = 0;

  /* USER CODE BEGIN PRE_FX_SD_INIT */
  UNUSED(instance);
  /* USER CODE END PRE_FX_SD_INIT */

#if (FX_STM32_SD_INIT == 1)
	MX_SDMMC2_SD_Init();
#endif

  /* USER CODE BEGIN POST_FX_SD_INIT */
	HAL_SD_ConfigSpeedBusOperation(&hsd2,SDMMC_SPEED_MODE_AUTO);
	if(Wait_SDCARD_Ready() != HAL_OK)
	{
	Error_Handler();
	}
  /* USER CODE END POST_FX_SD_INIT */

  return ret;
}

/* USER CODE BEGIN 1 */
/**
* @brief  Wait SD Card ready status
* @PAram  None
* @retval None
*/
static uint8_t Wait_SDCARD_Ready(void)
{
  uint32_t loop = SD_TIMEOUT;

  /* Wait for the Erasing process is completed */
  /* Verify that SD card is ready to use after the Erase */
  while(loop > 0)
  {
    loop--;
    if(HAL_SD_GetCardState(&hsd2) == HAL_SD_CARD_TRANSFER)
    {
      return HAL_OK;
    }
  }
  return HAL_ERROR;
}
/* USER CODE END 1 */