Generating a stable FLL frequency on a KL15

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

Generating a stable FLL frequency on a KL15

635 Views
Alex_HMBE
Contributor II

We've designed a custom board with a KL15 on it, and in trying to debug a different issue I've found that a PWM signal we're generating isn't as stable as I would've expected. Fortunately it hasn't been a show stopper, yet, but I was hoping to be able to figure out why it's happening before moving on to other things with this MCU.

Using Processor Expert, I've generated setup code for the MCG module to put it into FLL mode.

We have an external 32.768kHz oscillator.

I am measuring the output of TPM0C1 and seeing the frequency jump around by (my best guess), around 1%.

Am I expecting a more stable PWM frequency than what my setup can provide? Have I missed something in setting it up?

Processor Expert code:

void __init_hardware(void)

{

  /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/

  /*** ### MKL15Z128VLK4 "Cpu" init code ... ***/

  /*** PE initialization code after reset ***/

  SCB_VTOR = (uint32_t)(&__vector_table); /* Set the interrupt vector table position */

  /* Disable the WDOG module */

  /* SIM_COPC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COPT=0,COPCLKS=0,COPW=0 */

  SIM_COPC = SIM_COPC_COPT(0x00);                                

  /* System clock initialization */

  /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */

  SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x03)); /* Set the system prescalers to safe value */

  /* SIM_SCGC5: PORTA=1 */

  SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;   /* Enable clock gate for ports to enable pin routing */

  if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) {

    /* PMC_REGSC: ACKISO=1 */

    PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */

  }

  /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */

  SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01)); /* Update system prescalers */

  /* SIM_SOPT2: ??=0 */

  SIM_SOPT2 &= (uint32_t)~(uint32_t)(0x00010000U); /* Select FLL as a clock source for various peripherals */

  /* SIM_SOPT1: OSC32KSEL=0 */

  SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL(0x03)); /* System oscillator drives 32 kHz clock for various peripherals */

  /* SIM_SOPT2: TPMsrc=1 */

  SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(

               SIM_SOPT2_TPMSRC(0x02)

              )) | (uint32_t)(

               SIM_SOPT2_TPMSRC(0x01)

              ));                      /* Set the TPM clock */

  /* PORTA_PCR18: ISF=0,MUX=0 */

  PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));                                

  /* PORTA_PCR19: ISF=0,MUX=0 */

  PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));                                

  /* Switch to FEE Mode */

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

  MCG_C2 = (MCG_C2_RANGE0(0x00) | MCG_C2_EREFS0_MASK);                                

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

  OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                

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

  MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x00) | MCG_C1_IRCLKEN_MASK);                                

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

  MCG_C4 = (uint8_t)((MCG_C4 & (uint8_t)~(uint8_t)(

            MCG_C4_DRST_DRS(0x02)

           )) | (uint8_t)(

            MCG_C4_DMX32_MASK |

            MCG_C4_DRST_DRS(0x01)

           ));                               

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

  MCG_C5 = MCG_C5_PRDIV0(0x00);                                

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

  MCG_C6 = MCG_C6_VDIV0(0x00);                                

  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) != 0x00U) {    /* Wait until output of the FLL is selected */

  }

  /*** End of PE initialization code after reset ***/

  /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/

}

PWM setup:

int main(void)

{

  SIM_SCGC5|=(1<<9); //PORTA

  SIM_SCGC6|=(1<<24); //TPM0

  PORTA_PCR4=0x300;

  TPM0_C1SC=0b00101000; //Edge Aligned PWM

  TPM0_C1V=183;

  TPM0_MOD=366; //12Mhz/366=32768kHz

  TPM0_SC=0b00001010; //48Mhz/4=12Mhz

  for(;;)

  {  

  

  }

  return 0;

}

Labels (1)
0 Kudos
Reply
1 Reply

412 Views
apanecatl
Senior Contributor II

The accuracy and deviation present in your timer will be those inherent to the clock source you use to configure the timer, in this case you are using FEE using a 32.768KHz XTAL; thus the inherent deviation of the DCO will be passed onto the timer, I suggest you set register bit field MCG_C4[DMX32]=1, since the FLL module is fine tuned to work with 32.768KHz XTAL, setting DMX32=1 will reduce the frequency deviation present in your CLK signal.

If this answer is helpful, please remember to mark it as correct or helpful answer, thanks!!!

0 Kudos
Reply