Help with GPDMA Peripheral to Memory Transfer

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Dear All

uC: XMC4500-F144K1024 AB.
Board: Infineon Hexagon Application Kit.

I am working on a project that need DMA transfer from ADC result register to memory.I plan to use it to move data from VADC_G0->RES[6] to some variable named Var_Result. Below is the code i use to initialize the GPDMA0_CH0.

//De-assert reset signal for GPDMA0
SET_BIT(SCU_RESET->PRCLR2,SCU_RESET_PRCLR2_DMA0RS_Pos);
//Enable GPDMA0
SET_BIT(GPDMA0->DMACFGREG,GPDMA0_DMACFGREG_DMA_EN_Pos);

//Configure DMA channel
//Write the starting source register for GPDMA0_CH0
WR_REG(GPDMA0_CH0->SAR,GPDMA0_CH_SAR_SAR_Msk,GPDMA0_CH_SAR_SAR_Pos,(uint32_t)(&(VADC_G0->RES[6])));
//Write the destination register for GPDMA0_CH0
WR_REG(GPDMA0_CH0->DAR,GPDMA0_CH_DAR_DAR_Msk,GPDMA0_CH_DAR_DAR_Pos,(uint32_t)(&Var_Result));

//Configure DMA Control Register
GPDMA0_CH0->CTLL=(uint32_t)0;
GPDMA0_CH0->CTLH=(uint32_t)0;
GPDMA0_CH0->LLP=(uint32_t)0;

//Write one block size
WR_REG(GPDMA0_CH0->CTLH,GPDMA0_CH_CTLH_BLOCK_TS_Msk,GPDMA0_CH_CTLH_BLOCK_TS_Pos,0x01);
//Configure 32 bit width for source and destination register
WR_REG(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_SRC_TR_WIDTH_Msk,GPDMA0_CH_CTLL_SRC_TR_WIDTH_Pos,0x02);
WR_REG(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_DST_TR_WIDTH_Msk,GPDMA0_CH_CTLL_DST_TR_WIDTH_Pos,0x02);
//No increment or decrement for source and destination register
WR_REG(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_SINC_Msk,GPDMA0_CH_CTLL_SINC_Pos,0x02);
WR_REG(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_DINC_Msk,GPDMA0_CH_CTLL_DINC_Pos,0x02);
//Disable Scather, Gather, and linked list pointer for both source and destination register
CLR_BIT(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_DST_SCATTER_EN_Pos);
CLR_BIT(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_SRC_GATHER_EN_Pos);
CLR_BIT(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_LLP_DST_EN_Pos);
CLR_BIT(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_LLP_SRC_EN_Pos);
//1 burst transfer for source and destination register
WR_REG(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_SRC_MSIZE_Msk,GPDMA0_CH_CTLL_SRC_MSIZE_Pos,0x00);
WR_REG(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_DEST_MSIZE_Msk,GPDMA0_CH_CTLL_DEST_MSIZE_Pos,0x00);
//Set transfer type for peripheral to memory with GPDMA as flow controller
WR_REG(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_TT_FC_Msk,GPDMA0_CH_CTLL_TT_FC_Pos,0x02);

//Configure channel control register
//Route DLR line 0 for GPDMA0_CH0
WR_REG(GPDMA0_CH0->CFGH,GPDMA0_CH_CFGH_SRC_PER_Msk,GPDMA0_CH_CFGH_SRC_PER_Pos,0x00);
//Enable hardware handshaking for source
SET_BIT(GPDMA0_CH0->CFGL,GPDMA0_CH_CFGL_HS_SEL_SRC_Pos);
//Enable source reload address
SET_BIT(GPDMA0_CH0->CFGL,GPDMA0_CH_CFGL_RELOAD_SRC_Pos);
//Enable destination reload address
SET_BIT(GPDMA0_CH0->CFGL,GPDMA0_CH_CFGL_RELOAD_DST_Pos);

//Enable GPDMA0_CH0
GPDMA0->CHENREG |= (uint32_t)
(((uint32_t) 1 << GPDMA0_CHENREG_CH_Pos) &GPDMA0_CHENREG_CH_Msk)|\
(((uint32_t) 1<< GPDMA0_CHENREG_WE_CH_Pos) &GPDMA0_CHENREG_WE_CH_Msk);

//Connect GPDMA0_CH0 DLR0 to VADC_G0.SR3
WR_REG(DLR->SRSEL0,DLR_SRSEL0_RS0_Msk,DLR_SRSEL0_RS0_Pos,0x02);
//Enable DLR Line0
SET_BIT(DLR->LNEN,DLR_LNEN_LN0_Pos);


Below is part of the code to configure ADC service request.
//Route result register assignment
//Clear bit RESTBS to allow store result in source register
CLR_BIT(VADC_G0->CHCTR[0],VADC_G_CHCTR_RESTBS_Pos);
//Store result ADC G0CH0 in RESULT 0 Register
WR_REG(VADC_G0->CHCTR[0],VADC_G_CHCTR_RESREG_Msk,VADC_G_CHCTR_RESREG_Pos,0x00);
//Clear bit RESTBS to allow store result in source register
CLR_BIT(VADC_G0->CHCTR[6],VADC_G_CHCTR_RESTBS_Pos);
//Store result ADC G0CH6 in RESULT 6 Register
WR_REG(VADC_G0->CHCTR[6],VADC_G_CHCTR_RESREG_Msk,VADC_G_CHCTR_RESREG_Pos,0x06);

//Activate result 6 register interrupt
//Enable service result generation
SET_BIT(VADC_G0->RCR[6],VADC_G_RCR_SRGEN_Pos);
//Route ADC_G0_RES06 to VADC.G0.SR3
WR_REG(VADC_G0->REVNP0,VADC_G_REVNP0_REV0NP_Msk,VADC_G_REVNP0_REV6NP_Pos,0x03);


I can guarantee that the ADC is running and produce result on VADC_G0->RES[6] but the DMA is not working to transfer the data.
0 Likes
1 Reply
Not applicable
Case closed.

i found the problem. The correct initialization should be memory to memory transfer, not peripheral to memory
//Set transfer type for memory to memory with GPDMA as flow controller
WR_REG(GPDMA0_CH0->CTLL,GPDMA0_CH_CTLL_TT_FC_Msk,GPDMA0_CH_CTLL_TT_FC_Pos,0x00);
0 Likes