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.

MSP430F6659: Every OSC Fault (XT2OFFG, XT1LFOFFG, DCOFFG) gets set constantly.

Part Number: MSP430F6659

Here is the code involved, for the functions I'm calling, they're all found in DriverLib (http://dev.ti.com/tirex/content/msp/MSP430Ware_3_60_00_10/driverlib/doc/MSP430F5xx_6xx/html/index.html) (guide at http://dev.ti.com/tirex/content/msp430ware_3_80_07_00/driverlib/doc/MSP430FR5xx_6xx/MSP430FR5xx_6xx_DriverLib_Users_Guide-2_91_11_01.pdf)

To summarize the code blow: We successfully get into powermode 3, X2 always times out, then X1 times out, setting ACLK and FLLREF to REFO works just fine, then FLLSettle locks up due to DCOFFG fault.

Due to the fact that every clock fails, I expect I've done something wrong rather than there being such a terrible hardware fault in this custom board.

X2 is 19.2 MHz, X1 is the 32 and change kHz, and while I'll eventually want to try to make MCLK run at 20 via DCO, this was just my initial "do the oscillators work" test.

So, does anybody see what I'm missing here?

I'm gonna work on making a version of this that doesn't use DriverLib in the meantime.

int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	uint8_t working_crystals = init_crystals();            //The code for this is below, but in my actual project it's in another file that's included up top.
	while(1){
	    test_math();
	    test_freq();

	}
	return 0;
}

