Skip to main content
Graduate II
April 30, 2025
Question

STM32U5 SDMMC1 FATFS integration

  • April 30, 2025
  • 6 replies
  • 3784 views

Hi guys,

 

I'm trying to implement a sd card interface for the STM32U5 series using SDMMC1 interface. Since there is no native FATFS support over CubeMX, I guess, I started to use the generic fat file module from elm-chan.

Basic configuration:

1. SDMMC1 in SD 4 bits wide bus mode, clock divider 4, power safe for clock enabled, no hardware control, no external transceiver, SDMMC1 global interrupt enabled, gpios pullup all enabled despite of clk

2. Modified diskio.c see code example

The interface works and I can also kind of work with fatFS, f_mount, f_open works basiclly, but sometimes I got a FR_DISK_ERR. On my scope I can see that the SD clock is always on when the error occures. So I think there is an issue with the low level driver level or better say somethimg is going on with the diskio layer. Please see the attached pictures of working f_mount and f_open and the f_open where the clock doesn't stop.

I'm using FreeRTOS and I have a dedicated SD_Card Task.

Julian__0-1746000981422.png

My modified diskio.c:

/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/

#include "ff.h"			/* Obtains integer types */
#include "diskio.h"		/* Declarations of disk functions */
#include "stm32u5xx_hal.h"
#include "sdmmc.h"

/* Definitions of physical drive number for each drive */
#define DEV_RAM		0	/* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC		1	/* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB		2	/* Example: Map USB MSD to physical drive 2 */

extern SD_HandleTypeDef hsd1;
DSTATUS Stat = STA_NOINIT;


/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/

DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber to identify the drive */
)
{
 if (pdrv == 0) {
 HAL_SD_CardStateTypeDef state = HAL_SD_GetCardState(&hsd1);

 if (state == HAL_SD_CARD_TRANSFER || state == HAL_SD_CARD_READY) {
 return RES_OK; // Card is ready
 } else {
 return STA_NOINIT; // Card is not ready
 }
 }
 return STA_NOINIT; // Only drive 0 supported
}



/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
 if (pdrv != 0) return STA_NOINIT; // Only support drive 0 for SD

 if (!(Stat & STA_NOINIT)) // If already initialized
 {
 return RES_OK; // No need to reinitialize
 }

 // Otherwise, maybe check card presence etc if needed
 if (HAL_SD_GetCardState(&hsd1) == HAL_SD_CARD_TRANSFER) // Already ready
 {
 Stat &= ~STA_NOINIT; // Clear the NOINIT bit
 return RES_OK;
 }

 // (Optional) If you really need HAL_SD_Init() again, only under safe conditions

 return STA_NOINIT; // Fail if not ready
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
	BYTE *buff,		/* Data buffer to store read data */
	LBA_t sector,	/* Start sector in LBA */
	UINT count		/* Number of sectors to read */
)
{
 if (pdrv != 0) return RES_PARERR;

 if (Stat & STA_NOINIT) return RES_NOTRDY;

 HAL_StatusTypeDef hal_res = HAL_SD_ReadBlocks(&hsd1, buff, sector, count, HAL_MAX_DELAY);

 if (hal_res == HAL_OK)
 {
 /* Wait until SD card is ready */
 uint32_t timeout = HAL_GetTick() + 500; // 500ms timeout
 while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER)
 {
 if (HAL_GetTick() > timeout)
 {
 return RES_ERROR; // Timeout, SD busy too long
 }
 osDelay(1); // yield to other FreeRTOS tasks
 }
 return RES_OK;
 }

 return RES_ERROR;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/

#if FF_FS_READONLY == 0

DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
	const BYTE *buff,	/* Data to be written */
	LBA_t sector,		/* Start sector in LBA */
	UINT count			/* Number of sectors to write */
)
{

	if (pdrv != 0) return RES_PARERR;

	if (Stat & STA_NOINIT) return RES_NOTRDY;

	HAL_StatusTypeDef hal_res = HAL_SD_WriteBlocks(&hsd1, (uint8_t*)buff, sector, count, HAL_MAX_DELAY);

	if (hal_res == HAL_OK)
	{
		/* Wait until SD card is ready */
		uint32_t timeout = HAL_GetTick() + 500; // 500ms timeout
		while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER)
		{
			if (HAL_GetTick() > timeout)
			{
				return RES_ERROR; // Timeout
			}
			osDelay(1); // yield in FreeRTOS
		}
		return RES_OK;
	}

	return RES_ERROR;
}

#endif


/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/

DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
 if (pdrv != 0) return RES_PARERR;

 HAL_SD_CardInfoTypeDef info;
 HAL_SD_GetCardInfo(&hsd1, &info);

 switch (cmd) {
 case GET_SECTOR_COUNT:
 *(DWORD*)buff = info.LogBlockNbr;
 return RES_OK;
 case GET_SECTOR_SIZE:
 *(WORD*)buff = 512;
 return RES_OK;
 case GET_BLOCK_SIZE:
 *(DWORD*)buff = info.LogBlockSize / 512;
 return RES_OK;
 }
 return RES_PARERR;
}

