2022-04-04 10:14 PM
I'm on STM32CubeIDE Version: 1.9.0 Build: 12015_20220302_0855 (UTC), MCU STM32L4A6ZGTx, Firmware STM32Cube FW_L4 V1.17.1. I'm using a NUCLEO-L4A6ZG.
I'm trying to get FatFS working on SDMMC, with DMA, and having problems.
First, the bundled version of FatFS seems to be ancient. It is so old that it doesn't resemble the documented API at http://elm-chan.org/fsw/ff/00index_e.html. Is there a way I can update it such that my changes won't be wiped out each time I run or update the Device Configuration tool?
The big problem is that it won't work if I select "Use dma template" in Device Configuration Tool/Pinout & Configuration/FATFS/Advanced Settings. If I disable "Use dma template", it works OK (with polling).
With DMA enabled, it gets hung up here:
SD_write() at sd_diskio.c:351 0x80081c8
disk_write() at diskio.c:104 0x800837c
f_mkfs() at ff.c:5,661 0x8008af0
test() at test.c:23 0x80011fc
main() at main.c:103 0x8000914
where I see
if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
(uint32_t)(sector),
count) == MSD_OK)
{
/* Wait that writing process is completed or a timeout occurs */
timeout = HAL_GetTick();
while((WriteStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))
{
}
/* in case of a timeout return error */
if (WriteStatus == 0)
{
res = RES_ERROR;
}
(SD_write() at sd_diskio.c:351 is line 8 in the snippet).
Apparently, it is waiting for BSP_SD_WriteCpltCallback (or HAL_SD_TxCpltCallback, HAL_SD_IRQHandler, SDMMC1_IRQHandler) which is never called:
void BSP_SD_WriteCpltCallback(void)
{
WriteStatus = 1;
}
At this point, if I look at hsd1, I see:
Instance SDMMC_TypeDef * 0x40012800 (Hex)
POWER volatile uint32_t 0x3 (Hex)
CLKCR volatile uint32_t 0x4900 (Hex)
ARG volatile uint32_t 0x3f (Hex)
CMD volatile uint32_t 0x458 (Hex)
RESPCMD const volatile uint32_t 0x18 (Hex)
RESP1 const volatile uint32_t 0x900 (Hex)
RESP2 const volatile uint32_t 0x5b590000 (Hex)
RESP3 const volatile uint32_t 0x76b27f80 (Hex)
RESP4 const volatile uint32_t 0xa404012 (Hex)
DTIMER volatile uint32_t 0xffffffff (Hex)
DLEN volatile uint32_t 0x200 (Hex)
DCTRL volatile uint32_t 0x99 (Hex)
DCOUNT const volatile uint32_t 0x200 (Hex)
STA const volatile uint32_t 0x145000 (Hex)
ICR volatile uint32_t 0x0 (Hex)
MASK volatile uint32_t 0x1a (Hex)
RESERVED0 uint32_t [2] 0x40012840 (Hex)
FIFOCNT const volatile uint32_t 0x80 (Hex)
RESERVED1 uint32_t [13] 0x4001284c (Hex)
FIFO volatile uint32_t 0x4d90feeb (Hex)
I find it interesting that the MASK is Binary:11010, so only bits 1, 3, and 4 are set, which are:
so this list does not include Bit 8 DATAENDIE: Data end interrupt enable.
STA is Binary:101000101000000000000, which is bits 12, 14, 18, and 20:
It's trying to send a 512 byte block:
Since DCOUNT has not decremented, it looks like no data has been transferred.
What could be the problem?
I put the project on GitHub: https://github.com/carlk3/STM32L4A6ZGTx_SDMMC. It should be complete enough to build. (Is that the best way to share code here? It's fairly painless with EGit: the Git integration for Eclipse).
2022-04-11 10:39 AM
After the call to HAL_SD_WriteBlocks_DMA on the L4A6ZG, the TX DMA registers:
TX DMA registers:
3 2 1 0
10987654321098765432109876543210
CCR : 0b00000000000000000011101010011011
CNDTR : 0b00000000000000000000000010000000
CPAR : 0b01000000000000010010100010000000
CMAR : 0b00100000000000000001110101110000
ISR : 0b00000000000000000000000000000000
The DMA channel x configuration register (DMA_CCRx) says:
DMA channel x number of data to transfer register (DMA_CNDTRx): Decimal:128 (Hex:0x80) (which I assume is the number of WORDS).
DMA channel x peripheral address register (DMA_CPARx) is Hex:0x40012880.
DMA channel x memory address register (DMA_CMARx) is 0x20001d70.
DMA interrupt status register (DMA_ISR) is all 0.
If channel enable is 1: enabled, what's stopping it from running?
2022-04-11 12:06 PM
Thanks. I tried your code, but it still hangs up:
test:334: Starting
test:339: SD State: SD initialized and ready for use
test:340: SD Card State: Card is in transfer state
test:387: TX DMA registers:
3 2 1 0
10987654321098765432109876543210
CCR : 0b00000000000000000011101010011011
CNDTR : 0b00000000000000000000000010000000
CPAR : 0b01000000000000010010100010000000
CMAR : 0b00100000000000000001110101110000
ISR : 0b00000000000000000000000000000000
test:394: SD Card State: Card is receiving operation information
test:396: TX DMA State: DMA process is ongoing
SD State: SD process ongoing
test:394: SD Card State: Card is receiving operation information
test:396: TX DMA State: DMA process is ongoing
SD State: SD process ongoing
test:394: SD Card State: Card is receiving operation information
test:396: TX DMA State: DMA process is ongoing
SD State: SD process ongoing
test:394: SD Card State: Card is receiving operation information
test:396: TX DMA State: DMA process is ongoing
SD State: SD process ongoing
test:394: SD Card State: Card is receiving operation information
test:396: TX DMA State: DMA process is ongoing
SD State: SD process ongoing
2022-04-11 02:25 PM
Do these interrupt priorities seem reasonable?
NVIC Interrupt Table Enabled Preemption Priority Sub Priority
Non maskable interrupt TRUE 0 0
Hard fault interrupt TRUE 0 0
Memory management fault TRUE 0 0
Prefetch fault, memory access fault TRUE 0 0
Undefined instruction or illegal state TRUE 0 0
System service call via SWI instruction TRUE 0 0
Debug monitor TRUE 0 0
Pendable request for system service TRUE 0 0
System tick timer TRUE 15 0
PVD/PVM1/PVM2/PVM3/PVM4 interrupts through EXTI lines 16/35/36/37/38 FALSE 0 0
Flash global interrupt FALSE 0 0
RCC global interrupt FALSE 0 0
Time base: TIM1 trigger and commutation interrupts and TIM17 global interrupt TRUE 15 0
EXTI line[15:10] interrupts FALSE 0 0
SDMMC1 global interrupt TRUE 7 0
DMA2 channel4 global interrupt TRUE 6 0
DMA2 channel5 global interrupt TRUE 6 0
USB OTG FS global interrupt FALSE 0 0
LPUART1 global interrupt TRUE 10 0
FPU global interrupt FALSE 0 0
In case that's too hard to read:
2022-04-11 02:50 PM
Look to be reasonable.
I'd avoid printing the FIFO register, no good is likely to occur.
I'm not looking to put engineering hours into this.
2022-04-12 05:09 PM
I went to RM0351; Reference manual; STM32L47xxx, STM32L48xxx, STM32L49xxx and STM32L4Axxx
advanced Arm®-based 32-bit MCUs; June 2021 RM0351 Rev 9, 45.3.2 SDMMC APB2 interface, Example of write procedure using DMA, and implemented it as literally as I could. The behavior is still the same. The SD command (CMD24 WRITE BLOCK) is sent but no data is ever sent. The DMA just doesn't want to run.
I'm starting to suspect that the STM32L4A6ZGT6U does not work as specified.
2022-04-16 02:51 PM
> implemented it as literally as I could
I can see a bunch of both - HAL and LL - bloat. Also I see DMA enable=>disable=>enable for some strange reason...
2022-04-17 09:10 AM
2022-04-18 09:17 AM
I've opened Case Number 00155966. ST wanted to see it fail with one of their examples, so I ported https://github.com/STMicroelectronics/STM32CubeL4/tree/master/Projects/STM32L476G-EVAL/Applications/FatFs/FatFs_uSD_DMA_RTOS to STM32CubeIDE Version: 1.9.0 Build: 12015_20220302_0855 (UTC), and the NUCLEO-L4A6ZG board.
When I run it, it gets as far as this:
SD_write() at sd_diskio.c:458 0x8009450
disk_write() at diskio.c:104 0x800966c
f_mkfs() at ff.c:5,661 0x800c210
FS_FileOperations() at main.c:510 0x8000c34
StartDefaultTask() at main.c:608 0x8000dba
pxPortInitialiseStack() at port.c:214 0x800eb50
This is the wait in osMessageGet(SDQueueID, SD_TIMEOUT) after
BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
(uint32_t) (sector),
count) == MSD_OK)
It is waiting for BSP_SD_WriteCpltCallback(void) to osMessagePut(SDQueueID, WRITE_CPLT_MSG, 0), but SDMMC1_IRQHandler is never called because the transmission never completes because the DMA doesn't send any data.
After a long wait, the SD_TIMEOUT occurs, and it turns on "LED2" indicating an error has occurred.
Looking at the TX DMA after the call to BSP_SD_WriteBlocks_DMA, the state is HAL_DMA_STATE_BUSY, "DMA process is ongoing ".
CCR volatile uint32_t 0x3a9b (Hex) is Binary:11101010011011:
ISR volatile uint32_t is all 0.
2022-04-18 09:20 AM
2022-06-02 09:50 AM
ST suggested a workaround (https://community.st.com/s/case/5003W00000HN3wtQAD):
"The issue is not related to SDMMC HAL driver, it's related to the HW link between DMA2 Channel 4 and SDMMC ( this issue to be investigated by the HW team). As a workaround , please only use Channel 5 for read and write operation."
It does work, and saves me a DMA channel, I guess. Here is the reworked example: