Hi,
I want to measure the frequency of a square wave signal (around 25 Hz).
Hardware setup is given and not done by me. I used to do this on a different micro by counting the overflows of a 16 Bit counter and taking into account 2 captured values from 2 consecutive positive edges.
So I set up TIMER5 A in split / 16 Bit / upcounting "Input Edge Time Mode"
My init code looks like this (actual GPIO config done by pinmux tool elsewhere, I detect capture interrupts so the GPIO setup is fine)
void TimerCCPInit(void)
{
// Timer peripheral enable
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER5);
// Wait for the Peripheral to be ready for programming
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER5));
// disable Timer
TimerDisable(TIMER5_BASE,TIMER_BOTH);
// Timer clock source = system clock (high precision 120 MHz)
TimerClockSourceSet(TIMER5_BASE,TIMER_CLOCK_SYSTEM);
// Timer in split mode (2x 16 Bit, Up counting, Capture mode)
TimerConfigure(TIMER5_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP);
// set Timer event type for Timer A to positive edge count
TimerControlEvent(TIMER5_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
// set Timer prescaler to 4, resulting in 120Mhz : 4 => 30Mhz Timer clock
// in UP Counting mode the prescaler provides the MSB of the count value (pseudo 24bit mode)
TimerPrescaleSet(TIMER5_BASE, TIMER_A, 4);
// upper limit for TIMEOUT interrupt in up counting mode
TimerLoadSet(TIMER5_BASE, TIMER_A, 0xFFFF);
// register Timer5A handler
TimerIntRegister(TIMER5_BASE, TIMER_A, Timer5AIntHandler);
// enable capture interrupt
TimerIntEnable(TIMER5_BASE, TIMER_CAPA_EVENT | TIMER_TIMA_TIMEOUT);
// enable timer
TimerEnable(TIMER5_BASE, TIMER_A);
}
I expect the handler to be called either on a capture event (which works) and on the counter overflowing from 0xFFFF to 0x0000 (the datasheet states in paragraph 13.4.4 in the last sentence "In Input Edge Timing mode, the timer continues running after an edge event has been detected,
but the timer interval can be changed at any time by writing the GPTMTnILR register and clearing
the TnILD bit in the GPTMTnMR register. The change takes effect at the next cycle after the write."
So I would assume it also rolls over and generates a TIMEOUT interrupt.
My Handler code looks like this:
void Timer5AIntHandler(void)
{
// get masked interrupt state as we need to check if its a capture
// or an overflow interrupt
uint32_t InterruptFlags = TimerIntStatus(TIMER5_BASE, true);
// check for capture interrupt
if(InterruptFlags & TIMER_CAPA_EVENT)
{
// read capture value
uiTimer5CaptureValue = TimerValueGet(TIMER5_BASE, TIMER_A);
// if it was a capture interrupt, clear interrupt flag
TimerIntClear(TIMER5_BASE, TIMER_CAPA_EVENT);
uiTimer5Overflows = 0;
// toggle D73 green on each capture
bLEDToggleFlag++;
if(bLEDToggleFlag & 0x01)
GPIOPinWrite(LED_D73_GREEN_N_PORT,LED_D73_GREEN_N_PIN,0);
else
GPIOPinWrite(LED_D73_GREEN_N_PORT,LED_D73_GREEN_N_PIN,LED_D73_GREEN_N_PIN);
}
if(InterruptFlags & TIMER_TIMA_TIMEOUT)
{
TimerIntClear(TIMER5_BASE, TIMER_TIMA_TIMEOUT);
uiTimer5Overflows++;
}
}
The LED on my frontpanel flickers with half the 25Hz as expected, if I set a breakpoint I see uiTimer5CaptureValue (some global variable not shown above) is set each time to the current capture value.
If I set a breakpoint in the lower branch that checks for the TIMER_TIMA_TIMEOUT, it never gets triggered, also I see the variable stuck at zero.
What am I missing here?
Markus