Initalize SDMMC and HAL_SD:

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_FALLING;
 hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_ENABLE;
 hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
 hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
 hsd1.Init.ClockDiv = 4;
 if (HAL_SD_Init(&hsd1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SDMMC1_Init 2 */

 /* USER CODE END SDMMC1_Init 2 */

}

 Would be great if I get some input from you guys - how I can fix this.

 

Thanks,

Julian

    This topic has been closed for replies.

    6 replies

    Technical Moderator
    April 30, 2025

    Hi Julian,

    Below is the typical implementation for the MX_SDMMC1_SD_Init() API used in the STM32CubeH7 package:

    /**
    * @brief Initializes the SDMMC1 peripheral.
    * @PAram hsd SD handle
    * @retval HAL status
    */
    __weak HAL_StatusTypeDef MX_SDMMC1_SD_Init(SD_HandleTypeDef *hsd)
    {
    HAL_StatusTypeDef ret = HAL_OK;
    /* uSD device interface configuration */
    hsd->Instance = SDMMC1;
    hsd->Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
    hsd->Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
    hsd->Init.BusWide = SDMMC_BUS_WIDE_1B;
    hsd->Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
    hsd->Init.ClockDiv = 4; /* SDMMC_NSpeed_CLK_DIV */
    hsd->Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
    
    /* HAL SD initialization */
    if(HAL_SD_Init(hsd) != HAL_OK)
    {
    ret = HAL_ERROR;
    }
    
    return ret;
    }
    Julian_Author
    Graduate II
    April 30, 2025

    Thanks for your fast reply. I think that the SDMMC Init and HAL_SD Init is not the root cause of this issue. I already tested some other configuration of the sdmmc like SDMMC_BUS_WIDE_1B instead of SDMMC_BUS_WIDE_4B and clock rising instead of falling etc.

    So I think the issue is more related to the diskio setup or better say how the HAL_SD API for writing and reading is implemented to diskio.c

    Best,

    Julian

    Julian_Author
    Graduate II
    May 5, 2025

    @KORKADHi, are there any other suggestions to this issue? Would be great to get an update. Thanks.

    Technical Moderator
    May 6, 2025

    Hi Julian,

    Sorry for the delay. FATFS is supported natively over CubeMX on H7RS products. You can refer to the generated code as reference code.

     

     

     

    Julian_Author
    Graduate II
    May 7, 2025

    @KORKADThanks for the reference. I checked out the FatFs driver implementation for H7RS products. Therefore I downloaded the STM32Cube_FW_H7RS_V1.2.0 and compared the sd_diskio.c implemtation to my own implementation. Basiclly it's more or less the some - despite this fact I used the implementation in en.stm32cubeh7rs-v1-2-0.zip\STM32Cube_FW_H7RS_V1.2.0\Middlewares\Third_Party\FatFs\source\drivers\sd->diskio.c to test this too.

    Unfortunally I got the same issue with the never ending clock that appears sometimes. Do you know if the blocking read/write access to the sd card is possible in an own RTOS task. Or should switch to sd_diskio_dma_rtos.c? My preference is the blocking code, if possible.

    I appreciate your support hopefully we can fix the issue.

     

    Best,

    Julian

    Current diskio.c in my project:

    /*-----------------------------------------------------------------------*/
    /* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */
    /*-----------------------------------------------------------------------*/
    /* If a working storage control module is available, it should be */
    /* attached to the FatFs via a glue function rather than modifying it. */
    /* This is an example of glue functions to attach various exsisting */
    /* storage control modules to the FatFs module with a defined API. */
    /*-----------------------------------------------------------------------*/
    
    #include "ff.h"			/* Obtains integer types */
    #include "diskio.h"		/* Declarations of disk functions */
    #include "stm32u5xx_hal.h"
    #include "sdmmc.h"
    
    /* Definitions of physical drive number for each drive */
    #define DEV_RAM		0	/* Example: Map Ramdisk to physical drive 0 */
    #define DEV_MMC		1	/* Example: Map MMC/SD card to physical drive 1 */
    #define DEV_USB		2	/* Example: Map USB MSD to physical drive 2 */
    
    #define SD_TIMEOUT (1000)
    
    extern SD_HandleTypeDef hsd1;
    static volatile DSTATUS Stat = STA_NOINIT;
    
    
    /*-----------------------------------------------------------------------*/
    /* Get Drive Status */
    /*-----------------------------------------------------------------------*/
    
    DSTATUS disk_status (
    	BYTE pdrv		/* Physical drive nmuber to identify the drive */
    )
    {
    	 Stat = STA_NOINIT;
    
    	 if (HAL_SD_GetCardState(&hsd1) == HAL_SD_CARD_TRANSFER)
    	 {
    	 Stat &= ~STA_NOINIT;
    	 }
    
    	 return Stat;
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Inidialize a Drive */
    /*-----------------------------------------------------------------------*/
    
    DSTATUS disk_initialize (
    	BYTE lun				/* Physical drive nmuber to identify the drive */
    )
    {
    	Stat = STA_NOINIT;
    
    	#if (ENABLE_SD_INIT == 1)
    	 sdmmc_sd_init();
    	 Stat = SD_check_status(lun);
    	#else
    	 Stat = disk_status(lun);
    	#endif
    	 return Stat;
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Read Sector(s) */
    /*-----------------------------------------------------------------------*/
    
    DRESULT disk_read (
    	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
    	BYTE *buff,		/* Data buffer to store read data */
    	LBA_t sector,	/* Start sector in LBA */
    	UINT count		/* Number of sectors to read */
    )
    {
     if (pdrv != 0) return RES_PARERR;
    
     DRESULT res = RES_ERROR;
    
     if (HAL_SD_ReadBlocks(&hsd1, (uint8_t*)buff, sector, count, SD_TIMEOUT) == HAL_OK)
     {
     /* Wait until the card state is ready */
     while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER)
     {
     }
     res = RES_OK;
     }
     return res;
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Write Sector(s) */
    /*-----------------------------------------------------------------------*/
    
    #if FF_FS_READONLY == 0
    
    DRESULT disk_write (
    	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
    	const BYTE *buff,	/* Data to be written */
    	LBA_t sector,		/* Start sector in LBA */
    	UINT count			/* Number of sectors to write */
    )
    {
    
    	if (pdrv != 0) return RES_PARERR;
    
    	DRESULT res = RES_ERROR;
    
    	if (HAL_SD_WriteBlocks(&hsd1, (uint8_t*)buff, sector, count, SD_TIMEOUT) == HAL_OK)
    	{
    	 /* Wait until the card state is ready */
    	 while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER)
    	 {
    	 }
    	 res = RES_OK;
    	 }
    	 return res;
    }
    
    #endif
    
    
    /*-----------------------------------------------------------------------*/
    /* Miscellaneous Functions */
    /*-----------------------------------------------------------------------*/
    
    DRESULT disk_ioctl (
    	BYTE pdrv,		/* Physical drive nmuber (0..) */
    	BYTE cmd,		/* Control code */
    	void *buff		/* Buffer to send/receive control data */
    )
    {
    	 DRESULT res = RES_ERROR;
    	 HAL_SD_CardInfoTypeDef CardInfo;
    
    	 if (Stat & STA_NOINIT) return RES_NOTRDY;
    
    	 switch (cmd)
    	 {
    	 /* Make sure that no pending write process */
    	 case CTRL_SYNC:
    	 res = RES_OK;
    	 break;
    
    	 /* Get number of sectors on the disk (DWORD) */
    	 case GET_SECTOR_COUNT:
    	 HAL_SD_GetCardInfo(&hsd1, &CardInfo);
    	 *(DWORD*)buff = CardInfo.LogBlockNbr;
    	 res = RES_OK;
    	 break;
    
    	 /* Get R/W sector size (WORD) */
    	 case GET_SECTOR_SIZE:
    	 HAL_SD_GetCardInfo(&hsd1, &CardInfo);
    	 *(WORD*)buff = CardInfo.LogBlockSize;
    	 res = RES_OK;
    	 break;
    
    	 /* Get erase block size in unit of sector (DWORD) */
    	 case GET_BLOCK_SIZE:
    	 HAL_SD_GetCardInfo(&hsd1, &CardInfo);
    	 *(DWORD*)buff = CardInfo.LogBlockSize / BLOCKSIZE;
    	 res = RES_OK;
    	 break;
    
    	 default:
    	 res = RES_PARERR;
    	 }
    
    	 return res;
    }
    Technical Moderator
    May 7, 2025

    Hello @Julian_ 

    To effectively debug the issue, start by ensuring the SDMMC functions correctly using only HAL. Once confirmed, integrate FATFS and verify its operation. Finally, incorporate FreeRTOS and perform another check.

    Julian_Author
    Graduate II
    May 9, 2025

    @Saket_Om  @KORKAD 

    The SDMMC functions seems to work running in main.c without the RTOS. Today I checked if the FATFS works in main without starting the OS. f_mount, f_open, f_write seems to work fine but I used HAL_Delay(20) and after any function of fatfs is called the system tick isn't incremented so the code stucks in an endless loop when using HAL_Delay() maybe this is an interessting fact for you - to give me a hint.

    HAL LAyer works fine:

     while(1){
    	 HAL_StatusTypeDef res;
    
    	 // Wait until SD card is ready
    	 while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER) {
    	 HAL_Delay(1);
    	 }
    
    	 printf("Writing to SD sector %lu...\n", (unsigned long)TEST_SECTOR);
    	 res = HAL_SD_WriteBlocks(&hsd1, tx_buffer, TEST_SECTOR, 1, 1000);
    	 if (res != HAL_OK) {
    	 printf("Write failed: %d\n", res);
    
    	 }
    
    	 // Wait until SD card is ready
    	 while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER) {
    	 HAL_Delay(1);
    	 }
    
    	 printf("Reading back from SD...\n");
    	 res = HAL_SD_ReadBlocks(&hsd1, rx_buffer, TEST_SECTOR, 1, 1000);
    	 if (res != HAL_OK) {
    	 printf("Read failed: %d\n", res);
    
    	 }
    
    	 while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER) {
    	 HAL_Delay(1);
    	 }
    
    	 // Verify
    	 if (memcmp(tx_buffer, rx_buffer, SECTOR_SIZE) == 0) {
    	 printf("SD test successful: data match.\n");
    	 } else {
    	 printf("SD test failed: data mismatch.\n");
    	 }
    
    	 HAL_Delay(5);
     }

    When using:

    while(1){
     HAL_Delay(20);
     HAL_Delay(100);
    )
    
    // ticks increment so NVIC and Hal is initialized properly

     

    When using :

    while (1){
    
    	 // Mount SD card <-- mounting works
    	 fres = f_mount(&fs, "0", 1);
    	 if (fres != FR_OK) {
    		 printf("Mount failed: %d\n", fres);
    	 }
    	 printf("Mount successful.\n");
    
    	 HAL_Delay(20); <- stuck in endless loop due to uwTick isnt incremented an always 153
    
    	 // Create or overwrite file
    	 fres = f_open(&file, "testfile.txt", FA_WRITE | FA_CREATE_ALWAYS);
    	 if (fres != FR_OK) {
    		 printf("File create failed: %d\n", fres);
    	 }
    
    	 HAL_Delay(20);
    
    	 fres = f_write(&file, writeData, strlen(writeData), &bytesWritten);
    	 if (fres != FR_OK || bytesWritten == 0) {
    		 printf("Write failed: %d\n", fres);
    		 f_close(&file);
    	 }
    
    	 HAL_Delay(20);
    
    	 f_close(&file);
    
    	 HAL_Delay(20);
    
    	 f_mount(NULL, "", 1);
    	 printf("FatFS test complete.\n");
    	 HAL_Delay(20);
    
     }

     

    I don't know exaclly why and where the fatfs should change NVIC settings or disable interrupts.

     

    Would be nice to get some input from your side.

     

    Thanks and kind regards,

    Julian

    Technical Moderator
    May 9, 2025

    @Julian_ 

    You should configure timer (TIM6 for example) as time base when using FrreRTOS because Systick is used by the OS. 

    Julian_Author
    Graduate II
    May 12, 2025

    @Saket_Omhi and thanks for the fast reply. What I don't undestand right now is I just want to test the fatfs without RTOS as you mentioned before the seperate HAL,FatFS and RTOS to know where the issue is coming from.

    Therefopre I put some FatFs code to the main before the RTOS is inializied and starts the scheduler. As you see in the code snippet from main the first Delay works fine, but after the f_mount the delay doesn't work anymore.

    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 Power */
     SystemPower_Config();
    
     /* Configure the system clock */
     SystemClock_Config();
    
     /* USER CODE BEGIN SysInit */
    
     /* USER CODE END SysInit */
    
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_GPDMA1_Init();
     MX_ADC1_Init();
     MX_ADC2_Init();
     MX_CORDIC_Init();
     MX_CRC_Init();
     MX_DAC1_Init();
     MX_DCACHE1_Init();
     MX_DCACHE2_Init();
     MX_DMA2D_Init();
     MX_FDCAN1_Init();
     MX_GPU2D_Init();
     MX_HASH_Init();
     MX_I2C2_Init();
     MX_I2C4_Init();
     MX_ICACHE_Init();
     MX_LPTIM2_Init();
     MX_LTDC_Init();
     MX_OCTOSPI1_Init();
     MX_RNG_Init();
     MX_RTC_Init();
     MX_SPI1_Init();
     MX_SPI2_Init();
     MX_TIM3_Init();
     MX_TIM5_Init();
     MX_TIM6_Init();
     MX_TIM8_Init();
     MX_TIM15_Init();
     MX_I2C1_Init();
     MX_USART1_UART_Init();
     MX_SDMMC1_SD_Init();
     //MX_TouchGFX_Init();
     /* Call PreOsInit function */
     //MX_TouchGFX_PreOSInit();
    
     /* Initialize interrupts */
     MX_NVIC_Init();
     /* USER CODE BEGIN 2 */
     //MX_SDMMC1_SD_Init();
    
     char writeData[] = "Testdata written";
     char readBuffer[100];
    
     FATFS fs;
     FIL file;
     FRESULT fres;
     UINT bytesWritten, bytesRead;
    
     HAL_Delay(50); //this delay works
    
     while (1){
    
    	 // Mount SD card
    	 fres = f_mount(&fs, "0", 1);
    	 if (fres != FR_OK) {
    		 printf("Mount failed: %d\n", fres);
    		 //return;
    	 }
    	 printf("Mount successful.\n");
    
    	 HAL_Delay(20); //this delay doesn't work anymore
    
    	 // Create or overwrite file
    	 fres = f_open(&file, "testfile.txt", FA_WRITE | FA_CREATE_ALWAYS);
    	 if (fres != FR_OK) {
    		 printf("File create failed: %d\n", fres);
    		 //return;
    	 }
    
    	 HAL_Delay(20);
    
    	 fres = f_write(&file, writeData, strlen(writeData), &bytesWritten);
    	 if (fres != FR_OK || bytesWritten == 0) {
    		 printf("Write failed: %d\n", fres);
    		 f_close(&file);
    		 //return;
    	 }
    
    	 HAL_Delay(20);
    
    	 f_close(&file);
    
    	 HAL_Delay(20);
    
    	 // Reopen and read
    	// fres = f_open(&file, "test.txt", FA_READ);
    	// if (fres != FR_OK) {
    	//	 printf("Open for read failed: %d\n", fres);
    	//	 return;
    	// }
    
    
    	 //f_close(&file);
    
    	 // Unmount
    	 //f_mount(NULL, "", 1);
    	 printf("FatFS test complete.\n");
    
    	 HAL_Delay(20);
    	 // Mount SD card
     }
    
    
     SD_Init();
     /* USER CODE END 2 */
    
     /* Init scheduler */
     osKernelInitialize();
    
     /* Call init function for freertos objects (in app_freertos.c) */
     MX_FREERTOS_Init();
    
     /* Start scheduler */
     osKernelStart();
    
     /* We should never get here as control is now taken by the scheduler */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }

     

    I don't know why or where the fatfs should change the timebase or the systick. Do you have a hint for me? 

     

    Thanks and kind regards,

    Julian

    Technical Moderator
    May 12, 2025

    Hello @Julian_ 

    what is the time base timer you are using? 

    Could you re-enable interrupt before HAL_Delay. 

    __enable_irq();

    Could you please set the priorities of Systick interrupts higher (Lower numerically) than SDMMC.  Also try to remove the initialisation of all other peripheral. 

     

    Technical Moderator
    May 14, 2025

    @Julian_ 

    Any update concerning this issue?

    Julian_Author
    Graduate II
    May 14, 2025

    @Saket_Om 

    unfortunally no positive update...

    The interrupt priority for sysTick is the highest see .ioc config: 

    Julian__0-1747229362929.png

    Enabling the interrupts before HAL-Delay has also no influence to the issue:

     HAL_Delay(50); //this delay works
    
     while (1){
    
    	 // Mount SD card
    	 fres = f_mount(&fs, "0", 1);
    	 if (fres != FR_OK) {
    		 printf("Mount failed: %d\n", fres);
    		 //return;
    	 }
    	 printf("Mount successful.\n");
    
    	 __enable_irq(); //no influence on issue
    	 HAL_Delay(20); //<-- delay doesnt work

     

    I also disabled UART DMA initalization before the FATfs Test. 

    In my opinion anything during f_mount is responsible for this behaviour but I don't know what.

     

    Systick source is: systick_source = SYSTICK_CLKSOURCE_HCLK;

    Do you have some input how to move on?

    Thanks,

    Julian

     

    Technical Moderator
    May 14, 2025

    Hello @Julian_ 

    You did check with priorities of Timer (Timer used as time base) interrupts higher (Lower numerically) than SDMMC.