From 54f8371b39d29fdd88ba5b8a762b6bb3416c542a Mon Sep 17 00:00:00 2001
From: Thibaut VIARD <thibaut.viard@atmel.com>
Date: Thu, 8 May 2014 23:30:37 +0200
Subject: [PATCH]  Clocks inits checkpoint

---
 cores/arduino/main.cpp  |  11 ----
 cores/arduino/startup.c | 121 ++++++++++++++++++++++++++++++++--------
 cores/arduino/wiring.c  |   8 +--
 3 files changed, 103 insertions(+), 37 deletions(-)

diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp
index 0efdb70d..ae1eee26 100644
--- a/cores/arduino/main.cpp
+++ b/cores/arduino/main.cpp
@@ -20,17 +20,6 @@
 #define ARDUINO_MAIN
 #include "Arduino.h"
 
-/*
- * Cortex-M3 Systick IT handler
- */
-/*
-extern void SysTick_Handler( void )
-{
-  // Increment tick count each ms
-  TimeTick_Increment() ;
-}
-*/
-
 /*
  * \brief Main entry point of Arduino application
  */
diff --git a/cores/arduino/startup.c b/cores/arduino/startup.c
index 811e975a..d640f3ff 100644
--- a/cores/arduino/startup.c
+++ b/cores/arduino/startup.c
@@ -169,7 +169,8 @@ const DeviceVectors exception_table=
  * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference)
  * 4) Enable DFLL48M clock
  * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz.
- * 6) Put OSC8M as source for Generic Clock Generator 3
+ * 6) Modify PRESCaler value of OSCM to have 8MHz
+ * 7) Put OSC8M as source for Generic Clock Generator 3
  */
 // Constants for Clock generators
 #define GENERIC_CLOCK_GENERATOR_MAIN      (0u)
@@ -221,8 +222,10 @@ void SystemInit( void )
   }
 
   /* Write Generic Clock Generator 1 configuration */
+  *((uint8_t *) &GCLK->GENCTRL) = GENERIC_CLOCK_GENERATOR_XOSC32K ;
   GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1
                       GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator
+                      GCLK_GENCTRL_OE |
                       GCLK_GENCTRL_GENEN ;
 
   while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
@@ -248,37 +251,60 @@ void SystemInit( void )
 
   /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */
 
-  /* Enable the generic clock */
-  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( SYSCTRL_GCLK_ID_DFLL48 ) |
-                      GCLK_CLKCTRL_CLKEN ;
+  /* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */
+  SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0 ;
 
-  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
+  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
   {
     /* Wait for synchronization */
   }
 
-  /* DFLL Enable (Closed Loop) */
-  SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0 ; /* Remove the OnDemand mode,  */
+#if 0
+  SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value
+                         SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value
+                         SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK/VARIANT_MAINOSC) ) ; // External 32KHz is the reference
+#else
+  SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 10 ) | // Coarse step is 31, half of the max value
+                         SYSCTRL_DFLLMUL_FSTEP( 10 ) | // Fine step is 511, half of the max value
+                         SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK/VARIANT_MAINOSC) ) ; // External 32KHz is the reference
+#endif
 
   while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
   {
     /* Wait for synchronization */
   }
 
-  SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value
-                         SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value
-                         SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK/VARIANT_MAINOSC) ) ; // External 32KHz is the reference
-
   /* Write full configuration to DFLL control register */
-  SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */
+#if 0
+  SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */
                           SYSCTRL_DFLLCTRL_QLDIS | /* Disable Quick lock */
-                          SYSCTRL_DFLLCTRL_ENABLE ;
+                          SYSCTRL_DFLLCTRL_CCDIS ; /* Disable Chill Cycle */
+#else
+  SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */
+                           SYSCTRL_DFLLCTRL_QLDIS ; /* Disable Quick lock */
+#endif
 
   while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
   {
     /* Wait for synchronization */
   }
 
+  /* Enable the DFLL */
+  SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE ;
+
+  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
+  {
+    /* Wait for synchronization */
+  }
+
+#if 0
+  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) == 0 ||
+          (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF) == 0 )
+  {
+    /* Wait for locks flags */
+  }
+#endif
+
   /*
    * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz.
    */
@@ -292,6 +318,8 @@ void SystemInit( void )
   /* Write Generic Clock Generator 0 configuration */
   GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0
                       GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz
+                      GCLK_GENCTRL_OE |
+                      GCLK_GENCTRL_IDC | // Set 50/50 duty cycle
                       GCLK_GENCTRL_GENEN ;
 
   while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
@@ -299,16 +327,29 @@ void SystemInit( void )
     /* Wait for synchronization */
   }
 
-#if 0
+#if 1
   /*
-   * 6) Put OSC8M as source for Generic Clock Generator 3
+   * 6) Modify PRESCaler value of OSC8M to have 8MHz
    */
