Other Parts Discussed in Thread: EK-TM4C1294XL
Hi all,
I'm developing on a custom board that utilizes a TM4C1294NCPDT microcontroller.
My debugging environment is as follows:
- I use the debugging portion of EK-TM4C1294XL Launchpad for programming, debugging and flashing code onto my board
- Code Composer Studio v6
- LM Flash Programming
On my board, I have 6 circuits that convert optical PWM signals into a 10 KHz PWM electrical signals which go into both Timer A and B of all 6 timers (timer0 to timer5).
I noticed recently that using more than 3 inputs at a time (3 timers) decreases the range at which the timers can sense. Using less than 3 inputs at a time is shown to work perfectly fine at 1% to 99% within a reasonable tolerance. When I use 3 or more, then pushing any of the 3 inputs above 93% duty cycle will cause one of the 3 timers (slightly random) to display garbage. I am assuming at this point that the this is mainly due to the timers now essentially interrupting each other causing one the edge time capture registers to capture garbage. Unfortunately, I couldn't find any relevant information in the manual, and I was not able to find a similar regarding my issue.
Any help in solving this problem is greatly appreciated
Cheers,
Stephen B
Relevant files are attached (I attached the wrong configuration file, I will update when I get access to my work laptop. The handler file should be the correct one).
//***************************************************************************** // // timerconfiguration.c - Functions used to initialize the timers and components. // // This .c file contains the retrieval functions for the counter values of // the high time and period of the square wave input. Functions that convert // the counter values to frequency and duty cycle are also contained within the // file. // //***************************************************************************** #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include "inc/hw_ints.h" #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "inc/hw_nvic.h" #include "driverlib/gpio.h" #include "driverlib/sysctl.h" #include "driverlib/interrupt.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/pin_map.h" #include "driverlib/timer.h" #include "timerhandlers.h" #include "output.h" static volatile float pwmDutyCycle[6]; int32_t period[6]; int32_t highTime[6]; //***************************************************************************** // // Interrupt handler for events that occur for both halves of the timer // (Timer A and Timer B). This handler continuously samples the square wave // input and calculates their high time and period for future calculations. // //***************************************************************************** void Timer0IntHandler(void) { static int32_t firstEdge = 0; int32_t tempTimerValOne, tempTimerValTwo; // Checks if a rising edge event occured in Timer A if (MAP_TimerIntStatus(TIMER0_BASE, 0) & TIMER_CAPA_EVENT) { MAP_TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT); // Obtain the timer value when rising edge occured and calculate period. tempTimerValOne = MAP_TimerValueGet(TIMER0_BASE, TIMER_A); period[0] = tempTimerValOne - firstEdge; firstEdge = tempTimerValOne; // If rollover occurs (causing a negative period value) add 2^24. if (period[0] < 0) { period[0] += (1<<24); } } // Checks if a falling edge event occured in Timer B if (MAP_TimerIntStatus(TIMER0_BASE, 0) & TIMER_CAPB_EVENT) { MAP_TimerIntClear(TIMER0_BASE, TIMER_CAPB_EVENT); // Obtain the timer value when falling edge occured and calculate high time. tempTimerValTwo = MAP_TimerValueGet(TIMER0_BASE, TIMER_B); highTime[0] = tempTimerValTwo - firstEdge; // If rollover occurs (causing a negative period value) add 2^24. if (highTime[0] < 0) { highTime[0] += (1<<24); } } } //***************************************************************************** // // Interrupt handler for events that occur for both halves of the timer // (Timer A and Timer B). This handler continuously samples the square wave // input and calculates their high time and period for future calculations. // //***************************************************************************** void Timer1IntHandler(void) { static int32_t firstEdge = 0; int32_t tempTimerValOne, tempTimerValTwo; // Checks if a rising edge event occured in Timer A if (MAP_TimerIntStatus(TIMER1_BASE, 0) & TIMER_CAPA_EVENT) { MAP_TimerIntClear(TIMER1_BASE, TIMER_CAPA_EVENT); // Obtain the timer value when rising edge occured and calculate period. tempTimerValOne = MAP_TimerValueGet(TIMER1_BASE, TIMER_A); period[1] = tempTimerValOne - firstEdge; firstEdge = tempTimerValOne; // If rollover occurs (causing a negative period value) add 2^24. if (period[1] < 0) { period[1] += (1<<24); } } // Checks if a falling edge event occured in Timer B if (MAP_TimerIntStatus(TIMER1_BASE, 0) & TIMER_CAPB_EVENT) { MAP_TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT); // Obtain the timer value when falling edge occured and calculate high time. tempTimerValTwo = MAP_TimerValueGet(TIMER1_BASE, TIMER_B); highTime[1] = tempTimerValTwo - firstEdge; // If rollover occurs (causing a negative period value) add 2^24. if (highTime[1] < 0) { highTime[1] += (1<<24); } } } //***************************************************************************** // // Interrupt handler for events that occur for both halves of the timer // (Timer A and Timer B). This handler continuously samples the square wave // input and calculates their high time and period for future calculations. // //***************************************************************************** void Timer2IntHandler(void) { static int32_t firstEdge = 0; int32_t tempTimerValOne, tempTimerValTwo; // Checks if a rising edge event occured in Timer A if (MAP_TimerIntStatus(TIMER2_BASE, 0) & TIMER_CAPA_EVENT) { MAP_TimerIntClear(TIMER2_BASE, TIMER_CAPA_EVENT); // Obtain the timer value when rising edge occured and calculate period. tempTimerValOne = MAP_TimerValueGet(TIMER2_BASE, TIMER_A); period[2]= tempTimerValOne - firstEdge; firstEdge = tempTimerValOne; // If rollover occurs (causing a negative period value) add 2^24. if (period[2] < 0) { period[2] += (1<<24); } } // Checks if a falling edge event occured in Timer B if (MAP_TimerIntStatus(TIMER2_BASE, 0) & TIMER_CAPB_EVENT) { MAP_TimerIntClear(TIMER2_BASE, TIMER_CAPB_EVENT); // Obtain the timer value when falling edge occured and calculate high time. tempTimerValTwo = MAP_TimerValueGet(TIMER2_BASE, TIMER_B); highTime[2]= tempTimerValTwo - firstEdge; // If rollover occurs (causing a negative period value) add 2^24. if (highTime[2] < 0) { highTime[2] += (1<<24); } } } //***************************************************************************** // // Interrupt handler for events that occur for both halves of the timer // (Timer A and Timer B). This handler continuously samples the square wave // input and calculates their high time and period for future calculations. // //***************************************************************************** void Timer3IntHandler(void) { static int32_t firstEdge = 0; int32_t tempTimerValOne, tempTimerValTwo; // Checks if a rising edge event occured in Timer A if (MAP_TimerIntStatus(TIMER3_BASE, 0) & TIMER_CAPA_EVENT) { MAP_TimerIntClear(TIMER3_BASE, TIMER_CAPA_EVENT); // Obtain the timer value when rising edge occured and calculate period. tempTimerValOne = MAP_TimerValueGet(TIMER3_BASE, TIMER_A); period[3] = tempTimerValOne - firstEdge; firstEdge = tempTimerValOne; // If rollover occurs (causing a negative period value) add 2^24. if (period[3] < 0) { period[3] += (1<<24); } } // Checks if a falling edge event occured in Timer B if (MAP_TimerIntStatus(TIMER3_BASE, 0) & TIMER_CAPB_EVENT) { MAP_TimerIntClear(TIMER3_BASE, TIMER_CAPB_EVENT); // Obtain the timer value when falling edge occured and calculate high time. tempTimerValTwo = MAP_TimerValueGet(TIMER3_BASE, TIMER_B); highTime[3] = tempTimerValTwo - firstEdge; // If rollover occurs (causing a negative period value) add 2^24. if (highTime[3] < 0) { highTime[3] += (1<<24); } } } //***************************************************************************** // // Interrupt handler for events that occur for both halves of the timer // (Timer A and Timer B). This handler continuously samples the square wave // input and calculates their high time and period for future calculations. // //***************************************************************************** void Timer4IntHandler(void) { static int32_t firstEdge = 0; int32_t tempTimerValOne, tempTimerValTwo; // Checks if a rising edge event occured in Timer A if (MAP_TimerIntStatus(TIMER4_BASE, 0) & TIMER_CAPA_EVENT) { MAP_TimerIntClear(TIMER4_BASE, TIMER_CAPA_EVENT); // Obtain the timer value when rising edge occured and calculate period. tempTimerValOne = MAP_TimerValueGet(TIMER4_BASE, TIMER_A); period[4] = tempTimerValOne - firstEdge; firstEdge = tempTimerValOne; // If rollover occurs (causing a negative period value) add 2^24. if (period[4] < 0) { period[4] += (1<<24); } } // Checks if a falling edge event occured in Timer B if (MAP_TimerIntStatus(TIMER4_BASE, 0) & TIMER_CAPB_EVENT) { MAP_TimerIntClear(TIMER4_BASE, TIMER_CAPB_EVENT); // Obtain the timer value when falling edge occured and calculate high time. tempTimerValTwo = MAP_TimerValueGet(TIMER4_BASE, TIMER_B); highTime[4] = tempTimerValTwo - firstEdge; // If rollover occurs (causing a negative period value) add 2^24. if (highTime[4] < 0) { highTime[4] += (1<<24); } } } //***************************************************************************** // // Interrupt handler for events that occur for both halves of the timer // (Timer A and Timer B). This handler continuously samples the square wave // input and calculates their high time and period for future calculations. // //***************************************************************************** void Timer5IntHandler(void) { static int32_t firstEdge = 0; int32_t tempTimerValOne, tempTimerValTwo; // Checks if a rising edge event occured in Timer A if (MAP_TimerIntStatus(TIMER5_BASE, 0) & TIMER_CAPA_EVENT) { MAP_TimerIntClear(TIMER5_BASE, TIMER_CAPA_EVENT); // Obtain the timer value when rising edge occured and calculate period. tempTimerValOne = MAP_TimerValueGet(TIMER5_BASE, TIMER_A); period[5] = tempTimerValOne - firstEdge; firstEdge = tempTimerValOne; // If rollover occurs (causing a negative period value) add 2^24. if (period[5] < 0) { period[5] += (1<<24); } } // Checks if a falling edge event occured in Timer B if (MAP_TimerIntStatus(TIMER5_BASE, 0) & TIMER_CAPB_EVENT) { MAP_TimerIntClear(TIMER5_BASE, TIMER_CAPB_EVENT); // Obtain the timer value when falling edge occured and calculate high time. tempTimerValTwo = MAP_TimerValueGet(TIMER5_BASE, TIMER_B); highTime[5] = tempTimerValTwo - firstEdge; // If rollover occurs (causing a negative period value) add 2^24. if (highTime[5] < 0) { highTime[5] += (1<<24); } } } //***************************************************************************** // // // //***************************************************************************** float retrieveOptiPWMIn(uint8_t output) { pwmDutyCycle[output] = ((float) highTime[output]/ (float) period[output]) * 100.00; if (output < OPTICAL_PWMOUT_COUNT) { return pwmDutyCycle[output]; } return 0; }