[k20d50m]: external crystal doesn't start resuming from VLPR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[k20d50m]: external crystal doesn't start resuming from VLPR

1,347 Views
huishao2
Contributor IV

Hi-

I have problem to re-enable the external crystal after resuming back from VLPR mode on my k20d50m custom board. The k20 is clocked by 8MHz crystal with two ends connected to ground via a capacitor valued 10pF (both boards with and w/o them populated are tested, same results).

The crystal has no problem to start  after powering on but stops to oscillate on the way back to normal mode (via APIs of MQX4.1).

My IAR debugger hangs at

    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */

      MCG_C1 = (uint8_t)0x98U;

When the mode is changed from FBI to FBE and external clock is expected.

I traced the clock output of 8MHz crystal and found no oscillating there after

      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */

      OSC0_CR = (uint8_t)0x80U;

in FBI mode. The only I can see is the voltage on XTAL0 jumps back to 3V from 0V.

The external clock is stopped on the way to VLPR which seems to be OK to me.

What is the reason to cause the crystal NOT to start again? it is the HW or SW problem?

Labels (1)
0 Kudos
6 Replies

727 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Hui,

I suppose that you use internal reference clock when you put the K20 in VLPR mode. You would like to use external crystal of 8MHz after you put the K20 in Normal Run mode. I think this is the procedure of switching from FBI to FBE.

1)set the ERCLKEN=1 by code OSC0_CR = (uint8_t)0x80U;

2)polling the OSCINIT0 bit in MCG_S with code: while(!(MCG_S&OSCINIT0)) {}

3)set the MCG_C1 = (uint8_t)0x98U;

4)polling the CLKST bits of MCG_S, after the CLKST is zero, it is okay.

I suppose the OSCSEL bit is cleared as default setting in MCG_C7.

Hope it can help you.

BR

XiangJun Rong

0 Kudos

727 Views
huishao2
Contributor IV

Hi Xiangjun

Yes you are right, I need FBI to FBE for VLPR. Here is code from MQX4.1 I am using, can you please confirm it is correct?

static void Cpu_SetMCGModeFBI(uint8_t CLKMode)
{
  switch (CLKMode) {
    case 0U:
      /* Switch to FEI Mode */
      /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=0,IREFSTEN=0 */
      MCG_C1 = (uint8_t)0x44U;
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = (uint8_t)0x2DU;
      /* MCG_C4: DMX32=0,DRST_DRS=0 */
      MCG_C4 &= (uint8_t)~(uint8_t)0xE0U;
      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC0_CR = (uint8_t)0x80U;
      /* MCG_C7: OSCSEL=0 */
      MCG_C7 &= (uint8_t)~(uint8_t)0x01U;
      /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */
      MCG_C5 = (uint8_t)0x03U;
      /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x18 */
      MCG_C6 = (uint8_t)0x18U;
      while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */
      }

      while((MCG_S & 0x0CU) != 0x04U) { /* Wait until internal reference clock is selected as MCG output */
      }
      break;

....

static void Cpu_SetMCGModeFBE(uint8_t CLKMode)
{
  switch (CLKMode) {
    case 0U:
      /* Switch to FBE Mode */
      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC0_CR = (uint8_t)0x80U;
      /* MCG_C7: OSCSEL=0 */
      MCG_C7 &= (uint8_t)~(uint8_t)0x01U;
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = (uint8_t)0x2DU;
      /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */
      MCG_C1 = (uint8_t)0x98U;
      /* MCG_C4: DMX32=0,DRST_DRS=0 */
      MCG_C4 &= (uint8_t)~(uint8_t)0xE0U;
      /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */
      MCG_C5 = (uint8_t)0x03U;
      /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x18 */
      MCG_C6 = (uint8_t)0x18U;
      while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */
      }

      while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
       ;
      }

      while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
      }
      break;

....

Other than register settings above, any crystal circuit design problem could lead to clock re-starting failure? After  OSC0_CR = (uint8_t)0x80U, I see XTAL0 of K20 jump to 3V from 0V but there is no clock showing up. I think it is different to start oscillation between power-on and sleep-resume. Anything could go wrong?

thanks and regards

Hui

0 Kudos

727 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Hui,

I have tested the following code on my TWR-K20D50M board on which the 8MHz crystal is connected to the EXTAL/XTAL pins, I confirm the both of the function:static void Cpu_SetMCGModeFBE(uint8_t CLKMode) and static void Cpu_SetMCGModeFBI(uint8_t CLKMode) do not have problem. I do not use MQX and do not use VLPR mode either.

This is the mode transition FEI->FBI->FBE mode.

If you still have issue, pls develop a simple project which can duplicate your issue and paste it here so that we can test on K20 Tower board.

BR

Xiangjun Rong

This is my test code:

static void Cpu_SetMCGModeFBE(uint8_t CLKMode);

static void Cpu_SetMCGModeFBI(uint8_t CLKMode);

static int i = 0;

int main(void)

{

    /* Write your code here */

    //from FBI to FBE mode, the K20 is in FEI mode after reset

    Cpu_SetMCGModeFBI(0);

    Cpu_SetMCGModeFBE(0);

    /* This for loop should be replaced. By default this loop allows a single stepping. */

    for (;;) {

        i++;

    }

    /* Never leave main */

    return 0;

}

static void Cpu_SetMCGModeFBI(uint8_t CLKMode)

