This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TIMER0 interrupt not being triggered

Hi everyone. I'm using the Tiva C workshop series on the focus.ti.com section of the website. The workshop series is designed for use with the TM4C123G device, however I'm using the Connected Dev Kit which has a TM4C129X.

So far I've been able to easily change the code to make it work on my device. Seeing as how they are both Tiva C series micros, I figured that all the API calls and such should be identical on both. However now I'm starting to think that something else needs to be adapted.

I'm working on Lab 4, which uses TIMER0 as an interrupt generator to flash the on-board LED. I followed the instructions perfectly (modifying the port and pin names/numbers to reflect my board) but when I upload the code to the board and execute, nothing happens. I've put a breakpoint at the beginning of the ISR and it never gets hit, so the interrupt isn't even being called.

Here is my code:

#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c129xnczad.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"

int main(void)
{
	uint32_t ui32Period;
	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_25MHZ|SYSCTL_OSC_MAIN); // setup up system clock at 60MHz?

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ|SYSCTL_PERIPH_GPION); // enable GPIO peripherals for Ports Q and N
	GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_4|GPIO_PIN_7); // set PINQ4 and PINQ7 as outputs
	GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_5); // set PINN5 as output

	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // enable TIMER0 peripheral
	TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); // configuer TIMER0 as a periodic timer

	ui32Period = (SysCtlClockGet() / 20) / 2; // set period variable to 10Hz
	TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period - 1); // load the period into TIMER0

	IntEnable(INT_TIMER0A); // enable interrupts for TIMER0A
	TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // set the type of interrupt to timeout
	IntMasterEnable(); // enable master interrupts

	TimerEnable(TIMER0_BASE, TIMER_A); // enable timer0

	while(1);

}

void Timer0IntHandler(void)
{
	TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

	if(GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_5))
	{
		GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_4|GPIO_PIN_7, 0);
		GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, 0);
	}
	else
	{
		GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, 32);
	}
}

This differs from the included Lab 4 code only in the GPIO lines. For the TM4C123G board, all three of the RGB LED pins are on the same port. For some reason on the Connected Dev Board, two are on Port Q and one on Port N. So I have changed the code to reflect this. I am quite sure this is not causing the problem as all the labs up until now worked with my changes. I'm thinking the problem might be in the names used to configure and execute the timer, ie, TIMER0_BASE, INT_TIMER0A. I can't seem to find the information about this for my microcontroller. I know from my experience with Atmel microcontrollers and their datasheets that things like name changes across chips in the same family are detailed in the corresponding section of the datasheet. I've been trying to find any info in the datasheet, but seeing as how it's over 2000 pages long it seems a futile search. I've read the timers section, and the interrupts section to no avail.

Can anyone help me figure out why this isn't working? I really want to get to the bottom of this before I move forward.

