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.

MSP430F5151, UCS Module behavior

Other Parts Discussed in Thread: MSP430F5151

I am a programmer working on a customized board equipped with MSP430F5151.

We have an 12MHz oscillator on XT1. My intention is to use this oscillator as my MCLK and SMCLK for testing purpose.

I discovered a behavior that I don't understand.

void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    Clock_Init();
    GPIOnEINT_Init();
    Timer_Init();
    __enable_interrupt();
    for(;;);
}

void Clock_Init(void)
{
  // to support 12MHz
  SetVcoreUp (0x01);
 
  // Configure XT1
  PJSEL |= BIT4+BIT5;                       // Port select XT1
  UCSCTL6 |= XTS;                           // HF
  UCSCTL6 &= ~(XT1DRIVE1);                  // 12MHz
  UCSCTL6 &= ~(XT1OFF);                     // XT1 On
 
  // Configure DCO
  // __bis_SR_register(SCG0);                  // Disable the FLL control loop
  // UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  // UCSCTL3 = SELREF1;                        // Set RefClk
  // __bic_SR_register(SCG0);                  // Enable the FLL control loop

  __delay_cycles(375000);

  // Loop until XT1 & DCO fault flag is cleared
  do
  {
    UCSCTL7 &= ~(XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                            // Clear XT1, DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  } while ( UCSCTL7 & (XT1LFOFFG + XT1HFOFFG) );                   // Test oscillator fault flag
 
  UCSCTL4 = SELA0;    // Configure Clock Source
}

void Timer_Init(void)
{
    TA0CTL = TASSEL__SMCLK + MC__CONTINOUS;
    TA0CCR0 = 12000;
    TA0CCTL0 = CCIE;                          // Capture/compare interrupt enable
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0(void)    /* TA0CCR0 CCIFG0 */
{
    TA0CCR0 += 12000;
    one_ms_counter++;
    
    if ( ( one_ms_counter % 500 ) == 0 ) P3OUT ^= (1u<<1);    // Blink LED for 1 second interval
}

The above code give me an expected result, a blinking LED with 1 second interval.

But if I do not Clear OFIFG, the LED blinks with around 5 second interval.

I don't understand why, and worry about such a situation.


  • I have worked on this issue for two days with some help from our HW engineer. We tested the oscillator, verified the register configuration, rewrite the code to see what would be different. We also noticed that the XT1 amplitude is very low, the load capacitance may not be correct.

  • At power-on, the crystal isn't runningl This causes an ocillator fault. This fault prevents the crystal from being selected as clock source, even if you program the UCS to do so. instead, MCLK and SMCLK will fall back to DCO (which is running on default 2MHz speed). The fallback mechanism is only cleared when you clear OFIFG bit (which can only be done if all other OFFG bits are clear)

    So despite the fact that you dids program SELM and SELS for XT1, they will only switch to XT1 once OFIFG is clear.

  • John Linq said:
    But if I do not Clear OFIFG, the LED blinks with around 5 second interval.

    All the oscillators like external  XT1/XT2 or internal  DCO oscillators need some time to stabilize, and during this process the clock is said to be faulty and unless u resolve this fault (by clearing the fault flag) you cant assign these oscillators for any modules and by default they utilize the DCO.

  • Jens-Michael Gross and chethu gowda:

    Many thanks for your help.

    Originally, I thought that, I don't want to use DCO at this moment, so I can leave DCOFFG flag set, since DCOFFG is set, of course OFIFG is set too.

    Based on my testing result, it seems that I can pretend that all XT1LF, XT1HF, DCO are well configured, just clear (XT1LFOFFG + XT1HFOFFG + DCOFFG) and (OFIFG), then wait for XT1HFOFFG being cleared.

    Is it a mandatory requirement that I have to really configure all the XT1LF, XT1HF, DCO well, before I change anything on UCS module?

  • Our HW engineer tells me that the amplitude of XT1 is only 10mV, but my testing result shows that XT1 seems working fine. Do we need to do something about the low amplitude of XT1?

  • John Linq said:
    Our HW engineer tells me that the amplitude of XT1 is only 10mV

    How did he measure? Normal scope probes (even the better ones) add so much capacitance to the oscillator circuit that oscillationwill heavily drift and attenuate, if not cease at all.
    We use a $700 active FET probe (0.9pF input capacitance) to reliably measure crystal oscillation.

    However, amplitude can be raised by raising the XT1 driving strength (if available).

  • John Linq said:
    Is it a mandatory requirement that I have to really configure all the XT1LF, XT1HF, DCO well, before I change anything on UCS module?

    If you are using the XT1 to source any of the clock modules like MCLK, SMCLK or ACLK, you need to make sure about XT1LF/HFOFFG is cleared, checking about DCOOFFG/XT2OFFG is not necessary, but still you can check them along with XT1LF/HFOFFG as OFIFG is set because of any of the other oscillators too.

  • John Linq said:
    Our HW engineer tells me that the amplitude of XT1 is only 10mV

    Your HW engineer must have checked the voltage level at the leads of XT1 crystal, but the actual voltage level will be different as the MSP430's internal crystal oscillator circuit will amplify this signal.

    Jens-Michael Gross said:
    However, amplitude can be raised by raising the XT1 driving strength (if available).

    This will not again increase the amplitude which is measurable, this drive strength is useful only to improve the startup time of the crystal oscillator, that is the reason during startup the drive is kept high ex: XT1DRIVE=3 will result with startup time of 0.5s, while XT1DRIVE=0 will make the startup time of 1s.

  • chethu gowda said:
    checking about DCOOFFG/XT2OFFG is not necessary,

    It is. You cannot clear OFIFG if one of them is set. However, at power-on defaults, XT2 is disabled (so XT2OFFG isn't set) and the DCO shouldn't operate on its lower or upper limit (but it's starting there, so DCOFFG is initially set but as long as the FLL is operating, teh DCO is soon moved away from fault condition and DCOFFG can be cleared. But it takes about 1ms.)
    And you cannot clear OFIFG unless all OFFG bits are clear. And only after you did, any of the system clocks will switch to XT1 or XT2.

  • => How did he measure? Normal scope probes (even the better ones) add so much

    => Your HW engineer must have checked the voltage level at the leads of XT1 crystal

    I saw he used a normal scope probe to measure. (I almost don't know anything about Hardware Design and Electronics.)

    void Clock_Init(void)
    {
      // to support 12MHz
      SetVcoreUp (0x01);
     
      // Configure XT1
      PJSEL |= BIT4+BIT5;                       // Port select XT1
      UCSCTL6 |= XTS;                           // HF
      UCSCTL6 &= ~(XT1DRIVE1);                  // 12MHz
      UCSCTL6 &= ~(XT1OFF);                     // XT1 On

      __delay_cycles(375000);

      // Loop until XT1 fault flag is cleared
      do
      {
        UCSCTL7 &= ~(XT1LFOFFG + XT1HFOFFG);
      } while ( UCSCTL7 & (XT1LFOFFG + XT1HFOFFG) );
     
      UCSCTL4 = SELA0;    // Configure Clock Source.
      // MSP-FET430UIF checked both DCOFFG and OFIFG are set.
      SFRIFG1 &= ~OFIFG;
    }

    The above code also provide an expected result, a blinking LED with 1 second interval.

    And I checked the DCOFFG and OFIFG with MSP-FET430UIF Debugger on CCS IDE. I am sure they are both set before and after the line [ SFRIFG1 &= ~OFIFG; ].

    If I don't do the [ SFRIFG1 &= ~OFIFG; ], the LED blinks with around 5-6 seconds interval.

    Such testing result seems to show that, I can force OFIFG to be cleared for a tiny moment without clearing DCOFFG, so MSP430 can still switch to XT1 successfully.

  • I also use PJ.6/TD0.1 for PWM.

    The below code give me a PWM signal around 124.97kHz - 125.03kHz. (by Scope)

    void Clock_Init(void)
    {
      // to support 12MHz
      SetVcoreUp (0x01);
     
      // Configure XT1
      PJSEL |= BIT4+BIT5;                       // Port select XT1
      UCSCTL6 |= XTS;                           // HF
      UCSCTL6 &= ~(XT1DRIVE1);                  // 12MHz
      UCSCTL6 &= ~(XT1OFF);                     // XT1 On
     
      // Initialize DCO
      __bis_SR_register(SCG0);                  // Disable the FLL control loop
      UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
      UCSCTL3 = SELREF1;
      __bic_SR_register(SCG0);                  // Enable the FLL control loop
     
      __delay_cycles(375000);

      // Loop until XT1 & DCO fault flag is cleared
      do
      {
        UCSCTL7 &= ~(XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                                // Clear XT1, DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
      } while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
     
      UCSCTL4 = SELA0;    // Configure Clock Source.
    }

    void PWM_Init(void)
    {
        PJSEL |= BIT6;                       // Port select TD0.1
        PJDIR |= BIT6;                       // TD0.1, Output
        
        // Configure TD0
        TD0CCR0 = 96-1;                           // PWM Period
        TD0CCTL1 = OUTMOD_7;                     
        TD0CCR1 = 48;                             // CCR1 PWM duty cycle
        TD0CTL0 = TDSSEL_2 + MC_1 + TDCLR;        // SMCLK, Up to CCR0, Clear TDR
    }

    But if I turn on the Hi-resolution clock 8x TDCLK, like the below code.

    void PWM_Init(void)
    {
        PJSEL |= BIT6;                       // Port select TD0.1
        PJDIR |= BIT6;                       // TD0.1, Output
        
        TD0CTL1 |= TDCLKM_1;                      // Select Hi-res local clock
        TD0HCTL0 = TDHM_0 + TDHCALEN + TDHEN;     // Hi-res clock 8x TDCLK,
                                                  // Calibration and Hi-res mode enable
        // Configure TD0
        TD0CCR0 = 768-1;                          // PWM Period
        TD0CCTL1 = OUTMOD_7;                     
        TD0CCR1 = 384;                            // CCR1 PWM duty cycle
        TD0CTL0 = TDSSEL_2 + MC_1 + TDCLR;        // SMCLK, Up to CCR0, Clear TDR
    }

    It gives me a PWM signal around 123.35kHz - 123.55kHz. (by Scope).

    If I did not do anything wrong, may I get a conclusion that our HW engineer does not provide a real 12MHz XT1 to me?

  • John Linq said:
      __delay_cycles(375000);

    While DCOx bits are initially 0 and causing DCOFFG, the FLL immediately starts adjusting the DCO towards 1MHz. After 32 reference clock ticks (1ms) and therefore 32 modulation steps,  DCOx will be set to 1 and DCOFFG can be cleared. Your delay of 375000 MCLK ticks is way more than that 1ms. (it's almost 1/2 second).

    YOu should simply do UCSCTL7=0; (no need to only clear XT1HFOFFG and XT1LFOFFG

    However, since you don't clear DOCFFG and attempting to clear OFIFG makes a difference, it seems that the attempt to clear OFIFG generates a spike that resets the OFFG bits internal fault bits, where the fault was removed and the OFFG it was reset.
    This is not obvious by the users guides schematics. Possibly a racing condition in the logic - or a not documented preference of reset over set signal in the flipflops, whatever.

  • Jens-Michael Gross said:

    However, since you don't clear DOCFFG and attempting to clear OFIFG makes a difference, it seems that the attempt to clear OFIFG generates a spike that resets the OFFG bits where the fault was removed.
    This is not obvious by the users guides shematics. Possibly a racing condition inteh logic - or a not documented preference of reset over set signal in the flipflops, whatever.

    Many thanks for the explanation.

**Attention** This is a public forum