summaryrefslogtreecommitdiff
path: root/c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c')
-rw-r--r--c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c b/c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c
new file mode 100644
index 0000000000..6b6ef9e769
--- /dev/null
+++ b/c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c
@@ -0,0 +1,124 @@
+/**
+ * @file
+ *
+ * @ingroup lpc176x_clocks
+ *
+ * @brief System clocks.
+ */
+
+/*
+ * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/system-clocks.h>
+
+/**
+ * @brief Internal RC oscillator frequency in [Hz].
+ */
+#define LPC176X_OSCILLATOR_INTERNAL 4000000u
+
+#ifndef LPC176X_OSCILLATOR_MAIN
+#error "unknown main oscillator frequency"
+#endif
+
+#ifndef LPC176X_OSCILLATOR_RTC
+#error "unknown RTC oscillator frequency"
+#endif
+
+inline unsigned lpc176x_sysclk( void );
+
+void lpc176x_timer_initialize( void )
+{
+ /* Reset timer */
+ LPC176X_T1TCR = TCR_RST;
+ /* Set timer mode */
+ LPC176X_T1CTCR = 0u;
+ /* Set prescaler to zero */
+ LPC176X_T1PR = 0u;
+ /* Reset all interrupt flags */
+ LPC176X_T1IR = 0xffU;
+ /* Do not stop on a match */
+ LPC176X_T1MCR = 0u;
+ /* No captures */
+ LPC176X_T1CCR = 0u;
+ /* Start timer */
+ LPC176X_T1TCR = TCR_EN;
+}
+
+void lpc176x_micro_seconds_delay( const unsigned us )
+{
+ const unsigned start = lpc176x_get_timer1();
+ const unsigned delay = us * ( LPC176X_PCLK / 1000000u );
+ unsigned elapsed = 0u;
+
+ do {
+ elapsed = lpc176x_get_timer1() - start;
+ } while ( elapsed < delay );
+}
+
+unsigned lpc176x_sysclk( void )
+{
+ return ( LPC176X_SCB.clksrcsel & LPC176X_SCB_CLKSRCSEL_CLKSRC ) != 0u ?
+ LPC176X_OSCILLATOR_MAIN : LPC176X_OSCILLATOR_INTERNAL;
+}
+
+unsigned lpc176x_pllclk( void )
+{
+ const unsigned sysclk = lpc176x_sysclk();
+ const unsigned pllstat = ( LPC176X_SCB.pll_0 ).stat;
+ const unsigned enabled_and_locked = LPC176X_PLL_STAT_PLLE |
+ LPC176X_PLL_STAT_PLOCK;
+ unsigned pllclk = 0u;
+
+ if ( ( pllstat & enabled_and_locked ) == enabled_and_locked ) {
+ unsigned m = LPC176X_PLL_SEL_MSEL_GET( pllstat ) + 1u;
+ pllclk = sysclk * m;
+ }
+
+ /* else implies that the pllstat is unlocked. Also,
+ there is nothing to do. */
+
+ return pllclk;
+}
+
+unsigned lpc176x_cclk( void )
+{
+ const unsigned cclksel = LPC176X_SCB.cclksel;
+ unsigned cclk_in = 0u;
+ unsigned cclk = 0u;
+
+ if ( ( cclksel & LPC176X_SCB_CCLKSEL_CCLKSEL ) != 0u ) {
+ cclk_in = lpc176x_pllclk();
+ } else {
+ cclk_in = lpc176x_sysclk();
+ }
+
+ cclk = cclk_in / LPC176X_SCB_CCLKSEL_CCLKDIV_GET( cclksel );
+
+ return cclk;
+}
+
+CPU_Counter_ticks _CPU_Counter_read( void )
+{
+ return lpc176x_get_timer1();
+}
+
+inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+