2012-07-11 11:04 AM
Hello folks,
we are developing a measurement application for the STM32F103ZGT6 (1 MB Flash, 96 K RAM). The application uses the stm32f10x_stdperiph_lib v3.5.0, FreeRTOS V6.10 and FatFs R0.08b.
The application uses the example code from stm32_eval_sdio_sd.c/h.
We have some issues when using the SD Card interface. We're using the DMA Mode (DMA 2, Channel 4) to write Data from an external 16 MB PSRAM to the SD Card with the function SD_WriteMultiBlocks().
After that, we wait with SD_WaitWriteOperation() for the finished transfer. This process is repeated as long as new data is available / a measurement is ongoing. This works, but after a short period of time, the SD_WaitWriteOperation() will hang in the while loop forever. The reasons seems to be, that the DMA doesn't set either the DMA2_FLAG_TC4 (Transfer Complete) nor any error flags. Normally the DMA2_FLAG_HT4 Flag (Half Transfer) is set at that time. Most of the Time, the SDIO_STA has also some of the FIFO Over- or Underrun Flags (RXOVERR or TXUNDERR) set. It seems, it depends on the number of blocks written by SD_WriteMultiBlocks(), which flag is set. With 128 Blocks, it tends to be an RXOVERR, with 384 Blocks TXUNDERR. I'm still experimenting with the numbers.
Sometimes the same issues occurs also on SD_ReadMultiBlocks() / SD_WaitReadOperation().
If I implement a timeout in the wait functions, the hang occurs in the CmdResp1Error() function. With a timeout there, eventually a Hard Fault occurs.
---
I've written a small test loop, which I run in a endless loop in some medium prior task and active or inactive ADC.
SD_Error SdCard_WriteTest(uint8 megabytes, uint16 multiBlockCount)
{
SD_Error result, Status;
int
i = 0;
uint32_t adr = 5000;
for
(i = 0; i<megabytes*1024*1024/512/multiBlockCount; i++)
{
result = SD_WriteMultiBlocks((uint8_t*)SRAM_BASE, adr, 512, multiBlockCount);
// The SRAM is the lokal 96 K RAM memory of the CPU | works fine up to 184 Blocks
//result = SD_WriteMultiBlocks((uint8_t*)Bank1_ExtRam_ADDR, adr, 512, multiBlockCount); // The Bank1_ExtRam_ADDR is the external 16 MB RAM | may hang after some time
Status = SD_WaitWriteOperation();
while
(SD_GetStatus() != SD_TRANSFER_OK);
adr += 512*multiBlockCount;
}
return
result;
}
while
(1)
{
SdCard_WriteTest(30, SDCARDBLOCKS);
// up to 184 works fine (which corresponds to the SRAM size), 382 hangs
}
After those tests, it looks like the behavior depends on the source of data for the SD card. As long as we use the SRAM, it works out fine. Unfortunately the memory size is way too low. Also it seems, the ADC has no influence besides the likelihood of the occurrences of the data transfer errors.
---
Questions:
In the errata sheet for the STM32F103xC/D/E line processors from June 2011, there two described limitations that may affect the above scenario. In the errata sheet for the STM32F103xG/F line from February 2011, I can't find those issues? Are they missed or is the errata sheet correct and we having another error?
2.17 FSMC limitations
2.1 Multimaster access on the FSMC memory map
Description
When multimaster accesses are performed on the FSMC memory map (address space from
0x6000 0000 to 0xA000 0FFF), an error could be generated, leading to either a bus fault or
a DMA transfer error.
A multimaster can be:
�?
DMA1 and DMA2
�?
DMA1 and CPU
�?
DMA2 and CPU
Workaround
If multimaster accesses are required on the FSMC address space, the software must
ensure that accesses are performed one at a time, and not at the same time.
2.2 Data errors in SDIO hardware flow control mode
Description
When HW Flow Control is enabled by setting bit 14 of SDIO_CLKCR register, some glitches
can occur on the SDIO_CK output clock resulting in wrong data being written in the
SD/MMC Card or the SDIO device. As consequence a data CRC error is reported to the
SD/SDIO MMC host interface (DCRCFAIL bit in the SDIO_STA register is set).
Workaround
None. HW Flow Control must not be used. Software has to manage Overrun Errors (Rx
mode) and FIFO underrun (Tx mode).
---
Is there something particular, we should mention when initializing / using the external memory via FSMC?
Do we have an alternative to implement the SD Card access via polling or interrupt based?
=========
Another possible reason for this behavior may be in the architecture of the measurement device. We're using an external 8x16 Bit ADC Controller.
The data processing uses this scheme:
===
ADC IRQ->''Data Available'' (16 Byte)
-> CPU instructs the DMA1 Channel 2 to transfer the data in the 96k SRAM
DMA1CH2 IRQ->''Data Ready''
-> CPU makes some short calculations and copies the data (now 18 Byte) with memcpy to the external Bank1_ExtRam_ADDR (PSRAM).
-> If there are enough data in the external RAM, a Task will waken up (SD_WRITE_TASK).
=== This process repeats at 5000/10000/20000 or 40000 Hz however even on 5000Hz the described scenario occurs; only the odds are reduced.
SD_WRITE_TASK (with highest priority) -> The Task starts a DMA2CH4 transfer as described above and will hang in the endless-loop after a short while.
#sdio-rxoverr-stm32f1032016-02-19 12:22 AM
I have exactly the same problem without
FreeRTOS
, but on STM32F103VGT6. Program still waiting for transfer ending but data counter in DMA is constans. SDIO report about RX overrun. It happens in randomely time in the same operation. Program is hanged in sdio_sd.c in SD_ReadBlock procedure:while ((SD_DMAEndOfTransferStatus() == RESET) && (TransferEnd == 0) && (TransferError == SD_OK))<
br
> {}
2016-02-19 05:23 AM
It is important to understand that demonstration code is not the same as commercial code. You will need to add a lot more error handling, timeouts and retries, to handle the situations where things don't work in a semi-ideal fashion. The demo code can give you a starting point, but you need to invest time in it to create a commercial product. Any situation where there is a loop without a timeout is a big red flag that further attention is required.
Here I suspect that there is a race condition between submitting a command, and getting a completion IRQ. ie it is waiting for an IRQ that has already occured