BUG REPORT: Clocking K64 using 32KHz IRC in MQX 4.1.1/4.2?

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

BUG REPORT: Clocking K64 using 32KHz IRC in MQX 4.1.1/4.2?

Jump to solution
1,539 Views
nitinharish
Contributor V

Has anybody successfully used 32KHz IRC as REF for SYSTEM clock (using FLL) in MQX 4.1.1 ?

I need this PATH:

MCG_K64_FEI.png

Seems like the clock setting state machine (inside the function; CPU_SetClockConfigGenMode(LDD_TClockConfiguration ConfigID)) is coded in a way that this cannot happen.

Any Freescale folks want to pitch in ?

Message was edited by: Nitin Harish

Message was edited by: Nitin Harish

Tags (1)
1 Solution
886 Views
nitinharish
Contributor V

Thanks David

After doing some real digging, I found the root cause of my issue. This piece of code which is doing Auto-trimming strongly assumes that their is an external reference clock in-spite of the fact I am setting all registers for using 32KHz IRC as REF clock, this function is used and called in in MQX 4.1.1's "bsp_cm.c" but NOT in Processor Expert output (which seems like an issue to me with MQX 4.1.1)

Kindly read the comments in the function below. the line that is the main issue is BusClockMHz calculation.

I request you @David E Seymour​and soledadto NOT go quite on this. Please respond with your views and action plan if any or at least prove that I am wrong.

/*

** ===================================================================

**     Method      :  CPU_MCGAutoTrim (component MK64FN1M0LQ12)

*/

/*!

**     @brief

**         This method uses MCG auto trim feature to trim internal

**         reference clock. This method can be used only in a clock

**         configuration which derives its bus clock from external

**         reference clock ([MCG mode] must be one of the following

**         modes - FEE, FBE, BLPE, PEE, PBE) and if value of [Bus clock]

**         is in the range <8; 16>MHz.

**         The slow internal reference clock is trimmed to the value

**         selected by [Slow internal reference clock [kHz]] property.

**         The fast internal reference clock will be trimmed to value

**         4MHz.

**     @param

**         ClockSelect     - Selects which internal

**                           reference clock will be trimmed.

**                           0 ... slow (32kHz) internal reference clock

**                           will be trimmed

**                           > 0 ... fast (4MHz) internal reference

**                           clock will be trimmed

**     @return

**                         - Error code

**                           ERR_OK - OK

**                           ERR_SPEED - The method does not work in the

**                           active clock configuration.

**                           ERR_FAILED - Autotrim process failed.

*/

/* ===================================================================*/

LDD_TError CPU_MCGAutoTrim(uint8_t ClockSelect)

{

  uint16_t CompareValue;               /* Autotrim compare value expected count */

  uint16_t BusClockMHz = (uint16_t)((uint32_t)(CPU_ClockConfigDescriptors[ClockConfigurationID].BusClock) /1000000UL); /* Bus clock in MHz */

  /* Calculate compare value */

  if (((CPU_ClockConfigDescriptors[ClockConfigurationID].Mode & (CPU_CLOCK_EXTERNAL_CLOCK_MASK | CPU_CLOCK_EXTERNAL_CRYSTAL_MASK)) != 0) && (BusClockMHz >= 8U) && (BusClockMHz <= 16U)) {

    if (ClockSelect == 0x00U) {

      CompareValue = (uint16_t)(21000 * BusClockMHz / CPU_INT_SLOW_CLK_HZ); /* Slow internal reference clock */

    } else {

      CompareValue = (uint16_t)(672U * BusClockMHz); /* Fast internal reference clock */

    }

  } else {

    return ERR_SPEED;                  /* MCU has to be clocked from external clock and has to have bus clock in allowed range */

  }

  MCG_ATCVH = (uint8_t)(CompareValue >> 8U); /* Set compare value high half */

  MCG_ATCVL = (uint8_t)(CompareValue & 255U); /* Set compare value low half */

  if (ClockSelect == 0x00U) {

    /* MCG_SC: ATME=1,ATMS=0,LOCS0=0 */

    MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(

              MCG_SC_ATMS_MASK |

              MCG_SC_LOCS0_MASK

             )) | (uint8_t)(

              MCG_SC_ATME_MASK

             ));                       /* Start trimming of the slow internal reference clock */

  } else {

    /* MCG_SC: ATME=1,ATMS=1,LOCS0=0 */

    MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(

              MCG_SC_LOCS0_MASK

             )) | (uint8_t)(

              MCG_SC_ATME_MASK |

              MCG_SC_ATMS_MASK

             ));                       /* Start trimming of the fast internal reference clock */

  }

  while ((MCG_SC & MCG_SC_ATME_MASK) != 0x00U) { /* Wait until autotrim completes */

  }

  if ((MCG_SC & MCG_SC_ATMF_MASK) == 0x00U) {

    return ERR_OK;                     /* Trim operation completed successfully */

  } else {

    return ERR_FAILED;                 /* Trim operation failed */

  }

}

