summaryrefslogtreecommitdiff
path: root/nuttx/arch/avr
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-10-18 21:57:10 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-10-18 21:57:10 +0000
commit6b14a91cd88971a396a87058baef463cc097e9fe (patch)
tree19832efae75f7a6afe5f303abe56c5a0e6c41f9e /nuttx/arch/avr
parent41c81d4f8390bc03048b919606cdbb510f4d9cac (diff)
downloadpx4-nuttx-6b14a91cd88971a396a87058baef463cc097e9fe.tar.gz
px4-nuttx-6b14a91cd88971a396a87058baef463cc097e9fe.tar.bz2
px4-nuttx-6b14a91cd88971a396a87058baef463cc097e9fe.zip
Finish clocking logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3040 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/avr')
-rw-r--r--nuttx/arch/avr/src/at91uc3/at91uc3_clkinit.c317
-rwxr-xr-xnuttx/arch/avr/src/at91uc3/at91uc3_flashc.h18
-rwxr-xr-xnuttx/arch/avr/src/at91uc3/at91uc3_pm.h12
3 files changed, 328 insertions, 19 deletions
diff --git a/nuttx/arch/avr/src/at91uc3/at91uc3_clkinit.c b/nuttx/arch/avr/src/at91uc3/at91uc3_clkinit.c
index 5fa707600..1252021e9 100644
--- a/nuttx/arch/avr/src/at91uc3/at91uc3_clkinit.c
+++ b/nuttx/arch/avr/src/at91uc3/at91uc3_clkinit.c
@@ -47,11 +47,24 @@
#include "up_internal.h"
#include "at91uc3_internal.h"
#include "at91uc3_pm.h"
+#include "at91uc3_flashc.h"
/**************************************************************************
* Private Definitions
**************************************************************************/
+#if defined(AVR32_CLOCK_OSC0) || \
+ (defined (AVR32_CLOCK_PLL0) && defined(AVR32_CLOCK_PLL0_OSC0)) || \
+ (defined (AVR32_CLOCK_PLL0) && defined(AVR32_CLOCK_PLL0_OSC0))
+# define NEED_OSC0
+#endif
+
+#if defined(AVR32_CLOCK_OSC1) || \
+ (defined (AVR32_CLOCK_PLL0) && defined(AVR32_CLOCK_PLL0_OSC1)) || \
+ (defined (AVR32_CLOCK_PLL1) && defined(AVR32_CLOCK_PLL0_OSC1))
+# define NEED_OSC1
+#endif
+
/**************************************************************************
* Private Types
**************************************************************************/
@@ -104,11 +117,11 @@ static inline void up_enableosc32(void)
* Name: up_enableosc0
*
* Description:
- * Initialiaze clock/PLL settings per the definitions in the board.h
- * file.
+ * Initialiaze OSC0 settings per the definitions in the board.h file.
*
**************************************************************************/
+#ifdef NEED_OSC0
static inline void up_enableosc0(void)
{
uint32_t regval;
@@ -128,7 +141,7 @@ static inline void up_enableosc0(void)
#endif
putreg32(regval, AVR32_PM_OSCCTRL0);
- /* Enable CLK 0 using the startup time provided in board.h. This startup time
+ /* Enable OSC0 using the startup time provided in board.h. This startup time
* is critical and depends on the characteristics of the crystal.
*/
@@ -143,17 +156,229 @@ static inline void up_enableosc0(void)
regval |= PM_MCCTRL_OSC0EN;
putreg32(regval, AVR32_PM_MCCTRL);
- /* Wait for CLK0 to be ready */
+ /* Wait for OSC0 to be ready */
while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_OSC0RDY) == 0);
}
+#endif
+
+/**************************************************************************
+ * Name: up_enableosc1
+ *
+ * Description:
+ * Initialiaze OSC0 settings per the definitions in the board.h file.
+ *
+ **************************************************************************/
+
+#ifdef NEED_OSC1
+static inline void up_enableosc1(void)
+{
+ uint32_t regval;
+
+ /* Enable OSC1 in the correct crystal mode by setting the mode value in OSCCTRL1 */
+
+ regval = getreg32(AVR32_PM_OSCCTRL1);
+ regval &= ~PM_OSCCTRL_MODE_MASK;
+#if AVR32_FOSC1 < 900000
+ regval |= PM_OSCCTRL_MODE_XTALp9; /* Crystal XIN 0.4-0.9MHz */
+#elif AVR32_FOSC1 < 3000000
+ regval |= PM_OSCCTRL_MODE_XTAL3; /* Crystal XIN 0.9-3.0MHz */
+#elif AVR32_FOSC1 < 8000000
+ regval |= PM_OSCCTRL_MODE_XTAL8; /* Crystal XIN 3.0-8.0MHz */
+#else
+ regval |= PM_OSCCTRL_MODE_XTALHI; /* Crystal XIN above 8.0MHz */
+#endif
+ putreg32(regval, AVR32_PM_OSCCTRL1);
+
+ /* Enable OSC1 using the startup time provided in board.h. This startup time
+ * is critical and depends on the characteristics of the crystal.
+ */
+
+ regval = getreg32(AVR32_PM_OSCCTRL1);
+ regval &= ~PM_OSCCTRL_STARTUP_MASK;
+ regval |= (AVR32_OSC1STARTUP << PM_OSCCTRL_STARTUP_SHIFT);
+ putreg32(regval, AVR32_PM_OSCCTRL1);
+
+ /* Enable OSC1 */
+
+ regval = getreg32(AVR32_PM_MCCTRL);
+ regval |= PM_MCCTRL_OSC1EN;
+ putreg32(regval, AVR32_PM_MCCTRL);
+
+ /* Wait for OSC1 to be ready */
+
+ while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_OSC1RDY) == 0);
+}
+#endif
+
+/**************************************************************************
+ * Name: up_enablepll0
+ *
+ * Description:
+ * Initialiaze PLL0 settings per the definitions in the board.h file.
+ *
+ **************************************************************************/
+
+#ifdef AVR32_CLOCK_PLL0
+static inline void up_enableosc1(void)
+{
+ /* Setup PLL0 */
+
+ regval = (AVR32_PLL0_DIV << PM_PLL_PLLDIV_SHIFT) | (AVR32_PLL0_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT)
+
+ /* Select PLL0/1 oscillator */
+
+#if AVR32_CLOCK_PLL_OSC1
+ regval |= PM_PLL_PLLOSC;
+#endif
+
+ putreg32(regval, AVR32_PM_PLL0);
+
+ /* Set PLL0 options */
+
+ regval = getreg32(AVR32_PM_PLL0);
+ regval &= ~PM_PLL_PLLOPT_MASK
+#if AVR32_PLL0_FREQ < 160000000
+ regval |= PM_PLL_PLLOPT_VCO;
+#endif
+#if AVR32_PLL0_DIV2 != 0
+ regval |= PM_PLL_PLLOPT_XTRADIV;
+#endif
+#if AVR32_PLL0_WBWM != 0
+ regval |= PM_PLL_PLLOPT_WBWDIS;
+#endif
+ putreg32(regval, AVR32_PM_PLL0)
+
+ /* Enable PLL0 */
+
+ regval = getreg32(AVR32_PM_PLL0);
+ regval |= PM_PLL_PLLEN;
+ putreg32(regval, AVR32_PM_PLL0)
+
+ /* Wait for PLL0 locked. */
+
+ while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_LOCK0) == 0);
+}
+#endif
+
+/**************************************************************************
+ * Name: up_enablepll1
+ *
+ * Description:
+ * Initialiaze PLL1 settings per the definitions in the board.h file.
+ *
+ **************************************************************************/
+
+#ifdef AVR32_CLOCK_PLL1
+static inline void up_enableosc1(void)
+{
+ /* Setup PLL1 */
+
+ regval = (AVR32_PLL1_DIV << PM_PLL_PLLDIV_SHIFT) | (AVR32_PLL1_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT)
+
+ /* Select PLL0/1 oscillator */
+
+#if AVR32_CLOCK_PLL_OSC1
+ regval |= PM_PLL_PLLOSC;
+#endif
+
+ putreg32(regval, AVR32_PM_PLL1);
+
+ /* Set PLL1 options */
+
+ regval = getreg32(AVR32_PM_PLL1);
+ regval &= ~PM_PLL_PLLOPT_MASK
+#if AVR32_PLL1_FREQ < 160000000
+ regval |= PM_PLL_PLLOPT_VCO;
+#endif
+#if AVR32_PLL1_DIV2 != 0
+ regval |= PM_PLL_PLLOPT_XTRADIV;
+#endif
+#if AVR32_PLL1_WBWM != 0
+ regval |= PM_PLL_PLLOPT_WBWDIS;
+#endif
+ putreg32(regval, AVR32_PM_PLL1)
+
+ /* Enable PLL1 */
+
+ regval = getreg32(AVR32_PM_PLL1);
+ regval |= PM_PLL_PLLEN;
+ putreg32(regval, AVR32_PM_PLL1)
+
+ /* Wait for PLL1 locked. */
+
+ while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_LOCK1) == 0);
+}
+#endif
+
+/**************************************************************************
+ * Name: up_clksel
+ *
+ * Description:
+ * Configure derived clocks.
+ *
+ **************************************************************************/
+
+static inline void up_clksel(void)
+{
+ uint32_t regval = 0;
+
+#if AVR32_CKSEL_CPUDIV != 0
+ regval |= PM_CKSEL_CPUDIV;
+ regval |= (AVR32_CKSEL_CPUDIV << PM_CKSEL_CPUSEL_SHIFT)
+#endif
+
+#if AVR32_CKSEL_HSBDIV != 0
+ regval |= PM_CKSEL_HSBDIV;
+ regval |= (AVR32_CKSEL_HSBDIV << PM_CKSEL_HSBSEL_SHIFT)
+#endif
+
+#if AVR32_CKSEL_PBADIV != 0
+ regval |= PM_CKSEL_PBADIV;
+ regval |= (AVR32_CKSEL_PBADIV << PM_CKSEL_PBASEL_SHIFT)
+#endif
+
+#if AVR32_CKSEL_PBBDIV != 0
+ regval |= PM_CKSEL_PBBDIV;
+ regval |= (AVR32_CKSEL_PBBDIV << PM_CKSEL_PBBSEL_SHIFT)
+#endif
+
+ putreg32(regval, AVR32_PM_CKSEL);
+
+ /* Wait for CLKRDY */
+
+ while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_CKRDY) == 0);
+}
+
+/**************************************************************************
+ * Name: up_fws
+ *
+ * Description:
+ * Setup FLASH wait states.
+ *
+ **************************************************************************/
+
+static void up_fws(uint32_t cpuclock)
+{
+ uint32_t regval;
+
+ regval = getreg32(AVR32_FLASHC_FCR);
+ if (cpuclock > AVR32_FLASHC_FWS0_MAXFREQ)
+ {
+ regval |= FLASHC_FCR_FWS;
+ }
+ else
+ {
+ regval &= ~FLASHC_FCR_FWS;
+ }
+ putreg32(regval, AVR32_FLASHC_FCR);
+}
/**************************************************************************
* Name: up_mainclk
*
* Description:
- * Initialiaze clock/PLL settings per the definitions in the board.h
- * file.
+ * Select the main clock.
*
**************************************************************************/
@@ -168,6 +393,41 @@ static inline void up_mainclk(uint32_t mcsel)
}
/**************************************************************************
+ * Name: up_usbclock
+ *
+ * Description:
+ * Setup the USBB GCLK.
+ *
+ **************************************************************************/
+
+#ifdef CONFIG_USBDEV
+static inline void up_usbclock(void)
+{
+ uint32_t regval = 0;
+
+#if defined(AVR32_CLOCK_USB_PLL0) || defined(AVR32_CLOCK_USB_PLL1)
+ regval |= PM_GCCTRL_PLLSEL;
+#endif
+#if defined(AVR32_CLOCK_USB_OSC1) || defined(AVR32_CLOCK_USB_PLL1)
+ regval |= PM_GCCTRL_OSCSEL;
+#endif
+#if AVR32_CLOCK_USB_DIV > 0
+
+
+ u_avr32_pm_gcctrl.GCCTRL.diven = diven;
+ u_avr32_pm_gcctrl.GCCTRL.div = div;
+#endif
+ putreg32(regval, AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB))
+
+ /* Enable USB GCLK */
+
+ regval = getreg32(AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB))
+ regval |= PM_GCCTRL_CEN;
+ putreg32(regval, AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB))
+}
+#endif
+
+/**************************************************************************
* Public Functions
**************************************************************************/
@@ -186,19 +446,54 @@ void up_clkinitialize(void)
up_enableosc32();
-#if defined(AVR32_CLOCK_OSC0)
+#ifdef NEED_OSC0
/* Enable OSC0 using the settings in board.h */
up_enableosc0();
+
+ /* Set up FLASH wait states */
+
+ up_fws(AVR32_FOSC0);
/* Then switch the main clock to OSC0 */
up_mainclk(PM_MCCTRL_MCSEL_OSC0);
+#endif
-#elif defined(AVR32_CLOCK_PLL0)
-# warning "Missing Logic"
-#else
-# error "No main clock"
+#ifdef NEED_OSC1
+ /* Enable OSC1 using the settings in board.h */
+
+ up_enableosc1();
+#endif
+
+#ifdef AVR32_CLOCK_PLL0
+ /* Enable PLL0 using the settings in board.h */
+
+ up_enablepll0();
+
+ /* Set up FLASH wait states */
+
+ up_fws(AVR32_CPU_CLOCK);
+
+ /* Then switch the main clock to PLL0 */
+
+ up_mainclk(PM_MCCTRL_MCSEL_PLL0);
+#endif
+
+#ifdef AVR32_CLOCK_PLL1
+ /* Enable PLL1 using the settings in board.h */
+
+ up_enablepll1();
+#endif
+
+ /* Configure derived clocks */
+
+ up_clksel();
+
+ /* Set up the USBB GCLK */
+
+#ifdef CONFIG_USBDEV
+ void up_usbclock();
#endif
}
diff --git a/nuttx/arch/avr/src/at91uc3/at91uc3_flashc.h b/nuttx/arch/avr/src/at91uc3/at91uc3_flashc.h
index bb9a252d4..1d0d41884 100755
--- a/nuttx/arch/avr/src/at91uc3/at91uc3_flashc.h
+++ b/nuttx/arch/avr/src/at91uc3/at91uc3_flashc.h
@@ -56,11 +56,11 @@
/* Register Addresses ***************************************************************/
-#define AVR32_FLASHC_FCR (AVR32_FLASHC_BASE+AVR32_FLASHC_FCR_OFFSET)
-#define AVR32_FLASHC_FCMD (AVR32_FLASHC_BASE+AVR32_FLASHC_FCMD_OFFSET)
-#define AVR32_FLASHC_FSR (AVR32_FLASHC_BASE+AVR32_FLASHC_FSR_OFFSET)
-#define AVR32_FLASHC_FGPFRHI (AVR32_FLASHC_BASE+AVR32_FLASHC_FGPFRHI_OFFSET)
-#define AVR32_FLASHC_FGPFRLO (AVR32_FLASHC_BASE+AVR32_FLASHC_FGPFRLO_OFFSET)
+#define AVR32_FLASHC_FCR (AVR32_HFLASHC_BASE+AVR32_FLASHC_FCR_OFFSET)
+#define AVR32_FLASHC_FCMD (AVR32_HFLASHC_BASE+AVR32_FLASHC_FCMD_OFFSET)
+#define AVR32_FLASHC_FSR (AVR32_HFLASHC_BASE+AVR32_FLASHC_FSR_OFFSET)
+#define AVR32_FLASHC_FGPFRHI (AVR32_HFLASHC_BASE+AVR32_FLASHC_FGPFRHI_OFFSET)
+#define AVR32_FLASHC_FGPFRLO (AVR32_HFLASHC_BASE+AVR32_FLASHC_FGPFRLO_OFFSET)
/* Register Bit-field Definitions ***************************************************/
@@ -73,7 +73,6 @@
/* Flash Command Register */
-
#define FLASHC_FCMD_CMD_SHIFT (0) /* Bits 0-5: Command */
#define FLASHC_FCMD_CMD_MASK (0x3f << FLASHC_FCMD_CMD_SHIFT)
#define FLASHC_FCMD_PAGEN_SHIFT (8) /* Bits 8-23: Page number */
@@ -207,6 +206,13 @@
#define FLASH_CMD_EUP 14 /* Erase User Page */
#define FLASH_CMD_QPRUP 15 /* Quick Page Read User Page */
+/* Other constants ******************************************************************/
+
+/* Maximum CPU frequency for 0 and 1 FLASH wait states */
+
+#define AVR32_FLASHC_FWS0_MAXFREQ 33000000
+#define AVR32_FLASHC_FWS1_MAXFREQ 66000000
+
/************************************************************************************
* Public Types
************************************************************************************/
diff --git a/nuttx/arch/avr/src/at91uc3/at91uc3_pm.h b/nuttx/arch/avr/src/at91uc3/at91uc3_pm.h
index 20007dedb..ddb73c07a 100755
--- a/nuttx/arch/avr/src/at91uc3/at91uc3_pm.h
+++ b/nuttx/arch/avr/src/at91uc3/at91uc3_pm.h
@@ -65,7 +65,7 @@
#define AVR32_PM_ISR_OFFSET 0x004c /* Interrupt Status Register */
#define AVR32_PM_ICR_OFFSET 0x0050 /* Interrupt Clear Register */
#define AVR32_PM_POSCSR_OFFSET 0x0054 /* Power and Oscillators Status Register */
-#define AVR32_PM_GCCTRL_OFFSET 0x0060 /* 0x0060-0x070 Generic Clock Control Register */
+#define AVR32_PM_GCCTRL_OFFSET(n) (0x0060+((n)<<2)) /* 0x0060-0x070 Generic Clock Control Register */
#define AVR32_PM_RCCR_OFFSET 0x00c0 /* RC Oscillator Calibration Register */
#define AVR32_PM_BGCR_OFFSET 0x00c4 /* Bandgap Calibration Register */
#define AVR32_PM_VREGCR_OFFSET 0x00c8 /* Linear Regulator Calibration Register */
@@ -94,7 +94,7 @@
#define AVR32_PM_ISR (AVR32_PM_BASE+AVR32_PM_ISR_OFFSET)
#define AVR32_PM_ICR (AVR32_PM_BASE+AVR32_PM_ICR_OFFSET)
#define AVR32_PM_POSCSR (AVR32_PM_BASE+AVR32_PM_POSCSR_OFFSET)
-#define AVR32_PM_GCCTRL (AVR32_PM_BASE+AVR32_PM_GCCTRL_OFFSET)
+#define AVR32_PM_GCCTRL(n) (AVR32_PM_BASE+AVR32_PM_GCCTRL_OFFSET(n))
#define AVR32_PM_RCCR (AVR32_PM_BASE+AVR32_PM_RCCR_OFFSET)
#define AVR32_PM_BGCR (AVR32_PM_BASE+AVR32_PM_BGCR_OFFSET)
#define AVR32_PM_VREGCR (AVR32_PM_BASE+AVR32_PM_VREGCR_OFFSET)
@@ -311,6 +311,14 @@
/* These registers contain a 32-bit value with no smaller bit-field */
+/* GCLK Allocation ******************************************************************/
+
+#define AVR32_PM_GCLK0 (0) /* GCLK0 pin */
+#define AVR32_PM_GCLK1 (1) /* GCLK2 pin */
+#define AVR32_PM_GCLK2 (2) /* GCLK2 pin */
+#define AVR32_PM_GCLK_USBB (3) /* USBB */
+#define AVR32_PM_GCLK_ABDAC (4) /* ABDAC */
+
/************************************************************************************
* Public Types
************************************************************************************/