cancel
Showing results for 
Search instead for 
Did you mean: 

Interface SDMMC using FileX middleware issue in 4-bit bus width mode - STM32

ABust.3
Associate

Hi, i'm using STM32U575ZI-Q (in NUCLEO-U575), I want to write and read Fat32 files on SD using SDMMC interface, with FileX middleware. When I set the bus width in 1-bit the app work OK but when I switch the setting to 4-bit buswidth mode the app crashes, the debuging halt in the first reading command after SD initialization (in the HAL_SD_ReadBlocks function, it calls to SDMMC_CmdReadSingleBlock function and when it executes SDMMC_SendCommand the SDMMC bit transfer complete doesn't set)

I'm setting MCU CLK @ 160MHz (AHB & APB at 160MHz too), SDMMC CLK @ 6MHz (source PLL in 96MHz / (2* DIV) with DIV=8).

I repeat, in 1-bit buswidth the code working correctly ! But not in 4-bit mode

On the osciloscope I can see signals on pins D0-D3, so I can verify the 4-bit buswidth is set correctly.

I used a SDHC Standar and a SDHC UHS-1 and the result was the same.

The code includes fx_stm32_sd_driver_glue files.

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 SystemPower_Config();

 MX_GPIO_Init();

 MX_USART1_UART_Init();

 MX_ICACHE_Init();

 MX_FileX_Init();

 MX_SDMMC1_SD_Init();

 HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_SET);

 HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);

 HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET);

 fx_thread_entry(0);

 while(1)

 {

  HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);

  HAL_Delay(400);

 }

 while (1)

 {

 }

}

void fx_thread_entry(ULONG thread_input)

{

 UINT status;

 ULONG bytes_read;

 CHAR read_buffer[32];

 CHAR buffer_SD[1560];

 CHAR data[] = "This is FileX working on STM32 \0";

 uint32_t a = 0;

 for (a = 0; a < 1560; ++a) {

 buffer_SD[a] = 'G';

 }

 buffer_SD[0] = 'd';

 buffer_SD[1] = 'i';

 buffer_SD[2] = 'v';

 buffer_SD[3] = '2';

 buffer_SD[1559] = '!';

 /* Open the SD disk driver. */

 status = fx_media_open(&sdio_disk, "STM32_SDIO_DISK", fx_stm32_sd_driver, 0,(VOID *) media_memory, sizeof(media_memory));

 /* Check the media open status. */

 if (status != FX_SUCCESS)

 {

  Error_Handler();

 }

 /* Create a file called STM32.TXT in the root directory. */

 status = fx_file_create(&sdio_disk, "STM32.TXT");

 /* Check the create status. */

 if (status != FX_SUCCESS)

 {

  /* Check for an already created status. This is expected on the

  second pass of this loop! */

  if (status != FX_ALREADY_CREATED)

  {

   /* Create error, call error handler. */

   Error_Handler();

  }

 }

 /* Open the test file. */

 status = fx_file_open(&sdio_disk, &fx_file, "STM32.TXT", FX_OPEN_FOR_WRITE);

 /* Check the file open status. */

 if (status != FX_SUCCESS)

 {

  /* Error opening file, call error handler. */

  Error_Handler();

 }

 /* Seek to the beginning of the test file. */

 status = fx_file_seek(&fx_file, 0);

 /* Check the file seek status. */

 if (status != FX_SUCCESS)

 {

  /* Error performing file seek, call error handler. */

  Error_Handler();

 }

 LED_BLUE_GPIO_Port->BRR |= LED_BLUE_Pin;

 /* Write a string to the test file. */

 status = fx_file_write(&fx_file, buffer_SD, sizeof(buffer_SD));

 /* Check the file write status. */

 if (status != FX_SUCCESS)

 {

  /* Error writing to a file, call error handler. */

  Error_Handler();

 }

 LED_BLUE_GPIO_Port->BSRR |= LED_BLUE_Pin;

 /* Close the test file. */

 status = fx_file_close(&fx_file);

 /* Check the file close status. */

 if (status != FX_SUCCESS)

 {

  /* Error closing the file, call error handler. */

  Error_Handler();

 }

 status = fx_media_flush(&sdio_disk);

 /* Check the media flush status. */

 if (status != FX_SUCCESS)

 {

  /* Error closing the file, call error handler. */

  Error_Handler();

 }

 /* Open the test file. */

 status = fx_file_open(&sdio_disk, &fx_file, "STM32.TXT", FX_OPEN_FOR_READ);

 /* Check the file open status. */

 if (status != FX_SUCCESS)

 {

  /* Error opening file, call error handler. */

  Error_Handler();

 }

 /* Seek to the beginning of the test file. */

 status = fx_file_seek(&fx_file, 0);

 /* Check the file seek status. */

 if (status != FX_SUCCESS)

 {

  /* Error performing file seek, call error handler. */

  Error_Handler();

 }

 /* Read the first 28 bytes of the test file. */

 status = fx_file_read(&fx_file, read_buffer, sizeof(data), &bytes_read);

 /* Check the file read status. */

 if ((status != FX_SUCCESS) || (bytes_read != sizeof(data)))

 {

  /* Error reading file, call error handler. */

  Error_Handler();

 }

 /* Close the test file. */

 status = fx_file_close(&fx_file);

 /* Check the file close status. */

 if (status != FX_SUCCESS)

 {

  /* Error closing the file, call error handler. */

  Error_Handler();

 }

 /* Close the media. */

 status = fx_media_close(&sdio_disk);

 /* Check the media close status. */

 if (status != FX_SUCCESS)

 {

  /* Error closing the media, call error handler. */

  Error_Handler();

 }

}

