AnsweredAssumed Answered

DMA Circular Buffer Not Looping

Question asked by Benjamin Schroeder on Feb 18, 2016
Latest reply on Mar 28, 2016 by Donald Bosley

Hello,

 

I'm trying to implement code where every edge detected by the FTM gets DMA'd into a 32 element buffer, forever.  I'm not able to get the DMA to loop back around to the beginning though.  I suspect it's my "ScatterGather" settings, since that is confusing me on how to properly use it.

 

My code below actually allocates 36 elements, but I'm only trying to capture 32.  I want to view both sides of the buffer to ensure I'm not going beyond my memory space.

 

My result is:

dma_arr = {0, 0, 3, 11530, 23929, 35946, 47962, 59977, 6458, 18474, 30489, 42506, 54522, 1001, 13017, 25034, 37049, 49065, 61082, 7562, 19578, 31594, 43610, 55625, 2106, 14121, 26137, 38154, 50170, 62186, 8666, 20682, 32698, 44714, 0, 0}

 

I've tried changing the scattergather adjustment to -(sizeof(uint16_t)*32), but that doesn't seem to help either.

 

uint16_t dma_arr[36] = {0};

void init_dma(void) {

    SIM_PDD_SetClockGate(SIM_BASE_PTR, SIM_PDD_CLOCK_GATE_DMA, PDD_ENABLE);

    SIM_PDD_SetClockGate(SIM_BASE_PTR, SIM_PDD_CLOCK_GATE_DMA_MULTIPLEXOR0, PDD_ENABLE);

    DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 0, PDD_ENABLE);

    DMAMUX_PDD_SetChannelSource(DMAMUX0_BASE_PTR, 0, DMAMUX_PDD_CHANNEL_SOURCE_33); // Reference Page 102 for Channel Source info

 

    //DMA_CR

    DMA_PDD_EnableMinorLoopMapping(DMA_BASE_PTR, PDD_ENABLE);

    //DMA_TCD0_SADDR

    DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, &FTM_PDD_ReadChannelValueReg(FTM1_BASE_PTR, FTM_PDD_CHANNEL_1));

    //DMA_TCD0_SOFF

    DMA_PDD_SetSourceAddressOffset(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, 0);

    //DMA_TCD0_SLAST

    DMA_PDD_SetLastSourceAddressAdjustment(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, 0);

    //DMA_TCD0_DADDR

    DMA_PDD_SetDestinationAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, (uint32_t)dma_arr+4);

    //DMA_TCD0_DOFF

    DMA_PDD_SetDestinationAddressOffset(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, sizeof(uint16_t));

    //DMA_TCD0_DLASTSGA

    DMA_PDD_SetLastDestinationAddressAdjustment_ScatterGather(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, 0);

    //DMA_TCD0_ATTR

    DMA_PDD_SetSourceAddressModulo(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_CIRCULAR_BUFFER_DISABLED);

    DMA_PDD_SetSourceDataTransferSize(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_16_BIT);

    DMA_PDD_SetDestinationAddressModulo(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_CIRCULAR_BUFFER_2_BYTES);

    DMA_PDD_SetDestinationDataTransferSize(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_16_BIT);

    //DMA_TCD0_NBYTES_MLOFFYES

    DMA_PDD_EnableSourceMinorLoopOffset(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_DISABLE);

    DMA_PDD_EnableDestinationMinorLoopOffset(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE);

    DMA_PDD_SetMinorLoopOffset(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, sizeof(uint16_t));

    DMA_PDD_SetByteCount10(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, sizeof(uint16_t));

    //DMA_TCD0_CSR

    DMA_PDD_WriteControlStatusReg(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, 0);

    DMA_PDD_EnableScatterGather(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE);

    //DMA_TCD0_CITER_ELINKNO

    DMA_PDD_WriteCurrentMajorLoopCountReg(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, 32);

    //DMA_TCD0_BITER_ELINKNO

    DMA_PDD_WriteBeginningMajorLoopCountReg(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, 32);

    //DMA_ERQ

    DMA_PDD_EnableRequestMask(DMA_BASE_PTR, DMA_PDD_CHANNEL_MASK_0);

}

 

Thanks!

Outcomes