Other Parts Discussed in Thread: MSP430FR5969
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);
}