__delay_cycles() is not working with timerA interrupts

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

__delay_cycles() is not working with timerA interrupts

Kirill Popov
Hello!
I've got an issue with using __delay_cycles() while also utilizing
TimerA interrupts.
It seems that __delay_cycles(); is not working if TimerA interrupts
are enabled. Even if nothing is done in interrupt routine.
Here is a sample code:
========== main.c ============
#include <msp430g2553.h>

// Timer A0 interrupt service routine (at top value)
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void) {
    TACCTL0 &= ~(TAIFG); // clear interrupt  flag
}

// Timer A1 interrupt service routine (in the middle)
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A1 (void) {
    if (TACCTL1 & TAIFG) {
        TACCTL1 &= ~(TAIFG); // clear interrupt  flag
    }
}

int main(void) {
    WDTCTL = WDTHOLD | WDTPW; //halt watchdog
    P1REN = ~(BIT6); // pull-ups are disabled on pins 0 and 6
    P1DIR |= BIT6; // pins 0 and 6 are outputs
    P1OUT &= ~(BIT6); // pin 6 and pin 0 are LOW

    TACCR0 = 0x0fff; // set top value for timerA
    TACCR1 = 0x00ff; //set LED glow power
    TACCTL0 = (CCIE); // enable compare interrupt for TACCR0
    TACCTL1 = (CCIE); // enable compare interrupt for TACCR1
    TACTL = (TASSEL1 | MC0 | TACLR | TAIE); // SMCLK, cnt UP, clear, interrupt
    _BIS_SR(GIE); // enable blobal interrupts
    for (;;) {
        P1OUT ^= BIT6;
        __delay_cycles(1000000);
    }
    return 0;
}
======== end of main.c =============

I expect this code to blink with a LED on P1.6 with approximately 1
second interval (no precise timing required). But all I see is the LED
just lit all the time.
If I comment out the line with _BIS_SR(GIE); the LED is blinking as expected.

What could be the reason? My guess is interrupt routine is somehow
spoiling registers used by __delay_cycles(). Is that true?
Would be thankful for a workaround if there is such.

I'm using msp430-gcc (GCC) 4.6.3 20120301 (mspgcc LTS 20120406
unpatched) from Debian repository to build code for TI Launchpad
MSP-EXP430G2 (M430G2553 chip).

Thank you!
--
Best regards,
Kirill Popov.

----
Other ways to contact me:
Gtalk: [hidden email]
Cell phone: +79052062619
LinkedIn: http://ru.linkedin.com/in/kspopov

------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: __delay_cycles() is not working with timerA interrupts

Wayne Uroda-3
I believe your problem is that in the timer A1 ISR, you need to read from
TA0IV in order to clear the interrupt (timer A1 isn't fired from an
interrupt flag but rather from the grouping of events which are then routed
through TA0IV, unless I am mistaken)

17.2.6 Timer_A Interrupts
Two interrupt vectors are associated with the 16-bit Timer_A module:
• TAxCCR0 interrupt vector for TAxCCR0 CCIFG
• TAxIV interrupt vector for all other CCIFG flags and TAIFG

17.2.6.1 TAxCCR0 Interrupt
... The TAxCCR0 CCIFG flag is automatically reset when the TAxCCR0 interrupt
request is serviced.

17.2.6.2 TAxIV, Interrupt Vector Generator
...
Any access, read or write, of the TAxIV register automatically resets the
highest-pending interrupt flag. If
another interrupt flag is set, another interrupt is immediately generated
after servicing the initial interrupt.
...

- Wayne


On Fri, Jul 4, 2014 at 4:22 PM, Kirill Popov <[hidden email]>
wrote:

