//Setup:JM60系统初始化子程序-----------------------------------------------*
//功 能:系统初始化设置                                                     *
//      由外部晶振 f = 12MHz,产生内部总线时钟f = 24MHz                     *
//参 数:无                                                                 *
//返 回:无                                                                 *
//-------------------------------------------------------------------------*

#include <MC9S08JM60.h>    //映像寄存器地址头文件

void MCUInit(void)
{

   // Out of reset MCG is in FEI mode
   SOPT1       = SOPT1_STOPE_MASK; // disable COP & enable STOP instruction
   SPMSC1_BGBE = 1;                // Enable Bandgap Reference
   // 1. Switch from FEI (FLL engaged internal) to FBE (FLL bypassed external)
   
   // 1 a) Set up crystal 
   MCGC2 =                       // BDIV = 0, divide by 1
            MCGC2_HGO_MASK       // oscillator in high gain mode
          | MCGC2_EREFS_MASK     // because crystal is being used
          | MCGC2_RANGE_MASK     // 12 MHz is in high freq range
          | MCGC2_ERCLKEN_MASK;  // activate external reference clock
  
   // 1 b) Wait for crystal to start up        
   while (MCGSC_OSCINIT == 0) 
   {
   }
  
   // 1 c) Select clock mode
   MCGC1 = (2<<6)   // CLKS = 10 -> External reference clock
           | (3<<3);  // RDIV = 3  -> 12MHz/8=1.5 MHz
  
   // 1 d) Wait for mode change
   while (MCGSC_IREFST != 0) 
   {
   }
   
   // 1 e) Wait for MCGOUT indicating that the external reference to be fed to MCGOUT
   while (MCGSC_CLKST != 2) 
   {
   }    
   // 2. Switch FBE (FLL bypassed external) to PBE (PLL Bypassed External) mode
   // 2 b) Set RDIV for correct range
   // 2 c) Enable the PLL & set VDIV value
   MCGC3 = MCGC3_PLLS_MASK | (8<<0);        // VDIV=6 -> multiply by 32 -> 1.5MHz * 32 = 48MHz */
   
   // 2 e) Wait until PLLS clock source changes to the PLL
   while(MCGSC_PLLST != 1) 
   {
   }

   // 2 f)  Wait for PLL to acquired lock
   while(MCGSC_LOCK != 1) 
   {
   }
   
   // 3. PBE mode transitions into PEE mode:

   // 3 a) Set RDIV for correct range and select PLL.FLL clock
   MCGC1 =  (0<<6)       // CLKS = 0 -> PLL or FLL output clock
           | (3<<3);      // RDIV = 3 -> 12MHz/8=1.5 MHz (req. 1 < f < 2)

   // 3 c)  Wait for clock stable
   while(MCGSC_CLKST!=3) 
   {
   }
}
