Controlling power off
Chris Hall (132) 3510 posts |
I have a small RISC OS computer (4″ x 4¼″ x 1½″) which uses two push buttons: one to turn it on and one to request power off. (The button to turn it on also does a battery test and can be sensed so that a log download to pen drive can be initiated if a suitable drive is present.) It has no mouse, keyboard or monitor but uses an OLED display and a PaPiRus display. I use a simple circuit to turn it on, using one of the GPIO outputs (BCM 4) to hold it on. The software senses the ‘off’ button, closes the logs and (at present) sets GPIO 4 to low to power off. Ideally I would use SYS “TaskManager_Shutdown” with the ‘power off’ option (as that also updates the CMOS ‘last on at’ clock time) but that would produce an error ‘no power control available’ (even though there is). I also place a file in !Boot.Choices.Boot.PreDesk containing:
so that within about 6 seconds of start up, you can let go the ‘on’ button. Is there a way to issue these commands earlier in the boot sequence (or as a command in the Pi’s config.txt or as a blob)? How do I tell RISC OS that there is power control available? Vs is at 3.3V when just the internal battery (LiPo) is the only power source and rises to 5V if an external power source or battery is attached to float charge the internal battery. A clever little board boosts the 3.3V or 5V to 5.2V to supply the Pi and is turned on and off by the ‘ENABLE’ signal (shown as ‘EN’ above).. |
Martin Avison (27) 1428 posts |
Sorry, cannot help with your question … but your diagram on NetSurf 3.6 is big – I need to reduce the scale to 20% to see it. Then I cannot read the text! |
Chris Hall (132) 3510 posts |
OOps! Now sorted. |
Steve Pampling (1551) 7955 posts |
Wouldn’t if be better with a classic S-R latch? |
Chris Hall (132) 3510 posts |
Many thanks for the comments. There are complications so I designed it from first principles. The GPIO logic is 3.3V whereas the supply Vs is either 3.3V or 5V depending on whether an external battery is fitted. So it has to do level conversion as well (the ENABLE pin is pulled up to Vs via a 200k resistor on the powerboost circuit board and just needs to be grounded when nothing is happening and allowed to float when you want the power to be turned on but GPIO logic is 3.3V whether Vs is 3.3V or 5V). But in any case it works and my question is about software rather than hardware (I know I could improve on the hardware design but as my first hack worked that’s for another day). Also I need to be able to sense the ‘on’ button using 3.3V GPIO logic (resistors R1, R8 and R9 act as a voltage divider circuit with the LED forward voltage helping to obtain about 2.7 to 3.3V for GPIO 19 input whether Vs is 3.3V (LED out and thus open circuit) or 5V (LED lit with forward voltage of 2.7V)) and when pressed the ‘on’ button has to provide Vs to a panel voltmeter. I should probably add a diode from GPIO 19 to 3.3V to protect the GPIO input from the LED going open circuit whilst Vs=5V. R1 is 470, R8 is 220 and R9 is 900 or 1000 (chosen so that the LED just doesn’t light with Vs=3.3V) so GPIO 19 would go to 1220/1690*5 = 3.6V if the LED blows. |
Chris Hall (132) 3510 posts |
I think one element of my question I can answer myself. As power will go off if GPIO 4 is set to low or high impedance, a shutdown sequence followed by ‘restart’ will cause power to go off. I think this will be when the GPU is reset by RISC OS but it may be when the GPIO module is killed or restarted, not sure which. Hence I can just do a shutdown with forced restart to make power go off, rather than set GPIO 4 low. This will update the CMOS clock as well. |
Chris Hall (132) 3510 posts |
Many thanks for the ideas. I did think of a four transistor solution but there were too many components to fit in. One problem with the two transistor solution is that you have to hold the ‘on’ switch down for 6 seconds (until PreDesk takes over). I ended up with a four NAND gate solution – a single chip that works off a power supply between 2 and 6 volts – which seems to fit the bill (but as yet untested). Momentarily pressing the ‘on’ button puts the ENABLE output to high, turning on the powerboost board. Pressing ‘on’ later can be detected and used to initiate a log download. During start up (PreDesk) GPIO4 is set high so that the ‘off’ switch has to be sensed via GPIO 26, all software logging completed and a desktop shutdown/restart cycle initiated. This makes sure that the SD card is not being written to and that the ‘last time on’ time is updated in CMOS – there is no real time clock available until the GPS data can be processed – during the startup, the ROM modules (including GPIO) are initialised, taking GPIO 4 to a high impedance state and thus removing the power. A 3.3V ‘high’ input from GPIO 4 should be just within spec for a 74HC00 being fed at 5V. Power consumption whilst ‘off’ is a few tens of microamps. |
Chris Evans (457) 1614 posts |
We looked into doing something like this for the Pi’s power control when putting it into a MiniITX case, we thought we had a solution (similar to yours) but it was then pointed out to us that the state of key parts on power up wasn’t certain. Fortunately someone mentioned that using a PIC and talking to it over I2C was a good solution. Even better they offered to write the code:-) It only uses an 8 pin SOIC PIC and very little else! |
Jeffrey Lee (213) 6046 posts |
You should be able to move it a bit earlier by running the code from within the Choices:Boot.PreDesktop file. You could also try moving it directly to !Boot.!Run or !Boot.Utils.BootRun, but running PreDesktop looks like it’s the first significant thing that happens (time-wise), so I don’t think that would help much.
You can’t. The task manager checks for the functionality using OS_ReadSysInfo 8, and then requests the power-off via OS_Reset. Both of these calls go to the HAL, so apart from building your own ROM with suitable power control logic in place, there’s no (legal) way of overriding them. Since power control hardware seems to be a common thing, I’ve been thinking for a while that it would be nice to have some way of allowing soft-loadable power control drivers. But the feature is yet to reach the point where it’s near the top of my todo list. |
Rick Murray (539) 13422 posts |
Maybe extending the Portable module to include “power off”? And possibly deprecate a lot of the stuff there that was only supported on the A4 (which cannot run RO5)? It may also be good to allow extension modules to use/update the battery charge information as well – https://www.riscosopen.org/wiki/documentation/show/Battery%20Management%20Unit%20variables – and for an event to be available (if it isn’t already) for power loss (mains→battery) and vice versa, charging, and low-must-shutdown. The latter might also be of use of the machine is connected to a UPS? |
Rick Murray (539) 13422 posts |
Aha – there is an event. Good… https://www.riscosopen.org/wiki/documentation/show/Event%2028 – but it needs an extra bit too indicate “external power fail” (ie we’re now running only off battery – the implication being that unlike the A4, this is not a normal state of affairs…). Now what we need is an extra flag in the Quit and PreQuit Wimp messages to inform the application that the system will be shutting down due to power loss, refusal isn’t an option (could dump data to scrap or something?). |
Rick Murray (539) 13422 posts |
I say this because sometimes Mon had to sit down the server Pi because of thunderstorms. She knows how to do that with the keyboard (Ctrl-Shift-F12) but there’s a long list of things that could complain – I have to be sure to leave the machine with no RAMdisc, no TaskWindow, etc etc. |
Jeffrey Lee (213) 6046 posts |
Ironically, the task manager used to include code for power-off via the Portable module (using the “remove power” BMU command). But somewhere along the way that was lost and replaced with the kernel/HAL based approach.
There are quite a few SWIs which the HAL version of the Portable module doesn’t support, so I think we’ve got that covered.
That should be pretty straightforward, I just need to update the module to support registering/deregistering BMU devices at runtime.
Yes, the original version(s) had an event to notify the system of state changes. Those aren’t hooked up to the HAL version yet. https://www.riscosopen.org/wiki/documentation/show/Event%2028 |
Chris Hall (132) 3510 posts |
but it was then pointed out to us that the state of key parts on power up wasn’t certain I have found that BCM 4 is high impedance from power on, also is unchanged on a shutdown but selecting ‘restart’ initialises the ROM modules (including GPIO) causing GPIO 4 to go high impednace (removing power) after which I lose interest! The Vs supply is obtained from a battery, not the Pi, via the powerboost board which allows a LiPo internal battery (3.3V) to be float charged on top of an external power source (either 5V battery or mains adapter). If the external source is present, then the Pi is supplied [if ENABLE is high] and the LiPo battery is charged simultaneously, both from the external source. If not, then the Pi is supplied [if ENABLE is high] from the internal LiPo via a voltage booster. I can confirm that the two transistor method works perfectly with SatNav 1.61 (albeit with the need to hold ‘on’ button down for 6s until RISC OS has done !Boot.Choices.PreDesk.SetGPIO4 and asserted GPIO 4). Shall be testing the 74HC00 solution in the next few days (which should only need a momentary press of the ‘on’ button). Edit (5 Aug): And I can also confirm that the NAND gate method works as well. |