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.

TM4C1294NCPDT: timer interrupt question

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: ENERGIA, EK-TM4C1294XL

Tool/software:

I have uploaded the code below. I am using code composer studio v11.2.

Output of PF_0 toggles 18 times and when interrupt occurs, it stays at high state. I believe I can not clear interrupt flag using ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

Could you comment on following code?

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

#define SYSTEM_CLOCK 120000000
void Timer0IntHandler(void)
{
    ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    digitalWrite(PF_0, 0);
              delay(500);
              digitalWrite(PF_0, 1);
                        delay(500);
}

void ConfigureTimer(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    uint32_t timerLoad=399500000;
    TimerLoadSet(TIMER0_BASE,TIMER_A, timerLoad - 1);
    IntEnable(INT_TIMER0A);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    TimerEnable(TIMER0_BASE, TIMER_A);
}

void setup(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    pinMode(PF_0, OUTPUT);
    SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), SYSTEM_CLOCK);
    ConfigureTimer();
    IntMasterEnable();
    while (1)
    {
        digitalWrite(PF_0, 0);
          delay(100);
          digitalWrite(PF_0, 1);
                    delay(100);
    }
}

void loop() {}

  • Output of PF_0 toggles 18 times and when interrupt occurs, it stays at high state

    Are you seeing it stays high from a scope or from a LED?

    If you put a breakpoint in the ISR, does the processor halt each time the timer timesout?

    The flag is cleared in the ISR but you set the PF0 pin high again. If you are trying to view PF0 in a LED it will stay mostly lid even though you try to clear and set the pin repeatedly in a very short duration. To your eyes, you can't see it go low because it is too fast. 

  • With a 120MHz clock, 400M clocks is about 3.5 seconds, which is about 18 times through your (200ms) main loop. That suggests it's the first ISR call that fails.

    How is delay() implemented? I've seen it done using SysTick and counting interrupts, which would make it fail (never return) when called from an ISR.

  • Thanks for your answer. I am using a scope to check status of pins. I believe it does not enters into ISR. Since pulse width and period is same in PF0 waveform. In Timer0IntHandler I am using different pulse widths.

  • Hello Bruce,

    Thanks for your answer. I guess it does not enters into ISR as you have said.Total square wave duration is 3.36sec and it does not generate longer pulses in ISR.

    I have updated to SysCtlDelay insted of Delay. Again total square wave duration is 3.36 sec, then it goes to high. I am checking with oscilloscope. What can I use instead of delay or SysCtlDelay? I have imported this function from a Energia sketch.

  • Hello,

    I have inserted the following code segment into Configure Timer block.

    TimerIntRegister(TIMER0_BASE, TIMER_A,Timer0IntHandler); and it does not stucks at interrupt rutine. Thanks to your helps

  • TimerIntRegister(TIMER0_BASE, TIMER_A,Timer0IntHandler); and it does not stucks at interrupt rutine. Thanks to your helps

    Are you saying in your original posted code, you never had an interrupt vector specified n the vector table either statically or dynamically?

    Normally, you would add the vector to the vector table in the startup_ccs.c file. See below example. Using TimerIntRegister(TIMER0_BASE, TIMER_A,Timer0IntHandler) is a dynamic method to plug the vector into the table. 

    Why don't you try the example at C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\timers and compare with your code.

  • Dear Charles Tsai,

    Thanks for your help. This resolved my issue. I am checking example folders in TivaWare and I have another related question. In order to generate 200nsec pulse with 20msec period I am using TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
    Pulse period can not be increased more than  546usec(120000000*65536) it can not generate longer pulse periods. Could you suggest any other alternative?

  • Hi,

     Refer to the datasheet for details. What the example demonstrates is a split-timer using only 16-bit. In split-timer mode, you can add an additional 8-bit of prescaler to form a 24-bit counter and thus extend your period. Of course, you can also concatenate two 16-bit counters together to create a 32-bit counter. 

    13.3 Functional Description
    The main components of each GPTM block are two free-running up/down counters (referred to as
    Timer A and Timer B), two prescaler registers, two match registers, two prescaler match registers,
    two shadow registers, and two load/initialization registers and their associated control functions.
    The exact functionality of each GPTM is controlled by software and configured through the register
    interface. Timer A and Timer B can be used individually, in which case they have a 16-bit counting
    range for the 16/32-bit GPTM blocks. In addition, Timer A and Timer B can be concatenated to
    provide a 32-bit counting range for the 16/32-bit GPTM blocks. Note that the prescaler can only be
    used when the timers are used individually.

  • Hi Charles Tsai,
    This code generates 390nsec pulse width and 8msec PRI duration. However, time to time it can not generate required pulse widths but shorter pulses. Could you point out my errors?

    #define SYSTEM_CLOCK 120000000  
    
    void ConfigurePWM(void) {
        SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); 
        GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);
        GPIOPinConfigure(GPIO_PF1_M0PWM1);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
        PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 1200);  // Configure period for PWM
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, 47);
        PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, false);
    }
    
    void Timer0IntHandler_short(void) {
        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        PWMGenEnable(PWM0_BASE, PWM_GEN_0);
        PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, true);
        SysCtlDelay(320);  // corresponds to 8usec of delay
        PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, false);
    }
    void ConfigureTimer(void) {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
        TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
        TimerLoadSet(TIMER0_BASE, TIMER_A, 960000-1);//Multiple of 1200
        IntEnable(INT_TIMER0A);
        TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0IntHandler_short);
        TimerEnable(TIMER0_BASE, TIMER_A);
    }
    // Main function to start short pulse generation
    void SinglePulse_Short(void) {
        ConfigurePWM();
        ConfigureTimer();
    }
    
    

  • Hi,

      What is the reason to add SysCtlDelay(320) to you ISR? This delay is equal to 8.3 * 320 * 3 = 7960ns. This is much longer than your pulse width. SysCtlDelay(1) is equal to 3 CPU cycles. 

  • PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, 47); this part generates 390nsec pulse width,

    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 1200); then before completion of pwm cycle at 1200, using SysCtlDelay(320) and  PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, false); PWM is disabled.
     After 8msec PWMGenEnable(PWM0_BASE, PWM_GEN_0); enables PWM again in Timer0IntHandler_short.