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.
Hi,
I'm working with the new red MSP432P401R Rev. C Launchpad (with rev. C chips on the boards) I received last week and I believe there is a problem with the LFXT oscillator on the board, or hopefully there's just something I haven't figured out yet.
I'm using the same code that I've been developing on the Black Rev. B Launchpad and I've made success in loading and stepping through the beginning of my program with that code on the red board. But when I get to setting up clocks, using code taken from an MSPWare example, I consistently get LFXT oscillator faults pulling me into faultISR() when I try to clear bits associated with selecting the MCLK source, in these lines below:
// DCO = 48 MHz; MCLK = source CS->KEY = CS_KEY_VAL; // Unlock CS module for register access CS->CTL0 = CS_CTL0_DCORSEL_5 | CS_CTL0_DCOEN; // Set DCO to 48MHz CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK; // Select DCO as MCLK source CS->KEY = 0;
On the 4th line I get thrown into faultISR() because the LFXT fault IFG flag is flipped. I don't know if there is another reason, but I know for sure that the LFXT fault flag is flipped. This is in the first function I call at the start of main.
What makes me think this is a board-specific is because I then loaded this exact same code base into my black Rev. B board and it's working the same as usual, with no faultISR()'s in the beginning.
Thanks for any help you can give,
Here is my code that gets called at the top of main:
void CoreSystemClockInit(void) { // MCLK - HFXIN (48MHZ) - use DCO for this // ACLK - 32kHz - max value of ACLK is 128kHz // HSMCLK - 48MHz (Subsystem Master Clock) // SMCLK - 3MHz - using // - is ONLY sourced from HSMCLK // - can only be half of HSMCLK // Switches LDO VCORE0 to LDO VCORE1; - mandatory for 48 MHz setting while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1; while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); // Switches LDO VCORE1 to DCDC VCORE1 if requested #if __REGULATOR while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5; while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); #endif // 2 flash wait states (BANK0 VCORE1 max is 16 MHz, BANK1 VCORE1 max is 32 MHz) FLCTL->BANK0_RDCTL &= ~FLCTL_BANK0_RDCTL_WAIT_MASK | FLCTL_BANK0_RDCTL_WAIT_2; FLCTL->BANK1_RDCTL &= ~FLCTL_BANK1_RDCTL_WAIT_MASK | FLCTL_BANK1_RDCTL_WAIT_2; // DCO = 48 MHz; MCLK = source CS->KEY = CS_KEY_VAL; // Unlock CS module for register access CS->CTL0 = CS_CTL0_DCORSEL_5 | CS_CTL0_DCOEN; // Set DCO to 48MHz CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK; // Select DCO as MCLK source CS->KEY = 0; // Set Flash Bank read buffering FLCTL->BANK0_RDCTL |= (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); FLCTL->BANK1_RDCTL |= (FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); // Assert the frequencies of MCLK, ACLK, HSMCLK, and SMCLK CS_initClockSignal(CS_MCLK , CS_DCOCLK_SELECT , CS_CLOCK_DIVIDER_1); // WILL BE A 48MHz crystal CS_initClockSignal(CS_ACLK , CS_LFXTCLK_SELECT , CS_CLOCK_DIVIDER_1); // 32.768 kHz watch crystal CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT , CS_CLOCK_DIVIDER_1); // DCO set to midrange of range 5 = 48MHz CS_initClockSignal(CS_SMCLK , CS_DCOCLK_SELECT , CS_CLOCK_DIVIDER_16); // SMCLK set to 48/16 = 3MHz }
I do also have a line that halts the watchdog timer before it, but its just a single statement. Since my project will always be running at 48MHz, I have deleted all other clock possibilities from the original SystemInit() function from the system_msp432p401r.c file. In comparing it to an MSP432Ware file it looks like I did add " | CS_CTL0_DCOEN" to CS->CTL0. This "addition" has been in my code since working on the Rev. B board: its not something I added recently. I feel like that shouldn't make a difference, but let me know if you know otherwise.
Thanks,
/* --COPYRIGHT--,BSD_EX * Copyright (c) 2013, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************* * * MSP432 CODE EXAMPLE DISCLAIMER * * MSP432 code examples are self-contained low-level programs that typically * demonstrate a single peripheral function or device feature in a highly * concise manner. For this the code may rely on the device's power-on default * register values and settings such as the clock configuration and care must * be taken when combining code from several examples to avoid potential side * effects. Also see http://www.ti.com/tool/mspdriverlib for an API functional * library & https://dev.ti.com/pinmux/ for a GUI approach to peripheral configuration. * * --/COPYRIGHT--*/ //****************************************************************************** // MSP432P401 Demo - Device configuration for operation @ MCLK = DCO = 48MHz // // Description: Proper device configuration to enable operation at MCLK=48MHz // including: // 1. Configure VCORE level to 1 // 2. Configure flash wait-state to 2 // 3. Configure DCO frequency to 48MHz // 4. Ensure MCLK is sourced by DCO // // After configuration is complete, MCLK is output to port pin P4.3. // // MSP432p401rpz // ----------------- // /|\| | // | | | // --|RST | // | P4.3|----> MCLK // | | // // Add LFXT1 // // Dung Dang // Texas Instruments Inc. // October 2015 (updated) | November 2013 (created) // Built with Code Composer Studio V6.0 //****************************************************************************** #include "msp.h" #include "stdint.h" void error(void); int main(void) { uint32_t currentPowerState; WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // Stop WDT P1->DIR |= BIT0; // P1.0 set as output P4->DIR |= BIT2 | BIT3; P4->SEL0 |= BIT2 | BIT3; // Output ACLK & MCLK P4->SEL1 &= ~(BIT2 | BIT3); PJ->SEL0 |= BIT0 | BIT1; // set LFXT pin as second function /* NOTE: This example assumes the default power state is AM0_LDO. * Refer to MSP4322001_pcm_0x code examples for more complete PCM operations * to exercise various power state transitions between active modes. */ /* Step 1: Transition to VCORE Level 1: AM0_LDO --> AM1_LDO */ /* Get current power state, if it's not AM0_LDO, error out */ currentPowerState = PCM->CTL0 & PCM_CTL0_CPM_MASK; if (currentPowerState != PCM_CTL0_CPM_0) error(); while ((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1; while ((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); if (PCM->IFG & PCM_IFG_AM_INVALID_TR_IFG) error(); // Error if transition was not successful if ((PCM->CTL0 & PCM_CTL0_CPM_MASK) != PCM_CTL0_CPM_1) error(); // Error if device is not in AM1_LDO mode /* Step 2: Configure Flash wait-state to 2 for both banks 0 & 1 */ FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & (~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_2; FLCTL->BANK1_RDCTL = FLCTL->BANK0_RDCTL & (~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_2; /* * Turn on LFXT1, inserted here to try and recreate fault after setting DCO */ CS->KEY = CS_KEY_VAL ; // Unlock CS module for register access CS->CTL2 |= CS_CTL2_LFXT_EN; // LFXT on // Loop until XT1, XT2 & DCO fault flag is cleared do { // Clear LFXT,HFXT,DCO fault flags CS->CLRIFG |= CS_CLRIFG_CLR_DCOR_OPNIFG | CS_CLRIFG_CLR_HFXTIFG | CS_CLRIFG_CLR_LFXTIFG; //SYSCTL->NMI_CTLSTAT &= ~ SYSCTL_NMI_CTLSTAT_CS_SRC; } while (SYSCTL->NMI_CTLSTAT & SYSCTL_NMI_CTLSTAT_CS_FLG);// Test oscillator fault flag // } while (CS->IFG & (CS_IFG_FCNTLFIFG | CS_IFG_LFXTIFG));// Test oscillator fault flag CS->CTL1 = CS->CTL1 & ~(CS_CTL1_SELS_MASK | CS_CTL1_DIVS_MASK) | CS_CTL1_SELA_0;// Select ACLK as LFXTCLK CS->IE |= CS_IE_LFXTIE; CS->KEY = 0; // Lock CS module from unintended accesses __enable_interrupt(); /* Step 3: Configure DCO to 48MHz, ensure MCLK uses DCO as source*/ CS->KEY = CS_KEY_VAL; // Unlock CS module for register access CS->CTL0 = 0; // Reset tuning parameters CS->CTL0 = CS_CTL0_DCORSEL_5; // Set DCO to 48MHz /* Select MCLK = DCO, no divider */ CS->CTL1 = CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM_3; CS->KEY = 0; // Lock CS module from unintended accesses while(1); } void error(void) { volatile uint32_t i; P1->DIR |= BIT0; while (1) { P1->OUT ^= BIT0; for(i=0;i<20000;i++); // Blink LED forever } } /* * In the startup_msp432p401r_ccs.c replace default nmi function wit this * function. */ void lfxtError(void) { P1->OUT ^= BIT0; CS->KEY = CS_KEY_VAL; // Unlock CS module for register access do { // Clear LFXT,HFXT,DCO fault flags CS->CLRIFG |= CS_CLRIFG_CLR_DCOR_OPNIFG | CS_CLRIFG_CLR_HFXTIFG | CS_CLRIFG_CLR_LFXTIFG | CS_CLRIFG_CLR_FCNTLFIFG; //SYSCTL->NMI_CTLSTAT &= ~ SYSCTL_NMI_CTLSTAT_CS_SRC; // } while (SYSCTL->NMI_CTLSTAT & SYSCTL_NMI_CTLSTAT_CS_FLG);// Test oscillator fault flag } while (CS->IFG & (CS_IFG_FCNTLFIFG | CS_IFG_LFXTIFG));// Test oscillator fault flag CS->KEY = 0; // Lock CS module from unintended accesses }
It may be a board issue. I have tried to recreate the issue on my launchpad (revision 1.9) with the attached code and did not experience an issue and also verified that when I introduce a fault at the crystal (short) that the interrupt does occur.
Best Regards,
Chris
**Attention** This is a public forum