/*******************************************************************************
* Freescale Semiconductor Inc.
* (c) Copyright 2012 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
********************************************************************************
Services performed by FREESCALE in this matter are performed AS IS and without
any warranty. CUSTOMER retains the final decision relative to the total design
and functionality of the end product. FREESCALE neither guarantees nor will be
held liable by CUSTOMER for the success of this project.
FREESCALE DISCLAIMS ALL WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY INCLUDING,
BUT NOT LIMITED TO, IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
A PARTICULAR PURPOSE ON ANY HARDWARE, SOFTWARE ORE ADVISE SUPPLIED TO A PROJECT
BY FREESCALE, AND OR NAY PRODUCT RESULTING FROM FREESCALE SERVICES. IN NO EVENT
SHALL FREESCALE BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF
THIS AGREEMENT.
CUSTOMER agrees to hold FREESCALE harmless against any and all claims demands or
actions by anyone on account of any damage, or injury, whether commercial,
contractual, or tortuous, rising directly or indirectly as a result of an advise
or assistance supplied CUSTOMER in connection with product, services or goods
supplied under this Agreement.
********************************************************************************
* File main.c
* Owner b34874
* Version 1.0 // version 0.x is reserved for development phase and
// should not be placed in the repository
* Date June-28-2012
* Classification General Business Information/Internal Use Only/Confidential Proprietary
* Brief Brief description of the file
********************************************************************************
* Detailed Description:
* Set the bus clock 16MHz in PEE mode.
* Note: S12G has almost the same CPMU clock module as S12P(S12HY), therefore we can use
* S12XE_iPLL_Calculator for PLL parameters calculation   
* Tested on: PC9S12G240 0N95B, TWR-S12G240, 
* Clock source1:1MHz IRC1M; BUSCLK:6.25MHz
* Clock source2:8MHz crystal; BUSCLK:16MHz
********************************************************************************
Revision History:
Version Date Author Description of Changes
1.0 June/28/2012 b34874 Initial Version
*******************************************************************************/
#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */


//==============================================================================
//Important formulas:

//if external oscillator is enabled (OSCE = 1)
//  fref = fosc / (REFDIV + 1)

//if external oscillator is disabled (OSCE = 0)
//  fref = fIRC1M

//  fvco = 2 * fref * (SYNDIV + 1)

//if PLL is locked (LOCK = 1)
//  fpll = fvco / (POSTDIV + 1)

//if PLL is not locked (LOCK = 0)
//  fpll = fvco / 4

//if PLL is selected (PLLSEL = 1)
//  fbus = fpll / 2
//==============================================================================

//==============================================================================
//Delay
//==============================================================================
void Delay(void)
{
  unsigned int i,j;    
  
  for(i=0; i<65500; i++)  
    for(j=0; j<100; j++) asm nop;        
}


//==============================================================================
//PLL_LOCK_ISR
//==============================================================================
#pragma CODE_SEG NON_BANKED
interrupt 28 void PLL_LOCK_ISR(void)
{
  if(CPMUFLG_LOCK == 0)
  {
    //do something here
  }
  else
  {
    //do something here
  }
}
#pragma CODE_SEG DEFAULT
                      
                      
                    

//==============================================================================
//Main
//==============================================================================
void main(void) {
  
  ECLKCTL_NECLK = 0;  //enable ECLK output, bus clock is visible on pin PB0(for LQFP100) or PS7(for LQFP64/48/32, QFN48 and TSSOP20)
  
  //============================================================================
  //Default state after reset:
  
  //PLL Engaged Internal Mode (PEI)
  //Reference clock = internal RC oscillator 1MHz
  //Default settings:
  //REFDIV[3:0] = 0x0F;
  //REFFRQ[1:0] = 0x00;
  //SYNDIV[5:0] = 0x18;
  //VCOFRQ[1:0] = 0x01;
  //POSTDIV[4:0] = 0x03;
  //fvco = 50MHz
  //fpll = 12.5MHz
  //fbus = 6.25MHz
  
  Delay();    //delay in order to see default bus frequency on ECLK output

  //============================================================================
  //We want to set:
  //PLL Engaged External Mode (PEE)
  //Reference clock = external oscillator = 8MHz for example      
  //REFDIV[3:0] = 0x00;
  //REFFRQ[1:0] = 0x01;
  //SYNDIV[5:0] = 0x01;
  //VCOFRQ[1:0] = 0x00;
  //POSTDIV[4:0] = 0x00;
  //fvco = 32MHz
  //fpll = 32MHz
  //fbus = 16MHz  
  
  //To enter PEE mode from PEI mode:
  // 1. Configure the PLL for the desired frequency, via the CPMUSYNR, CPMUREFDIV,
  // and CPMUPOSTDIV registers.
  // 2. Enable the external oscillator bit (OSCE in CPMUOSC register).
  // 3. Wait for UPOSC bit - till the oscillator is qualified by the PLL 

  CPMUSYNR_SYNDIV = 0x01;
  CPMUSYNR_VCOFRQ = 0x00;
      
  CPMUREFDIV_REFDIV = 0x00;
  CPMUREFDIV_REFFRQ = 0x01;
  
  CPMUPOSTDIV = 0x00;   
  
  //writing into CPMUSYNR or CPMUREFDIV will unlock the PLL.
  //While PLL is unlocked fpll is fvco/4 to protect the system from high
  //core clock frequencies during the PLL stabilization time. 
  //if PLL is locked then fpll = fvco / (POSTDIV + 1)
  
  
  //if external oscillator is disabled (OSCE = 0) then fref = fIRC1M
  //if external oscillator is enabled (OSCE = 1) then fref = fosc / (REFDIV + 1)
  
  CPMUOSC_OSCE = 1; //enable external oscillator OSCE
    
  
  //Wait for the UPOSC bit to set, indicating the oscillator 
  //starting up - the oscillator is qualified by the PLL
  while(CPMUFLG_UPOSC == 0);    

  
  //Since the adaptive spike filter uses VCOCLK (from PLL) to continuously qualify 
  //the external oscillator clock, losing PLL lock status (LOCK=0) means losing 
  //the oscillator status information as well (UPOSC=0).
  //The impact of losing the oscillator status in PEE mode is as follows:
  //The MSCAN module, which can be configured to run on the oscillator clock, 
  //may need to be reconfigured.
  //Application software needs to be prepared to deal with the impact of losing 
  //the oscillator status at any time.  
  
  //wait until PLL clocks are within the desired tolerance of target frequency
  while(!CPMUFLG_LOCK);  
  //now the PLL has been locked and fpll = fvco / (POSTDIV + 1)
  
  
  EnableInterrupts;
  
  //We can enable the interrupt which will be requested whenever LOCKIF is set
  //LOCKIF interrupt flag is set whenever the LOCK status bit has been changed  
  CPMUFLG_LOCKIF = 1;   //clear flag
  CPMUINT_LOCKIE = 1;   //enable interrupt 
  
  
  //test                      
  //CPMUSYNR_SYNDIV = 0x00; //test - writing into CPMUSYNR or CPMUREFDIV will 
                            //trigger the interrupt because the PLL will
                            //become unlocked  
  
  for(;;) {
    _FEED_COP(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}