Thanks very much!

  • Hi Aurelius,

        Did you setup your Timer0IntHandler() at your startup file?

    -kel

  • Hi Aurelius,

    Kel has already pointed out one important cause. Besides that I would want to high light that the function SysCtlClockSet and SysCtlClockGet are for TM4C123 devices. This has been changed for the TM4C129 devices as SysCtlClockFreqSet and SysCtlClockFreqGet and also the arguments that get parsed to the function on TM4C129. You can check the example code in the TIVAWare installation.

    Regards

    Amit Ashara

  • Yes I did.

    If I pause the program during debug, apparently my ui32Period variable is set to 0. Can't figure out if this is really the case or if it's just an error with the debugger.

    I changed the SYSCTL_XTAL_16MHZ to SYSCTL_XTAL_25MHZ because my board has a 25MHz oscillator on it. Every lab up to now has worked fine with that setting. It seems that the SysCtlClockGet() isn't returning the correct value? I'm a bit confused, when I hover over SysCtlClockGet() it shows the value as decimal 1184, but when I hover over the SysCtlClockSet() it says the value is decimal 924. Are these values unreliable in the debug mode (ie, do they usually not show the correct values?) Or is there something wrong with my clock setup?

    Thanks for the help!

  • @Amit Ashara

    Then why has my code been working up till now? If the clock wasn't being initialized because I was calling the wrong function, shouldn't my program not have run at all?

    EDIT: I made the changes that Amit suggested, and now it's calculating the period to some ridiculous value, 805894364. But at least the LED is on solidly, at least that's an improvement.

    EDIT2: I just realized the LED was still on because it hadn't been reset. When I pause the debugger now, it's going to the FaultISR loop. Are you sure that I need to be using SysCtlClockFreqSet?

  • Hi Aurelius,

    The clock was "incorrectly" initialized so the wrong API call would configure the clock for an incorrect frequency. So your code may work but results will not be as expected.

    EDIT-1: What are the parameters you are parsing. Can you send the updated code for review

    EDIT-2: Also do send the startup.c file for your IDE.

    Regards

    Amit Ashara

  • Hi again. Sorry for taking so long to reply.

    Here's the clock init line as I have it now:

    SysCtlClockFreqSet(SYSCTL_OSC_INT|SYSCTL_USE_PLL|SYSCTL_CFG_VCO_320, 40000000);

    I couldn't figure out how to set it to an external crystal, the TivaWare documentation didn't seem to include an option for that. I also don't quite understand PLL but that's another issue altogether.

    As I said before, it's now getting stuck in FaultISR()

    I just double checked, and section 28.2.2.4 in SW_TM4C-DRL-UG-2.0.1.11577.pdf only shows options for the internal oscillator (PIOSC), and none for the MOSC (as defined by TI's video about Fundamental Clock Sources on TM4C129X devices, found here. Can anyone explain why this is? This is starting to be really confusing.

    EDIT: I think I may have fixed my code on my own. I just assumed you could start two GPIO Peripherals at the same time. A little breakpoint debugging showed me it was going into the FaultISR after the SYSCTL_PERIPH_GPIOQ|SYSCTL_PERIPH_GPION part. So now it seems to be working as intended, with the Timer0 interrupt working fine. However, the period is still wonky. Even when I set the period manually to 2 (which loads 1 into the TIMER0 period) it's still just on solidly. So either it's not blinking at all, or it's blinking so fast I can't see it. I'm going to double-check the TivaWare documentation but they don't seem to explain the arguments for each API call very well.

    Here's the startup code:

    (blanked for space purposes)

  • So yes, I finally got it all working. Two points from this whole debacle:

    1. They should NOT use the word 'Period' as the API call argument -- it ended up that 2000000 was the required 'period' to get the LED flashing at the 10Hz rate in the workshop. This is the same number that would have been calculated if the SysCtlClockGet() call had worked (which, it turns out, also does not work on 129X devices). The frequency for the period of two million is 0.0000005Hz. Clearly not the actual period of 10Hz!! Which, by the way, is 0.1s, or 100ms. Really can't figure out why they used that word. Very misleading and confusing!
    2. I still don't understand the arguments for SysCtlClockFreqSet(). Why can't I choose to use the external oscillator? How can I get the chip running at its nominal 120MHz? If anyone can answer that, I'd be a very happy person!
    3. I'm actually glad I figured this one out by myself -- I feel much more confident now working with Code Composer and the TI documentation. Now I can go ahead with the rest of the workshop.

    Thanks for all your help guys! If you can answer point 2, please do so! I'd really appreciate it!

  • Hello Aurelius,

    The define for using external crystal is SYSCTL_OSC_MAIN and it is present in sysctl.h

    There are example codes for tm4c129x in the TIVAWare installation which use this.

    Regards

    Amit Ashara

  • Dear Amit,

    You mention a SysCtlClockFreqGet () function in this post. Has this function been removed from Tivaware since February (It isn't defined in sysctl.h)? The only way I have been able to find the clock speed is by the return value to SysCtlClockFreqSet(). 

    thanks,

  • Hello Sheldon,

    I am sorry for the miscommunication. The function does not exist. There is only SysCtlClockFreqSet function which returns the current system clock frequency after configuring the same as per application requirement.

    Regards
    Amit
  • Dear Amit,

    Sounds good.