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