Hi
After receiving a lot of helpful input in the TM4C Microcontrollers Forum, one open issue which is related to the TI RTOS remains unsolved. Therefore Amit Ashara suggested to also post this question here. I hope someone can help me:
In my application, I have an external input providing a signal that will contain irregular bursts of pulses with frequencies ranging between 20kHz and 2Mhz. My goal is to detect the start and end of these bursts.
Detecting the start is as simple as configuring an Interrupt on the rising edge of the signal. To find the end of the burst I use a timer that is loaded with the equivalent of 55us on every rising edge of the input signal. This means that the interrupt of the timer running out will signal the end of a burst. In order to avoid servicing an interrupt at a very high rate I used a scatter gather DMA to copy the timer load value into the GPTM_TAV register on each rising edge of the input signal. For this to work indefinitely I configured the task list to loop itself upon completion.
Here is the relevant code:
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 1: 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_TAV), UDMA_ARB_1, UDMA_MODE_PER_SCATTER_GATHER ), // // Task 2: 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 dma channel 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); 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; } void ISR_GPIOPortE(){ GPIOIntClear(MLS_GPIO_PORT,MLS_GPIO_INT_FLAG); g_mlsDirtyFlag=1; Timer_start(g_mlsTimer); GPIODMATriggerEnable(MLS_GPIO_PORT, MLS_GPIO_PIN); uDMAChannelEnable(UDMA_CH14_GPIOE & 0xffff); } void ISR_Timer5(){ g_mlsDirtyFlag=1; uDMAChannelDisable(UDMA_CH14_GPIOE & 0xffff); GPIODMATriggerDisable(MLS_GPIO_PORT,MLS_GPIO_PIN); GPIOIntClear(MLS_GPIO_PORT,MLS_GPIO_INT_FLAG); }
This all works fine with one exception: Task execution gets suspended during the time the uDMA channel is enabled. (Irrespective of the presence or absence of toggling bursts on the inputsignal)
Here is what I observe on the logic analyzer by toggling GPIOs at the beginning and end of every task, timer interrupt and in the idle loop:
(channel 4 just indicates the correct detection of start and end of bursts)
A typical task yields execution by calling Task_sleep(). Here is the code:
/*********************************************************************************************************************//** * @brief task used to read the temperature. * * collectTemperature() is doing the reading/processing. * * @param arg0 argument 0 * @param arg1 argument 1 *************************************************************************************************************************/ Void taskTemperatureFxn(UArg arg0, UArg arg1) { while(runtime) { RegisterGPIOToToggle(START, TOGGLE_ALL_TASKS); collectTemperature(); UpdateHeater(); RegisterGPIOToToggle(STOP, TOGGLE_TEMPERATURE); Task_sleep(100); } }
Does anyone have an idea what's causing this issue? What do I need to do to prevent it or how can I further debg it?
Any help is greatly appreciated!
Regards,
Roman