I think I have found a hardware issue with the MSP430FR5969 launchpad/processor. If I run it in 16MHz, applying appropriate FRAM wait states and the steps to adjust clock and initializing MCLK/SMCLK, it still runs very unstable. Small changes to code can result in run/crash. Some more details here. In this code if you increase the wait by one cycle from 0xE to 0xF before changing the MCLK from 2 divider to 1, the processor will then crash. Also if you move the clock adjust line to the end of the init() function, it will crash.
#include "driverlib.h" #define TIMER_PERIOD 2 #define DUTY_CYCLE 1 void init(void); void main(void) { //Stop WDT WDT_A_hold(WDT_A_BASE); /* * Disable the GPIO power-on default high-impedance mode to activate * previously configured port settings */ init(); __delay_cycles(0xE); CS_initClockSignal(CS_MCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_1); //Enter LPM0 __bis_SR_register(LPM0_bits); //For debugger __no_operation(); } void init(void){ FRAMCtl_configureWaitStateControl(1); //Set DCO frequency to 1 MHz CS_setDCOFreq(CS_DCORSEL_1,CS_DCOFSEL_0); __delay_cycles(0xFF); CS_initClockSignal(CS_MCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_2); //Set SMCLK = DCO with frequency divider of 32 = 500kHz CS_initClockSignal(CS_SMCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_32); uint16_t tempCSCTL3 = 0; CSCTL0_H = CSKEY_H; // Unlock CS registers // Assuming SMCLK and MCLK are sourced from DCO // Store CSCTL3 settings to recover later tempCSCTL3 = CSCTL3; /* Keep overshoot transient within specification by setting clk sources to divide by 4*/ // Clear the DIVS & DIVM masks (~0x77)and set both fields to 4 divider CSCTL3 = CSCTL3 & (~(0x77)) | DIVS__4 | DIVM__4; CSCTL1 = DCOFSEL_4 | DCORSEL; // Set DCO to 16MHz /* Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))*/ __delay_cycles(0x60); CSCTL3 = tempCSCTL3; // Set all dividers CSCTL0_H = 0; // Lock CS registers //P1.4 as PWM output GPIO_setAsPeripheralModuleFunctionOutputPin( GPIO_PORT_P1, GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION ); //P2.6 as PWM output GPIO_setAsPeripheralModuleFunctionOutputPin( GPIO_PORT_P2, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION ); PMM_unlockLPM5(); //Generate PWM - Timer runs in Up mode Timer_B_outputPWMParam param = {0}; param.clockSource = TIMER_B_CLOCKSOURCE_SMCLK; //PWM = 25kHz param.clockSourceDivider = TIMER_B_CLOCKSOURCE_DIVIDER_32; param.timerPeriod = TIMER_PERIOD; param.compareRegister = TIMER_B_CAPTURECOMPARE_REGISTER_1; param.compareOutputMode = TIMER_B_OUTPUTMODE_RESET_SET; param.dutyCycle = DUTY_CYCLE; Timer_B_outputPWM(TIMER_B0_BASE, ¶m); }