/*
** ###################################################################
**     Processor:           Vybrid
**     Compilers:           ARM Compiler
**                          Freescale C/C++ for Embedded ARM
**                          GNU C Compiler
**                          IAR ANSI C/C++ Compiler for ARM
**
**     Reference manual:    Vybrid RM Rev. 1, Draft B Feb 2012
**     Version:             rev. 1.0, 2012-03-15
**
**     Abstract:
**         Provides a system configuration function and a global variable that
**         contains the system frequency. It configures the device and initializes
**         the oscillator (PLL) that is part of the microcontroller device.
**
**     Copyright: 2012 Freescale Semiconductor, Inc. All Rights Reserved.
**
**     http:                 www.freescale.com
**     mail:                 support@freescale.com
**
**     Revisions:
**     - rev. 1.0 (2012-03-15)
**         Initial version
**
** ###################################################################
*/

/**
 * @file Vybrid
 * @version 1.0
 * @date 2012-03-15
 * @brief Device specific configuration file for Vybrid (implementation file)
 *
 * Provides a system configuration function and a global variable that contains
 * the system frequency. It configures the device and initializes the oscillator
 * (PLL) that is part of the microcontroller device.
 */

#include <stdint.h>
#include "MVF50GS10MK50.h"
#include "tower.h"
#include "lpt.h"
#include "sysinit.h"

/* Moved to tower.h so it can be used in other files as well...like serial.c for uart init */
/*#define CLOCK_SETUP     1 */

/*----------------------------------------------------------------------------
  Define clock source values
 *----------------------------------------------------------------------------*/
#if (CLOCK_SETUP == 0) //396 MHz A5 Core - Sample Code Default set in tower.h
    #define CPU_XTAL_CLK_HZ                 24000000u /* Value of the external crystal or oscillator clock frequency in Hz */
    #define CPU_XTAL32k_CLK_HZ              32768u   /* Value of the external 32k crystal or oscillator clock frequency in Hz */
    #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */
    #define CPU_INT_FAST_CLK_HZ             24000000u /* Value of the fast internal oscillator clock frequency in Hz  */
    #define DEFAULT_SYSTEM_CLOCK            264000000u /* Default System clock value */
#elif (CLOCK_SETUP == 1) //500 MHz A5 Core - Max speed
    #define CPU_XTAL_CLK_HZ                 24000000u /* Value of the external crystal or oscillator clock frequency in Hz */
    #define CPU_XTAL32k_CLK_HZ              32768u   /* Value of the external 32k crystal or oscillator clock frequency in Hz */
    #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */
    #define CPU_INT_FAST_CLK_HZ             24000000u /* Value of the fast internal oscillator clock frequency in Hz  */
    #define DEFAULT_SYSTEM_CLOCK            264000000u /* Default System clock value */
#elif (CLOCK_SETUP == 2) //264 MHz A5 Core - BootROM default 
    #define CPU_XTAL_CLK_HZ                 24000000u /* Value of the external crystal or oscillator clock frequency in Hz */
    #define CPU_XTAL32k_CLK_HZ              32768u   /* Value of the external 32k crystal or oscillator clock frequency in Hz */
    #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */
    #define CPU_INT_FAST_CLK_HZ             24000000u /* Value of the fast internal oscillator clock frequency in Hz  */
    #define DEFAULT_SYSTEM_CLOCK            264000000u /* Default System clock value */
#elif (CLOCK_SETUP == 3) //396 MHz A5 Core setup that assumes BootROM did not run
    #define CPU_XTAL_CLK_HZ                 24000000u /* Value of the external crystal or oscillator clock frequency in Hz */
    #define CPU_XTAL32k_CLK_HZ              32768u   /* Value of the external 32k crystal or oscillator clock frequency in Hz */
    #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */
    #define CPU_INT_FAST_CLK_HZ             24000000u /* Value of the fast internal oscillator clock frequency in Hz  */
    #define DEFAULT_SYSTEM_CLOCK            24000000u /* Default System clock value */
