|
|
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.9 root 7: //
8: // RTC の共通部分
9: //
10:
1.1 root 11: #pragma once
12:
13: #include "device.h"
1.1.1.9 root 14: #include "event.h"
15: #include <sys/time.h>
1.1 root 16:
1.1.1.10 root 17: class Syncer;
18:
1.1 root 19: class RTCDevice : public IODevice
20: {
1.1.1.3 root 21: using inherited = IODevice;
1.1 root 22:
23: public:
1.1.1.10 root 24: RTCDevice();
1.1.1.11 root 25: ~RTCDevice() override;
1.1 root 26:
1.1.1.7 root 27: bool Init() override;
1.1 root 28:
1.1.1.9 root 29: virtual void StartTime();
30:
31: // 電源 OFF 時の実時間でのクロック入力。
32: // 次回のクロック発生までの時間間隔を返す。
33: uint64 ClockIn_PowerOff();
1.1.1.7 root 34:
35: // 現在の日付時刻を返す。
36: // ここで取得できる値は機種によらず共通のフォーマットだが、
37: // 値は範囲外の状態になる可能性が常にあることに注意。
38: //
39: // RP5C15 の場合、1つのレジスタが10進数一桁ごとを扱っているため、特に
40: // ゲストプログラムが月の更新するしようとするときに一時的に範囲外の
41: // 状態になることが避けられない。
42: // 例えば、もともと12月31日だったものを9月30日に変更する場合、
43: // 上の桁から更新したら(M10,M1,D10,D1)
44: // 12/31 -> 02/31 -> 09/31 -> 09/31 -> 09/30
45: // 下の桁から更新したら(D1,D10,M1,M10)
46: // 12/31 -> 12/30 -> 12/30 -> 19/30 -> 09/30
47: // このように、2/31, 9/31, 19/30 などが中間状態として発生する。
48: virtual uint GetSec() const = 0; // 秒(0-59)
49: virtual uint GetMin() const = 0; // 分(0-59)
50: virtual uint GetHour() const = 0; // 時(0-23)
51: virtual uint GetWday() const = 0; // 曜日(0-6、0が日曜)
52: virtual uint GetMday() const = 0; // 日(1-31)
53: virtual uint GetMon() const = 0; // 月(1-12)
54: virtual uint GetYear() const = 0; // 年(西暦)
55: virtual uint GetLeap() const = 0; // うるう年カウンタ(0-3、0がうるう年)
1.1 root 56:
57: protected:
1.1.1.9 root 58: // 32Hz クロック入力。
59: // clock-sync の設定に応じて、実時間または仮想時間で
60: // 32Hz ごとに呼ばれて、これが RTC の時計を進める処理をするところ。
61: void ClockIn();
62:
1.1.1.7 root 63: // 仮想 RTC のクロック出力
1.1 root 64:
1.1.1.7 root 65: // 継承クラス向けに 32Hz で呼び出される。
1.1.1.9 root 66: virtual void Tick32Hz();
1.1 root 67:
1.1.1.7 root 68: // 継承クラス向けに 2Hz で呼び出される。
69: // タイミングは、0/32秒目と 16/32秒目。
1.1.1.9 root 70: virtual void Tick2Hz();
1.1.1.7 root 71:
72: // 継承クラス向けに 1Hz で呼び出される。
73: // タイミングは、0/32秒目。
74: // この関数から秒カウンタ更新をすること。
1.1.1.9 root 75: virtual void Tick1Hz();
1.1.1.7 root 76:
77: // 秒をカウントアップし、秒以上の繰り上がりを処理する。
78: void CountUpSec();
79: // 分をカウントアップし、分以上の繰り上がりを処理する。
80: // RP5C15 の ADJUST 機能を実現するために秒と分離。
81: void CountUpMin();
82:
83: virtual void SetSec(uint v) = 0;
84: virtual void SetMin(uint v) = 0;
85: virtual void SetHour(uint v) = 0;
86: virtual void SetWday(uint v) = 0;
87: virtual void SetMday(uint v) = 0;
88: virtual void SetMon(uint v) = 0;
89: virtual void SetYear(uint v) = 0;
90: virtual void SetLeap(uint v) = 0;
91:
92: // 32Hz でカウントアップする内部カウンタ
93: uint64 cnt {};
94:
95: // 年エポック。システムに依存。
96: uint year_epoch {};
97:
98: // 時刻設定時に localtime を使う場合は true
99: bool use_localtime {};
100:
101: // レジスタとして読める値を定数にすることで、仮想マシン状態を
102: // 常に同じ状態にするためのパフォーマンス測定用フラグ。
103: // なお NVRAM 部分は影響されない。
104: bool force_fixed {};
105:
1.1.1.9 root 106: // RTC の入力クロックが実時間の場合は true
107: // 仮想時間の場合は false
108: bool sync_rt {};
109:
110: // 設定で指定された日付時刻
111: struct tm rtc_tm {};
112:
1.1.1.7 root 113: // 曜日文字列 (0 = "Sun", ...)
114: // MK48T02 の誤運用にも対応するため 0..7 の範囲をとる。
115: static const char * const wdays[8];
116:
117: private:
118: // デバッグオプションの日付時刻文字列を解析する。
119: bool ParseDate(const std::string& str, int *y, int *m, int *d, int *w);
120: bool ParseTime(const std::string& str, int *h, int *m, int *s);
1.1 root 121:
1.1.1.7 root 122: // 現在の月の最終日を返す (月の繰り上がり処理用)
1.1.1.12 root 123: uint GetLastMday() const;
1.1.1.9 root 124:
125: // イベントコールバック
126: void Callback(Event& ev);
127:
128: // イベント間隔
129: const uint period = 31.25_msec;
130:
131: // システムクロックが刻んでいる時刻
132: uint64 stime {};
133:
1.1.1.10 root 134: Syncer *syncer {};
135:
1.1.1.9 root 136: // RTC クロック入力
137: Event event { this };
1.1 root 138: };
139:
1.1.1.10 root 140: static inline RTCDevice *GetRTCDevice() {
141: return Object::GetObject<RTCDevice>(OBJ_RTC);
142: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.