Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDMMC Data End Interrupt sometimes does not occur #94

Open
by-gnome opened this issue Oct 28, 2024 · 7 comments
Open

SDMMC Data End Interrupt sometimes does not occur #94

by-gnome opened this issue Oct 28, 2024 · 7 comments
Assignees
Labels
bug Something isn't working hal HAL-LL driver-related issue or pull-request. internal bug tracker Issue confirmed and logged into the internal bug tracking system sdmmc Secure Digital input/output Multimedia Card interface

Comments

@by-gnome
Copy link

by-gnome commented Oct 28, 2024

Describe the set-up
The device based on STM32L496VG with high load application. ICCARM v8.32, STM32Cube_FW_L4_V1.18.1.

Describe the bug
Writing to an SD memory card using SDMMC+DMA sometimes times out in the SD_write() function. This happens because the DATAEND interrupt does not occur.
After some debugging I found that the SD_DMATransmitCplt() function enables the DATAEND interrupt by setting the DATAENDIE bit, but interrupt does not occur, and after the timeout in the SD_write() function the DATAEND bit is set and the DATAENDIE bit is not set.

How To Reproduce
SDMMC parameters:

  • Clock source - HSI48 RC
  • Clock transition - Rising
  • Clock divider bypass - Enable
  • Clock power save - Enable
  • HW flow control - Enable
  • Wide bus mode - 4 bit
  • DMA - DMA2 channel 5

The application writes data to the SD card for 12-24 hours, with a data rate of 128 kB/s. After writing several gigabytes of data, a timeout occurs in the SD_write() function.

Additional context
Let's consider the SD_DMATransmitCplt() function:

static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
  SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);

  /* Enable DATAEND Interrupt */
  __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DATAEND));
}

In case of abnormal operation, before setting DATAENDIE, the SDMMC_STA register has the state 0x00105400:
TXDAVL = 1, TXFIFOHE = 1, TXACT = 1, DBCKEND = 1 or 0 (doesn't matter)
and SDMMC_MASK register has the state 0x00000000 !!!

After setting DATAENDIE, the SDMMC_STA register has the state 0x00105400:
TXDAVL = 1, TXFIFOHE = 1, TXACT = 1, DBCKEND = 1 or 0 (doesn't matter)
and SDMMC_MASK register has the state 0x00000100:
DATAENDIE = 1

After timeout in SD_write the SDMMC_STA register has the state 0x00000500:
DBCKEND = 1, DATAEND = 1
and SDMMC_MASK register has the state 0x0000001A:
TXUNDERRIE = 1, DTIMEOUTIE = 1, DCRCFAILIE = 1

The correct values ​​in the SDMMC_MASK register are 0x0000001A and 0x0000011A. Therefore, it can be assumed that in the SD_DMATransmitCplt() function, reading/writing the SDMMC_MASK register is sometimes disrupted.

Possible solution
If I set the DATAENDIE bit in the HAL_SD_WriteBlocks_DMA() function, the problem does not occur.

--- a/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd.c
+++ b/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd.c
@@ -1566,7 +1566,7 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
       (void)SDMMC_ConfigData(hsd->Instance, &config);
 
       /* Enable SD Error interrupts */
-      __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR));
+      __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
 #else
       /* Enable transfer interrupts */
       __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
@@ -3225,9 +3225,6 @@ HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd)
 static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
 {
   SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
-
-  /* Enable DATAEND Interrupt */
-  __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DATAEND));
 }
@ALABSTM ALABSTM added bug Something isn't working hal HAL-LL driver-related issue or pull-request. sdmmc Secure Digital input/output Multimedia Card interface labels Oct 30, 2024
@by-gnome
Copy link
Author

by-gnome commented Oct 31, 2024

Project configuration

proj_sys_view

Clock configuration

proj_clock_config

@KRASTM
Copy link
Contributor

KRASTM commented Nov 1, 2024

Hello @by-gnome,

Thank you for the report.