#endif 


/* ----------------------------------------------------------------------------
   -- Core clock 
   ---------------------------------------------------------------------------- */

uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;

/* ----------------------------------------------------------------------------
   -- SystemInit()
   ---------------------------------------------------------------------------- */

void SystemInit(void) 
{
  /*
   * Enable CCM, SRC, GPC and more main modules. BootROM has already done most of these
   */
  CCM->CCGR4 |= CCM_CCGR4_CG10(CLK_ON_ALL_MODES); // WKPU ungate
  CCM->CCGR4 |= CCM_CCGR4_CG11(CLK_ON_ALL_MODES); // CCM ungate
  CCM->CCGR4 |= CCM_CCGR4_CG12(CLK_ON_ALL_MODES); // GPC ungate
  CCM->CCGR4 |= CCM_CCGR4_CG14(CLK_ON_ALL_MODES); // SRC ungate
  CCM->CCGR3 |= CCM_CCGR4_CG0(CLK_ON_ALL_MODES);  // ANADIG ungate
  CCM->CCGR3 |= CCM_CCGR4_CG2(CLK_ON_ALL_MODES);  // SCSC ungate  
  
  /*
   * Enable IOMUX modules
   */
  CCM->CCGR2 |= CCM_CCGR2_CG8(CLK_ON_ALL_MODES);              // IOMUX Controller ungate
  CCM->CCGR2 |= CCM_CCGR2_CG9(CLK_ON_ALL_MODES_EXCEPT_STOP);  // Port A Controller ungate
  CCM->CCGR2 |= CCM_CCGR2_CG10(CLK_ON_ALL_MODES);             // Port B Controller ungate - Tower buttons
  CCM->CCGR2 |= CCM_CCGR2_CG11(CLK_ON_ALL_MODES_EXCEPT_STOP); // Port C Controller ungate
  CCM->CCGR2 |= CCM_CCGR2_CG12(CLK_ON_ALL_MODES_EXCEPT_STOP); // Port D Controller ungate
  CCM->CCGR2 |= CCM_CCGR2_CG13(CLK_ON_ALL_MODES_EXCEPT_STOP); // Port E Controller ungate

  /* Enable PIT */
  CCM->CCGR1 |= CCM_CCGR1_CG7(CLK_ON_ALL_MODES);

  /* Enable ENET0 and ENET1 */
  CCM->CCGR9 |= CCM_CCGR9_CG0(CLK_ON_ALL_MODES);
  CCM->CCGR9 |= CCM_CCGR9_CG1(CLK_ON_ALL_MODES);

  /* Enable DDR */
  CCM->CCGR6 |= CCM_CCGR6_CG14(CLK_ON_ALL_MODES);

  /* Enable DMAs */
  CCM->CCGR0 |= CCM_CCGR0_CG4(CLK_ON_ALL_MODES);
  CCM->CCGR0 |= CCM_CCGR0_CG5(CLK_ON_ALL_MODES);

  /* Enable TRACE_EN*/
  CCM->CSCDR3 |= CCM_CSCDR3_TRACE_EN_MASK;
 
  /* Enable all modules */
/*
  CCM->CCGR0 = 0xFFFFFFFF;
  CCM->CCGR1 = 0xFFFFFFFF;
  CCM->CCGR2 = 0xFFFFFFFF;
  CCM->CCGR3 = 0xFFFFFFFF;
  CCM->CCGR4 = 0xFFFFFFFF;
  CCM->CCGR5 = 0xFFFFFFFF;
  CCM->CCGR6 = 0xFFFFFFFF;
  CCM->CCGR7 = 0xFFFFFFFF;
  CCM->CCGR8 = 0x3FFFFFFF;	//Turn off GPU since causes immediate interrupt
  CCM->CCGR9 = 0xFFFFFFFF; 
  CCM->CCGR10 = 0xFFFFFFFF;
  CCM->CCGR11 = 0xFFFFFFFF;
*/


#if (CLOCK_SETUP == 0)

    /*******************************************************
     * Setup the clocks to run in synchronous mode
     *
     * PLL1 (24M*22 = 528 MHz setting):
     * 	PFD1 = 500 MHz
     * 	PFD2 = 452 MHz
     * 	PFD3 = 396 MHz
     * 	PFD4 = 528 MHz
     *
     * PLL2 (24M*22 = 528 MHz setting):
     * 	PFD1 = 500 MHz
     * 	PFD2 = 396 MHz
     * 	PFD3 = 339 MHz
     * 	PFD4 = 413 MHz
     *
     ********************************************************/

    /* Power up FXOSC (24 MHz external quartz) */
    CCM->CLPCR = 0x00000078UL;

    /* Wait for FXOSC to lock */
    while ((CCM->CSR & 0x00000020UL) == 0x00000020UL) {}

    /* Set FXOSC as fast clock */
    CCM->CCSR = 0x00000020UL;

    /* Startup PLL1 @ 528MHz */
    ANADIG->PLL1_CTRL = 0x00002001UL;

    /* Wait for PLL1 to lock */
    while ((ANADIG->PLL1_CTRL & 0x80000000UL) == 0x80000000UL) {}

    /* Startup PLL2 @ 528MHz */
    ANADIG->PLL2_CTRL = 0x00002001UL;

    /* Wait for PLL2 to lock */
    while ((ANADIG->PLL2_CTRL & 0x80000000UL) == 0x80000000UL) {}

    /* Startup PLL3 @ 480 MHz for USB0 */
    ANADIG->PLL3_CTRL = 0x00003040UL;

    /* Wait for PLL3 to lock */
    while ((ANADIG->PLL3_CTRL & 0x80000000UL) == 0x80000000UL) {}

//  ANADIG->PLL4_CTRL=0x00002031; //PLL4 (Audio PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=0x31 (24M*49=1176MHz, range 600M-1300M)

    /* Startup PLL5 @ 50 MHz for ENET */
    ANADIG->PLL5_CTRL = 0x00002001UL;

    /* Wait for PLL5 to lock */
    while ((ANADIG->PLL5_CTRL & 0x80000000UL) == 0x80000000UL) {}

//  ANADIG->PLL6_CTRL=0x00002028; //PLL6 (Video PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=0x28 (24M*40=960M, range 600M-1300M)

    /*******************************************************
     * Setup the clocks to run in synchronous mode
     * using PLL1 PFD3 (396MHz CA5)
     * 396MHz CA5, 132MHz CM4, 396MHz DDR and 66MHz bus
     ********************************************************/
    /* Enable all PFDs sources, select Fast Clock, and set SYS_CLOCK_SEL as PLL1 PFD3 @ 396MHz */
    CCM->CCSR = 0xF003FF64UL;

    /* Set ARM_CLK_DIV=1, BUS_CLK_DIV=3, IPG_CLK_DIV=2 (synchronous mode) */
    CCM->CACRR = 0x00400810UL;

  SystemCoreClockUpdate();

#elif (CLOCK_SETUP == 1)
  
    /*******************************************************
     * Setup the clocks to run in asynchronous mode
     *
     * PLL1 (24M*20 = 500 MHz setting):
     * 	PFD1 = 474 MHz
     * 	PFD2 = 429 MHz
     * 	PFD3 = 375 MHz
     * 	PFD4 = 500 MHz
     *
     * PLL2 (24M*20 = 500 MHz setting):
     * 	PFD1 = 474 MHz
     * 	PFD2 = 375 MHz
     * 	PFD3 = 321 MHz
     * 	PFD4 = 391 MHz
     *
     ********************************************************/

    /* Power up FXOSC (24 MHz external quartz) */
    CCM->CLPCR = 0x00000078UL;

    /* Wait for FXOSC to lock */
    while ((CCM->CSR & 0x00000020UL) != 0x00000020UL) {}

    /* Set FXOSC as fast clock */
    CCM->CCSR = 0x00000020UL;

    /* Startup PLL1 @ 500MHz (Work-around for errata e6235) */
    /* Set PLL multiplier (MFI) to 20 */
    ANADIG->PLL1_CTRL = 0x00002000UL;
    /* Set MFD to 100 */
    ANADIG->PLL1_DENOM = 100;
    /* Set MFN to 83 */
    ANADIG->PLL1_NUM = 83;

    /* Wait for PLL1 to lock */
    while ((ANADIG->PLL1_CTRL & 0x80000000UL) == 0x80000000UL) {}

    /* Startup PLL2 @ 500MHz (Work-around for errata e6235) */
    /* Set PLL multiplier (MFI) to 20 */
    ANADIG->PLL2_CTRL = 0x00002000UL;
    /* Set MFD to 100 */
    ANADIG->PLL2_DENOM = 100;
    /* Set MFN to 83 */
    ANADIG->PLL2_NUM = 83;

    /* Wait for PLL2 to lock */
    while ((ANADIG->PLL2_CTRL & 0x80000000UL) == 0x80000000UL) {}

    /* Startup PLL3 @ 480 MHz for USB0 */
   // ANADIG->PLL3_CTRL = 0x00003040UL;

    /* Wait for PLL3 to lock */
    //while ((ANADIG->PLL3_CTRL & 0x80000000UL) == 0x80000000UL) {}

//  ANADIG->PLL4_CTRL=0x00002031; //PLL4 (Audio PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=0x31 (24M*49=1176MHz, range 600M-1300M)

    /* Startup PLL5 @ 50 MHz for ENET */
    ANADIG->PLL5_CTRL = 0x00002001UL;

    /* Wait for PLL5 to lock */
    while ((ANADIG->PLL5_CTRL & 0x80000000UL) == 0x80000000UL) {}

//  ANADIG->PLL6_CTRL=0x00002028; //PLL6 (Video PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=0x28 (24M*40=960M, range 600M-1300M)

    /*******************************************************
     * Setup the clocks to run in asynchronous mode
     * using PLL1 main (500MHz CA5)
     * 500MHz CA5, 167MHz CM4, 375MHz DDR and 83.5MHz bus
     ********************************************************/
    /* Enable all PFDs sources, select Fast Clock, set DDRC_CLK_SEL=PLL2_PFD2 and set SYS_CLOCK_SEL as PLL1 main @ 500MHz */
    CCM->CCSR = 0xF000FF24UL;

    /* Set ARM_CLK_DIV=1, BUS_CLK_DIV=3, IPG_CLK_DIV=2 (asynchronous mode) */
    CCM->CACRR = 0x00400810UL;

    /* Configure DDR for asynchronous mode */
    DDRMC->CR117 &= ~DDRMC_CR117_AXI0_FITYPREG_MASK;
                
    SystemCoreClockUpdate();

#elif (CLOCK_SETUP == 2)
  //264 MHz A5 - No clock init after BootROM
  //Do nothing, just update the SystemClock variable
  SystemCoreClockUpdate();
  
#elif (CLOCK_SETUP == 3)
  //396 MHz A5 - Debug case where BootROM did not run and thus PLLs not turned on and clock is 24MHz  
  //  Need to turn on the PLL to emulate what the BootROM does, and then further configure the PLLs like normal

  /* Mask Crystal Oscillator Ready Interrupt Bit */
  CCM->CIMR |= CCM_CIMR_M_FXOSC_READY_MASK;

  /* Enable CCM Reference Clock Enable */
  CCM->CCR |= CCM_CCR_FXOSC_EN_MASK;

  
  /* PLL lock depends on this bit, so make sure it is enabled (is enabled by default) */
  //SCSC->SIRC_CTR |= SCSC_SIRC_CTR_SIRC_EN_MASK;  

  /* Diable Crystal Power Down Bit in LPCR register */
  CCM->CLPCR &= ~CCM_CLPCR_FXOSC_PWRDWN_MASK;
  

  ANADIG->PLL1_CTRL=0x00002001;	//PLL1 (System PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=1 (1->Fout=Fref*22, 0->Fout=Fref*22=>24M*22=528MHz)
  ANADIG->PLL3_CTRL=0x80003040; //PLL3 (USB PLL)
  
  CCM->CCGR4 |= CCM_CCGR4_CG11(CLK_ON_ALL_MODES); // CCM ungate
  CCM->CCR=0x000110FF;
  CCM->CSR=0x00000030;
  CCM->CCSR=0x00040824;
  CCM->CACRR=0x00600809;


    /*******************************************************
   * Setup the clocks to run in synchronous mode
   * using PLL1 PFD3 
   * 396MHz CA5, 396 MHz DDR, 132MHz CM4, and 66MHz bus
   ********************************************************/
  //PLL1 uses PLL1_PFD3, enable all PLL1 and PLL2, enable PLL3_PFD4 for QSPI, select Fast Clock, and sys_clock_sel use PLL1  
  CCM->CCSR = (CCM_CCSR_PLL3_PFD4_EN_MASK | CCM_CCSR_PLL1_PFD_CLK_SEL(3) | \
		  	   0x0000FF00 | CCM_CCSR_FAST_CLK_SEL_MASK | (CCM_CCSR_SYS_CLK_SEL(4)));   
  CCM->CACRR=0x00000810; //ARM_DIV=0 (div by 1), BUS_DIV=2 (div by 3), ipg_div value is 1 (div by 2)

  /* enable all the PLLs in Anadig */
  ANADIG->PLL1_CTRL=0x00002001;	//PLL1 (System PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=1 (1->Fout=Fref*22, 0->Fout=Fref*22=>24M*22=528MHz)
  ANADIG->PLL2_CTRL=0x00002001;	//PLL2 (PLL 528) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=1 (1->Fout=Fref*22, 0->Fout=Fref*22=>24M*22=528MHz)
  /* PLL3 --> 480 MHz PLL for USB0 - leave as default */
  ANADIG->PLL4_CTRL=0x00002031; //PLL4 (Audio PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=0x31 (24M*49=1176MHz, range 600M-1300M)
  ANADIG->PLL5_CTRL=0x00002001; //PLL5 (ENET PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=0b01 (50MHz)
  ANADIG->PLL6_CTRL=0x00002028; //PLL6 (Video PLL) --> POWERDOWN=0, BYPASS=0, ENABLE=1, DIV_SELECT=0x28 (24M*40=960M, range 600M-1300M)
  
  SystemCoreClockUpdate();
#endif /* (CLOCK_SETUP == 3) */

}

