[rtems commit] beagle bsp: RTC support for BBB
Ben Gras
beng at rtems.org
Thu May 28 12:42:11 UTC 2015
Module: rtems
Branch: master
Commit: d55d7a067fedd9feb48fcd9755205da1558ab709
Changeset: http://git.rtems.org/rtems/commit/?id=d55d7a067fedd9feb48fcd9755205da1558ab709
Author: ragunath <ragunath3252 at gmail.com>
Date: Sun May 3 15:43:55 2015 +0530
beagle bsp: RTC support for BBB
---
c/src/lib/libbsp/arm/beagle/Makefile.am | 3 +
c/src/lib/libbsp/arm/beagle/configure.ac | 3 +
c/src/lib/libbsp/arm/beagle/rtc.c | 277 +++++++++++++++++++++++++++
c/src/lib/libcpu/arm/shared/include/am335x.h | 20 ++
c/src/lib/libcpu/arm/shared/include/omap3.h | 6 +
5 files changed, 309 insertions(+)
diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am b/c/src/lib/libbsp/arm/beagle/Makefile.am
index abef8ba..aa96294 100644
--- a/c/src/lib/libbsp/arm/beagle/Makefile.am
+++ b/c/src/lib/libbsp/arm/beagle/Makefile.am
@@ -114,6 +114,9 @@ libbsp_a_SOURCES += ../../shared/console.c \
# I2C
libbsp_a_SOURCES += misc/i2c.c
+#RTC
+libbsp_a_SOURCES += rtc.c
+libbsp_a_SOURCES += ../../shared/tod.c
# Clock
libbsp_a_SOURCES += clock.c
libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
diff --git a/c/src/lib/libbsp/arm/beagle/configure.ac b/c/src/lib/libbsp/arm/beagle/configure.ac
index a7e99eb..b0c99a3 100644
--- a/c/src/lib/libbsp/arm/beagle/configure.ac
+++ b/c/src/lib/libbsp/arm/beagle/configure.ac
@@ -30,6 +30,9 @@ RTEMS_BSPOPTS_HELP([CONSOLE_BAUD],[initial baud for console UART])
RTEMS_BSPOPTS_SET([CONSOLE_POLLED],[*],[0])
RTEMS_BSPOPTS_HELP([CONSOLE_POLLED],[polled console i/o (e.g. to run testsuite)])
+RTEMS_BSPOPTS_SET([BBB_DEBUG],[beaglebone*],[0])
+RTEMS_BSPOPTS_HELP([BBB_DEBUG],[Enable BBB debug])
+
RTEMS_BSP_CLEANUP_OPTIONS(0, 0)
RTEMS_BSP_LINKCMDS
diff --git a/c/src/lib/libbsp/arm/beagle/rtc.c b/c/src/lib/libbsp/arm/beagle/rtc.c
new file mode 100644
index 0000000..342caf7
--- /dev/null
+++ b/c/src/lib/libbsp/arm/beagle/rtc.c
@@ -0,0 +1,277 @@
+/**
+ * @file
+ *
+ * @ingroup arm_beagle
+ *
+ * @brief RTC driver for AM335x SoC.
+ *
+ */
+
+/*
+ * Copyright (c) 2015 Ragunath <ragunath3252 at gmail.com>.
+ *
+ * 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 <bspopts.h>
+
+#if IS_AM335X
+#include <rtems.h>
+#include <bsp.h>
+#include <time.h>
+#include <libchip/rtc.h>
+#include <libcpu/omap3.h>
+
+#define setbit(a,x) (a | (1<<x))
+#define bcd(a) ((a & 0x0f)+ (((a & 0xf0) >> 4 )*10))
+#define dec(a) (((a / 10) << 4) | (a % 10))
+#define WRITE_WAIT_MAX_COUNT 10000
+
+rtems_device_minor_number RTC_Minor;
+size_t RTC_Count = 1;
+
+static void rtc_write_enable(void);
+static void rtc_write_disable(void);
+static int rtc_write_wait(void);
+static void rtc_clk_init(void);
+void rtc_init(int minor);
+void print_time(void);
+int am335x_rtc_gettime(int minor,rtems_time_of_day *t);
+int am335x_rtc_settime(int minor, const rtems_time_of_day *t);
+void am335x_rtc_debug(void);
+
+/*
+ * probe for a rtc. we always claim to have one.
+ */
+static bool am335x_rtc_probe (int minor)
+{
+ return true;
+}
+
+/*
+ * Write key values to kick0 and kick1 registers to enable write access
+ */
+static void rtc_write_enable(void)
+{
+ mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK0,AM335X_RTC_KICK0_KEY);
+ mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK1,AM335X_RTC_KICK1_KEY);
+}
+
+/*
+ * Write random (0x11111111) value to kick0 and kick1 registers to disable write access
+ */
+static void rtc_write_disable(void)
+{
+ /* Write some random value other than key to disable*/
+ mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK0,0x11111111);
+ mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK1,0x11111111);
+}
+
+/*
+ * Wait till busy bit is reset
+ */
+static int rtc_write_wait(void)
+{
+ int i = WRITE_WAIT_MAX_COUNT;
+ while((mmio_read(AM335X_RTC_BASE+AM335X_RTC_STATUS_REG) & 0x1) && (i--));
+
+ if(i == 0)
+ return RTEMS_RESOURCE_IN_USE;
+ else
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * Initialize RTC clock
+ */
+static void rtc_clk_init(void)
+{
+ uint32_t a = 0x0;
+
+ a = setbit(a,1);
+ /* IDLEST = 0x0 & MODULEMODE = 0x1*/
+ mmio_write(CM_RTC_BASE+CM_RTC_RTC_CLKCTRL,a);
+ a = 0x0;
+
+ /*32K rtc clock active*/
+ a = setbit(a,9);
+ a = setbit(a,8);
+ mmio_write(CM_RTC_BASE+CM_RTC_CLKSTCTRL,a);
+}
+
+void rtc_init(int minor)
+{
+ uint32_t a = 0x0;
+
+ rtc_clk_init();
+ /*
+ * Steps to enable RTC
+ * 1. Enable the module clock domains (rtc_clk_init).
+ * 2. Enable the RTC module using CTRL_REG.RTC_disable. (Default enabled. Nothing done)
+ * 3. Enable the 32K clock from PER PLL, if using the internal RTC oscillator.
+ * 4. Write to the kick registers (KICK0R, KICK1R) in the RTC.
+ * 5. Configure the timer in RTCSS for desired application (set time and date, alarm wakeup, and so on).
+ * 6. Start the RTC (in CTRL_REG.STOP_RTC).
+ */
+ rtc_write_enable();
+ a = setbit(a,0);
+ mmio_write(AM335X_RTC_BASE+AM335X_RTC_SYSCONFIG,a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_OSC_CLOCK);
+ a = setbit(a,6);
+ mmio_write(AM335X_RTC_BASE+AM335X_RTC_OSC_CLOCK,a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_CTRL_REG);
+ a = setbit(a,0);
+ mmio_write(AM335X_RTC_BASE+AM335X_RTC_CTRL_REG,a);
+
+ rtc_write_disable();
+}
+
+int am335x_rtc_gettime(int minor,rtems_time_of_day *t)
+{
+ uint32_t a = 0x0;
+
+ if(minor != 0)
+ return RTEMS_INVALID_NUMBER;
+
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_SECS);
+ t->second = bcd(a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MINS);
+ t->minute = bcd(a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_HOURS);
+ t->hour = bcd(a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_DAYS);
+ t->day = bcd(a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MONTHS);
+ t->month = bcd(a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_YEARS);
+ t->year = bcd(a)+2000;
+ t->ticks=0;
+ return RTEMS_SUCCESSFUL;
+}
+
+int am335x_rtc_settime(int minor,const rtems_time_of_day *t)
+{
+ uint32_t a=0x0;
+ int rv;
+
+ if(minor != 0)
+ return RTEMS_INVALID_NUMBER;
+
+ rtc_write_enable();
+
+ /* Wait till the busy bit is reset to write again*/
+ a = t->second;
+ rv=rtc_write_wait();
+ if(rv != RTEMS_SUCCESSFUL)
+ return rv;
+ a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_SECS,dec(a) & 0x7f);
+
+ a = t->minute;
+ rv=rtc_write_wait();
+ if(rv != RTEMS_SUCCESSFUL)
+ return rv;
+ a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_MINS,dec(a) & 0x7f);
+
+ a = t->hour;
+ rv=rtc_write_wait();
+ if(rv != RTEMS_SUCCESSFUL)
+ return rv;
+ a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_HOURS,dec(a) & 0x3f);
+
+ a = t->day;
+ rv=rtc_write_wait();
+ if(rv != RTEMS_SUCCESSFUL)
+ return rv;
+ a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_DAYS,dec(a) & 0x3f);
+
+ a = t->month;
+ rv=rtc_write_wait();
+ if(rv != RTEMS_SUCCESSFUL)
+ return rv;
+ a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_MONTHS,dec(a) & 0x1f);
+
+ a = t->year;
+ rv=rtc_write_wait();
+ if(rv != RTEMS_SUCCESSFUL)
+ return rv;
+ a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_YEARS,(dec(a)%100) & 0xff);
+
+ rtc_write_disable();
+ return rv;
+}
+
+#if BBB_DEBUG
+void print_time(void)
+{
+ uint32_t a = 0x0;
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_SECS);
+ printk("\n\rSecs %x",a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MINS);
+ printk("\n\rMins %x",a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_HOURS);
+ printk("\n\rHours %x",a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_DAYS);
+ printk("\n\rDays %x",a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MONTHS);
+ printk("\n\r Months %x",a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_YEARS);
+ printk("\n\rYears %x",a);
+ a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_WEEKS);
+ printk("\n\rWeeks %x",a);
+}
+
+void am335x_rtc_debug(void)
+{
+ int i;
+ rtems_time_of_day t,r;
+
+ t.second = 1;
+ t.minute = 1;
+ t.hour = 1;
+ t.day = 7;
+ t.month = 3;
+ t. year = 2015;
+
+ am335x_rtc_settime(0,&t);
+ am335x_rtc_gettime(0,&r);
+
+ printk("Secs %x",r.second);
+ printk("Mins %x",r.minute);
+ printk("Hours %x",r.hour);
+ printk("Days %x",r.day);
+ printk("Months %x",r.month);
+ printk("Years %x",r.year);
+}
+#endif
+
+/*
+ * driver function table.
+ */
+rtc_fns am335x_rtc_fns = {
+ rtc_init,
+ am335x_rtc_gettime,
+ am335x_rtc_settime
+};
+
+/*
+ * the following table configures the RTC drivers used in this BSP
+ */
+
+rtc_tbl RTC_Table[] = {
+ {
+ "/dev/rtc", /* sDeviceName */
+ RTC_CUSTOM, /* deviceType */
+ &am335x_rtc_fns, /* pDeviceFns */
+ am335x_rtc_probe, /* deviceProbe */
+ NULL, /* pDeviceParams */
+ 0, /* ulCtrlPort1 */
+ 0, /* ulDataPort */
+ NULL, /* getRegister */
+ NULL /* setRegister */
+ }
+};
+
+#endif
diff --git a/c/src/lib/libcpu/arm/shared/include/am335x.h b/c/src/lib/libcpu/arm/shared/include/am335x.h
index 1f638bd..37c5eeb 100644
--- a/c/src/lib/libcpu/arm/shared/include/am335x.h
+++ b/c/src/lib/libcpu/arm/shared/include/am335x.h
@@ -280,3 +280,23 @@
/* Command posted status */
#define AM335X_WDT_WSPR 0x48
/* Activate/deactivate sequence */
+
+/* RTC registers */
+#define AM335X_RTC_BASE 0x44E3E000
+#define AM335X_RTC_SECS 0x0
+#define AM335X_RTC_MINS 0x4
+#define AM335X_RTC_HOURS 0x8
+#define AM335X_RTC_DAYS 0xc
+#define AM335X_RTC_MONTHS 0x10
+#define AM335X_RTC_YEARS 0x14
+#define AM335X_RTC_WEEKS 0x18
+#define AM335X_RTC_CTRL_REG 0x40
+#define AM335X_RTC_STATUS_REG 0x44
+#define AM335X_RTC_REV_REG 0x74
+#define AM335X_RTC_SYSCONFIG 0x78
+#define AM335X_RTC_KICK0 0x6c
+#define AM335X_RTC_KICK1 0x70
+#define AM335X_RTC_OSC_CLOCK 0x54
+
+#define AM335X_RTC_KICK0_KEY 0x83E70B13
+#define AM335X_RTC_KICK1_KEY 0x95A4F1E0
diff --git a/c/src/lib/libcpu/arm/shared/include/omap3.h b/c/src/lib/libcpu/arm/shared/include/omap3.h
index 1316f6d..f28e5e5 100644
--- a/c/src/lib/libcpu/arm/shared/include/omap3.h
+++ b/c/src/lib/libcpu/arm/shared/include/omap3.h
@@ -288,6 +288,12 @@
#define CLKSEL_TIMER7_CLK_SEL_SEL3 (0x2 << 0) /* Select CLK_32KHZ clock */
#define CLKSEL_TIMER7_CLK_SEL_SEL4 (0x3 << 0) /* Reserved */
+/*RTC CLOCK BASE & Registers*/
+#define CM_RTC_BASE 0x44E00800
+#define CM_RTC_RTC_CLKCTRL 0x0
+#define CM_RTC_CLKSTCTRL 0x4
+
+
#define OMAP3_CLKSEL_GPT1 (1 << 0)
#define OMAP3_CLKSEL_GPT10 (1 << 6)
#define OMAP3_CLKSEL_GPT11 (1 << 7)
More information about the vc
mailing list