|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2022 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // 電源周り
9: //
10:
11: #include "power.h"
12: #include "mainapp.h"
1.1.1.2 ! root 13: #include "mfp.h"
1.1 root 14: #include "scheduler.h"
15: #include "sync.h"
16: #include "uimessage.h"
17:
18: // グローバル参照用
19: PowerDevice *gPower;
20:
21: // コンストラクタ
22: PowerDevice::PowerDevice()
23: : inherited("Power")
24: {
1.1.1.2 ! root 25: event.func = ToEventCallback(&PowerDevice::PowerCallback);
! 26: event.time = 1_msec;
! 27: event.Regist("Power Off");
! 28:
1.1 root 29: gScheduler->ConnectMessage(MessageID::RESET, this,
30: ToMessageCallback(&PowerDevice::ResetCallback));
31: gScheduler->ConnectMessage(MessageID::POWEROFF_RESTART, this,
32: ToMessageCallback(&PowerDevice::PowerOffCallback));
1.1.1.2 ! root 33: gScheduler->ConnectMessage(MessageID::POWER_BUTTON, this,
! 34: ToMessageCallback(&PowerDevice::PowerButtonCallback));
1.1 root 35: }
36:
37: // デストラクタ
38: PowerDevice::~PowerDevice()
39: {
40: gPower = NULL;
41: }
42:
43: // リセットをスケジューラに指示する。(外部から呼ばれる用)
44: void
45: PowerDevice::MakeResetHard()
46: {
47: gScheduler->SendMessage(MessageID::RESET);
48: }
49:
50: // リスタートをスケジューラに指示する。(外部から呼ばれる用)
51: void
52: PowerDevice::MakeRestart()
53: {
54: gScheduler->SendMessage(MessageID::POWEROFF_RESTART);
55: }
56:
1.1.1.2 ! root 57: // 電源ボタンを押す。 (外部から呼ばれる用)
1.1 root 58: void
1.1.1.2 ! root 59: PowerDevice::PowerButton()
1.1 root 60: {
1.1.1.2 ! root 61: gScheduler->SendMessage(MessageID::POWER_BUTTON);
1.1 root 62: }
63:
64: // リセットのメッセージコールバック
65: void
66: PowerDevice::ResetCallback(MessageID msgid, uint32 arg)
67: {
68: DoResetHard();
69: }
70:
71: // 電源オフのメッセージコールバック
72: void
73: PowerDevice::PowerOffCallback(MessageID msgid, uint32 arg)
74: {
75: DoPowerOff(msgid);
76: }
77:
1.1.1.2 ! root 78: // 電源ボタンのメッセージコールバック
! 79: void
! 80: PowerDevice::PowerButtonCallback(MessageID msgid, uint32 arg)
! 81: {
! 82: DoPowerButton();
! 83: }
! 84:
1.1 root 85: // 電源オン操作 (Device::ResetHard ではない)
86: void
87: PowerDevice::DoPowerOn()
88: {
89: putlog(1, "PowerOn");
90:
91: if (ispower == false) {
92: // 全デバイス電源オン
93: ispower = true;
94: for (auto obj : gMainApp.GetObjects()) {
95: auto dev = dynamic_cast<Device *>(obj);
96: if (dev) {
97: dev->ResetHard(true);
98: }
99: }
100:
101: // 動作モード変更
102: gSync->RequestPowerOffMode(false);
103: }
104: }
105:
106: // リセット操作 (Device::ResetHard ではない)
107: void
108: PowerDevice::DoResetHard()
109: {
110: putlog(1, "Reset");
111:
112: if (ispower) {
113: // 全デバイスをリセット
114: for (auto obj : gMainApp.GetObjects()) {
115: auto dev = dynamic_cast<Device *>(obj);
116: if (dev) {
117: dev->ResetHard(false);
118: }
119: }
120: }
121: }
122:
123: // 電源オフ操作 (Device::PowerOff ではない)
124: void
125: PowerDevice::DoPowerOff(MessageID msgid)
126: {
127: putlog(1, "PowerOff");
128:
129: assertmsg(msgid == MessageID::POWEROFF_EXIT ||
130: msgid == MessageID::POWEROFF_RESTART,
131: "msgid=%d", (int)msgid);
132:
133: if (ispower) {
134: // 全デバイス電源オフ
135: for (auto obj : gMainApp.GetObjects()) {
136: auto dev = dynamic_cast<Device *>(obj);
137: if (dev) {
138: dev->PowerOff();
139: }
140: }
141: ispower = false;
142:
143: // 動作モード変更
144: gSync->RequestPowerOffMode(true);
145: }
146:
147: // 電源オフ後の動作は引数によって異なる
148: if (msgid == MessageID::POWEROFF_RESTART) {
149: // 時間を始め直す
150: gScheduler->StartTime();
151: // 再び電源オンにする (リスタート)
152: DoPowerOn();
153: } else {
154: // そうでなければ、GUI に終了を通知
155: UIMessage::Post(UIMessage::APPEXIT);
156: }
157: }
1.1.1.2 ! root 158:
! 159: // 電源ボタン操作
! 160: void
! 161: PowerDevice::DoPowerButton()
! 162: {
! 163: putlog(1, "PowerButton");
! 164:
! 165: if (gMainApp.GetVMType() == VMType::X68030) {
! 166: // X68030 の電源ボタンはオルタネート動作
! 167: power_button = !power_button;
! 168: Change();
! 169: // MFP の POWSW 信号は負論理
! 170: gMFP->SetPowSW(!power_button);
! 171: } else {
! 172: // LUNA の電源ボタンはモーメンタリ動作
! 173: power_button = true;
! 174: Change();
! 175: power_button = false;
! 176: }
! 177: }
! 178:
! 179: // RP5C15 の ALARM_OUT を受け取る
! 180: void
! 181: PowerDevice::SetAlarmOut(bool alarm_out_)
! 182: {
! 183: alarm_out = alarm_out_;
! 184: Change();
! 185: }
! 186:
! 187: // システム内の電源オン信号を受け取る。
! 188: // __
! 189: // X68030 だと PW ON/OFF 信号(の反転)、
! 190: // LUNA だと PIO1 の POWF* 信号で、どちらの場合も true がオン。
! 191: void
! 192: PowerDevice::SetSystemPowerOn(bool poweron)
! 193: {
! 194: system_poweron = poweron;
! 195: Change();
! 196: }
! 197:
! 198: // 電源状態の変更。
! 199: // power_button、alarm_out、system_poweron のいずれかの変更で呼ぶこと。
! 200: void
! 201: PowerDevice::Change()
! 202: {
! 203: bool old_power = ispower;
! 204: bool new_power = power_button | alarm_out | system_poweron;
! 205:
! 206: if (old_power == false && new_power) {
! 207: DoPowerOn();
! 208: } else if (old_power && new_power == false) {
! 209: if (gMainApp.GetVMType() == VMType::X68030) {
! 210: DoPowerOff(MessageID::POWEROFF_EXIT);
! 211: } else {
! 212: gScheduler->RestartEvent(event);
! 213: }
! 214: }
! 215:
! 216: bool old_led = led;
! 217: if (gMainApp.GetVMType() == VMType::X68030) {
! 218: // X68030 の電源制御部の回路による。
! 219: led = power_button | alarm_out;
! 220: } else {
! 221: // LUNA の場合は電源の状態そのまま?
! 222: led = ispower;
! 223: }
! 224: if (old_led != led) {
! 225: // LED の状態が変わったことを UI に通知
! 226: UIMessage::Post(UIMessage::LED);
! 227: }
! 228: }
! 229:
! 230: // LUNA の電源オフが信号状態の変化に対し 1msec 遅れて応答することを
! 231: // エミュレートするためのイベントコールバック
! 232: void
! 233: PowerDevice::PowerCallback(Event& ev)
! 234: {
! 235: if (system_poweron == false) {
! 236: DoPowerOff(MessageID::POWEROFF_EXIT);
! 237: }
! 238: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.