sd-cardhalstm32h7

SDMMC not working on STM32H7 uControllers


Good day

The problem

I am trying to get an SD card working using an STM32H7 uController. I have in the past successfully integrated SDIO with STM32F4/F7 microcontroller but cannot get it to work on an H7 microcontroller.

Env

CubeMx V6.11.1 for code generation

What I have tried:

Wiring & hardware:

I have double check and triple checked that my wiring is correct. I am using a Nucleo-H723ZG board with a SD breakout and some jumpers. Nothing special. Jumpers are ~10cm long, so nothing outrageous there. I have also tried a variety of different SD cards with no success. I have even tried a different sd breakout board with no success either.

CubeMX:

  1. Configure RCC with correct HSE and LSE
  2. Configure CPU clock to 550MHz with DIVQ1->PLL1Q set to 183.333MHz
  3. Enable SDMMC1 with "SD 4 bits Wide bus"
  4. Set SDMMC clock divide factor to 2 and enable NVIC interrupt
  5. Enable FATFS middleware with "SD Card" checkbox
  6. Set defines: Increase Max_ss to 4096
  7. Advanced Settings: Enable "Use dma template"
  8. Platform Settings: Select P0 as the Detect_SDIO pin.

Firmware:

I have removed everything I that worked for me such as f_mount(), etc. None of it worked and reduced it to: (all of main.c is otherwise unaltered)

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* 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_SDMMC1_SD_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */
  HAL_StatusTypeDef result_sd_init = HAL_SD_Init(&hsd1);

  FRESULT result_mount = f_mount(&SDFatFS, (TCHAR const*)SDPath, 1);

  /* USER CODE END 2 */

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

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

Following the code and stepping into it I arrive at: sd_diskio.c line 220:

DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
{
...
  while((ReadStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))
  {
  }
  /* in case of a timeout return error */
  if (ReadStatus == 0)
  {
    res = RES_ERROR;
  }
...
}

Heyre the code hangs in the while loop until the timeout is triggered.

Anyone got any ideas? What am I missing....what is different from F4/F7 uControllers?


Solution

  • After several days of debugging I finally stumbled onto the solution after uselessly trying SDMMC1 and 2, FreeRTOS, Cache settings, DMA settings and just about anything I could think of.

    As a last ditch effort pulled my SD card out of another device knowing it was a different SD card. And boom! It works.

    I have 3 different SanDisk SD cards, none of which work! Not one. The other no name SD card that I tried works great. Not sure what to make of that. Note that the SandDisk SD cards work just fine on my PC. They just dont work using SDMMC on STM32