mjbcswitzerland​: Some information for your consultancy too Smiley Happy

View solution in original post

0 Kudos
13 Replies
886 Views
nitinharish
Contributor V

Alright I got it working.

Correct settings are below for somebody else's reference:

/* Clock configuration 0 */

#define CPU_MCG_MODE_CONFIG_0                              (CPU_MCG_MODE_FEI | CPU_CLOCK_SLOW_MASK) /* Clock generator mode */

#define CPU_CLOCK_VLP_CONFIG_0                             0U /* Very low power mode disabled */

#define CPU_MCG_C1_CONFIG_0                                0x04U /* MCG_C1 */   //Slow internal reference, disabled in the STOP mode

#define CPU_MCG_C2_CONFIG_0                                0x80U /* MCG_C2 */

#define CPU_MCG_C4_CONFIG_0                                0xE0U /* MCG_C4 */ //FLL multiplication factor = 2929 yielding 32.768*2929 = 96MHz system clock

#define CPU_MCG_C5_CONFIG_0                                0x00U /* MCG_C5 */ // we are not using PLL

#define CPU_MCG_C6_CONFIG_0                                0x00U /* MCG_C6 */ // we are not using PLL

#define CPU_MCG_SC_CONFIG_0                                0x02U /* MCG_SC */

#define CPU_OSC_CR_CONFIG_0                                0x00U /* OSC_CR */

#define CPU_SIM_SOPT1_CONFIG_0                             0x00080000UL /* SIM_SOPT1 */

#define CPU_SIM_SOPT2_CONFIG_0                             0x00010000UL /* SIM_SOPT2 */

#define CPU_SIM_CLKDIV1_CONFIG_0                           0x01240000UL /* SIM_CLKDIV1 */

Also, I had to comment out a lot of checks in   CPU_SetClockConfigGenMode function (can somebody explain why) still 1/5 runs processor crashes:

void CPU_SetClockConfigGenMode(LDD_TClockConfiguration ConfigID)

