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.

How come back from LPM3 with disabled XT2?

Other Parts Discussed in Thread: MSP430F6638, MSP430F6438

Dear all,

I'm working on a msp430f6638. After the initialization I enter in an endless loop where I stop the XT2 clock (= Source of dco/fll, DCOCLKDIV -->MClk) (reason: save power) and then enter into LPM3 mode. A timer (sourced by AClk (timer clock source: XT1)) then generates interrupts from time to time, where I leave lpm3. After executing the ISR, I restart the XT2 clock and then execute code before again XT2 is stopped.

All this  works as expected as long as I work with the MSP-FET430UIF module and run button in ccs, but current consumption then is about 270uA in stand by (According to the literature the controller never enters in lpm3 when working with active JTAG)

Therefore I liked to run the code with the free run button in ccs. The standby current is now some microamps (as expected), but the controller never come back to active mode.

When I comment out the stop instruction for XT2, the code works correctly (with free run, but then I do not save power). Therefore I guess that the clock module does not restart correctly (in the initialization it does).

Enter in LPM3 is done as follows:

UCSCTL6 |= XT2OFF;

__bis_SR_register(LPM3_bits + GIE);

 

And in the ISR routine I leave with:

_low_power_mode_off_on_exit();

Has anyone an idea?

 

Addendum: I have recognised that the XT1LFOFFG Flag is set, if working with the free run button (with run, the flag staysat zero). That means that there is a problem with the XT1clock, which sources my interrupt timer... Any idea for this strange behaviour? Why should XT1 not work anymore, when entering LPM3?

  • As long as the debugger is attached and JTAG is active (which it is when using the run button), some LPM features are disabled, even if you try to enable them by entering LPM. Looks like your code depends on one of these, so as soon as you really enter LPM (with JTAG inactive), you lose your clock. Wihtout knowing the whole code, I can only guess.

    Also normally, ACLK, and therefore the crystal clocking it, shouldn't be disabled in LPM3. Maybe your crystal init code has a problem (in free running mode, you enter LPM before the crystal is up and then it never goes up at all).
    And then, if you have LFXT1->ACLK->Timer, even if the crystal isn't running, ACLK should fallback to REFO and continue working.

    A deeper look at your code is definitely needed.

  • Dear Jens-Michael,

    thank you for your reply. I'm also not sure, if the flag shows the correct status (because controller runs in free run mode --> are the registers updated correctly after press the HALT button?). 

    I insert also a __delay_cycles(200000) instruction after XT2 Initialization to get a longer active time, but that makes no difference. Here my actual code:

    void main(void){   
        //Initialization of Device
        WDTCTL    =    WDTPW + WDTHOLD;    //no watchdog
        SetVCore(PMMCOREV_3);    //maximum voltage on core, Core library function
       
        //clock Initialization
        InitXT1Clock();  

     
        //Init ports
        InitGPIO();  // In this function, relevant commands for XT2Clock  are:     P7SEL      =    0x0C; P7DIR     =    0xF3; 

        //Init Timer 0
        InitTimer0();


        //enable Interrupts
        __bis_SR_register(GIE);   

        while(1){
            //endless loop

            InitXT2Clock();

            __delay_cycles(200000);//wait for stable clock

            P6OUT^=1 << 0;//toggle Pin

            //go to sleep mode LPM3
            UCSCTL6 |= XT2OFF;//stop XT2
            __bis_SR_register(LPM3_bits + GIE);   
            __no_operation();//debug
            __no_operation();//debug   
        }

    }

     

    The ISR routine for the timer looks as follow:

    #pragma vector=TIMER0_A1_VECTOR
    __interrupt void TIMER0_A1_ISR(void)
    {
        TA0CCTL1 &= ~CCIFG;//clear ISR flag
        _low_power_mode_off_on_exit();
    }

     

    And my initialization codes:

    void InitXT1Clock(void)
    {

        while(BAKCTL&LOCKIO){
            BAKCTL &= ~(LOCKIO);//unlock external XT1
        }
        UCSCTL6 &= ~(XT1OFF);//start XT1LF
        do
        { UCSCTL7 &= ~XT1LFOFFG;
          __delay_cycles(65535);
        }while(UCSCTL7&XT1LFOFFG);//wait until flag ok
        UCSCTL4 |= SELA_0;//select XT1LF as source of ACLK
        UCSCTL7 = 0x00; //prevent UCS11 Error
       
    }

    void InitXT2Clock(void)
    {
        //Start XT2
        UCSCTL6 &= ~XT2OFF;
        do
        { UCSCTL7 &= ~XT2OFFG;
          __delay_cycles(65535);
        }while(UCSCTL7&XT2OFFG);
       
        //set lowest drive strength now
        UCSCTL6 &= ~XT2DRIVE_3;   
           
        //Select XT2 as Input for DCO/FLL 1:1
        UCSCTL3 = SELREF_5 + FLLREFDIV_0;
        //configure DCO/FLL for ratio 5
          __bis_SR_register(SCG0);
          UCSCTL0 = 0x0000;        
          UCSCTL2 = FLLD_1 + FLLN2;     
          UCSCTL1= DCORSEL_7 ; 
         // Turn on the FLL.  This routine always starts the FLL.
          __bic_SR_register(SCG0);

        while (SFRIFG1 & OFIFG) {                            // check OFIFG fault flag
            UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG);  // Clear OSC flaut Flags
            SFRIFG1 &= ~OFIFG;                                 // Clear OFIFG fault flag
          }
        __delay_cycles(4800); //wait
        UCSCTL4 |= SELM_4;//DCOCLKDIV as source of MCLK
        UCSCTL7 = 0x00; //prevent UCS11 Error
    }

    void InitTimer0(void)
    {   
        TA0CTL = TASSEL_1 + ID_0 + MC_1;
        TA0CCTL1 &= ~CCIFG;
        TA0CCTL1 = OUTMOD_3+CCIE;
        TA0CCR0 = 0x0B;
        TA0CCR1 = 0x0A;
    }

     

    Do you see where I make the mistake(s)?

    Regards

    Lukas

     

     

  • I changed my XT2Init code as follow:

    void InitXT2Clock(void)
    {
        //Start XT2
        UCSCTL6 &= ~XT2OFF;
        do
        { UCSCTL7 &= ~XT2OFFG;
          __delay_cycles(65535);
        }while(UCSCTL7&XT2OFFG);
       
        //set lowest drive strength now
        UCSCTL6 &= ~XT2DRIVE_3;   
           
        //Select XT2 as Input for DCO/FLL 1:1
        UCSCTL3 = SELREF_5 + FLLREFDIV_0;
        //configure DCO/FLL for ratio 5
          __bis_SR_register(SCG0);
          UCSCTL0 = 0x0000;        
          UCSCTL2 = FLLD_1 + FLLN2;     
          UCSCTL1= DCORSEL_7 ; 
         // Turn on the FLL.  This routine always starts the FLL.
          __bic_SR_register(SCG0);

    //old:
        while (SFRIFG1 & OFIFG) {                            // check OFIFG fault flag
            UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG);  // Clear OSC flaut Flags
            SFRIFG1 &= ~OFIFG;                                 // Clear OFIFG fault flag
          }

    //new:

        do
        { UCSCTL7 &= ~DCOFFG;
        __delay_cycles(65535);
        }while(UCSCTL7&DCOFFG);


        __delay_cycles(4800); //wait
        UCSCTL4 |= SELM_4;//DCOCLKDIV as source of MCLK
        UCSCTL7 = 0x00; //prevent UCS11 Error
    }

     

    Now, it seems to work (in fact I do not ask to fault flag of XT1LF). But I'm still not sure if my code works correctly....

    Especially I'm not sure, if XT1 clocks the AClk or if it runs on REFCLK (They have the same frequency). And if something goes wrong with XT1, REFOCLK is used, isn't it?

    Is there an easy test for checking which oscillator sources Aclk?

     

    Lukas

     

  • Lukas said:
        do
        { UCSCTL7 &= ~XT2OFFG;
          __delay_cycles(65535);
        }while(UCSCTL7&XT2OFFG);

    You don't need the delay. In 5x/6x family, the OFFG bit cannot be cleared if the crystal wasn't stable for a certain number of oscillations. So you can omit the delay. if the bit can be cleared, the crystal is running.

    Lukas said:
        UCSCTL6 &= ~XT2DRIVE_3;   

    The reduces driving strength to minimum, only suitable for 4..8MHz XT2.  If your XT2 is higher, it might initially work, but after you disabled XT2, it possibly won't come up again, because you never rise the driving strength (after power-up, it is set to maximum by default).
    This is not just a "let's waste power" setting. The higher driving strength is required for higher frequencies, to compensate for the increasing losses at higher frequencies.

    In the full code you posted, you call XT2_INIT in each loop again.
    But you never switch XT2 off (you drive the timer from it), so no need to switch it on.

    One thing I don't understand: you configure the DCO to be adjusted by the FLL to 8 times the crystal, then use DCODIV (DCO/2) as source for MCLK and SMCLK.
    Okay, this is a valid setup, but why don't you just use a crystal of the wanted speed, source MCLK and SMCLK directly from XT2 and deactivate the DCO completely?

    I think a permanently deactivated DCO compensates for the slightly higher current consumption of a higher frequency crystal, and you don't have any clock jitter (the DCO is only equal to the desired frequency over a longer period of time, and has a significant jitter between individual clock cycles, due to modulation).

    For sourcing your timer, SMCLK needs to be on all teh time, as does XT2. And with your setup, the DCO and FLL need to be on too. (well, the FLL is off during LPM, so you also have a small clock skew). Directly using a crystal of the desired frequency completely bypasses the DCO and the FLL and all problems introduced with them.

  • Dear Jens-Michael,

     

    thank you again for your inputs. I have again some questions / remarks to your post:

    Jens-Michael Gross said:
    You don't need the delay. In 5x/6x family, the OFFG bit cannot be cleared if the crystal wasn't stable for a certain number of oscillations. So you can omit the delay. if the bit can be cleared, the crystal is running.

    I will delete these delays.  I have seen some posts according to older devices and after my code has not worked I thought that I should insert them.

    Jens-Michael Gross said:
    The reduces driving strength to minimum, only suitable for 4..8MHz XT2.  If your XT2 is higher, it might initially work, but after you disabled XT2, it possibly won't come up again, because you never rise the driving strength (after power-up, it is set to maximum by default).

    You are right.

    Jens-Michael Gross said:
    This is not just a "let's waste power" setting. The higher driving strength is required for higher frequencies, to compensate for the increasing losses at higher frequencies.

    You are right again. However, I see no influence in behaviour when switching to lower drive strengths. But I will change this.

    Jens-Michael Gross said:
    In the full code you posted, you call XT2_INIT in each loop again.
    But you never switch XT2 off (you drive the timer from it), so no need to switch it on.

    I thought my timer works on Aclk, which is driven from XT1 clock. In XT1_Init I select for Aclk XT1 oscillator (this is also the initial setting) and in timer0_Init I select TASSEL_1 (--> #define TASSEL_1 (1*0x100u) --> 0000000100000000 which selects Aclk as timer source). It should also run continously (Initialization is done in XT1). In XT2_INIT I set/ delete the bits from USCTL4/ USCTL6 with the |= / &= statements to prevent clearing the settings for XT1. Did I overlook something?

    Jens-Michael Gross said:

    One thing I don't understand: you configure the DCO to be adjusted by the FLL to 8 times the crystal, then use DCODIV (DCO/2) as source for MCLK and SMCLK.
    Okay, this is a valid setup, but why don't you just use a crystal of the wanted speed, source MCLK and SMCLK directly from XT2 and deactivate the DCO completely?

    I think a permanently deactivated DCO compensates for the slightly higher current consumption of a higher frequency crystal, and you don't have any clock jitter (the DCO is only equal to the desired frequency over a longer period of time, and has a significant jitter between individual clock cycles, due to modulation).

    You are right. I have to check that. I work on a prototype which was designed from a colleague. I will ask him.

    Again do you know how I could test if I work on XT1 or REFOCLK?

    Regards

    Lukas

  • Lukas said:
    I see no influence in behaviour when switching to lower drive strengths. But I will change this.

    Once the crystal is oscillating, a lower drive strength may work. Also, the required drive strength depends on the crystal and load capacitor quality. The lower the ESRs are, the lower the required drive strength.

    Lukas said:
    I thought my timer works on Aclk, which is driven from XT1 clock.

    You're right, my fault, I got the timer clock settign wrong. Yes, the timer runs on ACLK and ACLK runs on XT1 (if XT1 is running).

    But after checkign this, I noticed some more issues with or without impact:

    Lukas said:
        while(BAKCTL&LOCKIO){
            BAKCTL &= ~(LOCKIO);//unlock external XT1
        }
        UCSCTL6 &= ~(XT1OFF);//start XT1LF
        do
        { UCSCTL7 &= ~XT1LFOFFG;
          __delay_cycles(65535);
        }while(UCSCTL7&XT1LFOFFG);//wait until flag ok
        UCSCTL4 |= SELA_0;//select XT1LF as source of ACLK
        UCSCTL7 = 0x00; /
        }

    BAKCTL has no LOCKIO bit. The name is LOCKBAK. Actually, LOCKIO is not found anywhere in teh users guide. Of course if it is your own define, it might be correct, bu tyou didn't post it then.
    However, I don't see you programming the RTS before, and LOCKBAK mshould be only cleared after the RTS has been programmed (this ensures, that the RTC hardware is not reset to default the very moment this bit is reset)

    Again, the delay isn't necessary.

    UCSCTL4|=SELA_0 is a nop. It does what it is indended to, as SELA_0 is the default. But or-ing 0 into a register will not change anything. In case of SMCLK with its default SELS_4, or-ing SELS_0 would still have the SMCLK on DCOCLKDIV.
    So using the OR operator with a bitfield, the result depends on the previous setting. (e.g. if the previsous setting was SELS_1 (VLO) and you do an |= SELS_2(REFO), you end up with DCOCLK being selected.
    In this specific case, it does what it is intended to do (keeping the default) but for systems where the configuration is changed fore and back, this can cause non-obvious trouble.

    Writing 0 to UCSCTL7 doesn't serve any purpose. The bits are either cleared due to proper init of the crystal(s) in the respectiver init functions, or they are not. Just writing 0 to this register won't help.

     

    Entering LMP3 should disable SMCLK, if it is not used anywhere else. I'm not sure whethe rthis disables XT2. You should manually set XT2OFF before entering LPM3.

    Lukas said:
    Again do you know how I could test if I work on XT1 or REFOCLK?

    If ACLK is configured for XT1 (it is), XT1 is configured for LF mode (it is, but I don't see you setting the XCAP and XT1DRIVE values, so they are on default maximum), the port is configured fro XT1 usage (Is it? If port config is necessary for the crystals, I would put this into the crystal init function, not in  a general GPIO init function) and teh crystal is oscillating, then if XT1LFOFFG is clear, your're on the crystal. Else XT1LFOFFG is set and you're on REFO.

    About using XT2 directly for MCLK: since you are deactivating XT2 in LPM, MCLK will temporarily switch back to DCO until XT2 is up again. So if the DCO is not synced to XT2 by FLL, you're still running on an unpredictable MCLK speed during wakeup ISR execution. Only after main has re-established XT2 you're on nominal speed again.
    Well, you cannot have everyhting at once. My suggestion was based on my (wrong) assumtion that the timer runs on SMCLK and therefore XT2 is not disabled.
    However, it might still be okay for you to run on a (slower, unstabilized) MCLK until main has re-enabled XT2.

    One more thing: _low_power_mode_off_on_exit will also reactivate the FLL, which is off during ISR execution (normally, there's not enough time for the FLL to sync with the reference during a short ISR, resulting in the FLL detuning the DCO rather than tuning it).
    If you want the FLL and DCO off after XT2 is stable again, you might want to do it manually. There is no need to use the predefined LMPx_BITS values. You can use any combination and e.g. switch clocks off while keeping the CPU on etc. The LMPs are just 'commonly used' combinations of control bits.

  • Dear Jens-Michael,

     

    Jens-Michael Gross said:
    BAKCTL has no LOCKIO bit. The name is LOCKBAK. Actually, LOCKIO is not found anywhere in teh users guide. Of course if it is your own define, it might be correct, bu tyou didn't post it then.

    I insert this after XT1 didn't worked and I have seen that others also had some problems with letting the clock running, see

    MSP430F6638 XT1 Problem (so it is the same processor!)

    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/104660/370319.aspx#370319

    I had exactly the same problem and after insering the code (ehm, well I didn't checked if this Bit exists...), it  worked... And as you mentioned in that thread, this behaviour is strange...

    Jens-Michael Gross said:
    UCSCTL4|=SELA_0 is a nop. It does what it is indended to, as SELA_0 is the default. But or-ing 0 into a register will not change anything. In case of SMCLK with its default SELS_4, or-ing SELS_0 would still have the SMCLK on DCOCLKDIV.
    So using the OR operator with a bitfield, the result depends on the previous setting. (e.g. if the previsous setting was SELS_1 (VLO) and you do an |= SELS_2(REFO), you end up with DCOCLK being selected.
    In this specific case, it does what it is intended to do (keeping the default) but for systems where the configuration is changed fore and back, this can cause non-obvious trouble.

    You are right, these lines are rather thought as a memory hook for myself than for presenting as an excellent code. However, it does the job at the moment.

     

    Jens-Michael Gross said:

    Writing 0 to UCSCTL7 doesn't serve any purpose. The bits are either cleared due to proper init of the crystal(s) in the respectiver init functions, or they are not. Just writing 0 to this register won't help.

     

    According to the errata sheet it would help to fix for the UCS11 error:

    "Function                            Modifying UCSCTL4 clock control register triggers an erroneous clock source request
    Description                       Changing the SELM, SELS, or SELA bits in the UCSCTL4 register might trigger the
                                                respective clocks to select an incorrect clock source that requests the XT1 or XT2 clock.
                                                If the crystals are not present at XT1/XT2 or are present but not yet configured in the
                                                application firmware, then the respective XT1/XT2 fault flag is falsely set.
    Workaround                     Clear all of the fault flags in UCSCTL7 register once after changing any of the SELM,
                                                SELS, or SELA bits in the UCSCTL4 register."

     

    Jens-Michael Gross said:
    Entering LMP3 should disable SMCLK, if it is not used anywhere else. I'm not sure whethe rthis disables XT2. You should manually set XT2OFF before entering LPM3.

    I manually set XT2OFF before entering LPM3 and the current consumption change if I comment out the corresponding code line:

      //go to sleep mode LPM3
            UCSCTL6 |= XT2OFF;//stop XT2
            __bis_SR_register(LPM3_bits + GIE);   
            __no_operation();//debug

     

    Jens-Michael Gross said:
    If ACLK is configured for XT1 (it is), XT1 is configured for LF mode (it is, but I don't see you setting the XCAP and XT1DRIVE values, so they are on default maximum), the port is configured fro XT1 usage (Is it? If port config is necessary for the crystals, I would put this into the crystal init function, not in  a general GPIO init function) and teh crystal is oscillating, then if XT1LFOFFG is clear, your're on the crystal. Else XT1LFOFFG is set and you're on REFO.


    I will put the port config for XT2  into the clock Init routine. However, XT1 has direct clock pins. If the "problem" above with the LOCKIO bit is solved, all should be as you described. Therefore I guess that XT1 works.

    Jens-Michael Gross said:

    About using XT2 directly for MCLK: since you are deactivating XT2 in LPM, MCLK will temporarily switch back to DCO until XT2 is up again. So if the DCO is not synced to XT2 by FLL, you're still running on an unpredictable MCLK speed during wakeup ISR execution. Only after main has re-established XT2 you're on nominal speed again.
    Well, you cannot have everyhting at once. My suggestion was based on my (wrong) assumtion that the timer runs on SMCLK and therefore XT2 is not disabled.
    However, it might still be okay for you to run on a (slower, unstabilized) MCLK until main has re-enabled XT2.

    One more thing: _low_power_mode_off_on_exit will also reactivate the FLL, which is off during ISR execution (normally, there's not enough time for the FLL to sync with the reference during a short ISR, resulting in the FLL detuning the DCO rather than tuning it).
    If you want the FLL and DCO off after XT2 is stable again, you might want to do it manually. There is no need to use the predefined LMPx_BITS values. You can use any combination and e.g. switch clocks off while keeping the CPU on etc. The LMPs are just 'commonly used' combinations of control bits.

    ok, I will looking on that again. Maybe I change to a higher clock frequency for XT2.

    I will update my code and write again if I have new informations...

    Thank you for your support!

    Lukas

     

     

     

     

  • Lukas said:
    According to the errata sheet it would help to fix for the UCS11 error:

    This time I learned something. :)  I didn't know of this erratum.

  • Lukas said:
    According to the errata sheet it would help to fix for the UCS11 error:

    This time I learned something. :)  I didn't know of this erratum.

  • Could you please let us know what was the solution for this problem,
    even we are having the same problem with MSP430F6438 when XT2 OFF -> ON during LPM3.

    In our case we use both XT1 and XT2, and XT1 will be ON all the time,
    and we OFF XT2 during LPM3, after coming out of LPM3 we reset the XT2OFF bit
    but the XT2 won't restart again.

    This is different while debugging using JTAG, while connected to JTAG
    the XT2 restarts properly while coming out from LPM3.
    The problem occurs only during Standalone mode.

  • Please let me know if there is any suggestion on this issue,
    we are still struck in XT2 restart problem.

  • Hi Prad1,


    did you find a solution to the XT2 restart problem? Could you share it with the forum?

    Thanks in advance,

**Attention** This is a public forum