cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 DCMI to SDRAM with DMA - OVERRUN flag

qbaj
Associate II

Hi,

I have problem (OVERRUN flag) with data transfer from DCMI to external SDRAM.

I have STM32H753 which in AN5020 has architecture like this:

(Application note, Digital camera interface (DCMI) for STM32 MCUs)

0693W000001pLLfQAM.bmp

So it has connection between DCMI and FMC via DMA1/2 and D2-D1-bridge.

Great, but ...

when I send frame 320x240@RGB888 from DCMI to SDRAM,

I get in HAL_DCMI_GetError value 0x41 (HAL_DCMI_ERROR_DMA | HAL_DCMI_ERROR_OVR)

and in HAL_DMA_GetError valueo 0x00 (HAL_DMA_ERROR_NONE).

Configuration for DCMI and DMA:

hdcmi.Instance = DCMI;
hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_HIGH;
hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL;
hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD;
hdcmi.Init.LineSelectMode = DCMI_LSM_ALL;
hdcmi.Init.LineSelectStart = DCMI_OELS_ODD;
...
hdma_dcmi.Instance = DMA1_Stream0;
hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_dcmi.Init.Mode = DMA_NORMAL;
hdma_dcmi.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;

Some system info:

  • SYSCLK = 400Mhz
  • AXI/HCLK = 400Mhz
  • FMC = 200Mhz (SDRAM @ 100Mhz)
  • SDRAM (is42s16800, 12-bit address , 16-bit data)
  • STM32Cube FW_H7 V1.6.0

Some tests:

  1. DMA1 (peripheral to memory) from DCMI to buffer in RAM_D2 (internal), it works and takes 78-83ms for frame 320x240x3
  2. DMA1 (memory to memory) from buffer in RAM_D2 to buffer in SDRAM, it works and takes 3-8ms for frame 320x240x3, so it is faster than 1)
  3. DMA1 (peripheral to memory) from DCMI to buffer in SDRAM, it does NOT WORK.
  4. DMA1 (peripheral to memory) from DCMI to buffer in AXI SRAM, it does NOT WORK

Has anyone had a similar problem?

Is there some other configuration for DCMI with external SDRAM? or DMA? or D2-D1-bridge?

Please, help.

BR

Jakub

1 ACCEPTED SOLUTION

Accepted Solutions
qbaj
Associate II

Hi there,

Yes, I'm using LTDC for LCD screen and also TouchGFX.

I've solved problem by buffering image in RAM_D2, so it looks like:

DCMI -> (DMA) -> CAPTURE_BUFFER in RAM_D2 -> (MDMA) -> FRAME_BUFFER in SD_RAM -> (PixelDataWidget from TouchGFX) -> LCD_BUFFER -> (LTDC) -> LCD

View solution in original post

6 REPLIES 6
qbaj
Associate II

Hi again,

ad.4)

I was able to run DMA1 with DCMI and AXI SRAM.

hdma_dcmi.Instance = DMA1_Stream0;
hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_dcmi.Init.Mode = DMA_NORMAL;
hdma_dcmi.Init.Priority = DMA_PRIORITY_VERY_HIGH;
 
hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
 
hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_dcmi.Init.MemBurst = DMA_MBURST_INC4;
 
hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

I understand that DCMI and AHB are (WORD)32bit, AXI and FMC are 64bit, SDRAM is 16bit bus width.

But for option 3) DCMI with SDRAM that config is still incorrect.

Could someone help me with this?

It would help if you could isolate the problem's source, i.e. exactly which DMA/DCMI flags are set. I don't think Cube helps in this, you should really look directly at the registers.

Try to decrease FIFO threshold, perhaps to half, but without burst (i.e. DMA_MBURST_INC1).

JW

qbaj
Associate II

When HAL_DCMI_IRQHandler triggered I got:

0693W000001pVIWQA2.jpg

So for DCMI I have in MISR register DCMI_FLAG_OVRRI = 0x02 and for DMA in LISR register DMA DMA_LISR_FEIF0 = 0x01.

FIFO treshold DMA_FIFO_THRESHOLD_HALFFULL without burst DMA_MBURST_SINGLE no effect.

sirius506
Associate III

Are you using LTDC with frame buffer allocated on the SDRAM?

If so, LTDC needs DMA transfer to refresh the LCD screen image and it conflicts with DCMI transfer.

You can try to disable LTDC clock while DCMI capture and see if it solves the problem.

Conflict with LTDC sound like a plausible reason, but on second thought, I wouldn't be surprised if it turns out that DCMI into SDRAM is simply not plausible at all, even without LTDC getting into way.

Let's put it this way: what's the incoming data rate to DCMI? Is there enough buffering in way (in DCMI itself, in DMA's FIFO, in FMC) to hold data for the longest SDRAM/FMC latency (probably the SDRAM refresh)?

JW

qbaj
Associate II

Hi there,

Yes, I'm using LTDC for LCD screen and also TouchGFX.

I've solved problem by buffering image in RAM_D2, so it looks like:

DCMI -> (DMA) -> CAPTURE_BUFFER in RAM_D2 -> (MDMA) -> FRAME_BUFFER in SD_RAM -> (PixelDataWidget from TouchGFX) -> LCD_BUFFER -> (LTDC) -> LCD