{

  CPU_TClockGenMode NextMode;

  CPU_TClockGenRegs NextModeRegs;

  CPU_TClockGenMode TargetMode = CPU_ClockConfigDescriptors[ConfigID].Mode;

 

  /* External clock source pin routing */

  if ((TargetMode & (CPU_CLOCK_EXTERNAL_CLOCK_MASK | CPU_CLOCK_EXTERNAL_CRYSTAL_MASK)) != 0) { /* Is external clock source used in targeted clock configuration? */

    /* If yes, initialize the EXTAL pin routing */

    SIM_SCGC5 |= (uint16_t)SIM_SCGC5_PORTA_MASK; /* Enable EXTAL/XTAL pins clock gate */

    /* PORTA_PCR18: MUX=0 */

    PORTA_PCR18 &= (uint32_t)~(uint32_t)0x0700;

    if ((TargetMode & CPU_CLOCK_EXTERNAL_CRYSTAL_MASK) != 0) { /* Is external crystal/resonator used in targeted clock configuration? */

      /* If yes, initialize also XTAL pin routing */

      /* PORTA_PCR19: MUX=0 */

      PORTA_PCR19 &= (uint32_t)~(uint32_t)0x0700;

    }

  }

 

  if ((MCG_SC & MCG_SC_FCRDIV_MASK) != CPU_ClockConfigDescriptors[ConfigID].GenRegs.MCG_SC_value) { /* Check if it is necessary to update Fast Clock Internal Reference Divider */

    if ((MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U) {

      MCG_SC = (MCG_SC & (uint8_t)(~(MCG_SC_FCRDIV_MASK))) | CPU_ClockConfigDescriptors[ConfigID].GenRegs.MCG_SC_value;

    } else {

      if ((MCG_C1 & (MCG_C1_IREFS_MASK || MCG_C1_IRCLKEN_MASK)) != 0x00U) { /* Is internal reference clock active? */     

        MCG_C2 &= (uint8_t)(~(MCG_C2_IRCS_MASK)); /* Disable the fast internal clock */

        while((MCG_S & MCG_S_IRCST_MASK) != 0x00U) { /* Check that the source internal reference clock is slow clock. */

        }

        MCG_SC = (MCG_SC & (uint8_t)(~(MCG_SC_FCRDIV_MASK))) | CPU_ClockConfigDescriptors[ConfigID].GenRegs.MCG_SC_value;   

        MCG_C2 |= MCG_C2_IRCS_MASK;    /* Re-enable the fast internal clock */

        while((MCG_S & MCG_S_IRCST_MASK) == 0x00U) { /* Check that the source internal reference clock is fast clock. */

        }

      } else {

        MCG_C2 &= (uint8_t)(~(MCG_C2_IRCS_MASK)); /* Disable the fast internal clock */

        MCG_SC = (MCG_SC & (uint8_t)(~(MCG_SC_FCRDIV_MASK))) | CPU_ClockConfigDescriptors[ConfigID].GenRegs.MCG_SC_value;   

        MCG_C2 |= MCG_C2_IRCS_MASK;    /* Re-enable the fast internal clock */

      }

    }

  }     

  NextMode = CPU_GetClockGenMode(); /* Identify the currently active MCG mode */

  do {

    NextMode = ClockGenModeMatrix[NextMode & CPU_MCG_MODE_INDEX_MASK][TargetMode & CPU_MCG_MODE_INDEX_MASK];

    if (NextMode == (TargetMode & CPU_MCG_MODE_INDEX_MASK)) {

      NextModeRegs = CPU_ClockConfigDescriptors[ConfigID].GenRegs;

    } else {

      NextModeRegs = *CPU_ClockGenModeRegs[NextMode & CPU_MCG_MODE_INDEX_MASK];

    }

    switch (NextMode & CPU_MCG_MODE_INDEX_MASK) {

      case CPU_MCG_MODE_FEI:

      case CPU_MCG_MODE_FBI:

        MCG_C1 = NextModeRegs.MCG_C1_value; /* Set C1 (clock source selection, FLL ext. reference divider, int. reference enable etc.) */

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

        }

        MCG_C2 = ((NextModeRegs.MCG_C2_value) & (uint8_t)(~(MCG_C2_FCFTRIM_MASK))) | (MCG_C2 & MCG_C2_FCFTRIM_MASK); /* Set C2 (freq. range, ext. and int. reference selection etc.; trim values not changed) */

        MCG_C4 = ((NextModeRegs.MCG_C4_value) & (uint8_t)(~(MCG_C4_FCTRIM_MASK | MCG_C4_SCFTRIM_MASK))) | (MCG_C4 & (MCG_C4_FCTRIM_MASK | MCG_C4_SCFTRIM_MASK)); /* Set C4 (FLL output; trim values not changed) */

        OSC_CR = NextModeRegs.OSC_CR_value; /* Set OSC_CR (OSCERCLK enable, oscillator capacitor load) */     

        if (TargetMode & CPU_CLOCK_RTC_OSC_MASK) {

          MCG_C7 = MCG_C7_OSCSEL(1);   /* Select RTC oscillator as MCG clock source */

        } else {

          #if defined(USE_IRC48MHz_INTERNAL_CLOCK)

              MCG_C7 = MCG_C7_OSCSEL(2);   /* Select IIRC48M oscillator as MCG clock source */

          #else

              MCG_C7 = 0;                  /* Select system oscillator as MCG clock source */

          #endif

        }

        MCG_C5 = NextModeRegs.MCG_C5_value; /* Set C5 (PLL settings, PLL reference divider etc.) */

        if (TargetMode & CPU_CLOCK_PLL_MASK) {

          MCG_C5 |= MCG_C5_PLLCLKEN0_MASK;

        }

        MCG_C6 = NextModeRegs.MCG_C6_value; /* Set C6 (PLL select, VCO divider etc.) */

        break;

      case CPU_MCG_MODE_BLPI:

        MCG_C1 = NextModeRegs.MCG_C1_value; /* Set C1 (clock source selection, FLL ext. reference divider, int. reference enable etc.) */

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

        }

        MCG_C2 = ((NextModeRegs.MCG_C2_value) & (uint8_t)(~(MCG_C2_FCFTRIM_MASK))) | (MCG_C2 & MCG_C2_FCFTRIM_MASK); /* Set C2 (freq. range, ext. and int. reference selection etc.; trim values not changed) */

        OSC_CR = NextModeRegs.OSC_CR_value; /* Set OSC_CR (OSCERCLK enable, oscillator capacitor load) */

        if (TargetMode & CPU_CLOCK_FAST_MASK) {

          while((MCG_S & MCG_S_IRCST_MASK) == 0x00U) { /* Check that the fast external reference clock is selected. */

       }

      }     

        break;

      case CPU_MCG_MODE_FEE:

      case CPU_MCG_MODE_FBE:

        MCG_C2 = ((NextModeRegs.MCG_C2_value) & (uint8_t)(~(MCG_C2_FCFTRIM_MASK))) | (MCG_C2 & MCG_C2_FCFTRIM_MASK); /* Set C2 (freq. range, ext. and int. reference selection etc.; trim values not changed) */

        OSC_CR = NextModeRegs.OSC_CR_value; /* Set OSC_CR (OSCERCLK enable, oscillator capacitor load) */     

        if (TargetMode & CPU_CLOCK_RTC_OSC_MASK) {

          MCG_C7 = MCG_C7_OSCSEL(1);   /* Select RTC oscillator as MCG clock source */

        } else {

          #if defined(USE_IRC48MHz_INTERNAL_CLOCK)

              MCG_C7 = MCG_C7_OSCSEL(2);   /* Select IIRC48M oscillator as MCG clock source */

          #else

              MCG_C7 = 0;                  /* Select system oscillator as MCG clock source */

          #endif

        }

        MCG_C1 = NextModeRegs.MCG_C1_value; /* Set C1 (clock source selection, FLL ext. reference divider, int. reference enable etc.) */

        if ((TargetMode & CPU_CLOCK_EXTERNAL_CRYSTAL_MASK) != 0) {

          while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */

          }

        }

       

        #if !defined(USE_IRC32KHz_INTERNAL_CLOCK) //try to use external switching only if we are using internal clock

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

            }

        #endif

       

        MCG_C4 = ((NextModeRegs.MCG_C4_value) & (uint8_t)(~(MCG_C4_FCTRIM_MASK | MCG_C4_SCFTRIM_MASK))) | (MCG_C4 & (MCG_C4_FCTRIM_MASK | MCG_C4_SCFTRIM_MASK)); /* Set C4 (FLL output; trim values not changed) */

        MCG_C5 = NextModeRegs.MCG_C5_value; /* Set C5 (PLL settings, PLL reference divider etc.) */

        if (TargetMode & CPU_CLOCK_PLL_MASK) {

          MCG_C5 |= MCG_C5_PLLCLKEN0_MASK;

        }

        MCG_C6 = NextModeRegs.MCG_C6_value; /* Set C6 (PLL select, VCO divider etc.) */

        break;

      case CPU_MCG_MODE_BLPE:

        MCG_C1 = NextModeRegs.MCG_C1_value; /* Set C1 (clock source selection, FLL ext. reference divider, int. reference enable etc.) */

        MCG_C2 = ((NextModeRegs.MCG_C2_value) & (uint8_t)(~(MCG_C2_FCFTRIM_MASK))) | (MCG_C2 & MCG_C2_FCFTRIM_MASK); /* Set C2 (freq. range, ext. and int. reference selection etc.; trim values not changed) */

        OSC_CR = NextModeRegs.OSC_CR_value; /* Set OSC_CR (OSCERCLK enable, oscillator capacitor load) */     

        if (TargetMode & CPU_CLOCK_RTC_OSC_MASK) {

          MCG_C7 = MCG_C7_OSCSEL(1);   /* Select RTC oscillator as MCG clock source */

        } else {

          #if defined(USE_IRC48MHz_INTERNAL_CLOCK)

              MCG_C7 = MCG_C7_OSCSEL(2);   /* Select IIRC48M oscillator as MCG clock source */

          #else

              MCG_C7 = 0;                  /* Select system oscillator as MCG clock source */

          #endif

        }

        if ((TargetMode & CPU_CLOCK_EXTERNAL_CRYSTAL_MASK) != 0) {

          while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */

          }

        }

        break;

      case CPU_MCG_MODE_PEE:

      case CPU_MCG_MODE_PBE:

        OSC_CR = NextModeRegs.OSC_CR_value; /* Set OSC_CR (OSCERCLK enable, oscillator capacitor load) */

        #if defined(USE_IRC48MHz_INTERNAL_CLOCK)

            MCG_C7 = MCG_C7_OSCSEL(2);   /* Select IIRC48M oscillator as MCG clock source */

        #else

            MCG_C7 = 0;                  /* Select system oscillator as MCG clock source */

        #endif

       

        MCG_C1 = NextModeRegs.MCG_C1_value; /* Set C1 (clock source selection, FLL ext. reference divider, int. reference enable etc.) */

        MCG_C2 = ((NextModeRegs.MCG_C2_value) & (uint8_t)(~(MCG_C2_FCFTRIM_MASK))) | (MCG_C2 & MCG_C2_FCFTRIM_MASK); /* Set C2 (freq. range, ext. and int. reference selection etc.; trim values not changed) */

        if ((TargetMode & CPU_MCG_MODE_INDEX_MASK) == CPU_MCG_MODE_PEE) {

          MCG_C5 = CPU_ClockConfigDescriptors[ConfigID].GenRegs.MCG_C5_value; /* Set C5 (PLL settings, PLL reference divider etc.) */

          MCG_C6 = CPU_ClockConfigDescriptors[ConfigID].GenRegs.MCG_C6_value; /* Set C6 (PLL select, VCO divider etc.) */

        } else {

          MCG_C5 = NextModeRegs.MCG_C5_value; /* Set C5 (PLL settings, PLL reference divider etc.) */

          MCG_C6 = NextModeRegs.MCG_C6_value; /* Set C6 (PLL select, VCO divider etc.) */

        }

        #if !defined(USE_IRC32KHz_INTERNAL_CLOCK) //try to use external switching only if we are using internal clock

            while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until PLL is locked*/

            }

        #endif

        break;

      default:

        break;           

    }

    switch (NextMode) {

      case CPU_MCG_MODE_FEI:

      case CPU_MCG_MODE_FEE:

        while((MCG_S & 0x0CU) != 0x00U) { /* Wait until output of the FLL is selected */

        }

        break;

      case CPU_MCG_MODE_FBI:

      case CPU_MCG_MODE_BLPI:

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

        }

        break;

      case CPU_MCG_MODE_FBE:

      case CPU_MCG_MODE_BLPE:

      case CPU_MCG_MODE_PBE:

        #if !defined(USE_IRC32KHz_INTERNAL_CLOCK) //try to use external switching only if we are using internal clock

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

            }

        #endif

        break;

      case CPU_MCG_MODE_PEE:

        #if !defined(USE_IRC32KHz_INTERNAL_CLOCK) //try to use external switching only if we are using internal clock

            while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the FLL is selected */

           }

        #endif

        break;

    }

      } while (NextMode != (TargetMode & CPU_MCG_MODE_INDEX_MASK)); /* Loop until the target MCG mode is set */

    /* SIM_CLKDIV2: USBDIV=1,USBFRAC=0 */

    SIM_CLKDIV2 = (uint32_t)0x09UL; /* Update USB clock prescalers */

}

