Hello to everybody
I am experiencing some troubles with MSP430F54XX XT1 clock.
I use a quartz to have a precise and reliable source for XT1CLK signal
to control uC clock.
On some boards, all of a sudden, the flag XT1LFOFFG becomes active
(I don't know the actual reason for this behaviour)
and the microprocessor reverts its clock source to DCOCLK,
and therefore it doesn't meet our standards for time precision.
Please notice that MSP software does set the correct capacitance for our quartz (which is 12.5pF)
I would like to know if there's a way to solve this issue by changing our code.
(Maybe the reason is low drive strength for XT1?)
My routine for clock initialization is the following
(as taken from MSP430F54XXX Demo Board software)
/*START XT1*/
// Set up XT1 Pins to analog function, and to lowest drive
P7SEL |= 0x03;
UCSCTL6 |= XCAP_3 ; // Set internal cap values (12pF)
while ( (SFRIFG1 & OFIFG)) // Check OFIFG fault flag
{// Clear OSC fault flags
UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT1HFOFFG + XT2OFFG);
SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
}
UCSCTL6 &= ~(XT1DRIVE1+XT1DRIVE0);
// Reduce the drive strength to 00
(..)
/* START BOARD CLOCK*/
/*Functions taken from Demo Board software*/
halBoardGetSystemClockSettings (systemClockSpeed, &setDcoRange,&setVCore, &setMultiplier);
halBoardSetVCore( setVCore );
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x00; // Set lowest possible DCOx, MODx
UCSCTL1 = setDcoRange; // Select suitable range
UCSCTL2 = setMultiplier + FLLD_1; // Set DCO Multiplier
UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV ;
__bic_SR_register(SCG0); // Enable the FLL control loop
// Loop until XT1,XT2 & DCO fault flag is cleared
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
// Worst-case settling time for the DCO when the DCO range bits have been
// changed is n x 32 x 32 x f_FLL_reference. See UCS chapter in 5xx UG
// for optimization.
// 32 x 32 x / f_FLL_reference (32,768 Hz) = .03125 = t_DCO_settle
// t_DCO_settle / (1 / 25 MHz) = 781250 = counts_DCO_settle
__delay_cycles(781250);