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.
Hi,
Our customer 's design of MSP430F552x UCS Module is below.
MCLK=XT2(12MHz), SMCLK=ACLK=XT1(32.768kHz)
And he worry about the details of power consumption.
So, his question is that how much speed is DCOCLKDIV under Fail-Safe Operation?
Depend on setting of (N+1)x(fFLLREFCLK/n), or unique freq. ?
Please let me know if there is any answers.
Thank you.
First, it doesn't make much sense to have ACLK and SMCLK both the same 32768Hz. Whereever you need this, you also have the choice to use ACLK or SMCLK, so this is a waste of recources, you only need one. If you just want to save power, disable SMCLK completely and use ACLK all the time. ACLK also has teh fallback to REFO if the external crystal fails.
Under fail-safe operation, the FLL uses REFO instead of XT1. The change in DCOCLKDIV is as much as the difference between XT1 and the REFO, which is in the range of a few % (see datasheet for REFO precision)
DCOCLKDIV is derived from DCO and DCO is independent of the crystals. The only connecting part is the FLL which has a fail-safe fallback from XT1 to REFO.
So the formula is: (N+1)x(fREFO/n) if FLLREFCLK was LFXT1 before.
If FLLREFCLK was not LFXT1, ther eis no fail-safe fallback for the reference. The FLL get 0Hz reference and the resulting DCO frequency (and relative to it DCOCLKDIV) is the lowest frequency for the currently configured RSELx frequency range. The FLL tries to adjust the DCO to 0, but cannot go lower than DCOx=0. This also sets the DCOFFG fault flag.
See teh datasheet for the frequency range for different RSELx settings.
Hi,
Jens-Michael san, thank you for your suggestion.
Our customer do some test below.
Please confirm that these result are right ?
case1: I trap my source code to generate MCLK sourced from DCOCLKDIV instead of XT2OFF automatically.
Settings : UCSCTL1=0x0050(DCORSEL_5)
result: MCLK=12.0MHz
UCSCTL7のDCOOFFG=0x0
UCSCTL0のDCO=0x18
UCSCTL0のMOD=0x58
case2:Follow after case1, I freezed external XT2 manually.
Settings : UCSCTL1=0x0050(DCORSEL_5)
result : MCLK=550KHz
case3:In jtag release mode, I freezed external XT2 manually without trap above.
Settings : UCSCTL1=0x0050(DCORSEL_5)
result : MCLK=550KHz
Thanks and Best Regards.
Tadaaki Matsumoto
Well, the DCO frequencies are different for every single device, so I cannot confirm any setting, I can only check whether it is a possible result.
case1:
DCORSEL_5 means a frequency of 6.0 to 23.7MHz at least, but possibly 2.5 to 54MHz.
DCO=0x18 is in the upper quarter. For the default divider for DCODIV = 2, this means that an MCLK of 12.0MHz requires 24MHz DCO. Sounds reasonable.
However, I don't know why 12MHz. Are these two registers the only ones you touched? Because per default, the FLL is active and adjusts the DCO to 2MHz (resulting in 1MHz MCLK). So you should end up with DCOx=0, MODx=0 and DCOFFG=1 when the FLL fails to get below the DCORSEL_5 range to reach the default 1.05MHz. (best case, it can go down to 1.25MHz, but possibly not below 3MHz on DCORSEL_5)
case2+3: You mean you switched the MCLK to be sourced by XT2 but XT2 has a forced fault? Then it should fall back to DCOCLKDIV.
If it is still DCORSEL_5 (and a DCOCLKDIV divider of 2), then the result is strange. The FLL (if active) cannot adjust RSELx, so for DCORSEL_5, the minimum DCO frequency is 2.5 to 6MHz and DCOCLKDIV should not be below the range of 1.25 to 3MHz. 550kHz is not what I'd expect with these settings (and the other default register contents).
550kHz are only plausible for a setting of DCORSEL_0, DCOx=0x18 and FLLD_1 or DCORSEL_3 and DCOx=0. However, the default is DCORSEL_2 and DCOx=0, which results in a DCOCLKDIV frequency of 0.16 to 0.375MHz until adjusted by the FLL to 1.05MHz.
For DCORSEL_5,the DCOCLK divider must be 8 or 16 (FLLD_3 or _4) to get 550kHz on DCOCLKDIV. Nothing of this is a default value or somehow adjusted by internal mechanisms.
I'd need to see the source code to say more.
Dear Jens-Michael san,
Thank you for the good advice.
And I'm sorry for keep you waiting.
We get partial source code of this test result.
Please let me know if there is any suggestions.
Thanks and Best Regards.
Tadaaki Matsumoto
========================================================================
#define USB_MCLK_FREQ 12000000
void Init_Clock(void)
{
//XT1 32768Hz
P5SEL |= BIT5 + BIT4;
UCSCTL6 &= ~(XCAP_3);
UCSCTL6 |= XCAP_1; // Internal load cap
UCSCTL6 &= ~(XT1BYPASS_L); // Internal load cap
UCSCTL6 &= ~(XTS_L); //
UCSCTL6 &= ~(XT1OFF); // XT1 On
//XT2 12MHz
P5SEL |= BIT3 + BIT2;
UCSCTL6 &= ~(XT2DRIVE_3);
UCSCTL6 |= XT2DRIVE_1;
UCSCTL6 &= ~(XT2BYPASS);
UCSCTL6 &= ~XT2OFF; // Enable XT2
UCSCTL3 = SELREF__XT2CLK + FLLREFDIV_0; // XT2->REFO, fFLLREFCLK/1
UCSCTL4 = SELA__XT1CLK + SELS__XT2CLK + SELM__XT2CLK; // SMCLK=MCLK=XT2, ACLK=XT1
do { // Loop until XT1,XT2 & DCO stabilizes
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
Init_DCO_Ex(USB_MCLK_FREQ/1000, USB_MCLK_FREQ/32768);
}
void Init_DCO_Ex(uint16_t fsystem, uint16_t ratio)
{
uint16_t d, dco_div_bits;
uint16_t mode = 0;
// Save actual state of FLL loop control, then disable it. This is needed to
// prevent the FLL from acting as we are making fundamental modifications to
// the clock setup.
uint16_t srRegisterState = __get_SR_register() & SCG0;
__bic_SR_register(SCG0);
d = ratio;
dco_div_bits = FLLD__2; // Have at least a divider of 2
if (fsystem > 16000) {
d >>= 1 ;
mode = 1;
}
else {
fsystem <<= 1; // fsystem = fsystem * 2
}
while (d > 512) {
dco_div_bits = dco_div_bits + FLLD0; // Set next higher div level
d >>= 1;
}
UCSCTL0 = 0x0000; // Set DCO to lowest Tap
UCSCTL2 &= ~(0x03FF); // Reset FN bits
UCSCTL2 = dco_div_bits | (d - 1);
UCSCTL1 = DCORSEL_5;
while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
}
__bis_SR_register(srRegisterState); // Restore previous SCG0
}
========================================================================
tmatsu said:do { // Loop until XT1,XT2 & DCO stabilizes
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
This loop possibly never exits.
At this point, you have the FLL reference set to XT2 (which is not up yet). So FLL tries to adjust DCO to 0Hz. This is (of course) outside the currently selected RSEL settings frequency range (outside any range, that is). So teh DCO is adjusted to the lowest tap, causing DCOFFG to be set.
Once the 12MHz crystal is up, FLL tries to adjust teh DCO to, well, 64 (the default UCSCTL2 value)*12MHz, which is (obviously) far above the default RSEL range (best case:7MHz). If the FLL reaches the maximum DCO tap before the LF crystal has stabilized (which is likely on a 12MHz reference and those slowly coming watch crystals), DCOFFG is set again and remains set while you're still in this loop - remaining there forever.
I think you meant setting SELREF_XT1CLK not SELREF_XT2CLK. :)
You should disable the FLL right at the start.
However, the FLL is disabled by setting the SCG0 bit, not by clearing it. So your save/disable/restor logic won't work.
**Attention** This is a public forum