Hi
Based on the information in

I tried to implement a DMA channel that reloads timer5 with a given constant value upon each rising edge on GPIO PortE Pin5.
As far as i can tell, this works once (the TIMER_TAILR register shows the value copied by the DMA, not the one set using timerParams.period = TIMER_LOAD_PERIOD; but then my application seems to lock up somehow.
Is my approach completely wrong, or am I only slightly off?
Any help is greatly appreciated!
Timer Initialization:
/* ********************************************************************************************************************
* @brief Initialize board specific Timer settings.
*
* This function initializes the board specific Timer settings
*
* ********************************************************************************************************************/
void B134_332_initTimer(void)
{
Timer_Params timerParams;
Error_Block eb;
Error_init(&eb);
Timer_Params_init(&timerParams);
timerParams.period = TIMER_LOAD_PERIOD;
timerParams.periodType = Timer_PeriodType_COUNTS;
timerParams.startMode = Timer_StartMode_USER;
timerParams.runMode = Timer_RunMode_ONESHOT;
g_mlsTimer = Timer_create(5, ISR_Timer5, &timerParams, &eb);
if (g_mlsTimer == NULL) {
System_abort("Timer create failed");
}
}
DMA Initialization:
uint8_t GPTMCTL_disable= 0x00;
uint8_t GPTMCTL_enable = TIMER_CTL_TAEN;
uint32_t GPTM_ILR= TIMER_DMA_LOAD_PEROID;
// Temporary storage for the first uDMA primary task, for scatter-gather looping
static tDMAControlTable uDMAsg_LoopTask;
static tDMAControlTable uDMAsg_TaskList[] =
{
//
// Task 2: copy source buffer to timer interval load
//
uDMATaskStructEntry(1,
UDMA_SIZE_32,
UDMA_SRC_INC_NONE,
&GPTM_ILR,
UDMA_DST_INC_NONE,
(void*)(TIMER5_BASE + TIMER_O_TAILR),
UDMA_ARB_1,
UDMA_MODE_PER_SCATTER_GATHER
),
//
// Task 4: loop
//
uDMATaskStructEntry(
4,
UDMA_SIZE_32,
UDMA_SRC_INC_32,
&uDMAsg_LoopTask,
UDMA_DST_INC_32,
&(B134_332_DMAControlTable[UDMA_CH14_GPIOE & 0x1f]),
UDMA_ARB_4,
UDMA_MODE_MEM_SCATTER_GATHER
)
};
void initMLSFallingEdgeDetection(){
// initialize interrupt
uDMAChannelDisable(UDMA_CH14_GPIOE & 0xffff); // Ensure channel is disabled before modifying register
uDMAChannelAssign(UDMA_CH14_GPIOE);
uDMAChannelAttributeDisable((UDMA_CH14_GPIOE & 0xffff)|UDMA_PRI_SELECT,UDMA_ATTR_ALL);
uDMAChannelAttributeDisable((UDMA_CH14_GPIOE & 0xffff)|UDMA_ALT_SELECT,UDMA_ATTR_ALL);
uDMAChannelAttributeEnable((UDMA_CH14_GPIOE & 0xffff)|UDMA_PRI_SELECT,UDMA_ATTR_USEBURST);
uDMAChannelAttributeEnable((UDMA_CH14_GPIOE & 0xffff)|UDMA_ALT_SELECT,UDMA_ATTR_USEBURST);
uDMAChannelScatterGatherSet(UDMA_CH14_GPIOE & 0xffff, 2, uDMAsg_TaskList, true);
// Copy the primary control structure from the uDMA controltable
uDMAsg_LoopTask.pvDstEndAddr = B134_332_DMAControlTable[UDMA_CH14_GPIOE & 0xffff].pvDstEndAddr;
uDMAsg_LoopTask.pvSrcEndAddr = B134_332_DMAControlTable[UDMA_CH14_GPIOE & 0xffff].pvSrcEndAddr;
uDMAsg_LoopTask.ui32Control = B134_332_DMAControlTable[UDMA_CH14_GPIOE & 0xffff].ui32Control;
uDMAsg_LoopTask.ui32Spare = B134_332_DMAControlTable[UDMA_CH14_GPIOE & 0xffff].ui32Spare;
Timer_setPeriod(g_mlsTimer, TIMER_LOAD_PERIOD);
}
Starting the DMA:
void startFallingEdgeDetection(){
Timer_start(g_mlsTimer);
GPIODMATriggerEnable(MLS_GPIO_PORT, MLS_GPIO_PIN);
uDMAChannelEnable(UDMA_CH14_GPIOE & 0xffff);
}
