|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.11! root 7: //
! 8: // RTC (RP5C15)
! 9: //
! 10:
1.1 root 11: #pragma once
12:
13: #include "device.h"
1.1.1.9 root 14: #include "monitor.h"
1.1 root 15: #include "rtc.h"
16:
17: struct RP5C15
18: {
19: // レジスタ 13, 14, 15 は Bank0/Bank1 どちらも同じものが見える。
20: // これらのレジスタは Bank1 だったら Bank0 を見せる。
21: //
22: // RTC の未使用ビットは、RTC への書き込み時に未使用ビットを
23: // mask[] で '0' にマスクしてから変数に書き込むこと。
24: union {
25: uint8 r[16 + 13];
26: struct {
27: uint8 sec1;
28: uint8 sec10;
29: uint8 min1;
30: uint8 min10;
31: uint8 hour1;
32: uint8 hour10;
33: uint8 wday;
34: uint8 day1;
35: uint8 day10;
36: uint8 mon1;
37: uint8 mon10;
38: uint8 year1;
39: uint8 year10;
40: uint8 mode;
41: uint8 test;
42: uint8 reset;
43:
44: uint8 clksel;
45: uint8 adjust;
46: uint8 alarm_min1;
47: uint8 alarm_min10;
48: uint8 alarm_hour1;
49: uint8 alarm_hour10;
50: uint8 alarm_wday;
51: uint8 alarm_day1;
52: uint8 alarm_day10;
53: uint8 padding1;
54: uint8 sel24;
55: uint8 leap;
56: uint8 padding2;
57: } __packed;
58: };
59:
60: // レジスタマスク (有効ビットを '1' としたもの)
61: static const uint8 mask[16 + 13];
62:
63: // バンク0
64: static const int SEC1 = 0x00; // $E8A001
65: static const int SEC10 = 0x01; // $E8A003
66: static const int MIN1 = 0x02; // $E8A005
67: static const int MIN10 = 0x03; // $E8A007
68: static const int HOUR1 = 0x04; // $E8A009
69: static const int HOUR10 = 0x05; // $E8A00B
70: static const int WDAY = 0x06; // $E8A00D
71: static const int DAY1 = 0x07; // $E8A00F
72: static const int DAY10 = 0x08; // $E8A011
73: static const int MON1 = 0x09; // $E8A013
74: static const int MON10 = 0x0a; // $E8A015
75: static const int YEAR1 = 0x0b; // $E8A017
76: static const int YEAR10 = 0x0c; // $E8A019
77: static const int MODE = 0x0d; // $E8A01B
78: static const int TEST = 0x0e; // $E8A01D
79: static const int RESET = 0x0f; // $E8A01F
80: // バンク1
81: static const int CLKSEL = 0x10; // $E8A001
82: static const int ADJUST = 0x11; // $E8A003
83: static const int ALARM_MIN1 = 0x12; // $E8A005
84: static const int ALARM_MIN10 = 0x13; // $E8A007
85: static const int ALARM_HOUR1 = 0x14; // $E8A009
86: static const int ALARM_HOUR10 = 0x15; // $E8A00B
87: static const int ALARM_WDAY = 0x16; // $E8A00D
88: static const int ALARM_DAY1 = 0x17; // $E8A00F
89: static const int ALARM_DAY10 = 0x18; // $E8A011
90: static const int notused1 = 0x19; // $E8A013
91: static const int SEL24 = 0x1a; // $E8A015
92: static const int LEAP = 0x1b; // $E8A017
93: static const int notused2 = 0x1c; // $E8A019
94: // バンク1 の 13, 14, 15 はバンク0 と共通
95: static const int MODE_BANK1 = 0x1d; // $E8A01B
96: static const int TEST_BANK1 = 0x1e; // $E8A01D
97: static const int RESET_BANK1 = 0x1f; // $E8A01F
98:
99: static const int MODE_TIMER_EN = 0x08;
100: static const int MODE_ALARM_EN = 0x04;
101: static const int MODE_BANK = 0x01;
102:
103: static const int RESET_1Hz = 0x08;
104: static const int RESET_16Hz = 0x04;
105: static const int RESET_TIMER = 0x02;
106: static const int RESET_ALARM = 0x01;
107: };
108:
109: class RP5C15Device : public RTCDevice
110: {
1.1.1.3 root 111: using inherited = RTCDevice;
1.1 root 112: public:
113: RP5C15Device();
1.1.1.6 root 114: virtual ~RP5C15Device() override;
1.1 root 115:
1.1.1.8 root 116: bool Init() override;
1.1.1.4 root 117:
1.1.1.10 root 118: // アラーム端子出力
119: // ALARM 端子は負論理(Low active) だが、ここでは
120: // アサート(L) のとき true とする。
121: // アラーム出力は内部のアラーム用 16Hz, 1Hz と
122: // アラーム時刻一致の alarm_on との OR 論理となっている。
123: bool AlarmOut() const { return alarm_16Hz | alarm_1Hz | alarm_on; }
124:
125: uint GetSec() const override; // 秒(0-59)
126: uint GetMin() const override; // 分(0-59)
127: uint GetHour() const override; // 時(0-23)
128: uint GetWday() const override; // 曜日(0が日曜)
129: uint GetMday() const override; // 日(1-31)
130: uint GetMon() const override; // 月(1-12)
131: uint GetYear() const override; // 年(西暦)
132: uint GetLeap() const override; // うるう年カウンタ(0..3)
1.1 root 133:
1.1.1.3 root 134: protected:
135: // BusIO インタフェース
136: static const uint32 NPORT = 16;
1.1.1.7 root 137: uint64 Read(uint32 offset);
138: uint64 Write(uint32 offset, uint32 data);
139: uint64 Peek(uint32 offset);
1.1.1.2 root 140:
1.1.1.10 root 141: // 仮想 RTC からのクロック
142: void Tick32Hz() override;
143: void Tick2Hz() override;
144: void Tick1Hz() override;
145:
146: void SetSec(uint v) override;
147: void SetMin(uint v) override;
148: void SetHour(uint v) override;
149: void SetWday(uint v) override;
150: void SetMday(uint v) override;
151: void SetMon(uint v) override;
152: void SetYear(uint v) override;
153: void SetLeap(uint v) override;
154:
1.1.1.3 root 155: private:
1.1 root 156: // レジスタを更新
157: void UpdateReg(uint32);
158:
1.1.1.9 root 159: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
160:
1.1 root 161: // レジスタ
162: RP5C15 reg {};
163:
164: // CLKOUT 端子の状態 (true なら 'H')
1.1.1.5 root 165: bool clkout {};
1.1.1.10 root 166:
167: // 分周段から秒カウンタへのカウントアップホールド内部信号。
168: bool clock_hold {};
169:
170: // CLKOUT 1/60Hz 用の 60秒カウンタ。カレンダとは独立。
171: uint32 cnt_60sec {};
172:
173: // 内部アラーム 16Hz 信号。CLKOUT、alarm_1Hz とは独立。
174: bool alarm_16Hz {};
175: // 内部アラーム 1Hz 信号。CLKOUT、alarm_16Hz とは独立。
176: bool alarm_1Hz {};
177: // アラーム時刻一致信号。
178: // XXX アラーム機能自体は未実装。
179: bool alarm_on {};
1.1.1.9 root 180:
181: Monitor monitor { this };
1.1 root 182: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.