[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