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.

Problems with sourcing SMCLK from XT2

Other Parts Discussed in Thread: MSP430F5336

I have an MSP430F5336 device and want to source SMCLK from XT2.  According to the documentation, this should be possible.  However, when I configure it for this mode, it gets sourced from DCOCLKDIV instead.  Am I missing something obvious here?

In my design, XT2 is being driven by a clock and not a crystal.  Therefore, XT2 is in bypass mode.  Also, all oscillator fault flags are cleared, so there is nothing that should be reverting the failsave source back to the DCOCLKDIV.

This is the code I am using:

  P7DIR = 0x0;            // XT2IN is input

  P7SEL = 0x04;         // P7.2 = special for XT2IN

  // since XT2 is bypassed, XT2 is turned off

  UCSCTL6 &= ~(XT2OFF + XT2DRIVE_3 + XT1DRIVE_3 + XCAP_3);

  UCSCTL6 |= XT2BYPASS + XT1OFF;

  UCSCTL4 = (SELA__DCOCLK |          // ACLK = DCOCLK
             SELM__DCOCLK |          // MCLK = DCOCLK
             SELS__XT2CLK);          // SMCLK = XT2

Some parts have been left out but this is the relevant parts.

Just to be thorough, I seem to remember reading that XT2 has to be enabled in order for XT2 to source other clocks.  I tried the following with the same results:

  P7DIR = 0x0;            // XT2IN is input

  P7SEL = 0x04;         // P7.2 = special for XT2IN

  // since XT2 is bypassed, XT2 is turned off

  UCSCTL6 &= ~(XT1DRIVE_3 + XCAP_3);

  UCSCTL6 |= XT1OFF;

  // Switch clock sources away from XT1 in order for it to be switched off
  //   and allow for XT2 to lock.
  UCSCTL4 = (SELA__DCOCLKDIV |        // ACLK = DCODIV clk
             SELM__DCOCLKDIV |        // MCLK = DCODIV clk
             SELS__DCOCLKDIV);        // SMCLK = DCODIV clk
  
  // Loop until XT1,XT2 & DCO stabilizes
  do
  {
    // Clear XT2,XT1,DCO fault flags
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
    // Clear fault flags
    SFRIFG1 &= ~OFIFG;
  }
  while (SFRIFG1&OFIFG);                    // Test oscillator fault flag


  UCSCTL4 = (SELA__DCOCLK |          // ACLK = DCOCLK
             SELM__DCOCLK |          // MCLK = DCOCLK
             SELS__XT2CLK);          // SMCLK = XT2

In both of these cases, the XT2 clock does not make it to the SMCLK.  I have it ported to one of the IO pins and can observe it.  It appears to be DCOCLKDIV but may also be just the DCOCLK.  I can't seem to make it work for the SMCLK, although it does work for the reference clock of the FLL and works great there, so I know that somewhere in the system is getting and using the correct XT2 clock.

Any insights would be great.

Thanks,

