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!