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.

CCS/MSP432P401R: Switching to 48MHz HFXT issues

Part Number: MSP432P401R
Other Parts Discussed in Thread: ENERGIA

Tool/software: Code Composer Studio

I am currently using a MSP432P401R (Rev C-The red one). Currently it is set to some random frequency which shows 5MHz on MCLK. I tried to run a code(Jonathan Valvano) to source HFXT from 48MHz crystal.

It involved using PCM(Power Control Management) to switch between modes.

ISSUE:

When I run the code to switch to 48MHz, the debug states this;-"Reset-running" in an alternating manner. I do not get the desired 48MHz on the MCLK pin. I rather get randomly varying values.

Could you let me know the solution to this problem?

I am attaching the code I referred

#include "msp.h"
#define CSKEY  (*((volatile uint32_t*)0x40010400))
#define CSCTL0 (*((volatile uint32_t*)0x40010404))
#define CSCTL1 (*((volatile uint32_t*)0x40010408))
#define PCMIFG (*((volatile uint32_t*)0x4001000C))
#define PCMCLRIFG (*((volatile uint32_t*)0x40010010))
#define PCMCTL0 (*((volatile uint32_t*)0x40010000))
#define PCMCTL1 (*((volatile uint32_t*)0x40010004))
#define CSCTL2 (*((volatile uint32_t*) 0x4001040C))
#define CSIFG (*((volatile uint32_t*) 0x40010448))
#define CSCLRIFG ( *((volatile uint32_t*)0x40010450))

uint32_t Prewait = 0;                   // loops between Clock_Init48MHz() called and PCM idle (expect 0)
uint32_t CPMwait = 0;                   // loops between Power Active Mode Request and Current Power Mode matching requested mode (expect small)
uint32_t Postwait = 0;                  // loops between Current Power Mode matching requested mode and PCM module idle (expect about 0)
uint32_t IFlags = 0;                    // non-zero if transition is invalid
uint32_t Crystalstable = 0;             // loops before the crystal stabilizes (expect small)

void Clock_Init48MHz(void){
  // wait for the PCMCTL0 and Clock System to be write-able by waiting for Power Control Manager to be idle
  while(PCMCTL1&0x0000010000){
    Prewait = Prewait + 1;
    if(Prewait >= 100000){
      return;                           // time out error
    }
  }
  // request power active mode LDO VCORE1 to support the 48 MHz frequency
  PCMCTL0 = (PCMCTL0&~0xFFFF000F) |     // clear PCMKEY bit field and AMR bit field
            0x695A0000 |                // write the proper PCM key to unlock write access
            0x00000001;                 // request power active mode LDO VCORE1
  // check if the transition is invalid (see Figure 7-3 on p344 of datasheet)
  if(PCMIFG&0x00000004){
    IFlags = PCMIFG;                    // bit 2 set on active mode transition invalid; bits 1-0 are for LPM-related errors; bit 6 is for DC-DC-related error
    PCMCLRIFG = 0x00000004;             // clear the transition invalid flag
    // to do: look at CPM bit field in PCMCTL0, figure out what mode you're in, and step through the chart to transition to the mode you want
    // or be lazy and do nothing; this should work out of reset at least, but it WILL NOT work if Clock_Int32kHz() or Clock_InitLowPower() has been called
    return;
  }
  // wait for the CPM (Current Power Mode) bit field to reflect a change to active mode LDO VCORE1
  while((PCMCTL0&0x00003F00) != 0x00000100){
    CPMwait = CPMwait + 1;
    if(CPMwait >= 500000){
      return;                           // time out error
    }
  }
  // wait for the PCMCTL0 and Clock System to be write-able by waiting for Power Control Manager to be idle
  while(PCMCTL1&0x00000100){
    Postwait = Postwait + 1;
    if(Postwait >= 100000){
      return;                           // time out error
    }
  }
  // initialize PJ.3 and PJ.2 and make them HFXT (PJ.3 built-in 48 MHz crystal out; PJ.2 built-in 48 MHz crystal in)
  PJSEL0 |= 0x0C;
  PJSEL1 &= ~0x0C;                      // configure built-in 48 MHz crystal for HFXT operation
//  PJDIR |= 0x08;                        // make PJ.3 HFXTOUT (unnecessary)
//  PJDIR &= ~0x04;                       // make PJ.2 HFXTIN (unnecessary)
  CSKEY = 0x695A;                       // unlock CS module for register access
  CSCTL2 = (CSCTL2&~0x00700000) |       // clear HFXTFREQ bit field
           0x00600000 |                 // configure for 48 MHz external crystal
           0x00010000 |                 // HFXT oscillator drive selection for crystals >4 MHz
           0x01000000;                  // enable HFXT
  CSCTL2 &= ~0x02000000;                // disable high-frequency crystal bypass
  // wait for the HFXT clock to stabilize
  while(CSIFG&0x00000002){
    CSCLRIFG = 0x00000002;              // clear the HFXT oscillator interrupt flag
    Crystalstable = Crystalstable + 1;
    if(Crystalstable > 100000){
      return;                           // time out error
    }
  }
  CSCTL1 = 0x20000000 |                 // configure for SMCLK divider /4
           0x00100000 |                 // configure for HSMCLK divider /2
           0x00000200 |                 // configure for ACLK sourced from REFOCLK
           0x00000050 |                 // configure for SMCLK and HSMCLK sourced from HFXTCLK
           0x00000005;                  // configure for MCLK sourced from HFXTCLK
  CSKEY = 0;                            // lock CS module from unintended access
}

