aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms/SAM4L
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/platforms/SAM4L')
-rw-r--r--os/hal/platforms/SAM4L/hal_lld.c17
-rw-r--r--os/hal/platforms/SAM4L/hal_lld.h257
2 files changed, 274 insertions, 0 deletions
diff --git a/os/hal/platforms/SAM4L/hal_lld.c b/os/hal/platforms/SAM4L/hal_lld.c
index 608fb6fe7..69e408bec 100644
--- a/os/hal/platforms/SAM4L/hal_lld.c
+++ b/os/hal/platforms/SAM4L/hal_lld.c
@@ -121,6 +121,23 @@ void sam_clock_init(void) {
SAM_PM_UNLOCK((uint32_t)&PM->PM_PBDSEL);
PM->PM_PBDSEL = SAM_PBDSEL;
+ /* Switching to the selected clock source, enabling it if necessary.*/
+#if SAM_MCCTRL_MCSEL == SAM_MCSEL_RCSYS
+ /* Nothing to do, already running from SYSIRC.*/
+#endif
+#if SAM_MCCTRL_MCSEL == SAM_MCSEL_OSC0
+#endif
+#if SAM_MCCTRL_MCSEL == SAM_MCSEL_PLL
+#endif
+#if SAM_MCCTRL_MCSEL == SAM_MCSEL_DFLL
+#endif
+#if SAM_MCCTRL_MCSEL == SAM_MCSEL_RC80M
+#endif
+#if SAM_MCCTRL_MCSEL == SAM_MCSEL_RCFAST
+#endif
+#if SAM_MCCTRL_MCSEL == SAM_MCSEL_RC1M
+#endif
+
#endif /* SAM_NO_INIT */
}
diff --git a/os/hal/platforms/SAM4L/hal_lld.h b/os/hal/platforms/SAM4L/hal_lld.h
index fe4b7230f..82c2446ef 100644
--- a/os/hal/platforms/SAM4L/hal_lld.h
+++ b/os/hal/platforms/SAM4L/hal_lld.h
@@ -21,6 +21,13 @@
/**
* @file templates/hal_lld.h
* @brief HAL subsystem low level driver header template.
+ * @pre This module requires the following macros to be defined in the
+ * @p board.h file:
+ * - SAM_OSC32K_CLK.
+ * - SAM_OSC32K_MODE_EXT (optional)
+ * - SAM_OSC0_CLK.
+ * - SAM_OSC0_MODE_EXT (optional)
+ * .
*
* @addtogroup HAL
* @{
@@ -46,6 +53,19 @@
#define PLATFORM_NAME "SAM4L Series"
/**
+ * @name Internal clock sources
+ * @{
+ */
+#define SAM_RC32K_CLK 32768
+#define SAM_RCSYS_CLK 115000
+#define SAM_RC1M_CLK 1000000
+#define SAM_RCFAST0_CLK 4000000
+#define SAM_RCFAST1_CLK 8000000
+#define SAM_RCFAST2_CLK 12000000
+#define SAM_RC80M_CLK 80000000
+/** @} */
+
+/**
* @name BUS IDs
* @{
*/
@@ -185,6 +205,23 @@
#define SAM_PBDIV (1 << 7) /**< PBDIV bit. */
/** @} */
+/**
+ * @name RCFASTCFG registers bits definitions
+ * @{
+ */
+#define SAM_RCFASTCFG_FRANGE_4M 0x00000000
+#define SAM_RCFASTCFG_FRANGE_8M 0x00000100
+#define SAM_RCFASTCFG_FRANGE_12M 0x00000200
+/** @} */
+
+/**
+ * @name PMCON registers bits definitions
+ * @{
+ */
+#define SAM_PMCON_PS0 (0 << 0)
+#define SAM_PMCON_PS1 (1 << 0)
+/** @} */
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -201,6 +238,13 @@
#endif
/**
+ * @brief Power mode.
+ */
+#if !defined(SAM_PMCON_PS) || defined(__DOXYGEN__)
+#define SAM_PMCON_PS SAM_PMCON_PS0
+#endif
+
+/**
* @brief MCCTRL register settings.
*/
#if !defined(SAM_MCCTRL_MCSEL) || defined(__DOXYGEN__)
@@ -242,12 +286,225 @@
#define SAM_PBDSEL SAM_PBSEL_DIV1
#endif
+/**
+ * @brief PBDSEL register settings.
+ */
+#if !defined(SAM_PBDSEL) || defined(__DOXYGEN__)
+#define SAM_RCFAST_FRANGE SAM_RCFASTCFG_FRANGE_4M
+#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
+/**
+ * @name Clock limits depending on power scaling mode
+ * @{
+ */
+#if (SAM_PMCON_PS == SAM_PMCON_PS0)|| defined(__DOXYGEN__)
+#define SAM_CPUCLK_MAX 50000000
+#define SAM_PBACLK_MAX 50000000
+#define SAM_PBBCLK_MAX 50000000
+#define SAM_PBCCLK_MAX 50000000
+#define SAM_PBDCLK_MAX 50000000
+
+#elif SAM_PMCON_PS == SAM_PMCON_PS1
+#define SAM_CPUCLK_MAX 12000000
+#define SAM_PBACLK_MAX 12000000
+#define SAM_PBBCLK_MAX 12000000
+#define SAM_PBCCLK_MAX 12000000
+#define SAM_PBDCLK_MAX 12000000
+
+#else
+#error "invalid SAM_PMCON_PS value specified"
+#endif
+/** @} */
+
+/**
+ * @brief Selected RCFAST clock frequency.
+ */
+#if (SAM_RCFAST_FRANGE == SAM_RCFASTCFG_FRANGE_4M)|| defined(__DOXYGEN__)
+#define SAM_RCFAST_CLK SAM_RCFAST0_CLK
+#elif SAM_RCFAST_FRANGE == SAM_RCFASTCFG_FRANGE_8M
+#define SAM_RCFAST_CLK SAM_RCFAST1_CLK
+#elif SAM_RCFAST_FRANGE == SAM_RCFASTCFG_FRANGE_12M
+#define SAM_RCFAST_CLK SAM_RCFAST2_CLK
+#else
+#error "invalid SAM_RCFAST_FRANGE value specified"
+#endif
+
+/**
+ * @brief Selected main clock frequency.
+ */
+#if (SAM_MCCTRL_MCSEL == SAM_MCSEL_RCSYS) || defined(__DOXYGEN__)
+#define SAM_MAIN_CLK SAM_RCSYS_CLK
+#elif SAM_MCCTRL_MCSEL == SAM_MCSEL_OSC0
+#define SAM_MAIN_CLK SAM_OSC0_CLK
+#elif SAM_MCCTRL_MCSEL == SAM_MCSEL_PLL
+#define SAM_MAIN_CLK 0
+#elif SAM_MCCTRL_MCSEL == SAM_MCSEL_DFLL
+#define SAM_MAIN_CLK 0
+#elif SAM_MCCTRL_MCSEL == SAM_MCSEL_RC80M
+#define SAM_MAIN_CLK SAM_RC80M_CLK
+#elif SAM_MCCTRL_MCSEL == SAM_MCSEL_RCFAST
+#define SAM_MAIN_CLK SAM_RCFAST_CLK
+#elif SAM_MCCTRL_MCSEL == SAM_MCSEL_RC1M
+#define SAM_MAIN_CLK SAM_RC1M_CLK
+#else
+#error "invalid SAM_MCCTRL_MCSEL value specified"
+#endif
+
+/**
+ * @brief CPU clock.
+ */
+#if (SAM_CPUSEL == SAM_CPUSEL_DIV1) || defined(__DOXYGEN__)
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 1)
+#elif SAM_CPUSEL == SAM_CPUSEL_DIV2
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 2)
+#elif SAM_CPUSEL == SAM_CPUSEL_DIV4
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 4)
+#elif SAM_CPUSEL == SAM_CPUSEL_DIV8
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 8)
+#elif SAM_CPUSEL == SAM_CPUSEL_DIV16
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 16)
+#elif SAM_CPUSEL == SAM_CPUSEL_DIV32
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 32)
+#elif SAM_CPUSEL == SAM_CPUSEL_DIV64
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 64)
+#elif SAM_CPUSEL == SAM_CPUSEL_DIV128
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 128)
+#elif SAM_CPUSEL == SAM_CPUSEL_DIV256
+#define SAM_CPU_CLK (SAM_MAIN_CLK / 256)
+#else
+#error "invalid SAM_CPUSEL value specified"
+#endif
+
+/* CPU clock check.*/
+#if SAM_CPU_CLK > SAM_CPUCLK_MAX
+#error "SAM_CPU_CLK above maximum rated frequency (SAM_CPUCLK_MAX)"
+#endif
+
+/**
+ * @brief PBA clock.
+ */
+#if (SAM_PBASEL == SAM_PBASEL_DIV1) || defined(__DOXYGEN__)
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 1)
+#elif SAM_PBASEL == SAM_PBASEL_DIV2
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 2)
+#elif SAM_PBASEL == SAM_PBASEL_DIV4
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 4)
+#elif SAM_PBASEL == SAM_PBASEL_DIV8
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 8)
+#elif SAM_PBASEL == SAM_PBASEL_DIV16
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 16)
+#elif SAM_PBASEL == SAM_PBASEL_DIV32
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 32)
+#elif SAM_PBASEL == SAM_PBASEL_DIV64
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 64)
+#elif SAM_PBASEL == SAM_PBASEL_DIV128
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 128)
+#elif SAM_PBASEL == SAM_PBASEL_DIV256
+#define SAM_PBA_CLK (SAM_MAIN_CLK / 256)
+#else
+#error "invalid SAM_PBASEL value specified"
+#endif
+
+/* PBA clock check.*/
+#if SAM_PBA_CLK > SAM_PBACLK_MAX
+#error "SAM_PBA_CLK above maximum rated frequency (SAM_PBACLK_MAX)"
+#endif
+
+/**
+ * @brief PBB clock.
+ */
+#if (SAM_PBBSEL == SAM_PBBSEL_DIV1) || defined(__DOXYGEN__)
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 1)
+#elif SAM_PBBSEL == SAM_PBBSEL_DIV2
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 2)
+#elif SAM_PBBSEL == SAM_PBBSEL_DIV4
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 4)
+#elif SAM_PBBSEL == SAM_PBBSEL_DIV8
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 8)
+#elif SAM_PBBSEL == SAM_PBBSEL_DIV16
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 16)
+#elif SAM_PBBSEL == SAM_PBBSEL_DIV32
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 32)
+#elif SAM_PBBSEL == SAM_PBBSEL_DIV64
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 64)
+#elif SAM_PBBSEL == SAM_PBBSEL_DIV128
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 128)
+#elif SAM_PBBSEL == SAM_PBBSEL_DIV256
+#define SAM_PBB_CLK (SAM_MAIN_CLK / 256)
+#else
+#error "invalid SAM_PBBSEL value specified"
+#endif
+
+/* PBB clock check.*/
+#if SAM_PBB_CLK > SAM_PBBCLK_MAX
+#error "SAM_PBB_CLK above maximum rated frequency (SAM_PBBCLK_MAX)"
+#endif
+
+/**
+ * @brief PBC clock.
+ */
+#if (SAM_PBCSEL == SAM_PBCSEL_DIV1) || defined(__DOXYGEN__)
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 1)
+#elif SAM_PBCSEL == SAM_PBCSEL_DIV2
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 2)
+#elif SAM_PBCSEL == SAM_PBCSEL_DIV4
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 4)
+#elif SAM_PBCSEL == SAM_PBCSEL_DIV8
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 8)
+#elif SAM_PBCSEL == SAM_PBCSEL_DIV16
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 16)
+#elif SAM_PBCSEL == SAM_PBCSEL_DIV32
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 32)
+#elif SAM_PBCSEL == SAM_PBCSEL_DIV64
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 64)
+#elif SAM_PBCSEL == SAM_PBCSEL_DIV128
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 128)
+#elif SAM_PBCSEL == SAM_PBCSEL_DIV256
+#define SAM_PBC_CLK (SAM_MAIN_CLK / 256)
+#else
+#error "invalid SAM_PBCSEL value specified"
+#endif
+
+/* PBC clock check.*/
+#if SAM_PBC_CLK > SAM_PBCCLK_MAX
+#error "SAM_PBC_CLK above maximum rated frequency (SAM_PBCCLK_MAX)"
+#endif
+
+/**
+ * @brief PBD clock.
+ */
+#if (SAM_PBDSEL == SAM_PBDSEL_DIV1) || defined(__DOXYGEN__)
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 1)
+#elif SAM_PBDSEL == SAM_PBDSEL_DIV2
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 2)
+#elif SAM_PBDSEL == SAM_PBDSEL_DIV4
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 4)
+#elif SAM_PBDSEL == SAM_PBDSEL_DIV8
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 8)
+#elif SAM_PBDSEL == SAM_PBDSEL_DIV16
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 16)
+#elif SAM_PBDSEL == SAM_PBDSEL_DIV32
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 32)
+#elif SAM_PBDSEL == SAM_PBDSEL_DIV64
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 64)
+#elif SAM_PBDSEL == SAM_PBDSEL_DIV128
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 128)
+#elif SAM_PBDSEL == SAM_PBDSEL_DIV256
+#define SAM_PBD_CLK (SAM_MAIN_CLK / 256)
+#else
+#error "invalid SAM_PBDSEL value specified"
+#endif
+
+/* PBD clock check.*/
+#if SAM_PBD_CLK > SAM_PBDCLK_MAX
+#error "SAM_PBD_CLK above maximum rated frequency (SAM_PBDCLK_MAX)"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/