Brent









  • Setting P7DIR is superfluous, P7SEL takes precedence and disables both, digital output and input. (see port pin schematics and truth table in the datasheet).

    Initialization looks good too (first version), the second one doesn't switch to bypass mode and doesn't clear the XT2OFF bit.
    Now the external frequency shoudl be there, should have a sufficient voltage swing, should have a proper duty cycle and needs to perform about 1000 cycles before the fault bit can be cleared.

    The fuirst version of your code doesn't do the fault clearing loop. Since after enablign XT2 the fault bit will immediately set, you need to clear it or teh clock module refuses to switch to XT2 as source.
    So you need to combine the first version of your code with the clearing loop of the second version.

  • We have a problem similar. XT2 HF crystal, no XT1 and we could not get XT2 to be the SMCLK source. It turns out to be an issue with the oscillator fail flag. If any oscillator is in fail, then it won't switch to the XT2 clock and you can't tell from looking at the registers.

    XT1 is used by ACLK and FLL at boot up so you have to set these to not use XT1 first before setting SMCLK to come from XT2.

    So the steps are configure:

    - the sources you want to use. In our case everything from XT2.

    - turn on XT2

    - wait for there to be no oscillator fail flags set (clear the individual flags and oscillator fail flag each pass)

    - set the SMCLK, MCLK, ACLK to the desired source

    And it now works.

    TI example code for the MSP430F532x C example MSP430F532x_UCS_08.c shows how to handle the flag clearing and waiting for XT2 to start.

    Hope that helps

    Ray Keefe

    Successful Endeavours

  • Ray Keefe said:
    If any oscillator is in fail, then it won't switch to the XT2 clock and you can't tell from looking at the registers.

    Right. If an oscillator has failed, it will go into fallback mode. And it will only return to the configured operation when the OFIFG flag is clear. Which can only be cleared when all fault flags are clear, not just the one of the faulty oscillator.

    The usual crystal initialization loop that is used in almost every demo code, ensures that the program won't proceed unless all active crystals are running and all faults have been removed.

  • The problem with the normal example code is that if you don't have XT1 fitted, then it goes into fault unless you set up the clock source registers so nothing is dependent on XT1.

    In the published example code, the loop never exits. The comments above the code snippet even acknowledge that this is what will happen.

    So to get ACLK, SMCLK and MCLK running from XT2, you not only have to turn XT1 off prior to the loop, but also set up the FLL so it isn't using XT1 and ACLK so it isn't using XT1. Then you can run the loop and it will exit.

    If on the other hand, you use XT2 as not being in fault as the exit condition, MCLK and SMCLK will run from the DCO even though XT2 isn't in fault and the registers are set up to route XT2 to MCLK and SMCLK. This is due to the logic for reverting back to the DO if an oscillator fails. It does it if any oscillator fails, not just the selected oscillator.

    If you look at figure 5-4 Oscillator fault logic, page 169 of the Use Guide slau208m, it shows the logic. This is what gave us the clue as to what was really going on. A fault on any oscillator sets the oscillator fault flag which automatically pushed SMCLK and MCLK back to the DCO.

    The paragraph on page 168 describing the fail over logic is not completely correct. Any oscillator fault will cause the fail over, not just a fault on the selected oscillator.

    What masked the problem for us initially, is that we had set the FLL to XT2 and so the DCO was actually running at about the right frequency (between 1% and 4% error). As a result we didn't initially notice it until we couldn't communications to run reliably. Yet the XT2 fault flag was cleared and the clock source for everything was set to XT2.

  • Hi Ray,

    Thanks for your response to my posting.  However, I am not quite sure it is the same.  I had switched everything away from XT1 (as you have done) and waited for all the flags to clear (as you have also done), yet, I still could not get it to take the XT2 clock.  Are you using the same micro controller as me - the MSP430F5336?  Would you mind sharing your code also?  (Just the portion dealing with the clocks.)

    Thanks,

    Brent

  • Here is our code for setting up to run from XT2.

    // clear existing controls and use DCO for now
    UCSCTL1 = DCORSEL_4 | DISMOD_L; // Frequency range setting without modulation

    // set up for crystal oscillator running as high frequency XT2
    UCSCTL2 = FLLN0_L; // Set FLL divider to 1

    UCSCTL3 = SELREF_5; // Select XT2
    P7SEL |= BIT2; // Set the PSEL bit for XT2IN SLAU208m 5.2.5
    UCSCTL5 = DIVS__1; // Divide the SMCLK by 1 for ACLK and SMCLK

    UCSCTL6 &= ~(XT2OFF); // Enable XT2 SLAU208m 5.2.5
    UCSCTL6 &= ~(XT2DRIVE0);// set the correct drive level for 20MHz
    UCSCTL6 |= XT2DRIVE1;

    // ensure ACLK is not using XT1 or else the oscillator fault flag will remain set and the stabilisation loop will never exit
    UCSCTL4 = SELM__XT2CLK | SELS__XT2CLK | SELA__XT2CLK;

    // turn off XT1 LF oscillator
    _BIC_SR(OSCOFF);

    // now to wait for the external crystal oscillator to start
    do
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
    // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    }
    while (SFRIFG1 & OFIFG); // Test oscillator fault flag

    // oscillator started so we can use it now - safe mode means that DCO will take over if XTAL fails
    UCSCTL4 = SELM__XT2CLK | SELS__XT2CLK | SELA__XT2CLK;
    UCSCTL7 &= ~(DCOFFG + XT2OFFG + XT1LFOFFG + XT1HFOFFG + XT2OFFG); // Clear fault flags according to erratum

    That works for our scenario which is no XT1, ACLK, MCLK, SMCLK from XT2

  • Older thread but why are two steps used for the following code? I'm trying to resolve XT2 issue and can't make any sense of this clock architecture.

    UCSCTL6 &= ~(XT2OFF + XT2DRIVE_3 + XT1DRIVE_3 + XCAP_3);
    
    UCSCTL6 |= XT2BYPASS + XT1OFF;

  • Hi Kenny,


    To be honest, I don't remember the exact reasons.  I believe it may only be convenience and readability because one set is turning bits on and the other is turning bits off.  In either case, with optimizations turned on, it would ultimately get resolved down to one line.

    It sounds like you are having more issues that just that.  Do you want to give more information to see if we can help get to the bottom of your problem?


    Brent

  • Thanks Brent. +1 for readability. I make those kinds of choices too. Especially when the code is not time critical.

    I posted a question with more detail before reading your post (and others). Last night I resolved it but it wasn't very satisfying--I never really learned why my code didn't work. Instead I took another pass through the family guide and wrote new code based on my improved understanding. My final solution involved bringing up XT2 while shutting down XT1 (In one hard-to-read line :)), then shutting down the FLL and modulator, assigning sources, clearing faults per an erratum, and then doing the usual do/while on all three flags.

    I feel like the interface to clocking could be much better. It'd be nice, for example, to view the configuration when in failsafe mode.  I also think the documentation could be much better. Maybe there is a good book. Jens-Michael seems to *really* understand this part and been an excellent contributor.

    K

  • Brent, operations on hardware registers are not combined. Imagine what would happen if you would set a port bit and then clear it and the compiler would combine the operations J
    The hardware registers are declared volatile, to tell the compiler to not optimize accesses to them.
    Of course, the two lines in question could have been combined into a single assignment of type x = (x&y)|z; But as you said, it Is more readable in two lines. And during startup, a few additional MCLK cycles are unimportant.

     Kenny, simplicity and versatility are mutual enemies. I agree that the clock system is rather complex if you start to use the many features it offers. But on the other side, a simple clock system wouldn’t give you all the choices. If the MSP clock system had the ease of use the PICs have, it would mean you’re stuck with two options: internal oscillator or external crystal.
    However, for first steps or simple cases, the clock system configuration is simple (down to ‘do nothing and be happy with the default’).

  • I think we can agree that for a given amount of versatility/complexity the quality of an interface and its documentation can vary. The MSP430 dominates low-power because its functionality in this domain is quite good but in my opinion it could be easier to use and understand.

  • Jens-Michael, digging through the post I located this thread. I'm also having problems starting the XT2CLK and I'm uing TI hardware--specifically the EM430F5137RF900 development board. I debugged my code using the jittery internal oscillator, but now need to switch to the 26MHz oscillator provided for the radio section. (It's a frequency counter application.)

    For testing, I'm poking registers within Code Composer, but the chip is not responding "correctly".

    1)  To avoid overspeeding SM_CLK, I first set the divider to divide-by-2 and I see this on pin 14 of the '5137 set to the default alternate of PM_SMCLK. The frequency changes from ~12 to 6MHz.

    2) I clear the XT2OFF bit in UCSCTL6 to enable XT2. I see the bias on the oscillator clock pins change from 0 to ~700mV, but the oscillator doesn't appear to oscillate. I generously attribute this to the scope loading, but I don't think it's working. I removed the scope probe.

    3)  I change the selection in UCSCTL4 to source SM_CLK from XT2CLK

    4) I check the fault flag in UCSCTL7, XT2OFFG, to make sure it's cleared.

    I believe the oscillator doesn't start and the SM_CLK on pin 14 never jumps to from 6MHz to 13MHz (26MHz/2).

    Where am I going wrong? Was I handed bum hardware? Does the radio need to be enabled to allow XT2CLK to function?

    David Ehrenberg

     

  • I grabbed another '5137 develops PWB loaded my code. I probed the oscillator--same behavior.

    I cut/pasted Ray Keefe's code into my program and after commenting out:

    // P7SEL |= BIT2; // Set the PSEL bit for XT2IN SLAU208m 5.2.5, not on '5137

    and modifying:

    // UCSCTL6 &= ~(XT2DRIVE0); // set the correct drive level for 20MHz
    // UCSCTL6 |= XT2DRIVE1;

    to read XT1DRIVEx the code compiled and but does not work. The clock(s) never come on and the nothing (as far as I can tell) is running.

    Examine fault flags in Code Composer shows all flags down, but i don't know whether to believe this as the clock system is inoperatable.

    Any suggestions out there on why this fails and how does one source SM_CLK from XT2?

    DE

  • There is a "mistake" in Ray Keefe's code where he points all the clocks to XT2CLK and then tests the fault flags. Apparently this leaves the the chip without a functioning clock and execution stops. I replaced Ray's line (for my MSP430F5137 application):

     // UCSCTL4 = SELM__XT2CLK | SELS__XT2CLK | SELA__XT2CLK;       // wrong

    with:

     UCSCTL4 = SELM__REFOCLK | SELS__REFOCLK | SELA__REFOCLK;   // this works

    and the SMCLK is the expected jitter free 13.000MHz. This change, along with the others noted above, finally achieve my goal of sourcing SMCLK from XT2CLK.

    If this post is ever read by TI personnel, a WORKING example of using XT2CLK to source SMCLK in the software distribution (for the many flavors of MSP430 uCs) would be helpful. Posts on this forum extend back many years with no definitive answer--at least not one I could find.

    DE

  • I just answered to your other thread http://e2e.ti.com/support/microcontrollers/msp430/f/166/p/372717/1357677.aspx#1357677

    In short: after clearing all OFFG bits, you also need to clear the OFIFG bit in SFRIFG1. As long as this bit is set, the clocks won’t switch from fallback (REFO or DCO) to the oscillator, even if the oscillator fault bit is clear.

    Also, on 5x family, none of the clocks is ever left without an oscillator. All clocks have a fallback to an oscillator that always works (REFO or DCO).

**Attention** This is a public forum