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.

TM4C123G : Issue with simple Timer2A interrupt

Other Parts Discussed in Thread: TM4C123GH6PM

(I previously posted the same question on the wrong forum)

Hello,

I have issues with triggering a Timer2A interrupt on my Tiva TM4C123GXL. I wrote the simple following program to illustrate the issue :  1) the main program sets a flag, 2) it should be interrupted, 3) the ISR should clear the flag, and 4) when back into the main thread the 0 flag should turn the green LED. Instead the red LED turns on (meaning the flag is 1, meaning the interrupt did not clear it, which probably means that the timer2A handler, handlerTimer2A, was not called).

The handler (handlerTimer2A) is initialized in the Interrupt Vector Table, in the startup file (ie 1) declaring : extern void handlerTimer2A (void); and 2) adding handlerTimer2A at vector 39 / IRQ 23 location).


I am aware of other people having similar issues (eg : e2e.ti.com/.../1136794, and I have checked that my problem was not coming from the same causes. Thanks for your help.

Jean

(PS: I follow the lower-level procedure, only for my own educational purpose)

Here is the code :

#include "tm4c123gh6pm.h"

unsigned char flag;

void initportF(void);
void initTimer2A(unsigned long period);

void handlerTimer2A(void){
   TIMER2_ICR_R = 0x00000001;                       // acknowledge
   flag = 0;                                        // SET THE FLAG - SHOULD TURN ON THE GREEN LED BACK IN MAIN

   TIMER2_CTL_R = 0x00000000;                       // disable timer2A
}


void main(void){
    flag = 1;                                       // INITIALIZE FLAG TO 1
    initportF();           
    initTimer2A(1*80000);                           // the reload value is not important here
    
    while(1){
        if (flag) {GPIO_PORTF_DATA_R = 0x02;}       // red   LED if flag is 1
        else {GPIO_PORTF_DATA_R = 0x08;}            // green LED if flag is 0 - which should be the case if the interrupt cleared the flag
    }
}



// init Timer2A
void initTimer2A(unsigned long period){
   unsigned long volatile delay;
   SYSCTL_RCGCTIMER_R |= 0x04;                    // activate timer2
   delay = SYSCTL_RCGCTIMER_R;                    // wait 3~5 bus cycle   
   TIMER2_CTL_R = 0x00000000;                     // disable timer2A
   TIMER2_CFG_R = 0x00000000;                     // 32-bit mode
   TIMER2_TAMR_R = 0x00000002;                    // periodic mode
   TIMER2_TAILR_R = period-1;                     // reload value
   TIMER2_TAPR_R = 0;                             // clock resolution
   TIMER2_ICR_R = 0x00000001;                     // clear timeout flag
   TIMER2_IMR_R = 0x00000001;                     // arm timeout
   NVIC_PRI5_R = (NVIC_PRI5_R&0x00FFFFFF)|0x80000000;   // priority 4
   NVIC_EN0_R = 1<<23;                            // enable IRQ 23 in
   TIMER2_CTL_R = 0x00000001;                     // enable timer2A
}

// init portF
void initportF(void){
   volatile unsigned long delay;                  
   SYSCTL_RCGC2_R |= 0x00000020;                  // activate clock portF
   delay = SYSCTL_RCGC2_R;                        // wait 3~5 bus cycle
   GPIO_PORTF_LOCK_R = 0x4C4F434B;                // unlock portF PF0
   GPIO_PORTF_CR_R = 0x1F;                        // allow change PF4,PF3,PF2,PF1,PF0
   GPIO_PORTF_DIR_R |= 0x0000000e;                // outputs for: PF1(OUTPUT), PF2(OUTPUT), PF3(OUTPUT)
   GPIO_PORTF_DIR_R &= ~0x00000011;               // inputs for: PF0(INPUT), PF4(INPUT)
   GPIO_PORTF_AFSEL_R &= ~0x0000001f;             // clear alternative function for: PF0(INPUT), PF4(INPUT), PF1(OUTPUT), PF2(OUTPUT), PF3(OUTPUT)
   GPIO_PORTF_DEN_R |= 0x0000001f;                // enable digital pins for: PF0(INPUT), PF4(INPUT), PF1(OUTPUT), PF2(OUTPUT), PF3(OUTPUT)
   GPIO_PORTF_AMSEL_R &= ~0x0000001f;             // disable analog mode for: PF0(INPUT), PF4(INPUT), PF1(OUTPUT), PF2(OUTPUT), PF3(OUTPUT)
   GPIO_PORTF_PCTL_R &= ~0x0000001f;              // disable PCTL for: PF0(INPUT), PF4(INPUT), PF1(OUTPUT), PF2(OUTPUT), PF3(OUTPUT)
   GPIO_PORTF_PUR_R |= 0x00000011;                // enable pull-up resistors for: PF0(INPUT), PF4(INPUT)
}

  • Hello Ja

    May I suggest that first move the code to TivaWare API's. It is extremely tough for another set of eyes to go through a small code with DRM's

    Regards
    Amit
  • Hi Amit
    Sorry I did not realize that the code is hard to read. I do not mind going the TivaWare ATI way but I have never tried before so it'll take some time before I resend a new version of the code.
    Thanks for your help.
  • May this serve as, "Vote #2" for your "lower-level procedure" code being - far more demanding & difficult - to test/verify.

    Such code forces your (helpers) to page repeatedly through the MCU manual - testing each/every register listed - down to "fine bit detail." It is that (extra effort) which makes your code, "so hard & effort heavy - to read."   Now you are well w/in your rights to employ direct register - as are your helpers - in "not" wishing to "wade thru" those, "so complex, register-centric" - code blocks...   Especially when a far easier, safer, faster & proven API stands ready/waiting (and rejected.)
     
    As Amit's noted - the API greatly simplifies - it has been tested by thousands - has proven (near) fool-proof. Your (or others) direct register code always, "Proves an adventure" and your "educational purpose" may extend to recognize this reality... (i.e. the Lone Ranger "rides again" - but not very fast - nor far!)

  • Besides the issues pointed out by other responders, you need to declare the variable "flag" as volatile.

    Randy