0 Kudos
886 Views
nitinharish
Contributor V

All the settings above just ran for 1 time and after a reboot I can never get it to run. Anybody like to exchange some thoughts/experience

0 Kudos
886 Views
nitinharish
Contributor V

Has anybody successfully used 32KHz IRC as REF for SYSTEM clock (using FLL) in MQX 4.1.1 ?

I need this PATH:

26994_26994.pngMCG_K64_FEI.png

Seems like the clock setting state machine (inside the function; CPU_SetClockConfigGenMode(LDD_TClockConfiguration ConfigID)) is coded in a way that this cannot happen.

Any Freescale folks want to pitch in ?

0 Kudos
886 Views
soledad
NXP Employee
NXP Employee

Hello Nitin,

Please check the attached document, this explains how to change the default clock configurations.

I hope this helps, have a nice day!


Have a great day,
Sol

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

886 Views
nitinharish
Contributor V

Thanks Soledad

But I am not using PE, I am using out of the box MQX4.1.1 with IAR (trying to tweak it so that it uses internal 32.7KHz-slow clock as system reference via FLL).

You seem like Freescale employee, can you please connect me with your MCG expert ?

0 Kudos
886 Views
nitinharish
Contributor V

soledad​I got PE working but the code generated out of it resembles out of the box MQX4.1.1 code as far as "CPU_SetClockConfigGenMode" function is concerned. And hence depicts exact same faulty behavior as post by red lines above (the code hangs on those lines and it should because it is waiting for external ref clock (which I have asked PE to disable), how can this loop ever END ?

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

Attached are code file output from PE.

0 Kudos
886 Views
nitinharish
Contributor V

Is it true that MQX/PE are NOT designed to operate with FLL referenced by "slow" clock of 32KHz ?

0 Kudos
886 Views
DavidS
NXP Employee
NXP Employee

Hi Nitin,

I used CW10.6.4 PE to configure the K64 BSP to clock from the internal slow 32KHz clock to FLL to get a core frequency ~96MHz.

I can POR, press reset button, and just debug the project without issue.

Attached is my BSP folder (bsp_frdmk64f) from folder path C:\Freescale\Freescale_MQX_4_1_1\mqx\build\cw10gcc.

I was able to open the bsp on PExDrv v10.4 to see the changes so you should be able to do that too.

Regards,

David

887 Views
nitinharish
Contributor V

Thanks David

After doing some real digging, I found the root cause of my issue. This piece of code which is doing Auto-trimming strongly assumes that their is an external reference clock in-spite of the fact I am setting all registers for using 32KHz IRC as REF clock, this function is used and called in in MQX 4.1.1's "bsp_cm.c" but NOT in Processor Expert output (which seems like an issue to me with MQX 4.1.1)

Kindly read the comments in the function below. the line that is the main issue is BusClockMHz calculation.

I request you @David E Seymour​and soledadto NOT go quite on this. Please respond with your views and action plan if any or at least prove that I am wrong.

/*

** ===================================================================

**     Method      :  CPU_MCGAutoTrim (component MK64FN1M0LQ12)

*/

/*!

**     @brief

**         This method uses MCG auto trim feature to trim internal

**         reference clock. This method can be used only in a clock

**         configuration which derives its bus clock from external

**         reference clock ([MCG mode] must be one of the following

**         modes - FEE, FBE, BLPE, PEE, PBE) and if value of [Bus clock]

**         is in the range <8; 16>MHz.

**         The slow internal reference clock is trimmed to the value

**         selected by [Slow internal reference clock [kHz]] property.

**         The fast internal reference clock will be trimmed to value

**         4MHz.

**     @param

**         ClockSelect     - Selects which internal

**                           reference clock will be trimmed.

**                           0 ... slow (32kHz) internal reference clock

**                           will be trimmed

**                           > 0 ... fast (4MHz) internal reference

**                           clock will be trimmed

**     @return

**                         - Error code

**                           ERR_OK - OK

**                           ERR_SPEED - The method does not work in the

**                           active clock configuration.

**                           ERR_FAILED - Autotrim process failed.

*/

/* ===================================================================*/

LDD_TError CPU_MCGAutoTrim(uint8_t ClockSelect)

{

  uint16_t CompareValue;               /* Autotrim compare value expected count */

  uint16_t BusClockMHz = (uint16_t)((uint32_t)(CPU_ClockConfigDescriptors[ClockConfigurationID].BusClock) /1000000UL); /* Bus clock in MHz */

  /* Calculate compare value */

  if (((CPU_ClockConfigDescriptors[ClockConfigurationID].Mode & (CPU_CLOCK_EXTERNAL_CLOCK_MASK | CPU_CLOCK_EXTERNAL_CRYSTAL_MASK)) != 0) && (BusClockMHz >= 8U) && (BusClockMHz <= 16U)) {

    if (ClockSelect == 0x00U) {

      CompareValue = (uint16_t)(21000 * BusClockMHz / CPU_INT_SLOW_CLK_HZ); /* Slow internal reference clock */

    } else {

      CompareValue = (uint16_t)(672U * BusClockMHz); /* Fast internal reference clock */

    }

  } else {

    return ERR_SPEED;                  /* MCU has to be clocked from external clock and has to have bus clock in allowed range */

  }

  MCG_ATCVH = (uint8_t)(CompareValue >> 8U); /* Set compare value high half */

  MCG_ATCVL = (uint8_t)(CompareValue & 255U); /* Set compare value low half */

  if (ClockSelect == 0x00U) {

    /* MCG_SC: ATME=1,ATMS=0,LOCS0=0 */

    MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(

              MCG_SC_ATMS_MASK |

              MCG_SC_LOCS0_MASK

             )) | (uint8_t)(

              MCG_SC_ATME_MASK

             ));                       /* Start trimming of the slow internal reference clock */

  } else {

    /* MCG_SC: ATME=1,ATMS=1,LOCS0=0 */

    MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(

              MCG_SC_LOCS0_MASK

             )) | (uint8_t)(

              MCG_SC_ATME_MASK |

              MCG_SC_ATMS_MASK

             ));                       /* Start trimming of the fast internal reference clock */

  }

  while ((MCG_SC & MCG_SC_ATME_MASK) != 0x00U) { /* Wait until autotrim completes */

  }

  if ((MCG_SC & MCG_SC_ATMF_MASK) == 0x00U) {

    return ERR_OK;                     /* Trim operation completed successfully */

  } else {

    return ERR_FAILED;                 /* Trim operation failed */

  }

}

