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.

Errors in example code 2xx series

 Hi all, my code got  stuck  due to some error in the examples codes.

 I got an uncalibrated part and behaved bad also other stuck at start, calibration area is erased when both not one is 0xff:

 Wrong code:

  if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
  {  
    while(1);                               // If calibration constants erased
                                            // do not load, trap CPU!!
  }    

Right code:

  if (CALBC1_1MHZ ==0xFF && CALDCO_1MHZ == 0xFF)

or short version

while  (CALBC1_1MHZ ==0xFF && CALDCO_1MHZ == 0xFF)     ; //  trap CPU!                 

So I BULK erased flash and loaded calibration code.

 Calibration routine failed again and oscillator was not @ correct frequency, code need an adjustment to wait oscillator settle out and stabilize.

More long delay is needed to oscillator startup and COMPLETE stabilization before to calibrate,  Best way is to check oscillator fault flag till reset then wait half a second then run calibration code.

This is the delay code in calibration routine, not enough to reliable operation of LF oscillator

  for (i = 0; i < 0xfffe; i++);             // Delay for XTAL stabilization

 Long time needed:

volatile long i;

for(i=0;i<300000,i++) _NOP;  // Delay for XTAL stabilization

Or best solution wait till oscillator startup then wait stabilization

while (BCSCTL3 & LFXT1OF) ; // Wait till Xtal fault flag reset

  for (i = 0; i < 0xfffe; i++);             // Delay for XTAL stabilization

