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;
}