summaryrefslogtreecommitdiffstats
path: root/bsps/m68k
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/m68k
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/m68k')
-rw-r--r--bsps/m68k/mcf5206elite/rtc/ds1307.c206
-rw-r--r--bsps/m68k/mcf5206elite/rtc/todcfg.c80
-rw-r--r--bsps/m68k/mvme162/rtc/tod.c88
3 files changed, 374 insertions, 0 deletions
diff --git a/bsps/m68k/mcf5206elite/rtc/ds1307.c b/bsps/m68k/mcf5206elite/rtc/ds1307.c
new file mode 100644
index 0000000000..ab7fc7daac
--- /dev/null
+++ b/bsps/m68k/mcf5206elite/rtc/ds1307.c
@@ -0,0 +1,206 @@
+/*
+ * This file interfaces with the real-time clock found in a
+ * Dallas Semiconductor DS1307/DS1308 serial real-time clock chip.
+ * This RTC have I2C bus interface. BSP have to provide I2C bus primitives
+ * to make this driver working. getRegister and setRegister primitives is
+ * not used here to avoid multiple transactions over I2C bus (each transaction
+ * require significant time and error when date/time information red may
+ * occurs). ulControlPort contains I2C bus number; ulDataPort contains
+ * RTC I2C device address.
+ *
+ * Year 2000 Note:
+ *
+ * This chip only uses a two digit field to store the year. This code
+ * uses the RTEMS Epoch as a pivot year. This lets us map the two digit
+ * year field as follows:
+ *
+ * + two digit years 00-87 are mapped to 2000-2087
+ * + two digit years 88-99 are mapped to 1988-1999
+ */
+
+/*
+ * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * 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 <rtems.h>
+#include <libchip/rtc.h>
+#include <string.h>
+#include "ds1307.h"
+#include "i2c.h"
+
+/* Convert from/to Binary-Coded Decimal representation */
+#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
+#define To_BCD( _x ) ((((_x) / 10) << 4) + ((_x) % 10))
+
+/* ds1307_initialize --
+ * Initialize DS1307 real-time clock chip. If RTC is halted, this
+ * function resume counting.
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ */
+static void ds1307_initialize(int minor)
+{
+ i2c_message_status status;
+ int try;
+ uint8_t sec;
+ i2c_bus_number bus;
+ i2c_address addr;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ /* Read SECONDS register */
+ try = 0;
+ do {
+ status = i2c_wbrd(bus, addr, 0, &sec, sizeof(sec));
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 15));
+
+ /* If clock is halted, reset and start the clock */
+ if ((sec & DS1307_SECOND_HALT) != 0) {
+ uint8_t start[8];
+ memset(start, 0, sizeof(start));
+ start[0] = DS1307_SECOND;
+ try = 0;
+ do {
+ status = i2c_write(bus, addr, start, 2);
+ } while ((status != I2C_SUCCESSFUL) && (try < 15));
+ }
+}
+
+/* ds1307_get_time --
+ * read current time from DS1307 real-time clock chip and convert it
+ * to the rtems_time_of_day structure.
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ * time -- place to put return value (date and time)
+ *
+ * RETURNS:
+ * 0, if time obtained successfully
+ * -1, if error occured
+ */
+static int ds1307_get_time(int minor, rtems_time_of_day *time)
+{
+ i2c_bus_number bus;
+ i2c_address addr;
+ uint8_t info[8];
+ uint32_t v1, v2;
+ i2c_message_status status;
+ int try;
+
+ if (time == NULL)
+ return -1;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ memset(time, 0, sizeof(rtems_time_of_day));
+ try = 0;
+ do {
+ status = i2c_wbrd(bus, addr, 0, info, sizeof(info));
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 10));
+
+ if (status != I2C_SUCCESSFUL) {
+ return -1;
+ }
+
+ v1 = info[DS1307_YEAR];
+ v2 = From_BCD(v1);
+ if (v2 < 88)
+ time->year = 2000 + v2;
+ else
+ time->year = 1900 + v2;
+
+ v1 = info[DS1307_MONTH] & ~0xE0;
+ time->month = From_BCD(v1);
+
+ v1 = info[DS1307_DAY] & ~0xC0;
+ time->day = From_BCD(v1);
+
+ v1 = info[DS1307_HOUR];
+ if (v1 & DS1307_HOUR_12) {
+ v2 = v1 & ~0xE0;
+ if (v1 & DS1307_HOUR_PM) {
+ time->hour = From_BCD(v2) + 12;
+ } else {
+ time->hour = From_BCD(v2);
+ }
+ } else {
+ v2 = v1 & ~0xC0;
+ time->hour = From_BCD(v2);
+ }
+
+ v1 = info[DS1307_MINUTE] & ~0x80;
+ time->minute = From_BCD(v1);
+
+ v1 = info[DS1307_SECOND];
+ v2 = v1 & ~0x80;
+ time->second = From_BCD(v2);
+
+ return 0;
+}
+
+/* ds1307_set_time --
+ * set time to the DS1307 real-time clock chip
+ *
+ * PARAMETERS:
+ * minor -- minor RTC device number
+ * time -- new date and time to be written to DS1307
+ *
+ * RETURNS:
+ * 0, if time obtained successfully
+ * -1, if error occured
+ */
+static int ds1307_set_time(int minor, const rtems_time_of_day *time)
+{
+ i2c_bus_number bus;
+ i2c_address addr;
+ uint8_t info[8];
+ i2c_message_status status;
+ int try;
+
+ if (time == NULL)
+ return -1;
+
+ bus = RTC_Table[minor].ulCtrlPort1;
+ addr = RTC_Table[minor].ulDataPort;
+
+ if (time->year >= 2088)
+ rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);
+
+ info[0] = DS1307_SECOND;
+ info[1 + DS1307_YEAR] = To_BCD(time->year % 100);
+ info[1 + DS1307_MONTH] = To_BCD(time->month);
+ info[1 + DS1307_DAY] = To_BCD(time->day);
+ info[1 + DS1307_HOUR] = To_BCD(time->hour);
+ info[1 + DS1307_MINUTE] = To_BCD(time->minute);
+ info[1 + DS1307_SECOND] = To_BCD(time->second);
+ info[1 + DS1307_DAY_OF_WEEK] = 1; /* Do not set day of week */
+
+ try = 0;
+ do {
+ status = i2c_write(bus, addr, info, 8);
+ try++;
+ } while ((status != I2C_SUCCESSFUL) && (try < 10));
+
+ if (status != I2C_SUCCESSFUL)
+ return -1;
+ else
+ return 0;
+}
+
+/* Driver function table */
+
+rtc_fns ds1307_fns = {
+ ds1307_initialize,
+ ds1307_get_time,
+ ds1307_set_time
+};
diff --git a/bsps/m68k/mcf5206elite/rtc/todcfg.c b/bsps/m68k/mcf5206elite/rtc/todcfg.c
new file mode 100644
index 0000000000..aacb8575bd
--- /dev/null
+++ b/bsps/m68k/mcf5206elite/rtc/todcfg.c
@@ -0,0 +1,80 @@
+/*
+ * This file contains the RTC driver table for Motorola MCF5206eLITE
+ * ColdFire evaluation board.
+ *
+ * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * 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 <i2c.h>
+#include <libchip/rtc.h>
+#include <ds1307.h>
+
+/* Forward function declaration */
+bool mcf5206elite_ds1307_probe(int minor);
+
+extern rtc_fns ds1307_fns;
+
+/* The following table configures the RTC drivers used in this BSP */
+rtc_tbl RTC_Table[] = {
+ {
+ "/dev/rtc", /* sDeviceName */
+ RTC_CUSTOM, /* deviceType */
+ &ds1307_fns, /* pDeviceFns */
+ mcf5206elite_ds1307_probe, /* deviceProbe */
+ NULL, /* pDeviceParams */
+ 0x00, /* ulCtrlPort1, for DS1307-I2C bus number */
+ DS1307_I2C_ADDRESS, /* ulDataPort, for DS1307-I2C device addr */
+ NULL, /* getRegister - not applicable to DS1307 */
+ NULL /* setRegister - not applicable to DS1307 */
+ }
+};
+
+/* Some information used by the RTC driver */
+
+#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
+
+size_t RTC_Count = NUM_RTCS;
+
+/* mcf5206elite_ds1307_probe --
+ * RTC presence probe function. Return TRUE, if device is present.
+ * Device presence checked by probe access to RTC device over I2C bus.
+ *
+ * PARAMETERS:
+ * minor - minor RTC device number
+ *
+ * RETURNS:
+ * TRUE, if RTC device is present
+ */
+bool
+mcf5206elite_ds1307_probe(int minor)
+{
+ int try = 0;
+ i2c_message_status status;
+ rtc_tbl *rtc;
+ i2c_bus_number bus;
+ i2c_address addr;
+
+ if (minor >= NUM_RTCS)
+ return false;
+
+ rtc = RTC_Table + minor;
+
+ bus = rtc->ulCtrlPort1;
+ addr = rtc->ulDataPort;
+ do {
+ status = i2c_wrbyte(bus, addr, 0);
+ if (status == I2C_NO_DEVICE)
+ return false;
+ try++;
+ } while ((try < 15) && (status != I2C_SUCCESSFUL));
+ if (status == I2C_SUCCESSFUL)
+ return true;
+ else
+ return false;
+}
diff --git a/bsps/m68k/mvme162/rtc/tod.c b/bsps/m68k/mvme162/rtc/tod.c
new file mode 100644
index 0000000000..abd353d11b
--- /dev/null
+++ b/bsps/m68k/mvme162/rtc/tod.c
@@ -0,0 +1,88 @@
+/*
+ * Real Time Clock (MK48T08) for RTEMS on MVME162
+ *
+ * Author:
+ * COPYRIGHT (C) 1997
+ * by Katsutoshi Shibuya - BU Denken Co.,Ltd. - Sapporo - JAPAN
+ * ALL RIGHTS RESERVED
+ *
+ * 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.
+ *
+ * This material is a part of the MVME162 Board Support Package
+ * for the RTEMS executive. Its licensing policies are those of the
+ * RTEMS above.
+ */
+
+#include <rtems.h>
+#include <rtems/tod.h>
+
+#define tod ((volatile unsigned char *)0xfffc1ff8)
+
+static int getTod(int n, unsigned char mask)
+{
+ unsigned char x;
+
+ x = tod[n]&mask;
+ return (x>>4)*10+(x&0x0f);
+}
+
+static void setTod(int n, unsigned char d)
+{
+ tod[n] = ((d/10)<<4)+(d%10);
+}
+
+void setRealTimeToRTEMS(void)
+{
+ rtems_time_of_day t;
+
+ tod[0] |= 0x40; /* Stop read register */
+ t.year = 1900+getTod(7,0xff);
+ t.month = getTod(6,0x1f);
+ t.day = getTod(5,0x3f);
+ t.hour = getTod(3,0x3f);
+ t.minute = getTod(2,0x7f);
+ t.second = getTod(1,0x7f);
+ t.ticks = 0;
+ tod[0] &= 0x3f; /* Release read register */
+
+ rtems_clock_set(&t);
+}
+
+void setRealTimeFromRTEMS()
+{
+ rtems_time_of_day t;
+
+ rtems_clock_get_tod(&t);
+ t.year -= 1900;
+
+ tod[0] |= 0x80; /* Stop write register */
+ setTod(7,t.year);
+ setTod(6,t.month);
+ setTod(5,t.day);
+ setTod(4,1); /* I don't know which day of week is */
+ setTod(3,t.hour);
+ setTod(2,t.minute);
+ setTod(1,t.second);
+ tod[0] &= 0x3f; /* Write these parameters */
+}
+
+int checkRealTime()
+{
+ rtems_time_of_day t;
+ int d;
+
+ tod[0] |= 0x40; /* Stop read register */
+ rtems_clock_get_tod(&t);
+ if((t.year != 1900+getTod(7,0xff))
+ || (t.month != getTod(6,0x1f))
+ || (t.day != getTod(5,0x3f)))
+ d = 9999;
+ else
+ d = (t.hour-getTod(3,0x3f))*3600
+ + (t.minute-getTod(3,0x7f))*60
+ + (t.second - getTod(1,0x7f));
+ tod[1] &= 0x3f;
+ return d;
+}