I am not sure this is corret place to post but i please TI personnel to do correction on code. Also correct xcap is needed to startup and stable run.

 Regards

  • No, the "||" is right. The code locks up if one of the two constants is 0xff, as then the combo is not a valid one.
    In other words: both values needs to be <>0xff to possibly be a valid calibration combo.

    Your modification would accept the values if one of the two is <>0xff, even if the other one is ==0xff which would be definitely invalid.

    Actually CALBC1 could be 0xff and still be a valid value for the BCSCTL1 register, but the claibration will keep the default values of the uppe r4 bits, so the value is always of type 0x8X (and never 0x8F).
    DCOCTL, however, cannot be > 0xF0 since the modulation is meaningless if the DCO is already on its highest tap.

    So the proper check would be:

    if ((CALBC1_1MHz & 0xF0 != 0x80)||(CALDCO_1MHZ >0xF0)) while(1);

    It will detect not only erased but also otherwise altered and invalid calibration data. But just checking for one of them being 0xff is fine to detect an erase.

  • Jens-Michael Gross said:

    DCOCTL, however, cannot be > 0xF0 since the modulation is meaningless if the DCO is already on its highest tap.

    So the proper check would be:

    if ((CALBC1_1MHz & 0xF0 != 0x80)||(CALDCO_1MHZ >0xF0)) while(1);

    Hi Jeans, you asserted  some thing about valid values of DCO registers, can you kindly show me from original TI code?

     

    void Set_DCO(unsigned int Delta)            // Set DCO to selected frequency
    {
      unsigned int Compare, Oldcapture = 0;

      BCSCTL1 |= DIVA_3;                        // ACLK = LFXT1CLK/8
      TACCTL0 = CM_1 + CCIS_1 + CAP;            // CAP, ACLK
      TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear

      while (1)
      {
        while (!(CCIFG & TACCTL0));             // Wait until capture occured
        TACCTL0 &= ~CCIFG;                      // Capture occured, clear flag
        Compare = TACCR0;                       // Get current captured SMCLK
        Compare = Compare - Oldcapture;         // SMCLK difference
        Oldcapture = TACCR0;                    // Save current captured SMCLK

        if (Delta == Compare)
          break;                                // If equal, leave "while(1)"
        else if (Delta < Compare)
        {
          DCOCTL--;                             // DCO is too fast, slow it down
          if (DCOCTL == 0xFF)                   // Did DCO roll under?
            if (BCSCTL1 & 0x0f)
              BCSCTL1--;                        // Select lower RSEL
        }
        else
        {
          DCOCTL++;                             // DCO is too slow, speed it up
          if (DCOCTL == 0x00)                   // Did DCO roll over?
            if ((BCSCTL1 & 0x0f) != 0x0f)
              BCSCTL1++;                        // Sel higher RSEL
        }
      }
      TACCTL0 = 0;                              // Stop TACCR0
      TACTL = 0;                                // Stop Timer_A
      BCSCTL1 &= ~DIVA_3;                       // ACLK = LFXT1CLK
    }

  • Roberto Romano said:
    ... Hi Jeans, you asserted  some thing about valid values of DCO registers, can you kindly show me from original TI code?

     

    void Set_DCO(unsigned int Delta)            // Set DCO to selected frequency
    {
      unsigned int Compare, Oldcapture = 0;

      BCSCTL1 |= DIVA_3;                        // ACLK = LFXT1CLK/8
      TACCTL0 = CM_1 + CCIS_1 + CAP;            // CAP, ACLK
      TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear

      while (1)
      {
        while (!(CCIFG & TACCTL0));             // Wait until capture occured
        TACCTL0 &= ~CCIFG;                      // Capture occured, clear flag
        Compare = TACCR0;                       // Get current captured SMCLK
        Compare = Compare - Oldcapture;         // SMCLK difference
        Oldcapture = TACCR0;                    // Save current captured SMCLK

        if (Delta == Compare)
          break;                                // If equal, leave "while(1)"
        else if (Delta < Compare)
        {
          DCOCTL--;                             // DCO is too fast, slow it down
          if (DCOCTL == 0xFF)                   // Did DCO roll under?
            if (BCSCTL1 & 0x0f)
              BCSCTL1--;                        // Select lower RSEL
        }
        else
        {
          DCOCTL++;                             // DCO is too slow, speed it up
          if (DCOCTL == 0x00)                   // Did DCO roll over?
            if ((BCSCTL1 & 0x0f) != 0x0f)
              BCSCTL1++;                        // Sel higher RSEL
        }
      }
      TACCTL0 = 0;                              // Stop TACCR0
      TACTL = 0;                                // Stop Timer_A
      BCSCTL1 &= ~DIVA_3;                       // ACLK = LFXT1CLK
    }

    I think the TI code shown above is silly.

    When the DCO frequency is too low, it increases DCOCTL by 1. But if DCOCTL reaches 0xE0, increasing it will not increase the frequency. Thus TI code wastes the next 32 rounds and finally increase RSEL by 1 and clear DCOCTL.

    DCOCTL  > 0xE0 generate the same frequency as DCOCTL = 0xE0.  It is silly to  waste time on those settings.

     

     

  • Lichen Wang88934 said:

    I think the TI code shown above is silly.

    When the DCO frequency is too low, it increases DCOCTL by 1. But if DCOCTL reaches 0xE0, increasing it will not increase the frequency. Thus TI code wastes the next 32 rounds and finally increase RSEL by 1 and clear DCOCTL.

    DCOCTL  > 0xE0 generate the same frequency as DCOCTL = 0xE0.  It is silly to  waste time on those settings.

     

     Hi Lichen, thank for pointing me again on DCO specification, from early day when I got first MSP i rewrote assembly code translating to C and old code was exactly like this, so now i realized code waste a lot of time if DCO has to be changed and lock near last step, From datasheet:

    The five MODx bits, switch between the frequency selected by the DCOx bits and the next higher
    frequency set by DCOx+1. When DCOx = 07h, the MODx bits have no effect because the DCO is
    already at the highest setting for the selected RSELx range.

     Ok another error added to code examples, no pain for recalibration purpose but silly if used to routinely recalibrate DCO. Due to this I hope also first RSELx and last RSELx-1 frequency overlap so again modulator cannot be used on next step and can result far than one on step, is this correct anyone measured how freqency increase?. A more clever calibration can be written?

    Thank you

     Roberto

  • The range of frequencies with one RSEL always overlap with that of the next RSEL. The amount of overlap various from chip to chip.

     

  • Roberto Romano said:
    Ok another error added to code examples

    :)

    Roberto Romano said:
    I hope also first RSELx and last RSELx-1 frequency overlap

    IN all datasheets where I looked t this so far, they did overlap. And more than a bit.
    So increasing RSEL may actually significantly decrease the DCO frequency (you'll have to lower the DCO setting before anyway, so the DCO won't overshoot and crash the CPU - applying a divider for MCLK is a good thing too)

    One more thing to consider: the firs RSEL/DCO setting found is not necessarily the best. There can be as many as three different RSEL/DCO combos for the same target frequency (but usually 2). With different results for precision and jitter.

    On newer MSPs (5x), there's also the possibility to massively overclock DCO and use DCODIV for the clocks. This will drastically reduce the jitter caused by modulation. But of course increase the current consumption by DCO. To a smaller extent this is possible for 4x devices too.
    And it allows for even more possible RSEL/DCO combinations for the 'near perfect' frequency match. Also, on these MSPs, DCO==0 and DCO==max will set DCOFFG, as it indicates that the FLL has reached its limits for adjusting the DCO (the FLL won't change RSEL).

  • Jens-Michael Gross said:
    One more thing to consider: the firs RSEL/DCO setting found is not necessarily the best. There can be as many as three different RSEL/DCO combos for the same target frequency (but usually 2). With different results for precision and jitter.

     Hi Jeans, thank for answer, in datasheet this is not so clear, when I finish actual rest time and i can use again my hand I try setup a test bench to measure frequency and jitter of few cpu to extract data.

     Also thank a lot to Lichen Wang88934 helping pinpoint these mismatches but before to confirm all answers and close this thread just one question remain:

     How ask TI staff correct what is wrong in example code? On first i corrected code due to incorrect calibration data on a Launchpad, that costed me two day searching for a inexistent bug before to connect LA to output.

     Regards

     Roberto

  • There are some TI employees around here and some of them have conversations enabled even for non-friends.
    Sometimes, the author of the code is available too.

    However, there is no official way. And from many datasheets the 'submit feedback' llink has vanished too.

    I fear that (not only) I am a reason for the reduced official feedback. When I joined the forum, there was much more official activity here (and much less total activity), but in the last 1.5 years the traffic has increased and much of the work once done by TI employees has been replaced by answers from experienced users. So maybe someone has decided to assign those officials, who were around here previously, to other tasks, saving money.
    I still read posts from Priya or Brandon from time to time, but much, much less than a year before.
    And it's a fulltime job now to scan the MSP430 forum, with all the traffic recently coming in. (not counting all the other forums on e2e)

**Attention** This is a public forum