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.

SMCLK can't switch back to DCOCLK after initially switching to LFXT1 and VLOCLK

Other Parts Discussed in Thread: MSP430G2452

Hi,

I am testing different clock source settings using MSP430g2452 chip on MSP-EXP430G2 rev 1.5 Launchpad board.

I am able to configure the MCLK and SMCLK from the LFXT1 (VLOCLK) and output SMCLK on P1.4 and see correct frequency count on a portable frequency counter.

In my code I initially switch both MCLK and SMCLK to the internal LFXT1/VLOCLK source.

However, I discovered that once SMCLK source is set to LFXT1, it doesn't want to go back to DCOCLK, and clock signal on SMCLK disappears (my counter shows 0 Hz on P1.4). Seems like the MCU is either ignoring subsequent setting of BCSCTL2.SELS=0  (set SMCLK source to DCO), or the DCO has somehow stopped running?

Is there anyway to reset the SMCLK back DCO or restart the DCO?
The status register viewed in CCS6 shows SGO0=0, so DCO should be on.
Is there any explanation for this behavior?

Test code is as follows:

int
iCounter;
WDTCTL = WDTPW | WDTHOLD;

// -- setup PIN1.4 to output SMCLK signal (per MSP430g2452 datasheet).
P1OUT = P1OUT & (~BIT4); // -- output 0 into P1.4.
P1DIR = P1DIR | BIT4;  // -- make P1.4 output (P1DIR.4=1).
P1SEL = P1SEL | BIT4; // -- output SMCLK (P1SEL.4=1)
P1SEL2 = P1SEL2 & (~BIT4); // -- output SMCLK (P1SEL2.4=0)
ADC10AE0 = ADC10AE0 & (~BIT4); // -- disable analog input.

BCSCTL3 = BCSCTL3 | LFXT1S_2; // => LFXT1 Source = VLOCLK (~12kHz)
IFG1 = IFG1 & (~OFIFG);  // => Clear OFIFG in IFG1
do{
iCounter = iCounter + 1;
 __delay_cycles(55);
}while((IFG1 & OFIFG) && (iCounter<10) );

if (IFG1 & OFIFG){
return 0; // -- if still fault, exit.
 }

BCSCTL2 = BCSCTL2 | (SELM_3 + DIVM_0); // -- Set MCLK source to LFXT1(VLOCLK)=~12kHz,
BCSCTL2 = BCSCTL2 & (~SELS); // -- SMCLK = DCOCLK (~1MHz) ... OK runs at ~1MHz on P1.4.
__delay_cycles(120000); // -- run for 10 sec.
BCSCTL2 = BCSCTL2 | SELS; // -- SMCLK = LFXT1 (VLOCLK) ... OK runs at ~12kHz on P1.4.
__delay_cycles(120000); // -- run for 10 sec.
BCSCTL2 = BCSCTL2 & (~SELS); // -- SMCLK=DCOCLK(~1MHz) doesn't work, SMCLK shows 0Hz on frequency counter on P1.4.
do{} while(1);

  • This sounds strange.

    A possible explanation: The DCO goes off if not used by anyone. When you switch SMCLK to VLO, nobody needs the DCO anymore. So it stops. Now switching SMCLK back to DCO won’t start it because nobody is needing SMCLK. If you had a timer assigned to use SMCLK, I guess the DCO would come up and provide a clock for SMCLK.

    However, from a logical view, I would expect DCO going off only if told so by SCG0 (?), or to go off immediately if the unused SMCLK is the last one needing the DCO.

**Attention** This is a public forum