void main(void)
{
	WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;		// stop watchdog timer
	Clock_Init48MHz();
	P4SEL0 |= 0X08;
	P4SEL1 &= ~0X08;
	P4DIR |= 0x08;
	while(1){};
}

to.


  • // Yours seems complicated this is all I had to do from the Touch screen demo:
    // I also do not see any wait states for the RAM.

    void clockInit(void) { /* 2 flash wait states, VCORE = 1, running off DC-DC, 48 MHz */ FlashCtl_setWaitState( FLASH_BANK0, 2); FlashCtl_setWaitState( FLASH_BANK1, 2); PCM_setPowerState( PCM_AM_DCDC_VCORE1 ); CS_setDCOCenteredFrequency( CS_DCO_FREQUENCY_48 ); CS_setDCOFrequency(48000000); CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, 1); CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, 1); CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, 1); return; }

  • Thanks for replying Keith, I have a few questions though.
    1. I want to run my clock via the 48MHz crystal and not the internal DCO.
    2. Is the above code in Energia? If yes, is there one in normal embedded C too?
    3. I did not get what the Touch Screen demo stands for.
  • This is driverlib code, not energia. It has been superceded by SimpleLink which should provide the same functionality.

    I pulled this code from the grlib democode for the touchscreen boosterpack:
    www.ti.com/.../BOOSTXL-K350QVG-S1

    Here is some code from the Driverlib manual that might do what you want:
    /* Configuring pins for peripheral/crystal usage and LED for output */
    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
    GPIO_PIN3 | GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    /* Setting the external clock frequency. This API is optional, but will
    * come in handy if the user ever wants to use the getMCLK/getACLK/etc
    * functions
    */
    CS_setExternalClockSourceFrequency(32000, 48000000);
    /* Starting HFXT in non-bypass mode without a timeout. Before we start
    * we have to change VCORE to 1 to support the 48MHz frequency */
    MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
    MAP_FlashCtl_setWaitState(FLASH_BANK0, 2);
    MAP_FlashCtl_setWaitState(FLASH_BANK1, 2);
    CS_startHFXT(false);
    /* Initializing MCLK to HFXT (effectively 48MHz) */
    MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    Fri
  • Just wanted to confirm what Kieth has already pointed out with regard to the wait states.  Additionally, with the revision C silicon the wait states can be reduced to 1 at 48Mhz operation (24-48Mhz range).  

    DriverLib examples can be found here: 

    Thanks and Regards,

    Chris

**Attention** This is a public forum