mjbcswitzerland​: Some information for your consultancy too Smiley Happy

0 Kudos
886 Views
DavidS
NXP Employee
NXP Employee

Dear Nitin,

I do not use the autotrim capability and therefore comment the function contents out as shown below in the bsp_cm.c file:

uint16_t _bsp_osc_autotrim

(

    void

)

{

    uint16_t        CPU_Error = ERR_OK;

    /*

     * Its assumed that before auto trimming process

     * the MCG is switched to a clock configuration

     * which derives its bus clock from external reference clock

     * and (<MCG mode> is set to one of the following modes

     * FEE, FBE, BLPE, PEE, PBE) and if value of <Bus clock>

     * is in the range <8; 16>MHz.

     */

//DES Commented out CPU_MCGAutoTrim() calls.

//    /* Auto trim Slow internal reference clock */

//    CPU_Error = CPU_MCGAutoTrim(0);

//    if (CPU_Error != ERR_OK) return CPU_Error;

//

//    /* Auto trim Fast internal reference clock */

//    CPU_Error = CPU_MCGAutoTrim(1);

//    if (CPU_Error != ERR_OK) return CPU_Error;

    return ERR_OK;

}

Regards,

David

0 Kudos
886 Views
nitinharish
Contributor V

Thanks David.

That proves my point. We both have to disable this feature for 32KHz internal REF. Reason being in no way you can achieve Auto trim using external clock when their is none.

How do we open a  bug for MQX versions ?

0 Kudos
886 Views
nitinharish
Contributor V

​I verified MQX 4.2 is also affected by this.

0 Kudos
886 Views
DavidS
NXP Employee
NXP Employee

Thanks Nitin.

I will report it.

Regards,

David

0 Kudos