I guess the IDMA is not working properly but I'am not sure. If anyone can help me i appreciate it !

19 REPLIES 19

SDMMC without DMA is very slow, but for me it is even worse as I have buffer overruns on the MCU side, so with DMA it does not work and without DMA it does not work. The only configuration that works for me is 1 bit, no DMA with the driver code like you. I did try to use the DMA version by adding

while(!sd_rx_cplt);

and

while(!sd_tx_cplt);

respective just after the HAL_SD_{Read,Write}Blocks_DMA() function in order to wait for the DMA operation to complete. But that does only work exactly one single time as the ISR at the end of the file is only called the first time for the read operation. I do not know if we should acknowledge the ISR, but normally it is the HAL that does that,

All in all I have a really hard time working with CubeMX and especially the ST HAL, I loose more time fixing such terrible bugs and searching all over the internet for examples as the documentation is really bad too as all the time I gain by configuring the project in the terrible slow CubeMX code generator.

Ah and I could not correct it yet, I would really like to destroy that ***** ** **** of dev board with a hammer.

Oh my first answer was deleted because I called things what they are with strong words.

So to resume, our fix is to use another MCU, and it. will be certainly no ST anymore.

Haithem Rahmani
ST Employee

Hi @cm0x4d​,

We have this example https://github.com/STMicroelectronics/STM32CubeU5/tree/main/Projects/STM32U575I-EV/Applications/FileX/Fx_File_Edit_Standalone

working correctly with SDMMC configured in 4-bits width. This should easily portable on your NUCLEO board.

Hope this helps you fixing your problem.

cm0x4d
Associate III

Now lower your SDMMC clock and your example will not work either...

I cannot run it in full clock speed as I am using cables to attach the SD card board and as the code to wait for completion is missing in your example's glue driver code too I highly doubt it will work at lower clock speeds, so no use to me.

Thanks @cm0x4d​  for the prompt reply,

Could you please share how did you lower your SDMMC clocking, that I can test in the same conditions as you?

for the "wait for completion" it is not missing 😊, it is implemented here.

https://github.com/STMicroelectronics/STM32CubeU5/blob/eb4d106d4ba5bbbc2eb2b0674ef5a3dcd2b3f4bd/Projects/STM32U575I-EV/Applications/FileX/Fx_File_Edit_Standalone/FileX/Target/fx_stm32_sd_driver.h#L127

and here:

https://github.com/STMicroelectronics/STM32CubeU5/blob/eb4d106d4ba5bbbc2eb2b0674ef5a3dcd2b3f4bd/Projects/STM32U575I-EV/Applications/FileX/Fx_File_Edit_Standalone/FileX/Target/fx_stm32_sd_driver.h#L143

so maybe the default timeout should be increased, after lowering the SD Clock?

regards

Haithem.

Well, makes perfect sense to implement the waiting in another file using a define :persevering_face:, this really helps to understand the code...

I did set SDMMC clock divide factor to 1000.

BUT in my fx_stm32_sd_driver.h, I have rather this code:

/* Define how to notify about Read completion operation */
#define FX_STM32_SD_READ_CPLT_NOTIFY()

So why did CubeMX not generate the code to wait?

Haithem Rahmani
ST Employee

Hi @cm0x4d​ 

going to check with lower SDMMC Clocking. Meanwhile I checked the using STM32CubeMX 6.8.0 and the code is correctly generated. Below are screenshot of the configuration steps.

  • Enable SDMMC 4-bits wide config.


_legacyfs_online_stmicro_images_0693W00000bhi2KQAQ.png

  • Select FileX MW and select SD interface.


_legacyfs_online_stmicro_images_0693W00000bhi2eQAA.png

  • In the configuration panel select the " HAL DMA API" & "Global state variables" for respectively "Glue function Implementation" & "Transfer Completion Mechanism"


_legacyfs_online_stmicro_images_0693W00000bhi3cQAA.png

  • After code generation Check the fx_stm32_driver.h file and the macros are there.


_legacyfs_online_stmicro_images_0693W00000bhi3wQAA.pngHaithem.

cm0x4d
Associate III

Well, using my version (STM32CubeIDE 1.9.0) it does not generate that code. So we found a very good solution. We switched to Nordic MCU and their HAL works.

I've got a similar problem on the Nucleo-U575ZI board. It always times out once I get to FX_STM32_SD_READ_CPLT_NOTIFY(). I used the same SD breakout board with the L496RG a couple of weeks ago and I got it to work. I'm using the Fx_File_Edit_Standalone from STM32U575I-EV as an example. Any ideas? Do I have to configure the DMA?