cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U585 GPDMA Config for DCMI in LL

Linas L
Senior II

Hello,

For my project I need to transfer 600x600x10b image from DCMI to SRAM.

I already got DCMI part working with all HSYNC / VSYNC interrupts showing correct numbers

LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_DCMI_PSSI);
NVIC_SetPriority(DCMI_PSSI_IRQn, NVIC_EncodePriority(prioritygroup, 4, 0)); NVIC_EnableIRQ(DCMI_PSSI_IRQn);
 
DCMI->IER =DCMI_IER_OVR_IE|DCMI_IER_VSYNC_IE|DCMI_IER_LINE_IE;
DCMI->CR  =DCMI_CR_ENABLE + (0x01<<10); //10bit

After this, I need to configure DMA. Now we get into trouble, because we need do more than 0xFFFF transfers. My understanding wthis is why we have lists.

Since we need 600x600 at half word, in reality we would need only half transfers, so we have 180.000 Transfers. I will split it in my lists into 3 chunks

65536

65536

48928

(note, at the moment, I fill all of my array with 0xAAAA data, and I set only small portion of DATA to be transferred in the list, so I could figure out how GDMA1 is working, after I confirm with debugger data was overwritten in requested locations, I will stitch it correctly)

static void DMA_LinkedListConfig(void)
{
 
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPDMA1);
 
  LL_DMA_InitNodeTypeDef       DMA_InitNodeStruct;
  LL_DMA_InitLinkedListTypeDef DMA_InitLinkedListStruct;
 
  /* Set node 1 configuration ################################################*/
  /* Set node type */
  DMA_InitNodeStruct.NodeType                 = LL_DMA_GPDMA_2D_NODE;
  DMA_InitNodeStruct.Request                  = LL_GPDMA1_REQUEST_DCMI_PSSI;
  /* Set node configuration */
  DMA_InitNodeStruct.BlkHWRequest             = LL_DMA_HWREQUEST_SINGLEBURST;
  DMA_InitNodeStruct.Direction                = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  DMA_InitNodeStruct.DestAllocatedPort        = LL_DMA_DEST_ALLOCATED_PORT1;
 
  DMA_InitNodeStruct.SrcBurstLength           = 1U;
  DMA_InitNodeStruct.SrcIncMode               = LL_DMA_SRC_FIXED;
  DMA_InitNodeStruct.SrcDataWidth             = LL_DMA_SRC_DATAWIDTH_WORD;
  DMA_InitNodeStruct.TransferEventMode        = LL_DMA_TCEM_LAST_LLITEM_TRANSFER;
 
  DMA_InitNodeStruct.DestBurstLength          = 1U;
  DMA_InitNodeStruct.DestIncMode              = LL_DMA_DEST_INCREMENT;
  DMA_InitNodeStruct.DestDataWidth            = LL_DMA_DEST_DATAWIDTH_WORD;
  DMA_InitNodeStruct.SrcAllocatedPort         = LL_DMA_SRC_ALLOCATED_PORT0;
 
  DMA_InitNodeStruct.DataAlignment            = LL_DMA_DATA_ALIGN_ZEROPADD;
  DMA_InitNodeStruct.DestHWordExchange        = LL_DMA_DEST_HALFWORD_PRESERVE;
  DMA_InitNodeStruct.DestByteExchange         = LL_DMA_DEST_BYTE_PRESERVE;
  DMA_InitNodeStruct.SrcByteExchange          = LL_DMA_SRC_BYTE_PRESERVE;
 
  DMA_InitNodeStruct.TriggerPolarity          = LL_DMA_TRIG_POLARITY_MASKED;
 
  DMA_InitNodeStruct.BlkRptDestAddrUpdateMode = LL_DMA_BLKRPT_DEST_ADDR_INCREMENT;
  DMA_InitNodeStruct.BlkRptSrcAddrUpdateMode  = LL_DMA_BLKRPT_SRC_ADDR_INCREMENT;
  DMA_InitNodeStruct.DestAddrUpdateMode       = LL_DMA_BURST_DEST_ADDR_INCREMENT;
  DMA_InitNodeStruct.SrcAddrUpdateMode        = LL_DMA_BURST_SRC_ADDR_INCREMENT;
  DMA_InitNodeStruct.BlkRptCount              = 0U;
  DMA_InitNodeStruct.DestAddrOffset           = 0U;
  DMA_InitNodeStruct.SrcAddrOffset            = 0U;
  DMA_InitNodeStruct.BlkRptDestAddrOffset     = 0U;
  DMA_InitNodeStruct.BlkRptSrcAddrOffset      = 0U;
 
  /* Set registers to be updated */
  DMA_InitNodeStruct.UpdateRegisters          = LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CLLR |LL_DMA_UPDATE_CTR2;
  DMA_InitNodeStruct.SrcAddress               = (uint32_t)&DCMI->DR;
  DMA_InitNodeStruct.DestAddress              = (uint32_t)&DCMI_DATA[0];
  DMA_InitNodeStruct.BlkDataLength            = 10;
  LL_DMA_CreateLinkNode(&DMA_InitNodeStruct, &pNode1);
 
  DMA_InitNodeStruct.UpdateRegisters          = LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CLLR;
  DMA_InitNodeStruct.SrcAddress               = (uint32_t)&DCMI->DR;
  DMA_InitNodeStruct.DestAddress              = (uint32_t)&DCMI_DATA[100];
  DMA_InitNodeStruct.BlkDataLength            = 20;
  LL_DMA_CreateLinkNode(&DMA_InitNodeStruct, &pNode2);
 
  DMA_InitNodeStruct.UpdateRegisters          = LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR |LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CLLR;
  DMA_InitNodeStruct.SrcAddress               = (uint32_t)&DCMI->DR;
  DMA_InitNodeStruct.DestAddress              = (uint32_t)&DCMI_DATA[200];
  DMA_InitNodeStruct.BlkDataLength            = 40;
  LL_DMA_CreateLinkNode(&DMA_InitNodeStruct, &pNode3);
 
 
  LL_DMA_ConnectLinkNode       (&pNode1, LL_DMA_CLLR_OFFSET5, &pNode2, LL_DMA_CLLR_OFFSET4);
  LL_DMA_ConnectLinkNode       (&pNode2, LL_DMA_CLLR_OFFSET4, &pNode3, LL_DMA_CLLR_OFFSET4);
  LL_DMA_DisconnectNextLinkNode(&pNode3, LL_DMA_CLLR_OFFSET4);
 
 
 
  DMA_InitLinkedListStruct.Priority          = LL_DMA_HIGH_PRIORITY;
  DMA_InitLinkedListStruct.TransferEventMode = LL_DMA_TCEM_LAST_LLITEM_TRANSFER;
  DMA_InitLinkedListStruct.LinkStepMode      = LL_DMA_LSM_FULL_EXECUTION;
  DMA_InitLinkedListStruct.LinkAllocatedPort = LL_DMA_LINK_ALLOCATED_PORT1;
 
  LL_DMA_List_Init            (GPDMA1, LL_DMA_CHANNEL_12, &DMA_InitLinkedListStruct);
  LL_DMA_SetLinkedListBaseAddr(GPDMA1, LL_DMA_CHANNEL_12, (uint32_t)&pNode1);
  LL_DMA_ConfigLinkUpdate     (GPDMA1, LL_DMA_CHANNEL_12, LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR |LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CLLR, (uint32_t)&pNode1);
 
  LL_DMA_EnableIT_USE(GPDMA1, LL_DMA_CHANNEL_12);
  LL_DMA_EnableIT_ULE(GPDMA1, LL_DMA_CHANNEL_12);
  LL_DMA_EnableIT_DTE(GPDMA1, LL_DMA_CHANNEL_12);
  LL_DMA_EnableIT_TC (GPDMA1, LL_DMA_CHANNEL_12);
 
  NVIC_SetPriority(GPDMA1_Channel12_IRQn,   NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
  NVIC_EnableIRQ(GPDMA1_Channel12_IRQn);
 
  LL_DMA_EnableChannel(GPDMA1, LL_DMA_CHANNEL_12);
}

At this point, camera does not generate any DATA, and HSYNC, VSYNC is on its default level. And I already get Increment error user flag

Fill_data();
  DMA_LinkedListConfig();
  Delay(0xFFFFFF);
  DCMI->CR |=DCMI_CR_CAPTURE;

And if I enable DCMI and trigger camera for single frame, no data is transferred.

Can any one spot what I am doing wrong ? I used memory to memory copy example, and changed settings to DCMI. At this point I have no idea whats wrong. I will spend some time reading about all registers, but is not exactly straight forward where problem is.

Thank you if you are still reading this, and hope you can see the problem I am facing !

For correct answer will send you STM32H743ZIT6 microcontroller for free !

1 REPLY 1
Linas L
Senior II

any ideas?