summaryrefslogtreecommitdiffstats
path: root/bsps/arm/lpc32xx
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:55:15 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:44 +0200
commit4fb1b79a804ca8de866be0ef718e54e1f62fa3ec (patch)
tree11b85c98244db22c927e7f1323ed222c43a589b0 /bsps/arm/lpc32xx
parentbsps: Move legacy network drivers to bsps (diff)
downloadrtems-4fb1b79a804ca8de866be0ef718e54e1f62fa3ec.tar.bz2
bsps: Move RTC drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps/arm/lpc32xx')
-rw-r--r--bsps/arm/lpc32xx/rtc/rtc-config.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/bsps/arm/lpc32xx/rtc/rtc-config.c b/bsps/arm/lpc32xx/rtc/rtc-config.c
new file mode 100644
index 0000000000..bd225248b3
--- /dev/null
+++ b/bsps/arm/lpc32xx/rtc/rtc-config.c
@@ -0,0 +1,142 @@
+/**
+ * @file
+ *
+ * @ingroup arm_lpc32xx
+ *
+ * @brief RTC configuration.
+ */
+
+/*
+ * Copyright (c) 2009-2011 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.org/license/LICENSE.
+ */
+
+#include <libchip/rtc.h>
+
+#include <bsp.h>
+#include <bsp/lpc32xx.h>
+
+#define LPC32XX_RTC_COUNT 1U
+
+#define LPC32XX_RTC_COUNTER_DELTA 0xfffffffeU
+
+#define LPC32XX_RTC_KEY 0xb5c13f27U
+
+#define LPC32XX_RTC_CTRL_FORCE_ONSW (1U << 7)
+#define LPC32XX_RTC_CTRL_STOP (1U << 6)
+#define LPC32XX_RTC_CTRL_RESET (1U << 4)
+#define LPC32XX_RTC_CTRL_MATCH_1_ONSW (1U << 3)
+#define LPC32XX_RTC_CTRL_MATCH_0_ONSW (1U << 2)
+#define LPC32XX_RTC_CTRL_MATCH_1_INTR (1U << 1)
+#define LPC32XX_RTC_CTRL_MATCH_0_INTR (1U << 0)
+
+static void lpc32xx_rtc_set(uint32_t val)
+{
+ unsigned i = lpc32xx_arm_clk() / LPC32XX_OSCILLATOR_RTC;
+
+ lpc32xx.rtc.ctrl |= LPC32XX_RTC_CTRL_STOP;
+ lpc32xx.rtc.ucount = val;
+ lpc32xx.rtc.dcount = LPC32XX_RTC_COUNTER_DELTA - val;
+ lpc32xx.rtc.ctrl &= ~LPC32XX_RTC_CTRL_STOP;
+
+ /* It needs some time before we can read the values back */
+ while (i != 0) {
+ __asm__ volatile ("nop");
+ --i;
+ }
+}
+
+static void lpc32xx_rtc_reset(void)
+{
+ lpc32xx.rtc.ctrl = LPC32XX_RTC_CTRL_RESET;
+ lpc32xx.rtc.ctrl = 0;
+ lpc32xx.rtc.key = LPC32XX_RTC_KEY;
+ lpc32xx_rtc_set(0);
+}
+
+static void lpc32xx_rtc_initialize(int minor)
+{
+ uint32_t up_first = 0;
+ uint32_t up_second = 0;
+ uint32_t down_first = 0;
+ uint32_t down_second = 0;
+
+ if (lpc32xx.rtc.key != LPC32XX_RTC_KEY) {
+ lpc32xx_rtc_reset();
+ }
+
+ do {
+ up_first = lpc32xx.rtc.ucount;
+ down_first = lpc32xx.rtc.dcount;
+ up_second = lpc32xx.rtc.ucount;
+ down_second = lpc32xx.rtc.dcount;
+ } while (up_first != up_second || down_first != down_second);
+
+ if (up_first + down_first != LPC32XX_RTC_COUNTER_DELTA) {
+ lpc32xx_rtc_reset();
+ }
+}
+
+static int lpc32xx_rtc_get_time(int minor, rtems_time_of_day *tod)
+{
+ struct timeval now = {
+ .tv_sec = lpc32xx.rtc.ucount,
+ .tv_usec = 0
+ };
+ struct tm time;
+
+ gmtime_r(&now.tv_sec, &time);
+
+ tod->year = time.tm_year + 1900;
+ tod->month = time.tm_mon + 1;
+ tod->day = time.tm_mday;
+ tod->hour = time.tm_hour;
+ tod->minute = time.tm_min;
+ tod->second = time.tm_sec;
+ tod->ticks = 0;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+static int lpc32xx_rtc_set_time(int minor, const rtems_time_of_day *tod)
+{
+ lpc32xx_rtc_set(_TOD_To_seconds(tod));
+
+ return 0;
+}
+
+static bool lpc32xx_rtc_probe(int minor)
+{
+ return true;
+}
+
+const rtc_fns lpc32xx_rtc_ops = {
+ .deviceInitialize = lpc32xx_rtc_initialize,
+ .deviceGetTime = lpc32xx_rtc_get_time,
+ .deviceSetTime = lpc32xx_rtc_set_time
+};
+
+size_t RTC_Count = LPC32XX_RTC_COUNT;
+
+rtc_tbl RTC_Table [LPC32XX_RTC_COUNT] = {
+ {
+ .sDeviceName = "/dev/rtc",
+ .deviceType = RTC_CUSTOM,
+ .pDeviceFns = &lpc32xx_rtc_ops,
+ .deviceProbe = lpc32xx_rtc_probe,
+ .pDeviceParams = NULL,
+ .ulCtrlPort1 = 0,
+ .ulDataPort = 0,
+ .getRegister = NULL,
+ .setRegister = NULL
+ }
+};