{

  switch (CLKMode) {

    case 0U:

      /* Switch to FEI Mode */

      /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=0,IREFSTEN=0 */

      MCG->C1 = (uint8_t)0x44U;

      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */

      MCG->C2 = (uint8_t)0x2DU;

      /* MCG_C4: DMX32=0,DRST_DRS=0 */

      MCG->C4 &= (uint8_t)~(uint8_t)0xE0U;

      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */

      OSC0->CR = (uint8_t)0x80U;

      /* MCG_C7: OSCSEL=0 */

      MCG->C7 &= (uint8_t)~(uint8_t)0x01U;

      /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */

      MCG->C5 = (uint8_t)0x03U;

      /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x18 */

      MCG->C6 = (uint8_t)0x18U;

      while((MCG->S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */

      }

      while((MCG->S & 0x0CU) != 0x04U) { /* Wait until internal reference clock is selected as MCG output */

      }

      break;

    default:

        break;

  }

  }

static void Cpu_SetMCGModeFBE(uint8_t CLKMode)

{

  switch (CLKMode) {

    case 0U:

      /* Switch to FBE Mode */

      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */

      OSC0->CR = (uint8_t)0x80U;

      /* MCG_C7: OSCSEL=0 */

      MCG->C7 &= (uint8_t)~(uint8_t)0x01U;

      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */

      MCG->C2 = (uint8_t)0x2DU;

      /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */

      MCG->C1 = (uint8_t)0x98U;

      /* MCG_C4: DMX32=0,DRST_DRS=0 */

      MCG->C4 &= (uint8_t)~(uint8_t)0xE0U;

      /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */

      MCG->C5 = (uint8_t)0x03U;

      /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x18 */

      MCG->C6 = (uint8_t)0x18U;

      while((MCG->S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */

      }

      while((MCG->S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */

       ;

      }

      while((MCG->S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */

      }

      break;

    default:

        break;

  }

}

////////////////////////////////////////////////////////////////////////////////

// EOF

////////////////////////////////////////////////////////////////////////////////

0 Kudos

727 Views
huishao2
Contributor IV

Hi Xiangjun

I am using MQX APIs to enter VLPR mode by similar code for single stepping on begin of my task:

   /* test code */

   {

           int a = 0;

           while (1) {

                   if ( a == 100 ) {

                           break;

                   }

           }

   }

   enter_VLPR();

   {

           int a = 0;

           while (1) {

                   if ( a == 100 ) {

                           break;

                   }

           }

   }

   exit_VLPR();

...

void enter_VLPR(void)
{
        /* Changing frequency to 2 MHz */
        if (CM_ERR_OK != _lpm_set_clock_configuration(BSP_CLOCK_CONFIGURATION_2MHZ))
        {
            //printf("Cannot change clock configuration");
            //_task_block();
        }

        if ( _lpm_set_operation_mode (LPM_OPERATION_MODE_WAIT) == 0 ) {
                /* OK */
        } else {
                /* NOK */
        }
}

void exit_VLPR(void)
{
        /* Return to RUN mode */
        if( _lpm_set_operation_mode (LPM_OPERATION_MODE_RUN) == 0 ) {
                /* OK */
        } else {
                /* NOK */
        }

        /* Return default clock configuration */
        if (CM_ERR_OK != _lpm_set_clock_configuration(BSP_CLOCK_CONFIGURATION_DEFAULT))
        {
            //printf("Cannot change clock configuration");
            //_task_block();
        }
}

exit_VLPR() exits VLPR mode by the code you tested. Can you please again to test it after putting your board in VLPR mode? and confirm the XTAL0 is back to 3v or clocking after resuming (FBE)? Our custom board clock circuit doesn't follow the TWR reference design. I tried with and without 10p capacitors but got same result. I only see voltage change on XTAL0, no clock comes back.

pastedImage_0.png

Some updates here which may be useful to you. I just tested the original MQX4.1 low power demo code on my board and got same results: it stuck at MCG_C1=0x98. Likely our clock circuit might have problem, can you please review the design shown above? We are using MK20DX128VFM5 while TWR board uses K20DX128VLH5.

thanks and regards

Hui

0 Kudos

727 Views
huishao2
Contributor IV

It seems like the problem is resolved by setting MCG_C2 = (uint8_t)0x25U in FBE mode above. By user manual, it is changed from high gain to low power for oscillator. Maybe it is the needed configuration for my crystal circuit. Can you please explain why?

thanks!

Hui

0 Kudos

727 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Hui,

Regarding the the setting of the MCG_C2, which you set as MCG_C2 = (uint8_t)0x25U in FBE, I think the disputable bit is the HGO bit, which is defined as the following:

HGO High Gain Oscillator Select:

Controls the crystal oscillator mode of operation. See the Oscillator (OSC) chapter for more details.

0 Configure crystal oscillator for low-power operation.

1 Configure crystal oscillator for high-gain operation.

But I do not have detailed description about the circuit and function except for the User manual of K20. I copy it here:

26.8.2.3 High-Frequency, High-Gain Mode

In high-frequency, high-gain mode, the oscillator uses a simple inverter-style amplifier.

The gain is set to achieve rail-to-rail oscillation amplitudes. This mode provides low pass

frequency filtering as well as hysteresis for voltage filtering and converts the output to

logic levels. In this mode, the internal capacitors could be used.

26.8.2.4 High-Frequency, Low-Power Mode

In high-frequency, low-power mode, the oscillator uses a gain control loop to minimize

power consumption. As the oscillation amplitude increases, the amplifier current is

reduced. This continues until a desired amplitude is achieved at steady-state. In this

mode, the internal capacitors could be used, the internal feedback resistor is connected,

and no external resistor should be used.

The oscillator input buffer in this mode is differential. It provides low pass frequency

filtering as well as hysteresis for voltage filtering and converts the output to logic levels.

I checked the clock part of DSC, it has the diagram:

pastedImage_3.png

But the DSC do not give detailed explanation either for the theory of :"low power Oscillator" and "High gain Oscillator".

If someone has knowledge about the topic, welcome share knowledge and inf on the open community platform.

BR

Xiangjun Rong

0 Kudos