cancel
Showing results for 
Search instead for 
Did you mean: 

stm32u5g9 dcmi double buffer linked list

rvminsta_01
Associate

Hello

 

Using a STM32U5G9NJHxQ.

Using a 646x480 1byte per pixel monochrome Dcmi camera --> 310080 bytes --> 77520 words (32 bits) --> according to AN5020 6.4.8 this means Double buffer mode for medium resolutions, continuous capture in my case.

Based on DCMI_ContinousCap_EmbeddedSynchMode example, I made some changes to try the linked list and double buffer.

Please see txt file attached explaining my testing.

Please, is there any official example from Stm on how to configure stm32u5g9 Dcmi with linked list and double buffer ?

 

Regards.

 

 

 

 

 

 

 

 

 

 

 

 

3 REPLIES 3
KDJEM.1
ST Employee

Hello @rvminsta_01 and welcome to the community;

 

Please see How to insert source code.

Could you give more details about the issue after changing code?

Which camera module are you used? 

Is the capture bit enabled?

Do you have any issues with low resolution?

I haven't found a DCMI example with STM32U5G9 and linked list but you can start with DCMI_ContinousCap_EmbeddedSynchMode.

I advise you to migrate this example from STM32U575I-EV to STM32U5G9. Then, try to change the resolution.

 

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.

Hello Kaouthar, thank you for your answer.

 

It is a Dcmi camera that was working with stm32h7, we had a firmware that worked with stm32h7b3i-dk. We are in fact migrating from h7 to u5.

I do not know what you mean with capture bit. Is it something to configure in u5 microcontroller ?.

The camera resolution is 640x480, 1 byte per pixel monochrome, Dcmi (we already had it tested with h7) .

 

DCMI_ContinousCap_EmbeddedSynchMode

example has 320x240x2/4=38400 words (32bits), we have 640x480x1/4=76800 words (32bits). That is why we need linked list double buffer, according to AN5020 6.4.8.

So we would need the ContinousCap example modified for double buffer linked list. I guess we need to somehow modify DCMIQueue_Config(void) function.

Please have a look at my code, I am posing some questions where I have the biggest doubts.

 

Regards.

#define CAMERA_FRAME_WIDTH              640U
#define CAMERA_FRAME_HEIGHT             480U
#define CAMERA_BYTES_PIXEL              1U
#define CAMERA_FRAME_SIZE_BYTES         (CAMERA_FRAME_WIDTH * CAMERA_FRAME_HEIGHT * CAMERA_BYTES_PIXEL)
#define CAMERA_FRAME_SIZE_WORDS         (CAMERA_FRAME_SIZE_BYTES / 4U)
#define CAMERA_FRAME_HALF_SIZE_WORDS    (CAMERA_FRAME_SIZE_WORDS/2U) 

static DMA_NodeTypeDef camera_DCMINode1;
static DMA_QListTypeDef camera_DCMIQueue;
static DMA_NodeTypeDef camera_DCMINode2;
__attribute__((aligned(4))) static uint32_t camera_frameBuffer[CAMERA_FRAME_SIZE_WORDS];

// This my last try of DCMIQueue_Config function
HAL_StatusTypeDef camera_DCMIQueue_Config(void)
{
  HAL_StatusTypeDef ret = HAL_OK;
  /* DMA node configuration declaration */
  DMA_NodeConfTypeDef pNodeConfig;

  /* Set node configuration ################################################*/
  pNodeConfig.NodeType = DMA_GPDMA_2D_NODE;
  pNodeConfig.Init.Request = GPDMA1_REQUEST_DCMI;
  pNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
  pNodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
  pNodeConfig.Init.SrcInc = DMA_SINC_FIXED;
  pNodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
  pNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
  pNodeConfig.Init.DestDataWidth = DMA_SRC_DATAWIDTH_WORD;
  pNodeConfig.Init.SrcBurstLength = 1;
  pNodeConfig.Init.DestBurstLength = 1;
  pNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
  pNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
  pNodeConfig.RepeatBlockConfig.RepeatCount = 1;
  pNodeConfig.RepeatBlockConfig.SrcAddrOffset = 0;
  pNodeConfig.RepeatBlockConfig.DestAddrOffset = 0;
  pNodeConfig.RepeatBlockConfig.BlkSrcAddrOffset = 0;
  pNodeConfig.RepeatBlockConfig.BlkDestAddrOffset = 0;
  pNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
  pNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
  pNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
  pNodeConfig.SrcAddress = (uint32_t)&DCMI->DR;
  pNodeConfig.DstAddress = (uint32_t)camera_frameBuffer;
  pNodeConfig.DataSize = CAMERA_FRAME_HALF_SIZE_WORDS;  // should be CAMERA_FRAME_SIZE_WORDS ?

  /* Build DCMINode1 Node */
  ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &camera_DCMINode1);

  /* Insert DCMINode1 to Queue */
  ret |= HAL_DMAEx_List_InsertNode_Tail(&camera_DCMIQueue, &camera_DCMINode1);

  /* Set node configuration ################################################*/

  /* Build DCMINode2 Node */
  pNodeConfig.DstAddress = (uint32_t)&camera_frameBuffer[CAMERA_FRAME_HALF_SIZE_WORDS]; // Is it right ?
  ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &camera_DCMINode2);

  /* Insert DCMINode2 to Queue */
  ret |= HAL_DMAEx_List_InsertNode_Tail(&camera_DCMIQueue, &camera_DCMINode2);

  ret |= HAL_DMAEx_List_SetCircularModeConfig(&camera_DCMIQueue, &camera_DCMINode1);

  // Link camera dcmi dma to Queue
  ret |= HAL_DMAEx_List_LinkQ(main_gethandler_Dma_DcmiCamera(), &camera_DCMIQueue);

  return ret;
}

// How should I make the call to HAL_DCMI_Start_DMA
// this way ?
HAL_DCMI_Start_DMA(p_camera_dcmi, DCMI_MODE_CONTINUOUS, (uint32_t)camera_frameBuffer, CAMERA_FRAME_SIZE_WORDS);
// this way ?
HAL_DCMI_Start_DMA(p_camera_dcmi, DCMI_MODE_CONTINUOUS, (uint32_t)camera_frameBuffer, CAMERA_FRAME_HALF_SIZE_WORDS);
// any other way ?

// This is how camera_DCMIQueue_Config gets called in initialization, main.c
  // ...
  MX_UART5_Init();
  MX_I2C3_Init();
  MX_DCMI_Init();
  MX_UART4_Init();
  /* USER CODE BEGIN 2 */
  if(HAL_OK != camera_DCMIQueue_Config()){
	  Error_Handler();
  }
  __HAL_LINKDMA(main_gethandlerDcmiCamera(), DMA_Handle, handle_GPDMA1_Channel12);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

 

 

 

KDJEM.1
ST Employee

Hello,

The CAPTURE bit is a bit in the DCMI_CR register.

KDJEM1_0-1749819630088.png

For HAL_DCMI_Start_DMA: 

HAL_StatusTypeDef HAL_DCMI_Start_DMA (DCMI_HandleTypeDef * hdcmi, uint32_t DCMI_Mode,
uint32_t pData, uint32_t Length)

With parameters
• hdcmi: pointer to a DCMI_HandleTypeDef structure that contains the configuration information for DCMI.
• DCMI_Mode: DCMI capture mode snapshot or continuous grab.
• pData: The destination memory Buffer address (LCD Frame buffer).
• Length: The length of capture to be transferred.

You can refer to Description of STM32U5 HAL and low-layer drivers for each peripheral driver description.

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.