Regarding the issue, I tested an application with STM32L496G-Disco and work just fine, it's under Projects\32L496GDISCOVERY\Applications\FatFs\FatFs_uSD_DMA_RTOS

However, I will share your proposal to our team in order to analyze it. In the meanwhile, I will try to investigate more and test an example using your config, especially as you mentioned The application writes data to the SD card for 12-24 hours, with a data rate of 128 kB/s. After writing several gigabytes of data, a timeout occurs in the SD_write() function, it's a lot of time and Data.

Just a few questions, if you may:

  • Did you do the test several times, and each time you have this error or timeout?
  • You project with a custom board or ST board?

With regards,

@KRASTM KRASTM moved this from To do to Analyzed in stm32cube-mcu-fw-dashboard Nov 1, 2024
@KRASTM KRASTM added the needs clarification Needs clarification or inputs from the user label Nov 1, 2024
@by-gnome
Copy link
Author

by-gnome commented Nov 2, 2024

The project runs on a custom board.
I tested for several weeks. The problem does not always occur, but quite often. More often with the FAT32 file system than with the exFAT. It might also depend on interrupt priorities and system load.
This problem might be similar to STM32CubeL4/pull/35

@by-gnome
Copy link
Author

by-gnome commented Nov 3, 2024

To localize the problem I modified the SD_DMATransmitCplt() and SD_write() as follows:

static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
  SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
  SdDmaTxCplt1 = SDMMC1->STA | 0x80000000;
  SdDmaTxCplt0 = SDMMC1->MASK | 0x80000000;
  /* Enable DATAEND Interrupt */
  __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DATAEND));
  SdDmaTxCplt3 = hsd->Instance->STA | 0x80000000;
  SdDmaTxCplt2 = hsd->Instance->MASK | 0x80000000;
}
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
  uint32_t tickstart;
  WriteStatus = 0;
  if (BSP_SD_WriteBlocks_DMA((uint32_t*)buff, (uint32_t)(sector), count) == MSD_OK)
  {
    tickstart = HAL_GetTick();
    while ((WriteStatus == 0) && ((HAL_GetTick() - tickstart) < SD_TIMEOUT));
    if (WriteStatus != 0) {
      do {
        if (BSP_SD_GetCardState() == SD_TRANSFER_OK) {
          return RES_OK;
        }
      } while ((HAL_GetTick() - tickstart) < SD_TIMEOUT);
    }
  }
  SdmmcTxCplt3 = hsd1.Instance->STA | 0x80000000;
  SdmmcTxCplt2 = hsd1.Instance->MASK | 0x80000000;
  return RES_ERROR;
}

When timeout, the variables contain the following values:

SdDmaTxCplt1 - 0x80105400
SdDmaTxCplt0 - 0x80000000
SdDmaTxCplt3 - 0x80105400
SdDmaTxCplt2 - 0x80000100
SdmmcTxCplt3 - 0x80000500
SdmmcTxCplt2 - 0x8000001a

It might be a hardware issue with SDMMC_MASK register.

@KRASTM
Copy link
Contributor

KRASTM commented Nov 11, 2024

ST Internal Reference: 196054

@KRASTM KRASTM added internal bug tracker Issue confirmed and logged into the internal bug tracking system and removed needs clarification Needs clarification or inputs from the user labels Nov 11, 2024
@KRASTM
Copy link
Contributor

KRASTM commented Nov 12, 2024

Hello @by-gnome,

The issue is reported internally. Just if you may, we want to know the type and specification of the SD card used in your project.

With regards,

@by-gnome
Copy link
Author

Hello @KRASTM

32GB ADATA Premier microSDHC UHS-I Class10 (AUSDH32GUICL10-R)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working hal HAL-LL driver-related issue or pull-request. internal bug tracker Issue confirmed and logged into the internal bug tracking system sdmmc Secure Digital input/output Multimedia Card interface
Projects
Development

No branches or pull requests

3 participants