Tool/software:
We are facing the following issue: during batch production, involving several hundred units, we identified 3, 4 MSP430FR2355 microcontrollers exhibiting very strange behavior. Upon further analysis, we observed that these devices enter in a some lock-up state.
The setup involves three MSPs connected on one board as follows:
- A main FPGA is connected to each MSP via SPI.
- The FPGA generates a single-ended 24MHz clock signal, which is supplied to the first MSP.
- The first MSP forwards the 24MHz clock to the second MSP, and the second MSP forwards it to the next, creating a daisy-chained clock configuration using the XIN and MCLK_OUT pins.
- For programming, we use the Spy-Bi-Wire interface. The FPGA programs the first MSP, the first MSP programs the second MSP via the Spy-Bi-Wire interface, and so on, forming a daisy-chained Spy-Bi-Wire programming configuration.
- We want the clock output from the MSP to be stable and to keep the next MSP in reset to avoid any clock-related issues during transitions or transient conditions.
With this setup, we have full control and the ability to program and manage each MSP. However, if the first or second MSP in the chain fails, the subsequent devices become sensitive to the failure. For example, if the first or second MSP stops generating the clock signal for the next MSP in the chain, the entire system is affected.
In the 3–4 affected units, we observed the following behavior:
- During startup, the MSP sometimes enters a lock-up state and remains stuck.
- When in this state, it does not generate the output clock for the next MSP in the chain.
- Resetting the device via the Spy-Bi-Wire interface is either impossible or very difficult.
- in Most cases, the devices work correctly without any issues.
Upon further investigation, we suspect that the device enters a lock-up state during the transition of MCLK from the internal 800kHz clock to the external 24MHz clock. Please review the following code snippet for potential issues and provide suggestions on how to detect and prevent this state.
This issue does not occur on every device, we have several hundred MSPs without this problem.
void main(void) { /* Stop watchdog timer */ WDT_A_hold(WDT_A_BASE); __delay_cycles(20000); init_ports(); SPI_init(); UART_init(); // Activate port configuration PMM_unlockLPM5(); memcpy((void*)ram_iv, (void*)fram_iv, sizeof(ram_iv)); SysCtl_enableRAMBasedInterruptVectors(); init_CS(); RTClock_init(); RTClock_start(); ADCC_init(); GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION); //GPIO_setAsInputPinWithPullUpResistor(SBW_OUT_PORT, SBW_OUT_DAT_PIN); GPIO_setOutputHighOnPin(SBW_OUT_PORT, SBW_OUT_DAT_PIN); reset_MSP_SBW(); get_ID(); init_ctrl(); init_registers(); SPI_enable(1); _EINT(); } void init_ports(void) { // XIN and MCLK_OUT GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN7, GPIO_SECONDARY_MODULE_FUNCTION); //GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION); GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN6); GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN6); // SBW pins //GPIO_setAsInputPinWithPullUpResistor(SBW_OUT_PORT, SBW_OUT_DAT_PIN); GPIO_setAsOutputPin(SBW_OUT_PORT, SBW_OUT_DAT_PIN); GPIO_setOutputLowOnPin(SBW_OUT_PORT, SBW_OUT_DAT_PIN); //GPIO_setAsInputPinWithPullDownResistor(SBW_OUT_PORT, SBW_OUT_CLK_PIN); GPIO_setAsOutputPin(SBW_OUT_PORT, SBW_OUT_CLK_PIN); GPIO_setOutputLowOnPin(SBW_OUT_PORT, SBW_OUT_CLK_PIN); } void init_CS(void) { // Configure two FRAM waitstate as required by the device datasheet for MCLK // operation at 24MHz(beyond 8MHz) _before_ configuring the clock system. FRAMCtl_configureWaitStateControl(FRAMCTL_ACCESS_TIME_CYCLES_2); //Enable HF/LF mode HWREG16(CS_BASE + OFS_CSCTL6) |= XTS_1; //Switch OFF XT1 oscillator and enable BYPASS mode HWREG16(CS_BASE + OFS_CSCTL6) |= (XT1BYPASS_1 | XT1AUTOOFF_1 | XT1HFFREQ_3); do { GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN1); //Clear XT1 and DCO fault flags HWREG8(CS_BASE + OFS_CSCTL7) &= ~(XT1OFFG | DCOFFG); // Clear the global fault flag. In case the XT1 caused the global fault // flag to get set this will clear the global error condition. If any // error condition persists, global flag will get again. HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG; GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN1); } while (HWREG8(SFR_BASE + OFS_SFRIFG1) & OFIFG); // Test oscillator fault flag GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN1); CS_initClockSignal(CS_ACLK, CS_XT1CLK_SELECT, CS_CLOCK_DIVIDER_640); // ACLK = 37500Hz CS_initClockSignal(CS_MCLK, CS_XT1CLK_SELECT, CS_CLOCK_DIVIDER_1); // MCLK = 24MHz CS_initClockSignal(CS_SMCLK, CS_XT1CLK_SELECT, CS_CLOCK_DIVIDER_1); // SMCLK = 24MHz }