cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U575 GPDMA DCMI High resolution image

JMarshall123
Associate II

Hi

I've been struggling trying to get an Image from a Image sensor over DCMI via the GPDMA on an STM32U575.

The image sensor has a resolution of 752*480, though I only want to capture 420*420, which I've configured on the sensor to output. I've also configured it to output a B&W image meaning I only get one byte per pixel.

I've used the DCMI_ContinousCap_EmbeddedSychMode example as the basis for my code, though I'm not using an omnivision sensor so I've swapped out the configuration for one required for my image sensor. However, for the most part, I have not modified the GPDMA or linked list settings from this example, just the I2C comms (swapped to SPI) and DCMI to external synchro, and DCMI polarities to match my image sensors output.

when I try to pull a full image in one DMA transfer, I get an overflow error after only receiving half the image (88200 bytes). When I make the image size 360*360 I get the full image just fine (129600 bytes).

I did try splitting this into 3 requests of 420*140, after receiving the first of these 3 requests the DCMI remains in the busy state and never returns to a ready state, if I force it into the ready state in the line callback, it goes into the ready state but then fails to start on the next HAL_DCMI_Start_DMA call.

 

I also tried adding additional nodes to my linked list, the original example had 2 set up, I've attempted adding 2 additional nodes with the same settings and this didn't work either.


Also I am never getting a DCMI_FLAG_FRAMERI interrupt, even if I set my image size to 16*16 I get all 256 bytes but I don't receive an interrupt, instead I get a line interrupt. I can see my VSYNC line going high from my image sensor.

I am curious as to what the STM treats as "active high" in the DCMI parameter settings related to synchronization, does "active" mean in the process of receiving data or syncing at the end of a given line or frame. The reason I'm asking is that if it's active in the state that it is receiving data (pixels being output), I'm getting nothing in terms of data, only when i set these to the opposite of what my sensors datasheet states do I receive any data, this datasheet explicitly states that the LEN and FEN (vsync and hsync equivalent) are active low (0 means that pixels are being output).

I've attached my ioc used to generate my code.
I call in my main:
MX_DCMIQueue_Config();
HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel12, &DCMIQueue);
__HAL_LINKDMA(&hdcmi, DMA_Handle, handle_GPDMA1_Channel12);

 

I initialise my sensor then call:
HAL_DCMI_Start_DMA(ev76c541Dcmi, DCMI_MODE_SNAPSHOT, (uint32_t)Buff1, TRANSFER_LEN / 4);

where TRANSFER_LEN is 176400

There isnt really anything outside of this that i'm doing in my code I just wait in a while one loop waiting for the transfer to complete then check my buffer and dcmi->State after a period of time.

Thanks and regards

Jack

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

I think my problem is related to alignment, when I pass the data from the DMA into a 32 bit buffer rather than an 8 bit one, the data goes through just fine. I made the assumption that passing in the memory location by pointer meant that it didn't matter what it was filling into. I am able to create a union allowing me to fill in a 32 bit buffer and use individual bytes, so this solution works for me.

View solution in original post

8 REPLIES 8
KDJEM.1
ST Employee

Hello @JMarshall123 and welcome to the community :),

Could you please refer to the sensor datasheet and check PIXCLK, HSYNC and VSYNC.

The DCMI is a slave and doesn't stat work only if DCMI_VSYNC and DCMI_HSYNC signals are coming.

Regarding the meaning of "active high", for example, if VSYNC is programmed active high:

• When VSYNC is low, the data is valid.
• When VSYNC is high, the data is not valid (vertical blanking)

The below figure shows an example of data transfer when DCMI_VSYNC and DCMI_HSYNC are active high, and when the capture edge for DCMI_PIXCLK is the rising edge.

KDJEM1_0-1708521764496.png

For more information, I advise you to take a look to AN5020 and precisely 5.4.1 Hardware (or external) synchronization section.

Note that generally the synchronization polarity must not be inverted.

I hope this help you.

Thank you.

Kaouthar

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

JMarshall123
Associate II

Just a quick update, turns out __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_FRAME) was being called prematurely in the hal dcmi source fill, only when I regenerated by code again did I notice this. I'm guessing I just dragged it in my IDE by mistake at some point. I am now getting frame interrupts but I am still not able to receive any more than a 360 x 360 image, without an overflow error, this limitation appears to be 2*65535 as, in my dcma structure, when XferCount is 2 after requesting, everything is fine but as soon as this increases to XferCount is 3, I get overflow issues. This is why I assumed I required additional linked list items as the example only had 2 nodes and I wasn't sure how the dma would handle 3 transfers over 2 nodes. I also noticed the example didnt have the Source address, Destination address and data size configured for either node, but I assumed that this is because calling HAL_DCMI_Start_DMA configures these values automatically using its input parameters. Is this correct?

 