-  GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) ; // Generic Clock Generator 3
+  SYSCTRL->OSC8M.bit.PRESC = SYSCTRL_OSC8M_PRESC_0_Val ;
+  SYSCTRL->OSC8M.bit.ONDEMAND = 0 ;
 
-  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
+/*
+  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY) == 0 )
   {
-    /* Wait for synchronization */
+    /* Wait for synchronization
   }
+*/
+
+  /*
+   * 7) Put OSC8M as source for Generic Clock Generator 3
+   */
+  GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) ; // Generic Clock Generator 3
+
+  //while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
+  //{
+    ///* Wait for synchronization */
+  //}
 
   /* Write Generic Clock Generator 3 configuration */
   GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3
@@ -325,10 +366,10 @@ void SystemInit( void )
    * Now that all system clocks are configured, we can set CPU and APBx BUS clocks.
    * There values are normally the one present after Reset.
    */
-  //PM->CPUSEL.reg  = PM_CPUSEL_CPUDIV_DIV1 ;
-  //PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val ;
-  //PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val ;
-  //PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val ;
+  PM->CPUSEL.reg  = PM_CPUSEL_CPUDIV_DIV1 ;
+  PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val ;
+  PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val ;
+  PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val ;
 
   SystemCoreClock=VARIANT_MCK ;
 }
@@ -385,3 +426,39 @@ void Dummy_Handler( void )
   {
   }
 }
+
+#if 0
+GCLK->GENDIV.reg = GCLK_GENDIV_ID(O) | GCLK_GENDIV_DIV(O); // No div since RC8M is at 1MHz by default
+while (GCLK->STATUS.bit.SYNCBUSY);
+GCLK->GENCTRL.reg = ( GCLK_GENCTRL_ID(O) | GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSC8M_Val) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_IDC | GCLK_GENCTRL_OE ) & (~GCLK_GENCTRL_OOV);
+while (GCLK->STATUS.bit.SYNCBUSY);
+
+//-------------------------- EXAMPLE -------------------------------------------
+
+#define DFLLREF32K_GENERATOR_GCLK_ID 		2
+void init_dfll_on_xosc32k(void)
+{
+  // Setup generator on XOSC32K
+  gclk_gen_setup(DFLLREF32K_GENERATOR_GCLK_ID,GCLK_SOURCE_XOSC32K,1);
+  gclk_gen_output_conf(DFLLREF32K_GENERATOR_GCLK_ID,false,0);
+  gclk_setup(SYSCTRL_GCLK_ID_DFLL48,DFLLREF32K_GENERATOR_GCLK_ID,0);
+
+  //Use DFLL @ 48MHz
+  SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0;   // Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905
+  while((SYSCTRL->PCLKSR.reg&SYSCTRL_PCLKSR_DFLLRDY)==0);
+
+  SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_MUL(1465)|SYSCTRL_DFLLMUL_FSTEP(10)|SYSCTRL_DFLLMUL_CSTEP(10);
+  while((SYSCTRL->PCLKSR.reg&SYSCTRL_PCLKSR_DFLLRDY)==0);
+
+  SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_CCDIS|SYSCTRL_DFLLCTRL_QLDIS|SYSCTRL_DFLLCTRL_MODE;
+  while((SYSCTRL->PCLKSR.reg&SYSCTRL_PCLKSR_DFLLRDY)==0);
+
+  //SYSCTRL->DFLLCTRL.reg |=  SYSCTRL_DFLLCTRL_ENABLE | SYSCTRL_DFLLCTRL_RUNSTDBY;
+  SYSCTRL->DFLLCTRL.reg |=  SYSCTRL_DFLLCTRL_ENABLE;
+  while((SYSCTRL->PCLKSR.reg&SYSCTRL_PCLKSR_DFLLRDY)==0);
+
+  // Wait for locks flags .
+  while((SYSCTRL->PCLKSR.reg&SYSCTRL_PCLKSR_DFLLLCKC)==0 || (SYSCTRL->PCLKSR.reg&SYSCTRL_PCLKSR_DFLLLCKF)==0);
+
+}
+#endif
diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c
index 02e193f8..693f1924 100644
--- a/cores/arduino/wiring.c
+++ b/cores/arduino/wiring.c
@@ -52,10 +52,10 @@ void init( void )
   }
 
   // Clock PORT for Digital I/O
-	PM->APBBMASK.reg |= PM_APBBMASK_PORT ;
-
-  // Clock EIC for I/O interrupts
-	PM->APBAMASK.reg |= PM_APBAMASK_EIC ;
+//	PM->APBBMASK.reg |= PM_APBBMASK_PORT ;
+//
+//  // Clock EIC for I/O interrupts
+//	PM->APBAMASK.reg |= PM_APBAMASK_EIC ;
 
   // Clock SERCOM for Serial
 	PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 | PM_APBCMASK_SERCOM1 | PM_APBCMASK_SERCOM2 | PM_APBCMASK_SERCOM3 | PM_APBCMASK_SERCOM4 | PM_APBCMASK_SERCOM5 ;
-- 
GitLab