> Hello!
> I've got an issue with using __delay_cycles() while also utilizing
> TimerA interrupts.
> It seems that __delay_cycles(); is not working if TimerA interrupts
> are enabled. Even if nothing is done in interrupt routine.
> Here is a sample code:
> ========== main.c ============
> #include <msp430g2553.h>
>
> // Timer A0 interrupt service routine (at top value)
> #pragma vector=TIMER0_A0_VECTOR
> __interrupt void Timer_A0 (void) {
>     TACCTL0 &= ~(TAIFG); // clear interrupt  flag
> }
>
> // Timer A1 interrupt service routine (in the middle)
> #pragma vector=TIMER0_A1_VECTOR
> __interrupt void Timer_A1 (void) {
>     if (TACCTL1 & TAIFG) {
>         TACCTL1 &= ~(TAIFG); // clear interrupt  flag
>     }
> }
>
> int main(void) {
>     WDTCTL = WDTHOLD | WDTPW; //halt watchdog
>     P1REN = ~(BIT6); // pull-ups are disabled on pins 0 and 6
>     P1DIR |= BIT6; // pins 0 and 6 are outputs
>     P1OUT &= ~(BIT6); // pin 6 and pin 0 are LOW
>
>     TACCR0 = 0x0fff; // set top value for timerA
>     TACCR1 = 0x00ff; //set LED glow power
>     TACCTL0 = (CCIE); // enable compare interrupt for TACCR0
>     TACCTL1 = (CCIE); // enable compare interrupt for TACCR1
>     TACTL = (TASSEL1 | MC0 | TACLR | TAIE); // SMCLK, cnt UP, clear,
> interrupt
>     _BIS_SR(GIE); // enable blobal interrupts
>     for (;;) {
>         P1OUT ^= BIT6;
>         __delay_cycles(1000000);
>     }
>     return 0;
> }
> ======== end of main.c =============
>
> I expect this code to blink with a LED on P1.6 with approximately 1
> second interval (no precise timing required). But all I see is the LED
> just lit all the time.
> If I comment out the line with _BIS_SR(GIE); the LED is blinking as
> expected.
>
> What could be the reason? My guess is interrupt routine is somehow
> spoiling registers used by __delay_cycles(). Is that true?
> Would be thankful for a workaround if there is such.
>
> I'm using msp430-gcc (GCC) 4.6.3 20120301 (mspgcc LTS 20120406
> unpatched) from Debian repository to build code for TI Launchpad
> MSP-EXP430G2 (M430G2553 chip).
>
> Thank you!
> --
> Best regards,
> Kirill Popov.
>
> ----
> Other ways to contact me:
> Gtalk: [hidden email]
> Cell phone: +79052062619
> LinkedIn: http://ru.linkedin.com/in/kspopov
>
>
> ------------------------------------------------------------------------------
> Open source business process management suite built on Java and Eclipse
> Turn processes into business applications with Bonita BPM Community Edition
> Quickly connect people, data, and systems into organized workflows
> Winner of BOSSIE, CODIE, OW2 and Gartner awards
> http://p.sf.net/sfu/Bonitasoft
> _______________________________________________
> Mspgcc-users mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>

------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: __delay_cycles() is not working with timerA interrupts

Kirill Popov
Thank you, Wayne!

After reading your response I understood I've been reading incorrect
registers to check for Interrupt flag. Here is a snippet of the code
that worked for me:
============ code ==================
// Timer A0 interrupt service routine (at top value)
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void) {
    _NOP();
}

// Timer A1 interrupt service routine (in the middle)
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A1 (void) {
    if (TAIV == TA0IV_TACCR1) {
        TACCTL1 &= ~(TAIFG); // clear interrupt  flag
    }
}
============ end of code ============

After reading some example I also realized that it's better to use
switch() during TIMER0_A1_VECTOR interrupt "routing" - this allows to
read TAIV only once and select the appropriate interrupt.
--
Best regards,
Kirill Popov.

----
Other ways to contact me:
Gtalk: [hidden email]
Cell phone: +79052062619
LinkedIn: http://ru.linkedin.com/in/kspopov


On Fri, Jul 4, 2014 at 10:57 AM, Wayne Uroda <[hidden email]> wrote:

> I believe your problem is that in the timer A1 ISR, you need to read from
> TA0IV in order to clear the interrupt (timer A1 isn't fired from an
> interrupt flag but rather from the grouping of events which are then routed
> through TA0IV, unless I am mistaken)
>
> 17.2.6 Timer_A Interrupts
> Two interrupt vectors are associated with the 16-bit Timer_A module:
> • TAxCCR0 interrupt vector for TAxCCR0 CCIFG
> • TAxIV interrupt vector for all other CCIFG flags and TAIFG
>
> 17.2.6.1 TAxCCR0 Interrupt
> ... The TAxCCR0 CCIFG flag is automatically reset when the TAxCCR0 interrupt
> request is serviced.
>
> 17.2.6.2 TAxIV, Interrupt Vector Generator
> ...
> Any access, read or write, of the TAxIV register automatically resets the
> highest-pending interrupt flag. If
> another interrupt flag is set, another interrupt is immediately generated
> after servicing the initial interrupt.
> ...
>
> - Wayne
>
>
> On Fri, Jul 4, 2014 at 4:22 PM, Kirill Popov <[hidden email]>
> wrote:
>>
>> Hello!
>> I've got an issue with using __delay_cycles() while also utilizing
>> TimerA interrupts.
>> It seems that __delay_cycles(); is not working if TimerA interrupts
>> are enabled. Even if nothing is done in interrupt routine.
>> Here is a sample code:
>> ========== main.c ============
>> #include <msp430g2553.h>
>>
>> // Timer A0 interrupt service routine (at top value)
>> #pragma vector=TIMER0_A0_VECTOR
>> __interrupt void Timer_A0 (void) {
>>     TACCTL0 &= ~(TAIFG); // clear interrupt  flag
>> }
>>
>> // Timer A1 interrupt service routine (in the middle)
>> #pragma vector=TIMER0_A1_VECTOR
>> __interrupt void Timer_A1 (void) {
>>     if (TACCTL1 & TAIFG) {
>>         TACCTL1 &= ~(TAIFG); // clear interrupt  flag
>>     }
>> }
>>
>> int main(void) {
>>     WDTCTL = WDTHOLD | WDTPW; //halt watchdog
>>     P1REN = ~(BIT6); // pull-ups are disabled on pins 0 and 6
>>     P1DIR |= BIT6; // pins 0 and 6 are outputs
>>     P1OUT &= ~(BIT6); // pin 6 and pin 0 are LOW
>>
>>     TACCR0 = 0x0fff; // set top value for timerA
>>     TACCR1 = 0x00ff; //set LED glow power
>>     TACCTL0 = (CCIE); // enable compare interrupt for TACCR0
>>     TACCTL1 = (CCIE); // enable compare interrupt for TACCR1
>>     TACTL = (TASSEL1 | MC0 | TACLR | TAIE); // SMCLK, cnt UP, clear,
>> interrupt
>>     _BIS_SR(GIE); // enable blobal interrupts
>>     for (;;) {
>>         P1OUT ^= BIT6;
>>         __delay_cycles(1000000);
>>     }
>>     return 0;
>> }
>> ======== end of main.c =============
>>
>> I expect this code to blink with a LED on P1.6 with approximately 1
>> second interval (no precise timing required). But all I see is the LED
>> just lit all the time.
>> If I comment out the line with _BIS_SR(GIE); the LED is blinking as
>> expected.
>>
>> What could be the reason? My guess is interrupt routine is somehow
>> spoiling registers used by __delay_cycles(). Is that true?
>> Would be thankful for a workaround if there is such.
>>
>> I'm using msp430-gcc (GCC) 4.6.3 20120301 (mspgcc LTS 20120406
>> unpatched) from Debian repository to build code for TI Launchpad
>> MSP-EXP430G2 (M430G2553 chip).
>>
>> Thank you!
>> --
>> Best regards,
>> Kirill Popov.
>>
>> ----
>> Other ways to contact me:
>> Gtalk: [hidden email]
>> Cell phone: +79052062619
>> LinkedIn: http://ru.linkedin.com/in/kspopov
>>
>>
>> ------------------------------------------------------------------------------
>> Open source business process management suite built on Java and Eclipse
>> Turn processes into business applications with Bonita BPM Community
>> Edition
>> Quickly connect people, data, and systems into organized workflows
>> Winner of BOSSIE, CODIE, OW2 and Gartner awards
>> http://p.sf.net/sfu/Bonitasoft
>> _______________________________________________
>> Mspgcc-users mailing list
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>
>

------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: __delay_cycles() is not working with timerA interrupts

Kirill Popov
Thanks, Stephen!
Yes, clearing TAIFG is not required (found out during experiments).