Thank you for your reply,
This makes sense you've confirmed my suspision that ST is refering to the "active" state as the state where data is not valid or point of line sync, in which blanking data is sent. This is the opposite to what my sensors datasheet is refering to as the "active" state. See image from my imagers datasheet below where LEN is HSYNC and FEN is VSYNC:

JMarshall123_0-1708523984516.png


It's not that I was inverting the syncronization, what is referred to in my sensors datasheet as active low or active high is flipped compared to how ST describe it. To be honest I think STs terminology is better, for the most part I think its what is considered standard, though I am not the only one that realised this terminology is confusing See this post.

I've managed to confirm that there isnt an issue with my frame interrupt at all though, just that the largest dma image I can request is 360x360, I've confirmed my data width is word and not half word. I was under the assumption that the largest DMA transfer was 4*65535 in bytes when using word as the datawidth, is this correct? And if so why would I getting overflow errors when requesting more than 2*65535? Is the configuration of the gpdma and linked lists in the DCMI_ContinousCap_EmbeddedSychMode example suitable for receiving a 420*420 image (176400 bytes)?

Hello @JMarshall123 ,

The max number of bytes depends on the resolution and on mode RGB565, YCbCr or Y only.

For that I advise you to refer to AN5020 and precisely these section:

- 6.4.6 Normal mode for low resolution in snapshot capture 

-6.4.7 Circular mode for low resolution in continuous capture DMA transfer

-6.4.8 Double-buffer mode for medium resolutions (snapshot or continuous capture) 

-6.4.9 DMA configuration for higher resolutions

As mentioned in the readme for DCMI_ContinousCap_EmbeddedSychMode example describe how to configure the camera in continuous mode in QVGA (320x240) resolution, with synchronization mode set to Embedded Synchronization and to suspend/Resume the capture.

I hope this help you to answer your request!

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

My imager is configured to output in Y only format and my resolution is 420x420 (176400 bytes 1 byte per pixel, 44100 words). According to table 11, with a Bit depth of 1 byte per pixel I should be able to receive up to 262140 pixels worth of data, this is quite a bit more than I require. This means I should be able to capture a snapshot in normal mode. To do this I configure my imager to output a 420x420 image then pass into my HAL_DCMI_Start_DMA function the following arguments:

&hdcmi - address of the dcma handle created by cubeMx
DCMI_MODE_SNAPSHOT - single capture
(uint32_t)buff - pointer to 420*420 uint8 array cast to a unsigned 32 bit value
length - 420*420/4

When I use these arguments I get an DCMI_FLAG_OVRRI after receiving half the data into my buffer. If I instead configure my imager to output a 360x360 image and change my length in the start command to 360*360/4 I receive all 129600 bytes as I would expect from a 360x360 monochrome image. I don't understand why I would be be getting an overflow error if I haven't exceeded any size limitations. It's almost as if the Data width of word isnt being set, and half word is being used instead, but my LINKED_LIST settings in cubeMX, the data width is deffinitly being set to word, the settings are as follows:

JMarshall123_1-1708536000333.png

Here are my dcmi handle values before the request:

JMarshall123_2-1708536486404.png

After the request (but before error interrupt):

JMarshall123_3-1708536545983.png

and after the error interrrupt:

JMarshall123_4-1708536591217.png

I cant tell exactly whats gone wrong, as far as I can see it got half way through the 2nd XferCount then hit an overflow error but I don't know why this has triggered.

 

 

 

Hi @JMarshall123 ,

Could you please try to increase the SYSCLCK?

Are you using other peripherals with same DCMI bus "AHB2".

KDJEM1_0-1708695765006.png

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

My system clock is at maximum (160MHz), using an external crystal as the PLL souce, I've also slowed down the output of my image sensor to minimum in case it were the cause.

Other than SPI1 for the sensor config, TIM1 for a usec tic and USART1 for serial debugging, the only Peripherals on the AHB2 bus I am using based on the STM32U575 datasheet are GPIO.

 

I think my problem is related to alignment, when I pass the data from the DMA into a 32 bit buffer rather than an 8 bit one, the data goes through just fine. I made the assumption that passing in the memory location by pointer meant that it didn't matter what it was filling into. I am able to create a union allowing me to fill in a 32 bit buffer and use individual bytes, so this solution works for me.