text: /*******************************************************************************
   CLOCK PLIB
  
    Company:
      Microchip Technology Inc.
  
    File Name:
      plib_clock.c
  
    Summary:
      CLOCK PLIB Implementation File.
  
    Description:
      None
  
  *******************************************************************************/
  
  /*******************************************************************************
  * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries.
  *
  * Subject to your compliance with these terms, you may use Microchip software
  * and any derivatives exclusively with Microchip products. It is your
  * responsibility to comply with third party license terms applicable to your
  * use of third party software (including open source software) that may
  * accompany Microchip software.
  *
  * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
  * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
  * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
  * PARTICULAR PURPOSE.
  *
  * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
  * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
  * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
  * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
  * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
  * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  *******************************************************************************/
  
  #include "plib_clock.h"
  #include "device.h"
  
  static void OSCCTRL_Initialize(void)
  {
  
      /****************** XOSC1 Initialization   ********************************/
  
      /* Configure External Oscillator */
      OSCCTRL_REGS->OSCCTRL_XOSCCTRL[1] = OSCCTRL_XOSCCTRL_STARTUP(0) | OSCCTRL_XOSCCTRL_IMULT(4) | OSCCTRL_XOSCCTRL_IPTAT(3) | OSCCTRL_XOSCCTRL_ENABLE_Msk;
      while((OSCCTRL_REGS->OSCCTRL_STATUS & OSCCTRL_STATUS_XOSCRDY1_Msk) != OSCCTRL_STATUS_XOSCRDY1_Msk)
      {
          /* Waiting for the XOSC Ready state */
      }
  }
  
  static void OSC32KCTRL_Initialize(void)
  {
  
      OSC32KCTRL_REGS->OSC32KCTRL_RTCCTRL = OSC32KCTRL_RTCCTRL_RTCSEL(0);
  }
  
  static void FDPLL0_Initialize(void)
  {
  
      /****************** DPLL0 Initialization  *********************************/
  
      /* Configure DPLL    */
      OSCCTRL_REGS->DPLL[0].OSCCTRL_DPLLCTRLB = OSCCTRL_DPLLCTRLB_FILTER(0) | OSCCTRL_DPLLCTRLB_LTIME(0x0)| OSCCTRL_DPLLCTRLB_REFCLK(3) | OSCCTRL_DPLLCTRLB_DIV(3);
  
  
      OSCCTRL_REGS->DPLL[0].OSCCTRL_DPLLRATIO = OSCCTRL_DPLLRATIO_LDRFRAC(0) | OSCCTRL_DPLLRATIO_LDR(79);
  
      while((OSCCTRL_REGS->DPLL[0].OSCCTRL_DPLLSYNCBUSY & OSCCTRL_DPLLSYNCBUSY_DPLLRATIO_Msk) == OSCCTRL_DPLLSYNCBUSY_DPLLRATIO_Msk)
      {
          /* Waiting for the synchronization */
      }
  
      /* Enable DPLL */
      OSCCTRL_REGS->DPLL[0].OSCCTRL_DPLLCTRLA = OSCCTRL_DPLLCTRLA_ENABLE_Msk   ;
  
      while((OSCCTRL_REGS->DPLL[0].OSCCTRL_DPLLSYNCBUSY & OSCCTRL_DPLLSYNCBUSY_ENABLE_Msk) == OSCCTRL_DPLLSYNCBUSY_ENABLE_Msk )
      {
          /* Waiting for the DPLL enable synchronization */
      }
  
      while((OSCCTRL_REGS->DPLL[0].OSCCTRL_DPLLSTATUS & (OSCCTRL_DPLLSTATUS_LOCK_Msk | OSCCTRL_DPLLSTATUS_CLKRDY_Msk)) !=
                  (OSCCTRL_DPLLSTATUS_LOCK_Msk | OSCCTRL_DPLLSTATUS_CLKRDY_Msk))
      {
          /* Waiting for the Ready state */
      }
  }
  
  static void FDPLL1_Initialize(void)
  {
  
      /****************** DPLL1 Initialization  *********************************/
  
      /* Configure DPLL    */
      OSCCTRL_REGS->DPLL[1].OSCCTRL_DPLLCTRLB = OSCCTRL_DPLLCTRLB_FILTER(0) | OSCCTRL_DPLLCTRLB_LTIME(0x0)| OSCCTRL_DPLLCTRLB_REFCLK(3) | OSCCTRL_DPLLCTRLB_DIV(5);
  
  
      OSCCTRL_REGS->DPLL[1].OSCCTRL_DPLLRATIO = OSCCTRL_DPLLRATIO_LDRFRAC(0) | OSCCTRL_DPLLRATIO_LDR(99);
  
      while((OSCCTRL_REGS->DPLL[1].OSCCTRL_DPLLSYNCBUSY & OSCCTRL_DPLLSYNCBUSY_DPLLRATIO_Msk) == OSCCTRL_DPLLSYNCBUSY_DPLLRATIO_Msk)
      {
          /* Waiting for the synchronization */
      }
  
      /* Enable DPLL */
      OSCCTRL_REGS->DPLL[1].OSCCTRL_DPLLCTRLA = OSCCTRL_DPLLCTRLA_ENABLE_Msk   ;
  
      while((OSCCTRL_REGS->DPLL[1].OSCCTRL_DPLLSYNCBUSY & OSCCTRL_DPLLSYNCBUSY_ENABLE_Msk) == OSCCTRL_DPLLSYNCBUSY_ENABLE_Msk )
      {
          /* Waiting for the DPLL enable synchronization */
      }
  
      while((OSCCTRL_REGS->DPLL[1].OSCCTRL_DPLLSTATUS & (OSCCTRL_DPLLSTATUS_LOCK_Msk | OSCCTRL_DPLLSTATUS_CLKRDY_Msk)) !=
                  (OSCCTRL_DPLLSTATUS_LOCK_Msk | OSCCTRL_DPLLSTATUS_CLKRDY_Msk))
      {
          /* Waiting for the Ready state */
      }
  }
  
  static void DFLL_Initialize(void)
  {
      /****************** DFLL Initialization  *********************************/
      GCLK_REGS->GCLK_PCHCTRL[0] = GCLK_PCHCTRL_GEN(0x1)  | GCLK_PCHCTRL_CHEN_Msk;
      while ((GCLK_REGS->GCLK_PCHCTRL[0] & GCLK_PCHCTRL_CHEN_Msk) != GCLK_PCHCTRL_CHEN_Msk)
      {
          /* Wait for synchronization */
      }
  
      OSCCTRL_REGS->OSCCTRL_DFLLMUL = OSCCTRL_DFLLMUL_MUL(1500) | OSCCTRL_DFLLMUL_FSTEP(10) | OSCCTRL_DFLLMUL_CSTEP(10);
      while((OSCCTRL_REGS->OSCCTRL_DFLLSYNC & OSCCTRL_DFLLSYNC_DFLLMUL_Msk) == OSCCTRL_DFLLSYNC_DFLLMUL_Msk )
      {
          /* Waiting for the DPLL enable synchronization */
      }
  
      /* Configure DFLL    */
      OSCCTRL_REGS->OSCCTRL_DFLLCTRLB = OSCCTRL_DFLLCTRLB_MODE_Msk ;
  
      while((OSCCTRL_REGS->OSCCTRL_DFLLSYNC & OSCCTRL_DFLLSYNC_DFLLCTRLB_Msk) == OSCCTRL_DFLLSYNC_DFLLCTRLB_Msk )
      {
          /* Waiting for the DPLL enable synchronization */
      }
  
      OSCCTRL_REGS->OSCCTRL_DFLLCTRLA = OSCCTRL_DFLLCTRLA_ENABLE_Msk ;
  
      while((OSCCTRL_REGS->OSCCTRL_DFLLSYNC & OSCCTRL_DFLLSYNC_ENABLE_Msk) == OSCCTRL_DFLLSYNC_ENABLE_Msk )
      {
          /* Waiting for the DFLL enable synchronization */
      }
  
      while((OSCCTRL_REGS->OSCCTRL_STATUS & OSCCTRL_STATUS_DFLLRDY_Msk) != OSCCTRL_STATUS_DFLLRDY_Msk)
      {
          /* Waiting for the DFLL Ready state */
      }
  }
  
  
  static void GCLK0_Initialize(void)
  {
  
      /* selection of the CPU clock Division */
      MCLK_REGS->MCLK_CPUDIV = MCLK_CPUDIV_DIV(0x01);
  
      while((MCLK_REGS->MCLK_INTFLAG & MCLK_INTFLAG_CKRDY_Msk) != MCLK_INTFLAG_CKRDY_Msk)
      {
          /* Wait for the Main Clock to be Ready */
      }
      GCLK_REGS->GCLK_GENCTRL[0] = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_SRC(7) | GCLK_GENCTRL_GENEN_Msk;
  
      while((GCLK_REGS->GCLK_SYNCBUSY & GCLK_SYNCBUSY_GENCTRL_GCLK0) == GCLK_SYNCBUSY_GENCTRL_GCLK0)
      {
          /* wait for the Generator 0 synchronization */
      }
  }
  
  static void GCLK1_Initialize(void)
  {
      GCLK_REGS->GCLK_GENCTRL[1] = GCLK_GENCTRL_DIV(375) | GCLK_GENCTRL_SRC(1) | GCLK_GENCTRL_GENEN_Msk;
  
      while((GCLK_REGS->GCLK_SYNCBUSY & GCLK_SYNCBUSY_GENCTRL_GCLK1) == GCLK_SYNCBUSY_GENCTRL_GCLK1)
      {
          /* wait for the Generator 1 synchronization */
      }
  }
  
  static void GCLK2_Initialize(void)
  {
      GCLK_REGS->GCLK_GENCTRL[2] = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_SRC(6) | GCLK_GENCTRL_GENEN_Msk;
  
      while((GCLK_REGS->GCLK_SYNCBUSY & GCLK_SYNCBUSY_GENCTRL_GCLK2) == GCLK_SYNCBUSY_GENCTRL_GCLK2)
      {
          /* wait for the Generator 2 synchronization */
      }
  }
  
  static void GCLK3_Initialize(void)
  {
      GCLK_REGS->GCLK_GENCTRL[3] = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_SRC(8) | GCLK_GENCTRL_GENEN_Msk;
  
      while((GCLK_REGS->GCLK_SYNCBUSY & GCLK_SYNCBUSY_GENCTRL_GCLK3) == GCLK_SYNCBUSY_GENCTRL_GCLK3)
      {
          /* wait for the Generator 3 synchronization */
      }
  }
  
  static void GCLK4_Initialize(void)
  {
      GCLK_REGS->GCLK_GENCTRL[4] = GCLK_GENCTRL_DIV(48) | GCLK_GENCTRL_SRC(6) | GCLK_GENCTRL_GENEN_Msk;
  
      while((GCLK_REGS->GCLK_SYNCBUSY & GCLK_SYNCBUSY_GENCTRL_GCLK4) == GCLK_SYNCBUSY_GENCTRL_GCLK4)
      {
          /* wait for the Generator 4 synchronization */
      }
  }
  
  static void GCLK5_Initialize(void)
  {
      GCLK_REGS->GCLK_GENCTRL[5] = GCLK_GENCTRL_DIV(10) | GCLK_GENCTRL_SRC(7) | GCLK_GENCTRL_GENEN_Msk;
  
      while((GCLK_REGS->GCLK_SYNCBUSY & GCLK_SYNCBUSY_GENCTRL_GCLK5) == GCLK_SYNCBUSY_GENCTRL_GCLK5)
      {
          /* wait for the Generator 5 synchronization */
      }
  }
  
  void CLOCK_Initialize (void)
  {
      /* Function to Initialize the Oscillators */
      OSCCTRL_Initialize();
  
      /* Function to Initialize the 32KHz Oscillators */
      OSC32KCTRL_Initialize();
  
      FDPLL0_Initialize();
      FDPLL1_Initialize();
      GCLK1_Initialize();
      GCLK0_Initialize();
      GCLK5_Initialize();
      GCLK3_Initialize();
      DFLL_Initialize();
      GCLK2_Initialize();
      GCLK4_Initialize();
  
  
  
      /* Selection of the Generator and write Lock for OSCCTRL_FDPLL032K OSCCTRL_FDPLL132K SDHC0_SLOW SDHC1_SLOW SERCOM0_SLOW SERCOM1_SLOW SERCOM2_SLOW SERCOM3_SLOW SERCOM4_SLOW SERCOM5_SLOW SERCOM6_SLOW SERCOM7_SLOW */
      GCLK_REGS->GCLK_PCHCTRL[3] = GCLK_PCHCTRL_GEN(0x5)  | GCLK_PCHCTRL_CHEN_Msk;
  
      while ((GCLK_REGS->GCLK_PCHCTRL[3] & GCLK_PCHCTRL_CHEN_Msk) != GCLK_PCHCTRL_CHEN_Msk)
      {
          /* Wait for synchronization */
      }
      /* Selection of the Generator and write Lock for TC0 TC1 */
      GCLK_REGS->GCLK_PCHCTRL[9] = GCLK_PCHCTRL_GEN(0x3)  | GCLK_PCHCTRL_CHEN_Msk;
  
      while ((GCLK_REGS->GCLK_PCHCTRL[9] & GCLK_PCHCTRL_CHEN_Msk) != GCLK_PCHCTRL_CHEN_Msk)
      {
          /* Wait for synchronization */
      }
      /* Selection of the Generator and write Lock for USB */
      GCLK_REGS->GCLK_PCHCTRL[10] = GCLK_PCHCTRL_GEN(0x2)  | GCLK_PCHCTRL_CHEN_Msk;
  
      while ((GCLK_REGS->GCLK_PCHCTRL[10] & GCLK_PCHCTRL_CHEN_Msk) != GCLK_PCHCTRL_CHEN_Msk)
      {
          /* Wait for synchronization */
      }
      /* Selection of the Generator and write Lock for EVSYS_0 */
      GCLK_REGS->GCLK_PCHCTRL[11] = GCLK_PCHCTRL_GEN(0x0)  | GCLK_PCHCTRL_CHEN_Msk;
  
      while ((GCLK_REGS->GCLK_PCHCTRL[11] & GCLK_PCHCTRL_CHEN_Msk) != GCLK_PCHCTRL_CHEN_Msk)
      {
          /* Wait for synchronization */
      }
      /* Selection of the Generator and write Lock for CCL */
      GCLK_REGS->GCLK_PCHCTRL[33] = GCLK_PCHCTRL_GEN(0x0)  | GCLK_PCHCTRL_CHEN_Msk;
  
      while ((GCLK_REGS->GCLK_PCHCTRL[33] & GCLK_PCHCTRL_CHEN_Msk) != GCLK_PCHCTRL_CHEN_Msk)
      {
          /* Wait for synchronization */
      }
      /* Selection of the Generator and write Lock for SERCOM4_CORE */
      GCLK_REGS->GCLK_PCHCTRL[34] = GCLK_PCHCTRL_GEN(0x3)  | GCLK_PCHCTRL_CHEN_Msk;
  
      while ((GCLK_REGS->GCLK_PCHCTRL[34] & GCLK_PCHCTRL_CHEN_Msk) != GCLK_PCHCTRL_CHEN_Msk)
      {
          /* Wait for synchronization */
      }
      /* Selection of the Generator and write Lock for SDHC1 */
      GCLK_REGS->GCLK_PCHCTRL[46] = GCLK_PCHCTRL_GEN(0x3)  | GCLK_PCHCTRL_CHEN_Msk;
  
      while ((GCLK_REGS->GCLK_PCHCTRL[46] & GCLK_PCHCTRL_CHEN_Msk) != GCLK_PCHCTRL_CHEN_Msk)
      {
          /* Wait for synchronization */
      }
  
      /* Configure the AHB Bridge Clocks */
      MCLK_REGS->MCLK_AHBMASK = 0xffffff;
  
      /* Configure the APBA Bridge Clocks */
      MCLK_REGS->MCLK_APBAMASK = 0x47ff;
  
      /* Configure the APBB Bridge Clocks */
      MCLK_REGS->MCLK_APBBMASK = 0x180d7;
  
      /* Configure the APBC Bridge Clocks */
      MCLK_REGS->MCLK_APBCMASK = 0x6000;
  
      /* Configure the APBD Bridge Clocks */
      MCLK_REGS->MCLK_APBDMASK = 0x1;
  
  
  }
  