Why do you recommend to read the vector register and store its value
in a local register? Isn't it read only once (and cleared after that)
if I use switch() statement to select the correct handler?
--
Best regards,
Kirill Popov.

----
Other ways to contact me:
Gtalk: [hidden email]
Cell phone: +79052062619
LinkedIn: http://ru.linkedin.com/in/kspopov


On Wed, Jul 9, 2014 at 2:53 PM, Stephen R Phillips
<[hidden email]> wrote:

> Just reading the TA0IV should clear the flag (highest to lowest) but as you said their are 2 vectors.
>
> I would read the vector register and store its value in a local register at the begining of the interrupt then proceed to a comparison switch or something else. you do NOT need to clear the bits you should check the user guide for the archetecture and it should verify this behavior. I've not seen an errata that this doesn't work.
>
> Direct manipulation of the IFG flags can lead to weird behavior so it's not frowned on but can be troublesome.
>
> The worst to do that with is the serial UCA and UCB ports. That's just a big "don't do" with those.
>
>
> Stephen R. Phillips was here
>
>
>
>
>
>
> Please be advised what was said may be absolutely wrong, and hereby this disclaimer follows.  I reserve the right to be wrong and admit I was wrong in front of the entire world. It won't be the first or the last in all likelyness.
>
>
>
>
>
>
>> On Monday, July 7, 2014 8:50 PM, Kirill Popov <[hidden email]> wrote:
>> >T hank you, Wayne!
>>
>> After reading your response I understood I've been reading incorrect
>> registers to check for Interrupt flag. Here is a snippet of the code
>> that worked for me:
>> ============ code ==================
>> // Timer A0 interrupt service routine (at top value)
>> #pragma vector=TIMER0_A0_VECTOR
>> __interrupt void Timer_A0 (void) {
>>     _NOP();
>> }
>>
>> // Timer A1 interrupt service routine (in the middle)
>> #pragma vector=TIMER0_A1_VECTOR
>> __interrupt void Timer_A1 (void) {
>>     if (TAIV == TA0IV_TACCR1) {
>>         TACCTL1 &= ~(TAIFG); // clear interrupt  flag
>>     }
>> }
>> ============ end of code ============
>>
>> After reading some example I also realized that it's better to use
>> switch() during TIMER0_A1_VECTOR interrupt "routing" - this allows to
>> read TAIV only once and select the appropriate interrupt.
>> --
>> Best regards,
>> Kirill Popov.
>>
>> ----
>> Other ways to contact me:
>> Gtalk: [hidden email]
>> Cell phone: +79052062619
>> LinkedIn: http://ru.linkedin.com/in/kspopov
>>
>>
>>
>> On Fri, Jul 4, 2014 at 10:57 AM, Wayne Uroda <[hidden email]> wrote:
>>>  I believe your problem is that in the timer A1 ISR, you need to read from
>>>  TA0IV in order to clear the interrupt (timer A1 isn't fired from an
>>>  interrupt flag but rather from the grouping of events which are then routed
>>>  through TA0IV, unless I am mistaken)
>>>
>>>  17.2.6 Timer_A Interrupts
>>>  Two interrupt vectors are associated with the 16-bit Timer_A module:
>>>  • TAxCCR0 interrupt vector for TAxCCR0 CCIFG
>>>  • TAxIV interrupt vector for all other CCIFG flags and TAIFG
>>>
>>>  17.2.6.1 TAxCCR0 Interrupt
>>>  ... The TAxCCR0 CCIFG flag is automatically reset when the TAxCCR0
>> interrupt
>>>  request is serviced.
>>>
>>>  17.2.6.2 TAxIV, Interrupt Vector Generator
>>>  ...
>>>  Any access, read or write, of the TAxIV register automatically resets the
>>>  highest-pending interrupt flag. If
>>>  another interrupt flag is set, another interrupt is immediately generated
>>>  after servicing the initial interrupt.
>>>  ...
>>>
>>>  - Wayne
>>>
>>>
>>>  On Fri, Jul 4, 2014 at 4:22 PM, Kirill Popov
>> <[hidden email]>
>>>  wrote:
>>>>
>>>>  Hello!
>>>>  I've got an issue with using __delay_cycles() while also utilizing
>>>>  TimerA interrupts.
>>>>  It seems that __delay_cycles(); is not working if TimerA interrupts
>>>>  are enabled. Even if nothing is done in interrupt routine.
>>>>  Here is a sample code:
>>>>  ========== main.c ============
>>>>  #include <msp430g2553.h>
>>>>
>>>>  // Timer A0 interrupt service routine (at top value)
>>>>  #pragma vector=TIMER0_A0_VECTOR
>>>>  __interrupt void Timer_A0 (void) {
>>>>      TACCTL0 &= ~(TAIFG); // clear interrupt  flag
>>>>  }
>>>>
>>>>  // Timer A1 interrupt service routine (in the middle)
>>>>  #pragma vector=TIMER0_A1_VECTOR
>>>>  __interrupt void Timer_A1 (void) {
>>>>      if (TACCTL1 & TAIFG) {
>>>>          TACCTL1 &= ~(TAIFG); // clear interrupt  flag
>>>>      }
>>>>  }
>>>>
>>>>  int main(void) {
>>>>      WDTCTL = WDTHOLD | WDTPW; //halt watchdog
>>>>      P1REN = ~(BIT6); // pull-ups are disabled on pins 0 and 6
>>>>      P1DIR |= BIT6; // pins 0 and 6 are outputs
>>>>      P1OUT &= ~(BIT6); // pin 6 and pin 0 are LOW
>>>>
>>>>      TACCR0 = 0x0fff; // set top value for timerA
>>>>      TACCR1 = 0x00ff; //set LED glow power
>>>>      TACCTL0 = (CCIE); // enable compare interrupt for TACCR0
>>>>      TACCTL1 = (CCIE); // enable compare interrupt for TACCR1
>>>>      TACTL = (TASSEL1 | MC0 | TACLR | TAIE); // SMCLK, cnt UP, clear,
>>>>  interrupt
>>>>      _BIS_SR(GIE); // enable blobal interrupts
>>>>      for (;;) {
>>>>          P1OUT ^= BIT6;
>>>>          __delay_cycles(1000000);
>>>>      }
>>>>      return 0;
>>>>  }
>>>>  ======== end of main.c =============
>>>>
>>>>  I expect this code to blink with a LED on P1.6 with approximately 1
>>>>  second interval (no precise timing required). But all I see is the LED
>>>>  just lit all the time.
>>>>  If I comment out the line with _BIS_SR(GIE); the LED is blinking as
>>>>  expected.
>>>>
>>>>  What could be the reason? My guess is interrupt routine is somehow
>>>>  spoiling registers used by __delay_cycles(). Is that true?
>>>>  Would be thankful for a workaround if there is such.
>>>>
>>>>  I'm using msp430-gcc (GCC) 4.6.3 20120301 (mspgcc LTS 20120406
>>>>  unpatched) from Debian repository to build code for TI Launchpad
>>>>  MSP-EXP430G2 (M430G2553 chip).
>>>>
>>>>  Thank you!
>>>>  --
>>>>  Best regards,
>>>>  Kirill Popov.
>>>>
>>>>  ----
>>>>  Other ways to contact me:
>>>>  Gtalk: [hidden email]
>>>>  Cell phone: +79052062619
>>>>  LinkedIn: http://ru.linkedin.com/in/kspopov
>>>>
>>>>
>>>>
>> ------------------------------------------------------------------------------
>>>>  Open source business process management suite built on Java and Eclipse
>>>>  Turn processes into business applications with Bonita BPM Community
>>>>  Edition
>>>>  Quickly connect people, data, and systems into organized workflows
>>>>  Winner of BOSSIE, CODIE, OW2 and Gartner awards
>>>>  http://p.sf.net/sfu/Bonitasoft
>>>>  _______________________________________________
>>>>  Mspgcc-users mailing list
>>>>  [hidden email]
>>>>  https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>>>
>>>
>>
>> ------------------------------------------------------------------------------
>> Open source business process management suite built on Java and Eclipse
>> Turn processes into business applications with Bonita BPM Community Edition
>> Quickly connect people, data, and systems into organized workflows
>> Winner of BOSSIE, CODIE, OW2 and Gartner awards
>> http://p.sf.net/sfu/Bonitasoft
>> _______________________________________________
>> Mspgcc-users mailing list
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>>

------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users