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.

msp430f5xx timer compare output mode, TACCR0 == TACCRx



I am using the msp430's timer output to generate a PWM. I need the full scale from 0 to 100 % duty cycle.

The timer is setup in Continuous mode (it is used for other stuff as well). The output modes used for generating PWM use the EQU0 and EQUx interrupt events for switching the output signal.

For example in output mode 7 (Reset/Set), the signal gets low on EQUx event, and high on EQU0 event.

Is there any description of what happens if TACCR0 is equal to TACCRx? As far as I can see the behavior is not specified. Maybe there is a hierarchy of the EQU events, that I missed?

I can test and see what the chip actually does, that is not the problem. What I want to know is if the situation is specified somewhere, or if I have no right to expect anything. 

If this is unspecified, my solution is to use the Set and Reset modes in the relevant cases.

Even if specified, TACCR0 == TACCRx means either 0 % or 100 %, and I need to take care of the other case with Set or Reset mode (or Output mode).

 

I suspect that I am not the first one to wonder, is there a common practice for this full-range PWM application?

  • The description of the CCR units has some minor flaws which may lead to misunderstanding.

    There is no direct relation between CCR0 and CCRx. ALL units are just compared to TAR. However, CCR0 plays a specific role in UP or UP/DOWN mode:
    In UP mode, when the timer reaches CCR0, it will roll over to 0 with the next timer tick. In up/down mode it will reverse counting direction with the next tick.

    Anyway, the double action modes have the first action happening when TAR counts to CCRx, and the second action happening when TAR counts to 0 (so not if TAR is reset or written to 0).

    In case of CCR0, this means that there is eactly 1 timer tick between the two actions (so these modes are not as useless as the description implies)

    Since 0 is a count, you should program CCR0 to 1 less than the number of ticks per cycle.

    If CCRx is set to the same as CCR0, the same happens. First action happens when TAR counts to CCRx, second action one tick later.
    Usually, you'll use reset/set mode. So on TAR->=, the output is set, and on TAR->CCRx it is reset. The duty cycle is calculated with (CCR0+1)*percentage. So for 100% duty cycle, set CCRx to CCR0+1. What happens is that the output is set on TAR->0 but never reset since TAR never reaches CCR0+1. Which is 100% duty cycle.

    However, 0% duty cycle are not specified, as both actions would take place on TAR->0, which results in a race condition. To get 0% duty cycle, you should e.g. switch the output mode to reset.

     

  • Jens-Michael Gross said:

    Anyway, the double action modes have the first action happening when TAR counts to CCRx, and the second action happening when TAR counts to 0 (so not if TAR is reset or written to 0).

    In Continuous mode, the first action happens when TAR counts to CCRx, and the second when TAR counts to CCR0. Not to 0. See slau208H (x5xx family), page 364.

    Anyway, if I put CCR0 to 0 I have the same behavior.

    But if CCRx is also 0, TAR counts to CCR0 and and CCRx at the same time. Which action takes place, Reset or Set? Or both? In which order?

     

     

    Jens-Michael Gross said:
    In case of CCR0, this means that there is eactly 1 timer tick between the two actions (so these modes are not as useless as the description implies)

     

    Since 0 is a count, you should program CCR0 to 1 less than the number of ticks per cycle.

    The specification says:

    The OUTn signal is changed when the timer reaches the TAxCCRn and TAxCCR0 values, depending on the output mode.

    Why would there be 1 timer tick between the two actions?

    Jens-Michael Gross said:

    Usually, you'll use reset/set mode. So on TAR->=, the output is set, and on TAR->CCRx it is reset. The duty cycle is calculated with (CCR0+1)*percentage. So for 100% duty cycle, set CCRx to CCR0+1. What happens is that the output is set on TAR->0 but never reset since TAR never reaches CCR0+1. Which is 100% duty cycle.

    I am using Continuous Mode. The timer does not reset on CCR0. Do you refer to Up Mode? The timer is also used for other functionalities, so I can't change its mode.

     

     

     

     

     

  • Gauthier ��stervall said:
    In Continuous mode, the first action happens when TAR counts to CCRx, and the second when TAR counts to CCR0. Not to 0. See slau208H (x5xx family), page 364.

    Yes, that's what the users guide lists. Personally I have never used teh combination of CCR outputs and cont mode. But some time ago we had a long thread in this forum discussing this (up mode, but it doesn't matter much) and in tests we discovered that there IS something happening on the output of CCR0 when usign up mode and running CCR0 in a double-action mode.

    Gauthier ��stervall said:
    Which action takes place, Reset or Set? Or both? In which order?

    Unspecified. It's a racing condition and the outcome depends on the internal implementation. Which is of course not disclosed. I think it would be reliable to test it and then use the test result, as it is not likely that the behavior will change on a specific MSP model. I would not, however, project the TimerA results on TimerB or TimerD without further tests.

    Did you do any programming/testing yourself or are you just in the stage of reading the users guide?

    I think this is another case for Jeff Tenney, who did the tests last time for up mode and might be willing to extend them to cont mode.

  • I posted this note in September after being surprised a little bit by the behavior I found.  After re-reading that note, I don't think I was clear enough that the strange behavior was unique to "up" mode.

    This thread is from October and might also be of some use.

    In summary, the second action of the double action modes usually occurs when TAR equals CCR0.  However, in "up" mode, the second action occurs when the counter rolls from CCR0 back to zero.

    As for the documentation, all of the examples in the User's Guide that are specific to a counting mode (up/continuous/up-down) are actually correct.  They show the true behavior.  However, some of the summary statements later on are wrong because they gloss over this nuance relating to "up" mode.

    To the original question from Gauthier, no, you didn't miss any documentation.  Any configuration that tells the Timer to both set and reset the output on the same clock tick will result in undefined behavior.

    Jeff

  • Thanks. That would be a valuable note to add in the specification.

  • Jeff Tenney said:
    In summary, the second action of the double action modes usually occurs when TAR equals CCR0.  However, in "up" mode, the second action occurs when the counter rolls from CCR0 back to zero.

    This is a bit surprining. Why should it work differently on the two modes?
    One possible explanation is that the second action doesn't happen when TAR counts to CCR0 but when TAR counts from CCR0. This would be the moment TAR counts to 0 in up mode and when it counts to CCR0+1 in cont mode.
    This one tick difference (if this is indeed the answer) might have slipped through unnoticed when you tested cont mode.

    It's difficult to test something that is the reference for your test :)

    Just an 'educated' guess. As usual.

    Jeff Tenney said:
    Any configuration that tells the Timer to both set and reset the output on the same clock tick will result in undefined behavior.

    Based on the above, what happens when CCR0 is set to 0? Does it do the first action on TAR->CCR0 = 0 and the second on TAR->(CCR0+1) = 1?

  • Hi JMG,

    I was intrigued by your idea that the second action might always occur as the counter counts from CCR0.  So I reviewed my notes from before and even did a couple of extra tests.  Alas, no, the second action occurs counting to CCR0 in continuous and up-down modes, and it occurs counting from CCR0 to zero in up mode.

    Since two pair of eyes are better than one, please take a look at this:

    int main( void )
    {
      WDTCTL = WDTPW + WDTHOLD;
     
      UCA0CTL1 = UCSSEL_2 + UCSWRST;
      UCA0CTL0 = UCMSB + UCMST + UCSYNC;
      UCA0BRW = 1;
      UCA0CTL1 &= ~UCSWRST;
     
      P3SEL |= BIT3; // MOSI
      P2SEL |= BIT7; // SCLK
     
      TA0CCR0 = 2;
      TA0CCTL0 = CCIE;
      TA0CCR1 = 1;
      TA0CCTL1 = OUTMOD_3; // Set/Reset
      TA0CTL = TASSEL__ACLK + MC__CONTINUOUS + TACLR;

      P1SEL |= BIT0 + BIT2; // ACLK and TA0.OUT1
      P1DIR |= BIT0 + BIT2;

      _BIS_SR(CPUOFF + GIE);
    }


    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void test( void )
    {
      UCA0TXBUF = TA0R;
    }


    Which generated the following scope image:

    When I switched to MC__UP instead of continuous, the ISR still captured a TA0R value of 2, but the falling edge on TA0.OUT1 came afterwards; one cycle delayed:

    So the final conclusion remains the same, and the documentation is still mostly right.  The examples and diagrams that are specific to each counting mode are accurate.  The summary statements later are too general and don't mention the peculiarity of double-action outputs in "up" mode.

    Jeff

  • Jeff Tenney said:
    Alas, no, the second action occurs counting to CCR0 in continuous and up-down modes, and it occurs counting from CCR0 to zero in up mode.

    That's strange. This difference makes no sense except if intentionally included (or accidentally, which then indicates a bug or at least a glitch in the design, and may disappear in future MSPs when the timer circut is refined)
    Did you get the same results for TimerB?

    However, things are as they are.

    On the bottom line, this means that CCR0 cannto be used for PWM output under any circumstances (even if accepting a full TimerA cycle as PWM cycle).
    Makes the TimerA2 on the G2x devices even less usable.

    p.s: you have a nice scope. What is it?

  • Yes, TimerB has the same results.  Don't forget that these results match the documentation specific to up mode:

    and for Timer B:

    I would say TI definitely provides this special behavior on purpose.  For some people using PWM, it makes considering the CCRn values simpler knowing that the second action occurs at zero.

    And I agree about the lowly TimerA2.  Effectively it has only one PWM channel.  To get two, you'd have to use continuous mode and be very very careful with high and low duty cycles.  Not really practical.

    Jeff

    My scope is a Tek.  I really like it.  http://www.tek.com/products/oscilloscopes/mso4000/  (and no, I don't work for Tek).

  • Jeff Tenney said:
    I would say TI definitely provides this special behavior on purpose.  For some people using PWM, it makes considering the CCRn values simpler knowing that the second action occurs at zero.

    Sure, starting with 0 is easier (and makes more sense). Still, having to set CCR0 to x-1 as '0' is a count too, seems to be still too difficult for some :)

    Jeff Tenney said:
    And I agree about the lowly TimerA2.  Effectively it has only one PWM channel.  To get two, you'd have to use continuous mode and be very very careful with high and low duty cycles.  Not really practical.

    With all the above, I'd say it is impossible to get 2 real PWM outputs on TA2. Since first and second action always happen at the same time for CCR0,, you can only use th esingle action modes, where only 'toggle' does something useful without software intervention. And this gives you always 50% duty cycle independently of the CCR0 value. (only the phase changes, compared to CCR1 output).

    Also, it makes no sense to have the second action happening on CCR0. You can achieve the very same result in cont mode when you just select CCR1 relative to the timer overflow. (if the second action would happen at timer overflow instead of CCR0).
    So in cont mode, CCR0 is pretty much useless for an unattended hardware function. It's only use is something you could have gotten as well completely without it.
    So you're left with a software-supported increment function as its only use.

     

  • I would also have preferred second action on return to 0. As you said it does not make much sense to have reset on CCR0 in continuous mode. Return to 0 is actually (logically, I don't mean how it's done) what triggers the second action in up mode. I suppose TI did not want to or could not take the TAIFG signal in the signal generation.

    There are only few applications I could think of: if you want a pulse of length x, starting in y ticks. Not very useful compared to a real PWM.

    Or if you want to have several PWM signals with a defined phase shift.

  • Gauthier ��stervall said:
    if you want a pulse of length x, starting in y ticks.

    Since all pulses end at CCR0, you couls simply shift this so they end at TAR->0 (just add 65536-CCR0 to teh CCRx values) and you'll get the very same result.

    Gauthier ��stervall said:
    Or if you want to have several PWM signals with a defined phase shift.

    Only if the pulse length matches the phase shift, so all end at CCR0. Which you can also get when inverting the standard PWM logic :)

  • Jens-Michael Gross said:
    Since all pulses end at CCR0, you couls simply shift this so they end at TAR->0 (just add 65536-CCR0 to teh CCRx values) and you'll get the very same result.

    I wrote "starting in y ticks". Assume that you do not want to change the value of TAR.

    Jens-Michael Gross said:
    Only if the pulse length matches the phase shift, so all end at CCR0. Which you can also get when inverting the standard PWM logic :)

    I was thinking when using several timers that would somehow be synchronized.

     

    Note that I wrote these possible use cases as an attempt to explain to myself why TI would make CCR0 behave that way. As I mentioned, I'd find a second action of PWM on TAIFG much more worthwhile.

     

  • Gauthier ��stervall said:
    I wrote "starting in y ticks". Assume that you do not want to change the value of TAR.

    Okay, yes, well, htat's a very special case but you're right.
    If one thinks long enough, he'll find a possible use fo reverything, even used toilet paper :)

    Gauthier ��stervall said:
    I was thinking when using several timers that would somehow be synchronized.

    hmmm, interesting thought. If you need to synchronize several of these TimerA3 (some MSPs have 3 of them) to get 6 synchronized PWM outputs while the timers have independent starting points.

    Gauthier ��stervall said:
    As I mentioned, I'd find a second action of PWM on TAIFG much more worthwhile.

    So we are two (and possibly many more). However, I don't think this will be ever happen, at least not for existing devices with TimerA,B or D. Due to (fruitless, I think) backwards compatibility reasons.

  • While we're discussing the drawbacks of timer A, the fact that they don't have latches for CCR make them very hard to use for PWM LED control or sound generation, where the duty cycle varies constantly. For that you need timer B. But we've really got far from the original topic, now.

**Attention** This is a public forum