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
JCout.11
Associate II

Were you able to resolve this issue? I'm seeing a similar issue on the same processor.

Hi JCout, I can't solve this issue, so I'm using other microcontroller (stm32h7b) and it works fine! This iC don't have FileX, the Middleware is the FATfs. (I am using binary files so i am not using the Middleware). Please comment your solution Regards Enviado desde Outlook Mobile<>
AScha.3
Chief II

>SDMMC CLK @ 6MHz

this is very slow clk , sdcard should be at 50MHz , so 96 M source set div 1 ( = /2 ) -> 48M clk.

try... maybe at first without dma setting/use , i had not much "luck" when dma template on.

If you feel a post has answered your question, please click "Accept as Solution".
cm0x4d
Associate III

I have the very same problems using FileX and the glue driver too. I found out that when the driver reads a block from the SD card, data is shifted by 4 bits. When the FileX driver checks if there is a valid partition table, it reads a the following:

partition_sector_ptr[510] = 0x5A

partition_sector_ptr[511] = 0xA4

According to a minimal partition table specification the values should be 0x55 at index 510 and 0xAA at index 511. So by curiosity I read the value at index 509, it was 0x05.

So the data is shifted by 4 bits!

Maybe this information can help ST to fix the problem...

cm0x4d
Associate III

When changing to 1 bit mode, at least the partition table can be read, the driver fails a couple of lines later though.

What is the point of CubeMX when we have to investigate the time we gained searching for all those terrible bugs in the HAL. ST has a serious code quality problem!

cm0x4d
Associate III
/**
* @brief Read Data from the SD device into a buffer.
* @param UINT instance SD IP instance to read from.
* @param UINT *buffer buffer into which the data is to be read.
* @param UINT start_block the first block to start reading from.
* @param UINT total_blocks total number of blocks to read.
* @retval 0 on success error code otherwise
*/
INT fx_stm32_sd_read_blocks(UINT instance, UINT *buffer, UINT start_block, UINT total_blocks)
{
  INT ret = 0;
 
  /* USER CODE BEGIN PRE_READ_BLOCKS */
  /* USER CODE END PRE_READ_BLOCKS */
  sd_rx_cplt = 0;
 
  if(HAL_SD_ReadBlocks_DMA(&hsd1, (uint8_t *)buffer, start_block, total_blocks) != HAL_OK)
  {
    ret = 1;
  }
 
  /* USER CODE BEGIN POST_READ_BLOCKS */
 
  /* USER CODE END POST_READ_BLOCKS */
 
  return ret;
}
 
/**
* @brief Write data buffer into the SD device.
* @param UINT instance SD IP instance to write into.
* @param UINT *buffer buffer to write into the SD device.
* @param UINT start_block the first block to start writing into.
* @param UINT total_blocks total number of blocks to write.
* @retval 0 on success error code otherwise
*/
INT fx_stm32_sd_write_blocks(UINT instance, UINT *buffer, UINT start_block, UINT total_blocks)
{
  INT ret = 0;
 
  /* USER CODE BEGIN PRE_WRITE_BLOCKS */
  /* USER CODE END PRE_WRITE_BLOCKS */
 
  sd_tx_cplt = 0;
 
  if(HAL_SD_WriteBlocks_DMA(&hsd1, (uint8_t *)buffer, start_block, total_blocks) != HAL_OK)
  {
    ret = 1;
  }
 
  /* USER CODE BEGIN POST_WRITE_BLOCKS */
 
  /* USER CODE END POST_WRITE_BLOCKS */
 
  return ret;
}

@ST, you may want to add code to actually wait for completion here...

cm0x4d
Associate III

I can not believe how that code could be released by such a big enterprise. Do they hire 16 year old internships for the HAL?

cm0x4d
Associate III

After fixing that bug I ran into a dangling pointer in the FileX library:

    /* Invoke media open callback. */
    if (media_ptr -> fx_media_open_notify)
    {
        media_ptr -> fx_media_open_notify(media_ptr);
    }

If anyone has the same problem, you need to set that function pointer before using the function:

FX_MEDIA media;
fx_media_open_notify_set(&media, NULL);

before calling the fx_media_open() function.

:pouting_face:

How did you correct this? I corrected it by switching the HAL_SD_WriteBlocks_DMA to HAL_SD_WriteBlocks, (and the same on the read side) which works, but now I'm having massive performance issues, and am wondering if this is why.