msx2: add rp5c01 rtc driver
authorgeijoenr <enric.geijo@gmail.com>
Sat, 31 Jan 2015 04:16:11 +0000 (05:16 +0100)
committergeijoenr <enric.geijo@gmail.com>
Sun, 1 Feb 2015 18:26:54 +0000 (18:26 +0000)
Kernel/dev/rp5c01.c [new file with mode: 0755]
Kernel/dev/rp5c01.h [new file with mode: 0755]
Kernel/platform-msx2/Makefile
Kernel/platform-msx2/config.h
Kernel/platform-msx2/devices.c
Kernel/platform-msx2/devrtc.c [new file with mode: 0755]
Kernel/platform-msx2/fuzix.lnk

diff --git a/Kernel/dev/rp5c01.c b/Kernel/dev/rp5c01.c
new file mode 100755 (executable)
index 0000000..cb8705b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * rp5c01a-rtc
+ * Real Time Clock with internal non-volatile RAM
+ */
+#include <rp5c01.h>
+
+
+uint8_t rp5c01_rtc_secs(void)
+{
+    uint8_t sl, rv;
+
+    /* set mode 00 */
+    rp5c01_write_reg(MODE_SEL, TIMER_ENABLE | MODE00);
+
+    /* BCD encoded */
+    do {
+        sl = rp5c01_read_reg(REG_1_SEC_CTR);
+        rv = sl + rp5c01_read_reg(REG_10_SEC_CTR) * 10;
+    } while (sl != rp5c01_read_reg(REG_1_SEC_CTR));
+
+    //rp5c01_write_reg(MODE_SEL, TIMER_ENABLE | MODE01);
+
+    return rv;
+}
+
+#ifdef CONFIG_RTC_RP5C01_NVRAM
+void rp5c01_nvram_write(uint8_t addr, uint8_t value)
+{
+    if (addr > 0xC)
+       return;
+
+    /* store 4 msb in mode 10 regs, 4 lsb in mode 01 regs */
+    rp5c01_write_reg(MODE_SEL, TIMER_ENABLE | MODE10);
+    rp5c01_write_reg(addr, value & 0xF0 >> 4);
+    rp5c01_write_reg(MODE_SEL, TIMER_ENABLE | MODE11);
+    rp5c01_write_reg(addr, value & 0x0F);
+}
+
+uint8_t rp5c01_nvram_read(uint8_t addr)
+{
+    uint8_t val, data;
+
+    if (addr > 0xC)
+       return;
+
+    /* read 4 msb from mode 10 regs, 4 lsb from mode 01 regs */
+    rp5c01_write_reg(MODE_SEL, TIMER_ENABLE | MODE10);
+    val = rp5c01_read_reg(addr);
+    data = val << 4;
+
+    rp5c01_write_reg(MODE_SEL, TIMER_ENABLE | MODE11);
+    val = rp5c01_read_reg(addr);
+    data |= val & 0x0F;
+
+    return data;
+}
+#endif
+
diff --git a/Kernel/dev/rp5c01.h b/Kernel/dev/rp5c01.h
new file mode 100755 (executable)
index 0000000..b78f708
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef __RTC_REG_DOT_H__
+#define __RTC_REG_DOT_H__
+
+/*
+ * rp5c01a
+ *
+ * Real Time Clock with internal non-volatile RAM
+ *
+ */
+
+#include "cpu.h"
+
+/* mode 00 registers */
+#define REG_1_SEC_CTR      0x0
+#define REG_10_SEC_CTR     0x1
+#define REG_1_MIN_CTR      0x2
+#define REG_10_MIN_CTR     0x3
+#define REG_1_HOUR_CTR     0x4
+#define REG_10_HOUR_CTR            0x5
+#define REG_WKDAY_CTR      0x6
+#define REG_1_DAY_CTR      0x7
+#define REG_10DAY_CTR      0x8
+#define REG_1_MONTH_CTR            0x9
+#define REG_10_MONTH_CTR    0xA
+#define REG_1_YEAR_CTR     0xB
+#define REG_10_YEAR_CTR            0xC
+/* common registers */
+#define MODE_SEL           0xD
+#define TEST_SEL           0xE
+#define RESET              0xF
+
+/* MODE_SEL modes */
+#define TIMER_ENABLE       0x8
+#define MODE00             0x0     /* set/read time */
+#define MODE01             0x1     /* set/read alarm, 12/24 and leap yaer */
+#define MODE10             0x2     /* read/write ram block 0 */
+#define MODE11             0x3     /* read/write ram block 1 */
+
+/* platform specific */
+uint8_t rp5c01_read_reg(uint8_t reg);
+void rp5c01_write_reg(uint8_t reg, uint8_t value);
+
+/* read seconds */
+uint8_t rp5c01_rtc_secs(void);
+
+#ifdef CONFIG_RTC_REG_NVRAM
+/* read/write non volatile ram */
+void rp5c01_nvram_write(uint8_t addr, uint8_t value);
+uint8_t rp5c01_nvram_read(uint8_t addr);
+#endif
+
+#endif
index 7599b99..3859f95 100644 (file)
@@ -1,6 +1,6 @@
 
 CSRCS = ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c devfd.c devhd.c devlpr.c
-CSRCS += devices.c main.c devtty.c
+CSRCS += devices.c main.c devtty.c ../dev/rp5c01.c devrtc.c
 DSRCS = devmegasd.c
 ASRCS = msx2.s crt0.s vdp.s
 ASRCS += tricks.s commonmem.s bootrom.s
index 0554315..d62e44b 100644 (file)
@@ -45,3 +45,5 @@
 #define SD_DRIVE_COUNT 1
 
 #define MAX_BLKDEV 1      /* Single SD drive */
+#define CONFIG_RTC
+//#define CONFIG_RTC_RP5C01_NVRAM
index 98bf22c..ac2d001 100644 (file)
@@ -38,8 +38,14 @@ bool validdev(uint16_t dev)
         return true;
 }
 
+DISCARDABLE
+
 void device_init(void)
 {
+#ifdef CONFIG_RTC
+    inittod();
+#endif
+
     if (megasd_probe()) {
         /* probe for megaflash rom sd */
         devsd_init();
diff --git a/Kernel/platform-msx2/devrtc.c b/Kernel/platform-msx2/devrtc.c
new file mode 100755 (executable)
index 0000000..f9777cf
--- /dev/null
@@ -0,0 +1,21 @@
+#include <rp5c01.h>
+
+__sfr __at (0xb4) RTC_REGSEL;
+__sfr __at (0xb5) RTC_DATA;
+
+uint8_t rp5c01_read_reg(uint8_t reg)
+{
+    RTC_REGSEL = reg & 0xf;
+    return RTC_DATA;
+}
+
+void rp5c01_write_reg(uint8_t reg, uint8_t value)
+{
+    RTC_REGSEL = reg & 0xf;
+    RTC_DATA = value;
+}
+
+uint8_t rtc_secs(void)
+{
+    return rp5c01_rtc_secs();
+}
index 455dcc0..d6a6bb4 100644 (file)
@@ -40,4 +40,6 @@ platform-msx2/blkdev.rel
 platform-msx2/devsd.rel
 platform-msx2/devmegasd.rel
 platform-msx2/mbr.rel
+platform-msx2/devrtc.rel
+platform-msx2/rp5c01.rel
 -e