/* ----------------------------------------------------------------------------
   -- SystemCoreClockUpdate()
   ---------------------------------------------------------------------------- */

void SystemCoreClockUpdate (void) 
{                                                       
  uint8_t sys_clk_select;  /* Variable to store output clock frequency of the MCG module */
  uint8_t temp_select;
  uint32_t MFI = 0;
  uint32_t PLLout = 0;
  
  uint32_t PLL2_NUM=ANADIG->PLL2_NUM;
  uint32_t PLL2_DENOM=ANADIG->PLL2_DENOM;
  uint32_t PLL1_NUM=ANADIG->PLL1_NUM;
  uint32_t PLL1_DENOM=ANADIG->PLL1_DENOM;
   
  sys_clk_select = (CCM->CCSR & CCM_CCSR_SYS_CLK_SEL_MASK);
  
  switch (sys_clk_select)
  {
    case 0:  // CASE 0:  FAST Clock!!! ///////////////////////////////////////////////////////////////////////////////////////
      SystemCoreClock = 24000;
      break;
    case 1:  // CASE 1:  SLOW Clock!!! ///////////////////////////////////////////////////////////////////////////////////////
      SystemCoreClock = 32;
      break;
    case 2:  // CASE 2:  PLL2 PFD Clock!!! ///////////////////////////////////////////////////////////////////////////////////////
      temp_select = (CCM->CCSR & CCM_CCSR_PLL2_PFD_CLK_SEL_MASK);
      MFI = 20 + (2 * (ANADIG->PLL2_CTRL & ANADIG_PLL2_CTRL_DIV_SELECT_MASK));
      switch (temp_select)
      {
        case 0:
          if (ANADIG->PLL2_CTRL & ANADIG_PLL2_CTRL_BYPASS_MASK)
            SystemCoreClock = 24000;
          else
            SystemCoreClock = (24000*MFI)+(24000*PLL2_NUM)/PLL2_DENOM;
          break;
        case 1:  //CASE 1!!! ///////////////////////////////////////////////////////////////////////////////////
          if (ANADIG->PLL2_CTRL & ANADIG_PLL2_CTRL_BYPASS_MASK)
           PLLout = 24000;
          else
           PLLout = (24000*MFI)+(24000*PLL2_NUM)/PLL2_DENOM;
          SystemCoreClock = (PLLout * 18) / ((ANADIG->PLL2_PFD & ANADIG_PLL2_PFD_PFD1_FRAC_MASK)>>ANADIG_PLL2_PFD_PFD1_FRAC_SHIFT);
          break;
        case 2:   //CASE 2!!! ///////////////////////////////////////////////////////////////////////////////////
          if (ANADIG->PLL2_CTRL & ANADIG_PLL2_CTRL_BYPASS_MASK)
            PLLout = 24000;
          else
           PLLout = (24000*MFI)+(24000*PLL2_NUM)/PLL2_DENOM;
         SystemCoreClock = (PLLout * 18) / ((ANADIG->PLL2_PFD & ANADIG_PLL2_PFD_PFD2_FRAC_MASK)>>ANADIG_PLL2_PFD_PFD2_FRAC_SHIFT);
         break;
        case 3:  //CASE 3!!! ///////////////////////////////////////////////////////////////////////////////////
          if (ANADIG->PLL2_CTRL & ANADIG_PLL2_CTRL_BYPASS_MASK)
           PLLout = 24000;
          else
           PLLout = (24000*MFI)+(24000*PLL2_NUM)/PLL2_DENOM;
         SystemCoreClock = (PLLout * 18) / ((ANADIG->PLL2_PFD & ANADIG_PLL2_PFD_PFD3_FRAC_MASK)>>ANADIG_PLL2_PFD_PFD3_FRAC_SHIFT);
         break;
        case 4:  //CASE 4!!! ///////////////////////////////////////////////////////////////////////////////////
          if (ANADIG->PLL2_CTRL & ANADIG_PLL2_CTRL_BYPASS_MASK)
            PLLout = 24000;
          else
            PLLout = (24000*MFI)+(24000*PLL2_NUM)/PLL2_DENOM;
          SystemCoreClock = (PLLout * 18) / ((ANADIG->PLL2_PFD & ANADIG_PLL2_PFD_PFD4_FRAC_MASK)>>ANADIG_PLL2_PFD_PFD4_FRAC_SHIFT);
          break;
        default:
          break;
      }
	  break;
    case 3:  // CASE 3:  PLL2 Main Clock!!! ///////////////////////////////////////////////////////////////////////////////////////
      if (ANADIG->PLL2_CTRL & ANADIG_PLL2_CTRL_BYPASS_MASK)
        SystemCoreClock = 24000;
      else
      {
        MFI = 20 + (2 * (ANADIG->PLL2_CTRL & ANADIG_PLL2_CTRL_DIV_SELECT_MASK));
        SystemCoreClock = (24000*MFI)+(24000*PLL2_NUM)/PLL2_DENOM;
      }
      break;
    case 4:  // CASE 4:  PLL1 PFD Clock!!! ///////////////////////////////////////////////////////////////////////////////////////
      temp_select = (CCM->CCSR & CCM_CCSR_PLL1_PFD_CLK_SEL_MASK)>>CCM_CCSR_PLL1_PFD_CLK_SEL_SHIFT ;
      MFI = 20 + (2 * (ANADIG->PLL1_CTRL & ANADIG_PLL1_CTRL_DIV_SELECT_MASK));
      switch (temp_select)
      {
        case 0:
          if (ANADIG->PLL1_CTRL & ANADIG_PLL1_CTRL_BYPASS_MASK)
            SystemCoreClock = 24000;
          else
            SystemCoreClock = (24000*MFI)+(24000*PLL1_NUM)/PLL1_DENOM;
          break;
        case 1:  //CASE 1!!! ///////////////////////////////////////////////////////////////////////////////////
          if (ANADIG->PLL2_CTRL & ANADIG_PLL1_CTRL_BYPASS_MASK)
            PLLout = 24000;
          else
            PLLout = (24000*MFI)+(24000*PLL1_NUM)/PLL1_DENOM;
          SystemCoreClock = (PLLout * 18) / ((ANADIG->PLL1_PFD & ANADIG_PLL1_PFD_PFD1_FRAC_MASK)>>ANADIG_PLL1_PFD_PFD1_FRAC_SHIFT);
          break;
        case 2:   //CASE 2!!! ///////////////////////////////////////////////////////////////////////////////////
          if (ANADIG->PLL1_CTRL & ANADIG_PLL1_CTRL_BYPASS_MASK)
            PLLout = 24000;
          else
            PLLout = (24000*MFI)+(24000*PLL1_NUM)/PLL1_DENOM;
          SystemCoreClock = (PLLout * 18) / ((ANADIG->PLL1_PFD & ANADIG_PLL1_PFD_PFD2_FRAC_MASK)>>ANADIG_PLL1_PFD_PFD2_FRAC_SHIFT);
          break;
        case 3:  //CASE 3!!! ///////////////////////////////////////////////////////////////////////////////////
          if (ANADIG->PLL1_CTRL & ANADIG_PLL1_CTRL_BYPASS_MASK)
            PLLout = 24000;
          else
            PLLout = (24000*MFI)+(24000*PLL1_NUM)/PLL1_DENOM;
          SystemCoreClock = (PLLout * 18)/ ((ANADIG->PLL1_PFD & ANADIG_PLL1_PFD_PFD3_FRAC_MASK)>>ANADIG_PLL1_PFD_PFD3_FRAC_SHIFT);
          break;
        case 4:  //CASE 4!!! ///////////////////////////////////////////////////////////////////////////////////
          if (ANADIG->PLL1_CTRL & ANADIG_PLL1_CTRL_BYPASS_MASK)
            PLLout = 24000;
          else
            PLLout = (24000*MFI)+(24000*PLL1_NUM)/PLL1_DENOM;
          SystemCoreClock = (PLLout * 18) / ((ANADIG->PLL1_PFD & ANADIG_PLL1_PFD_PFD4_FRAC_MASK)>>ANADIG_PLL1_PFD_PFD4_FRAC_SHIFT);
          break;
        default:
          break;
      }
      break;
    case 5:
      SystemCoreClock = 480000;
      break;
    default:
      break;
  }     
  
  //System clock is then divided by the CCM_CACRR[ARM_CLK_DIV] 
  SystemCoreClock=SystemCoreClock/((CCM->CACRR & CCM_CACRR_ARM_CLK_DIV_MASK)+1);
}