uint8_t init_crystals(){
    uint8_t working_crystals = (BIT1 | BIT2);           //Bit 1 is for X1, bit 2 is for X2
    uint8_t VCore = 0;
    uint8_t core_set_counter = 17;

    //At outset, PMMVCore is 0, we want to move it to 3, that happens one at a time.
    while ((VCore < 3) && (core_set_counter > 0)){      //While we're below our desired VCore, and we've tried less than 16 times to change it
        core_set_counter--;                             //Mark off one try
        if(PMM_setVCoreUp(VCore + 1)){                  //Try to bump it up one, and if you succeed
            VCore++;                                        //Update your VCore tracker, and thus your target
            core_set_counter = 17;                          //And reset your number of tries
        }
    }
    //Note, due manufacturer errata, failing to use the driverlib version of this function could potentially cause malfunctions.
    //Test to see if this system can feasibly run at 16, 12, 8 MHz.
    //TODO: Use the following information to set the clocks better.
    uint8_t MaxCPU = 8 + (VCore << 2);          //MaxCpu speed in MHz = 8 + VCore * 4
    UCS_setExternalClockSource(32768,           //X1 freq, 32.768 kHz
                               19200000);       //X2 freq, 19.2MHz

    //UCS_turnOnXT2(UCS_XT2_DRIVE_16MHZ_24MHZ);
    int16_t outer;
    int16_t inner;
    _no_operation();                                //Delay loop
    for(outer = 24000; outer > 0; outer--){
        for(inner = 10; inner > 0; inner--){
            _no_operation();                        
        }
    }
//~~~~~~~~~~~~~~~~~~~~~~~Everything above this line works~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//This if statement always fails (the Timeout always occurs)
    if (UCS_turnOnXT2WithTimeout(UCS_XT2_DRIVE_16MHZ_24MHZ,0xFFFF)){   //Sets up XT2 in the correct frequency range
        //But if some error bits take 65536 cycles to clear, fall back to another clock.
        //Anyway, this case is for it working and proceeding as normal.
        UCS_initClockSignal(UCS_MCLK, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_1);      //Main clock runs at the basic 19.2MHz for now
        UCS_initClockSignal(UCS_SMCLK, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_1);     //Submain runs at 19.2 for now but we might change this later

        if (UCS_turnOnLFXT1WithTimeout(UCS_XT1_DRIVE_3, UCS_XCAP_0, 0xFFFF)){        //DRIVE_3 is high stability high power, DRIVE_0 is low stability low power
            //Cap is 0 because we have our own external caps so we don't need to use the internal ones. That said, we could tune further with the internal ones if necessary.
            //And again, if some error bits take a full 65536 cycles and still haven't cleared, we'll fall back to a different timer.
            //But this is the case where it works and we proceed as normal.
            UCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);      //And Aux clock runs at the 32.768 kHz standard for... reasons.

        }
        else{       //This is the case where X2 works fine but X1 does not. In this case, we use REFO for ACLK
            UCS_initClockSignal(UCS_ACLK, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
            //And also turn off X1 explicitly.
            UCS_turnOffXT1();
            working_crystals &= !(BIT1);
        }

    }

    else{       //This is the case where X2 does not work (which right now always happens)
        //So first step, turn off X2
        UCS_turnOffXT2();
        working_crystals &= !(BIT2);

        //Then deal with X1
        //Which right now always also times out
        if (UCS_turnOnLFXT1WithTimeout(UCS_XT1_DRIVE_3, UCS_XCAP_0, 0xFFFF)){        //DRIVE_3 is high stability high power, DRIVE_0 is low stability low power
            //Cap is 0 because we have our own external caps so we don't need to use the internal ones. That said, we could tune further with the internal ones if necessary.
            //And again, if some error bits take a full 65536 cycles and still haven't cleared, we'll fall back to a different timer.
            //But this is the case where it works and we proceed as normal.
            UCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);      //And Aux clock runs at the 32.768 kHz standard for... reasons.
            //And now that we have X1 setup and running through ACLK, we also run it through FLL,
            UCS_initClockSignal(UCS_FLLREF, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);


        }
        else{       //This is the case where X2 fails and X1 fails. In this case, we use REFO for ACLK
            //Right now this always occurs, and these to clock signal inits seem to work just fine
            UCS_initClockSignal(UCS_ACLK, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
            //And then run it through FLL
            UCS_initClockSignal(UCS_FLLREF, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
            //And turn off X1 explicitly
            UCS_turnOffXT1();
            working_crystals &= !(BIT1);

        }
        //And now that one of those two has setup ACLK and FLL, we use our FLL to set up our DCO, which we use for our MCLK and SMCLK
        //But this FLLSettle always hangs at the DCOFFG compare loop
        UCS_initFLLSettle(19200, 59);
        UCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);      //Technically this one is redundant, as the initFLL sets MCLK and SCLK to DCO, but still we'll write it out here.
        while (HWREG8(UCS_BASE + OFS_UCSCTL7_L) & DCOFFG);
        UCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);     //Submain runs at 19.2 MHz for now, but we might change this later.
        //Also note that while we're using methods to measure the clock frequencies when we need to know them, rather than just assuming, this actually gives 19.33312 MHz


    }

    return working_crystals;
}

  • Update: It appears these were all distinct faults, or at least the first one was. X2 was failing because I didn't properly set P7.2 and P7.3 to run X2 as opposed to their default GPIO configuration. 
    Specifically, adding the line " P7SEL |= (BIT2 | BIT3); " at any point before attempting to turn on the crystal.

    Still getting the X1 timeout though, and no longer finding the DCO error because in this mode my code doesn't try to turn on the DCO.

  • Hello Andy,

    Thanks for your detailed post and for following up with your findings. We're happy to hear that you figured out the XT2 issue. For XT1, the oscillator fault flag could be due to an incorrect configuration in the code or possibly the wrong effective load capacitance, which could be the issue since you're using a custom board.

    As you dig deeper in your investigation, I would recommend reading through the MSP430 32-kHz Crystal Oscillators app note where it talks about how to calculate the required effective load capacitance used externally for the XT1 crystal. Also, I would recommend looking through our code examples that have XT1 setup code in them as a reference. Assuming the load capacitance is correct, then the code example should work fine on your custom board.

    Regards,

    James

**Attention** This is a public forum