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.

Problem with activating Timer 1A and Timer 2A in TIVA C MC

I initialized Timer 1A with ISR every 2.5 ms and then initialized Timer 2A with ISR every 1s .. but it seems like they are not working together at the same time for the results are messed up. Only one works when I cancel the other.  How can I have them both working together at the same time ? 

  • Hello Islam,

    How can we help if there is no code to look at?

    Regards
    Amit
  • #include "tm4c123gh6pm2.h"
    
    int flag,flag2;
    
    void (*PeriodicTask)(void);   // user function
    void (*PeriodicTask2)(void);   // user function
    
    // ***************** TIMER1_Init ****************
    // Activate TIMER1 interrupts to run user task periodically
    // Inputs:  task is a pointer to a user function
    //          period in units (1/clockfreq)
    // Outputs: none
    void Timer1_Init(void(*task)(void), unsigned long period){
      SYSCTL_RCGCTIMER_R |= 0x02;   // 0) activate TIMER1
      PeriodicTask = task;          // user function
      TIMER1_CTL_R = 0x00000000;    // 1) disable TIMER1A during setup
      TIMER1_CFG_R = 0x0000004;    // 2) configure for 16-bit mode
      TIMER1_TAMR_R = 0x00000002;   // 3) configure for periodic mode, default down-count settings
      TIMER1_TAILR_R = period-1;    // 4) reload value
      TIMER1_TAPR_R = 3;            // 5) bus clock resolution
      TIMER1_ICR_R = 0x00000001;    // 6) clear TIMER1A timeout flag
      TIMER1_IMR_R = 0x00000001;    // 7) arm timeout interrupt
      NVIC_PRI5_R = (NVIC_PRI5_R&0xFFFF00FF)|0x00008000; // 8) priority 4
    // interrupts enabled in the main program after all devices initialized
    // vector number 37, interrupt number 21
      NVIC_EN0_R = 1<<21;           // 9) enable IRQ 21 in NVIC
      TIMER1_CTL_R = 0x00000001;    // 10) enable TIMER1A
    }
    
    void Timer1A_Handler(void){
      TIMER1_ICR_R = TIMER_ICR_TATOCINT;// acknowledge TIMER1A timeout
      (*PeriodicTask)();                // execute user task
    
    }
    
    
    void Timer2_Init(void(*task2)(void), unsigned long period2){
      SYSCTL_RCGCTIMER_R |= 0x04;   // 0) activate timer2
      PeriodicTask = task2;          // user function
      TIMER2_CTL_R = 0x00000000;    // 1) disable timer2A during setup
      TIMER2_CFG_R = 0x00000000;    // 2) configure for 32-bit mode
      TIMER2_TAMR_R = 0x00000002;   // 3) configure for periodic mode, default down-count settings
      TIMER2_TAILR_R = period2-1;    // 4) reload value
      TIMER2_TAPR_R = 0;            // 5) bus clock resolution
      TIMER2_ICR_R = 0x00000001;    // 6) clear timer2A timeout flag
      TIMER2_IMR_R = 0x00000001;    // 7) arm timeout interrupt
      NVIC_PRI5_R = (NVIC_PRI5_R&0x00FFFFFF)|0x80000000; // 8) priority 4
    // interrupts enabled in the main program after all devices initialized
    // vector number 39, interrupt number 23
      NVIC_EN0_R = 1<<23;           // 9) enable IRQ 23 in NVIC
      TIMER2_CTL_R = 0x00000001;    // 10) enable timer2A
    }
    
    void Timer2A_Handler(void){
      TIMER2_ICR_R = TIMER_ICR_TATOCINT;// acknowledge TIMER2A timeout
      (*PeriodicTask2)();                // execute user task
    }
    
    void get_raw(void)
    {
    //some calcualtions
    
    flag=1;
    
    }
    
    
    void PID (void) 
    {
    x++;
    flag2=1;
    }
    
    int main () 
    {
    
    Timer2_Init(&PID,80000000);  // 1 sec ISR
    Timer1_Init(&get_raw,50000); // 2.5 msec ISR
    
    while (1)
    
    {
    
    if (flag==1)
    
    {
    //dispaly data
    
    flag=0;
    
    }
    
    if (flag2==1)
    
    {
    
    //display x
    
    flag2=0;
    
    }
    
    
    
    }
    

    ----------------------------------

    I thought there's a sort of interference between configurations of timers or a certain order for activation more than one. That's why I didn't attach the code. Here it is. 

  • Hello Islam,

    First and foremost, we do not debug DRM anymore and suggest that users move to TivaWare APIs. As you can see other than you, anyone debugging the same will have a hard time moving though the data sheet to identify each register and bit. Secondly, there is an almost certainty that an error would have been made. For e.g how is the value of 80000000 gives 1 second is not clear?

    Regards
    Amit
  • 80000000 is the Timer A Interval Load value written in GPTMTAILR register. When the timer is counting down, this register is used to load the starting count value into the timer. When the timer is counting up, this register sets the upper bound for the timeout event.
    one second ISR requires 32 bit mode, so I think 8000000 is valid for that register.
  • Hello Islam,

    My question is: How did you compute the value of 8000000 would generate a 1 second interval? And did you pay attention to DRM v/s TivaWare?

    Regards
    Amit
  • Since the PLL is set to 80MHz, it takes that number to count down to zero in 1 sec..
    - Yes I payed attention. But I'm stuck with DRM now since I've taken a long way with it.. But surely will turn to API when I finish my current work..

    Thanks
  • Hello Islam,

    Which functions locks the PLL at 80MHz?

    Regards
    Amit
  • Islam Elnady said:
    I'm stuck with DRM now ... But surely will turn to API when I finish my current work..

    May I fully support Amit - and other vendor Reps - who (most properly) reject the "Vast, extra effort which DRM forces upon them!"

    Your being "stuck" resulted from your actions - and now (your rescue) will unduly absorb Amit's (or vendor others) time, effort, forum service.   Can that be fair - or right - and what if many others see this - and "also being stuck" - demand similar treatment?   Forum response will "grind to a near halt" isn't that so?

    Your use of the API is almost certain to "unstick you" - and should that not prove immediately  true - Amit and/or many others here are far more likely - and able - to assist.

    While your use of DRM is claimed to have taken you a "long way" - I'd bet that distance would have been covered in FAR LESS time - and struggle - had you (originally) opted for the "Tried, True, Tested API."   As always - DRM "creations" are UnTried, UnTested and so often, UnTrue.   (just as your post here reveals...)

  • Hi  Amit,

    I didn't  insert the PLL function (which is working well and tested). I set the PLL in a portion of the code I didn't include here. I just wanted to focus on the timer part to save helpers time and effort.

    My main inquiry  was ... does a timer affect another timer's performance or functionality  when both are set  together?

    This probelm happened only when I added timer 2A on the track. Before that all was good.

    Thanks

  • Hi cb1,
    I'm just a beginner in the field. I started with a course in EdX ( Embedded Systems - Shape The World) where they used DRM all over the course. I have walked a quite long way with it regardless of how much I gained, but I still have so very much to learn. Those are unnecessary details here. But I want to get my work done ( which is based on DRM form the start) and I will start with API after that. I understand API is much easier and efficient. And totally appreciate all of your efforts and patience.

    Thank you,
    Islam
  • Islam,

    Your efforts & persistence ARE to be admired. Perhaps this suggestion will, "Speed, Ease & Enhance" your results:

    As Amit directed - review the API - especially the "Peripheral Driver Library" and revisit your issue (this time) via the API. (which is "rich" in such Timer functions.) Should the API resolve your challenge - you may review the source code w/in the API (it's all there - w/in the individual "C functions" for your review. By those means - you'll identify which Registers - and which "key bits" succeed under the API.

    Armed w/that confirmed detail - your second pass via DRM - has a far greater likelihood of success.

    And again - Amit is (often) alone here - tasking him w/such extra time/effort (imposed by DRM) impacts ALL forum users - which cannot be good.

    Bon chance, mon ami.

  • A quick "follow" for Islam - I note two distinct interrupts for Timer_0 (subtimers A & B (both) appear w/in my "Start-Up file") - thus your fear that, "One may swallow the other" appears unfounded.

    Cannot you monitor the successful entry into each Timer_0 interrupt - to "prove" that your code achieves - at least - that?

    And - IIRC - your timer periods may be integrally related - so that the (shorter) timer occurs in unison w/the longer.   That adds complication - does it not?   If you (temporarily) "break that overlap" (i.e. by changing the duration of your long timer) such may indicate if such "Timer overlap" leads to or aids/abets your issue...

  • Hi,

    Something to add: since inside interrupts some "tasks" are executed, there is the possibility to get faults if the task execution is much longer than the timer interval.

  • Hello Islam,

    No. it does not. I have 4 timers working fine in parallel. However I use TivaWare API's and that makes it very simpler to enable timer and generate the interrupts. I would strongly urge you to move to TivaWare (and in the past users making the move have benefited)

    Regards
    Amit