paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

A Start-Stop button with Shutdown & Powerdown

Mon Aug 10, 2015 12:04 pm

This post is a follow-up one from some work done by SparkyPi, to create a button for the Pi with shutdown and power down features. viewtopic.php?f=107&t=113789 Initially, he wanted to use the Device Tree features to create a needed /KILL signal.
I found yet another way to create a GPIO pin that signals the end of the shutdown sequence, and that is posted here : viewtopic.php?f=41&t=114975

I liked SparkyPi's idea of using a simple chip to create a start-stop button, so I ordered some LTC2951-1 Pushbutton On/Off Controller chips. I was able to build and verify a prototype and was pleased to find that it does not even need Device Tree features, although that can be used to extend the functionality.

Initially, I wanted to control an XL6009S Buck Convertor with the EN output from the LTC 2951, to shut the power to the Pi. I use the combination Boost-Buck to always supply a precise 5V0 to the Pi, measured at TP-1 and TP-2, or at the end of the USB cable. However, I completely overlooked the real meaning of the EN input for the XL6009S. My initial understanding was that by driving the EN input low, the output would be cut. Not so! The EN input only disables the working of the chip, but the input power still goes to the output. If you look at the schematic, you'll see why. Duh!
XL6009-LM2596.png
XL6009-LM2596.png (15.22 KiB) Viewed 10628 times
Even if the chip has been disabled by pulling the EN low, the input voltage still goes through the coil and the Schottkey diode.

So the result was that I used one of my earlier trusted power switches in the schematic below:
Start_Stop.png
Start_Stop.png (40.69 KiB) Viewed 10628 times
Let's go over the building blocks. It makes sense to also look at the datasheet of the controller for more details. http://cds.linear.com/docs/en/datasheet/295112fb.pdf In short, U1 is the Start/Stop controller. It gets activated by a simple push button. When the power comes on, the Pi is powerless. When you push the button, the controller debounces the button, adds some delay and activates the EN output. The EN output goes to a power switch configured with an N-channel and a P-channel MOSFET. I selected a small device (Si4563DY) that packages both FET's. Most MOSFET's that are able to switch with a low voltage come in an SMD package, typically 3 pins, so why not go through the trouble to solder a few more and have a complete solution.

Note that if you use the LTC2951-2 variant, you don't need the N-FET. The polarity of the EN signal is inverted so it can drive the P-FET directly.

In any case when the EN signal goes high, power is applied to the Pi and it can boot.

When you push the button again, the /INT output goes low, to signal that power will be cut. This output needs to go to a GPIO input and needs to be monitored by a (daemon) program running on the Pi. As soon as the low has been detected, the Pi must start a shutdown sequence. After some delay, the controller drives the EN output low and the power to the Pi will be cut.

The required delay, needed for the shutdown sequence to finish, can be set by a capacitor on the KILLT input. I selected a 4.7uF to give me about 35 seconds between the button press and the EN signal going low.

To avoid an accidental shutdown by touching the button, a capacitor can be added to the OFFT input. I selected 470nF to create a delay of about 4 seconds. This means that you need to press the button for at least 4 seconds for the chip to validate this as a valid shutdown request. Note that this does not change the turn-on button press. I have added an LED to the output of the /INT output, because that LED will turn on as soon as the validation period has been met. So you have a visual indication. The LED will turn off when the EN signal is driven low at the end of the delay period, or the /KILL has been asserted.

Note that the (red) LED together with the 4K7 bias resistor lowers the 5V1 supply to about 3V6. This makes the LED light rather dim, but together with the series resistor of 1K, it provides sufficient protection for the GPIO input port so everything can be powered from the 5V1 coming from the wallwart. (tks Jojopi) If you cut a good quality (thick power wires) USB cable, you can easily put this circuit in the middle.

If you're concerned, or want a brighter LED, use a low current 3V3 Zener diode between the junction of the LED and the 1K series resistor and GND.

This is optional:
If you want to be really clever, you can use the procedure I wrote about in this post viewtopic.php?f=41&t=114975, and program a GPIO pin that changes state when the Pi is halted. The added benefit is that as soon as the Pi is telling us that the shutdown is finished, by changing the GPIO port, it will send the /KILL signal to the LTC-2951 and it will immediately cut the power to the Pi. In effect, cutting the delay period (set by C3) short. This can be useful if you need to do a lot of work to save the state of your environment on the Pi (making a backup of whatever) before the shutdown. You can now easily make C3 larger, knowing that the power will be cut anyway. If, for whatever reason, the Pi does not signal the /KILL, the Controller will still cut the power at the end of the delay period.

All in all, with two tiny SMD packages, a few resistors and capacitors and a very small piece of code, you can now create a start/stop button and remove the power to the Pi.

Note that the Pi will not start automatically when main power is switched on, you have to push the button.

Here is an example of the code to detect the /INT signal as an interrupt. This code needs to run as a daemon at startup.

Code: Select all

#!/usr/bin/env python
#-------------------------------------------------------------------------------
# Name:        module1
# Purpose:
#
# Author:      Paul
#
# Created:     15-06-2015
# Copyright:   (c) Paul 2015
# Licence:     <your licence>
#-------------------------------------------------------------------------------

import RPi.GPIO as GPIO
import subprocess

DEBUG = True

GPIO.setmode(GPIO.BCM) # use GPIO numbering
GPIO.setwarnings(False)

INT = 17 # GPIO-17 /INT signal
GPIO.setup(INT, GPIO.IN)

def main():
    while True:
        # set an interrupt on a falling edge and wait for it to happen
        GPIO.wait_for_edge(INT, GPIO.FALLING)

        if DEBUG: print "edge detected on /INT", GPIO.input(INT)

        subprocess.call(['halt'], shell=True, \
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)

if __name__ == '__main__':
    main()
Enjoy!
Last edited by paulv on Tue Aug 11, 2015 10:42 am, edited 4 times in total.

User avatar
jojopi
Posts: 3817
Joined: Tue Oct 11, 2011 8:38 pm

Re: How-To Create a GPIO Halt Signal

Mon Aug 10, 2015 9:40 pm

paulv wrote:I have added an LED to the output of the /INT output, because that LED will turn on as soon as the validation period has been met. So you have a visual indication. The LED will turn off when the EN signal is driven low at the end of the delay period, or the /KILL has been asserted.
I thought the LED was to avoid pulling the GPIO input all the way to 5.1V, which would be bad. Either way, since /INT is open drain, I think it would be better to pull it to 3.3V. That should not stop the LED working when the pin goes low.

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: How-To Create a GPIO Halt Signal

Tue Aug 11, 2015 6:40 am

Jojopi, that is true.
But by needing a 3V3 level, you now need two extra wires and cannot put this circuit in the middle of a cut USB cable easily anymore, unless you add a Zener and bias resistor. The 4K7 resistor and the LED together with a 1K resistor in series (not shown, but I always use that) should provide sufficient protection to the GPIO port.

I've updated the circuit diagram and provide a warning in the text.
Tks for pointing it out.

sparkyPi
Posts: 33
Joined: Thu May 21, 2015 8:51 pm

Re: A Start-Stop button with Shutdown & Powerdown

Sun Aug 16, 2015 9:30 pm

paulv wrote:This post is a follow-up one from some work done by SparkyPi, to create a button for the Pi with shutdown and power down features. viewtopic.php?f=107&t=113789 Initially, he wanted to use the Device Tree features to create a needed /KILL signal.
I found yet another way to create a GPIO pin that signals the end of the shutdown sequence, and that is posted here : viewtopic.php?f=41&t=114975

I liked SparkyPi's idea of using a simple chip to create a start-stop button, so I ordered some LTC2951-1 Pushbutton On/Off Controller chips. I was able to build and verify a prototype and was pleased to find that it does not even need Device Tree features, although that can be used to extend the functionality.

<snip>

This is optional:
If you want to be really clever, you can use the procedure I wrote about in this post viewtopic.php?f=41&t=114975, and program a GPIO pin that changes state when the Pi is halted. The added benefit is that as soon as the Pi is telling us that the shutdown is finished, by changing the GPIO port, it will send the /KILL signal to the LTC-2951 and it will immediately cut the power to the Pi.

<snip>
Excellent summary of using the LTC2951-1 on/off controller! Thanks, Paul, for bringing it all together with clear schematics and description. Also, thanks for your acknowledgement back to my original work. I will post schematics of my implementation which is a bit different later. For now, I just want to make a comment regarding the "power cut" signal.

Implementing /KILL signal from the Broadcom chip is exactly the purpose of the gpio-poweroff overlay, and it can be configured in just one line of /boot/config.txt, without need to edit and compile device-tree source files. For example, in /boot/config.txt add:

Code: Select all

dtoverlay=gpio-poweroff,gpiopin=4,active_low="y"
I suggest using gpio-poweroff overlay as an alternative and simpler approach to what you discuss in "How-To Create a GPIO Halt Signal" thread, which requires customizing dt-blob.dts and steps to compile it. I think editing/compiling dt-blob.dts is more troublesome, and will be more effort to maintain overtime, e.g. you change to a different Raspberry Pi model (e.g. B to A+) you will need to edit a different section of dt-blob.dts. In addition, you may have to occasionally re-download the source dt-blob.dts file as it may get updated, and then re-incorporate your edits and compile it again.

One other related but general comment: by thoughtful choice of GPIO output for /KILL (e.g. GPIO 4 which has default pull-high), and specifying "active_low" parameter for the gpio-poweroff overlay (as above), you can simplify your circuit: Q1, R2, R3 no longer required.

Have you tried the gpio-poweroff overlay with your LTC2951-1 circuit? I wonder what problems or issues you have with it, such that you prefer to, or must, manually edit and compile dt-blob.dts.

sparkyPi

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: A Start-Stop button with Shutdown & Powerdown

Tue Aug 18, 2015 5:55 pm

Hi sparkiPy,

Thank you for taking the time to look at my post.
To clarify a comment you made, I'm not advocating one method over the other, however, there are, in my opinion, three side effects introduced by using the GPIO-poweroff method that users need to be aware of. I already reported that in your original post with some scope traces.

To recap, when you use the GPIO-poweroff method:
1. There is a 3.5 Sec. delay after a power-up before the targeted pad is pulled high. Of course that can be masked by either installing a hardware pull-up or use one of the pins that already have a hardware pull-up.
2. The TxD pin now behaves differently at the end of the Halt/Shutdown sequence because the kernel sends out more information it didn't do before, and, more importantly, it no longer goes low at the end of the sequence.
3. Most important is that the reset from Halt by shortening GPIO-4 to GND no longer works.

I could not find any side effects when using the dts method, apart from maybe an installation or maintenance issues as you pointed out.

All in all, I think that we have now two methods to implement something that has eluded users for a long time, and even commercial products do not really solve well.

So, between the two of us with some help from PhilE, we have found a solution and in the process established two different methods to create a GPIO pin that will signal the end of the Halt/Shutdown sequence. It's now up to the user to know what the effects are, and then use whatever works best for them.

Going back to the use of the LTC start-stop controller. I have shown that by selecting the right capacitor value for the KILLT pin, there is no need to have the /KILL signal implemented through the kernel at all. The suggestion in my post was that you only use that if you are interested to kill the power immediately after the Halt or Shutdown sequence has finished. If you can allow a little delay between the sequence and the cutting of the power, you don't need the /KILL signal and don't need to have the FET and resistors. This is totally optional and I guess we can leave that to the user.

I hope this clarifies it more.

sparkyPi
Posts: 33
Joined: Thu May 21, 2015 8:51 pm

Re: A Start-Stop button with Shutdown & Powerdown

Mon Aug 24, 2015 2:36 am

paulv wrote:Hi sparkiPy,
Thank you for taking the time to look at my post.

<snip>

Going back to the use of the LTC start-stop controller. I have shown that by selecting the right capacitor value for the KILLT pin, there is no need to have the /KILL signal implemented through the kernel at all. The suggestion in my post was that you only use that if you are interested to kill the power immediately after the Halt or Shutdown sequence has finished. If you can allow a little delay between the sequence and the cutting of the power, you don't need the /KILL signal and don't need to have the FET and resistors. This is totally optional and I guess we can leave that to the user.

I hope this clarifies it more.
Thanks for the follow-up, Paul, that does help clarify your findings.

Before I had the /KILL signal implemented I used the same method as you describe for delaying the power cut by careful sizing of the KILLT capacitor. In my case I set it to ~90 seconds, which is much longer than I observed it ever take for the RPi to shutdown, and so no matter what the RPi might have been doing at the time of the shutdown request, I really expect shutdown to be complete after 90 seconds. It is fortunate that using /KILL is optional, because that extra I/O might be required for other hardware in some systems, and in those cases using gpio-poweroff wouldn't be a viable because the I/O would always be tied up as the KILL signal.

Cheers,
sparkyPi

guischall
Posts: 1
Joined: Tue Sep 08, 2015 12:35 am

Re: A Start-Stop button with Shutdown & Powerdown

Tue Sep 08, 2015 2:00 am

Hi guys,

I'm researching on this subject for some time now, but I have very little experience on both Raspberry Pi and (even less) on circuit design. I stumbled upon this discussion and read all related threads, but I still lack a bit of understanding. Maybe you can help me out a little.

My goal is to use LC295x-1 to drive the Enable Pin on a Adafruit Powerboost 1000C board to power up/down a Raspberry Pi.

I have a few concerns, though:

1 - Where is the best source to pull-up /INT? I was aiming to use the regulated 3V3 pin from GPIO. But the example circuit here uses the 5V line in series with a diode. Are there any differences?

2 - I understand the option to tie /KILL to the source and keep it always on, so I'll wait for the Kill timer to shut EN down every time. But I still feel the need to give a more elegant solution and drive /KILL down by myself (I was even thinking to use LC2954-1 instead of LC2951-1, this version waits forever for a /KILL signaling or you press PB long enough to cut EN). But I'm really confused about all this "GPIO-TXD-halt-state-pull-up-down" information. I thought it would be easy to set a pin high (output, high, pulled down) on startup and this pin would go automatically low by default once a system shutdown completes. Could you guys explain this behavior in a more beginner friendly way?

3 - All versions of this IC states about a 512ms blanking time, during this period /KILL and PB will be ignored so the system have enough time to startup and drive /KILL high. Is this enough to Raspberry Pi to receive power, startup and drive /KILL high (if I decide to go through the elegant solution road)?

any help will be welcome.
thx.

paulv
Posts: 564
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: A Start-Stop button with Shutdown & Powerdown

Thu Sep 10, 2015 10:11 am

My answers and comments are in the text below:
guischall wrote:Hi guys,

I'm researching on this subject for some time now, but I have very little experience on both Raspberry Pi and (even less) on circuit design. I stumbled upon this discussion and read all related threads, but I still lack a bit of understanding. Maybe you can help me out a little.

My goal is to use LC295x-1 to drive the Enable Pin on a Adafruit Powerboost 1000C board to power up/down a Raspberry Pi.
-- Since you say you do not have a lot of experience, I would caution you to be extremely careful when dealing with Lipo cells. These cells have a volatile attitude and will explode when mistreated.

I have a few concerns, though:

1 - Where is the best source to pull-up /INT? I was aiming to use the regulated 3V3 pin from GPIO. But the example circuit here uses the 5V line in series with a diode. Are there any differences?
-- Depends on what you want to do/have. I used the 5V line to get a visual by the dual purpose LED. If you don't want/need that, you could use the 3V3 to pull this output up.

2 - I understand the option to tie /KILL to the source and keep it always on, so I'll wait for the Kill timer to shut EN down every time. But I still feel the need to give a more elegant solution and drive /KILL down by myself (I was even thinking to use LC2954-1 instead of LC2951-1, this version waits forever for a /KILL signaling or you press PB long enough to cut EN). But I'm really confused about all this "GPIO-TXD-halt-state-pull-up-down" information. I thought it would be easy to set a pin high (output, high, pulled down) on startup and this pin would go automatically low by default once a system shutdown completes. Could you guys explain this behavior in a more beginner friendly way?

-- Well, as you have already noticed, it's more difficult than you at first think. Since you say you are not that well versed, I would stay with the above circuit, and at first not deal with the /KILL signal at this moment. After you have gotten everything to work, you can tune the shutdown period by selecting a more appropriate capacitor value. If still not satisfied, then start to experiment with the two methods (that of sparkyPi and my own) that are discussed to create this signal. The posts and comments for both versions should give you enough information to make it work.

3 - All versions of this IC states about a 512ms blanking time, during this period /KILL and PB will be ignored so the system have enough time to startup and drive /KILL high. Is this enough to Raspberry Pi to receive power, startup and drive /KILL high (if I decide to go through the elegant solution road)?

-- Good point. At first I thought this would pose a problem too, but it works for me in both variations (with and without using /KILL) of the circuit I posted. Note that if you use the other method, which takes a lot longer to drive the GPIO pin after power-up, you may run into this. I have not tested this myself. Maybe sparkyPi can chime in.

any help will be welcome.
thx.
Last edited by paulv on Thu Dec 03, 2015 10:18 am, edited 2 times in total.

sparkyPi
Posts: 33
Joined: Thu May 21, 2015 8:51 pm

Re: A Start-Stop button with Shutdown & Powerdown

Fri Oct 09, 2015 6:31 am

paulv wrote: <snip>
Maybe sparkyPi can chime in.
Thanks, paulv, I'm pretty late to the party, so to speak, but happy to offer my thoughts :) When reading my responses below you might like to refer to this post with schematics of the implementation I use.
guischall wrote: 1 - Where is the best source to pull-up /INT? I was aiming to use the regulated 3V3 pin from GPIO. But the example circuit here uses the 5V line in series with a diode. Are there any differences?
You can use the 3.3V from the GPIO header; that's what I do. Referring to the link I posted above you'll see in the schematics therein have /INT pulled to "3.3VRpi" (meaning the 3.3V on the 40-way header of the Raspberry Pi). Even though I have an additional 3.3V low drop-out (LDO) regulator on my board (U10) to power various sensors, I have the option of not populating the LDO and sourcing the 3.3V needed for the sensors from the GPIO header. I'm always guaranteed that 3.3V is available at the GPIO header, so I use that as the pull-up voltage.
guischall wrote: 2 - I understand the option to tie /KILL to the source and keep it always on, so I'll wait for the Kill timer to shut EN down every time. But I still feel the need to give a more elegant solution and drive /KILL down by myself (I was even thinking to use LC2954-1 instead of LC2951-1, this version waits forever for a /KILL signaling or you press PB long enough to cut EN). But I'm really confused about all this "GPIO-TXD-halt-state-pull-up-down" information. I thought it would be easy to set a pin high (output, high, pulled down) on startup and this pin would go automatically low by default once a system shutdown completes. Could you guys explain this behavior in a more beginner friendly way?
As Paul has mentioned and explained in his posts there are some "gotchas" to be aware of, but I don't think it has to be complicated --- it can be simple with some consideration of the GPIO pin you use, and use a 4.x.y kernel. Refer again to my schematics and you'll note GPIO4 is tied to the /KILL pin. As I mention in some posts above GPIO4 is pulled-high by default (internally of Broadcom, automatically and "instantaneously" at power-up and restored to the high state at cold boot and reboot (but beware: default GPIO behavior has changed over time and this is not true for older kernels)) and as it's connected to /KILL the LTC2951-1 is not shutdown.

To elegantly kill power (i.e. remove power only once the system reaches halt state) use the gpio-poweroff DT overlay (as shown in my code snippets above). This will instruct the kernel to drive GPIO4 low when the system reaches halt. If the system hangs during shutdown and prevents /KILL from going low, the LTC2951-1 will eventually "time out" and release the EN output. I like the idea of a finite shutdown time because I am assured that, even in the event of some kind of shutdown error, the system power will eventually be cut. This is important for me as my system runs on battery power.
guischall wrote: 3 - All versions of this IC states about a 512ms blanking time, during this period /KILL and PB will be ignored so the system have enough time to startup and drive /KILL high. Is this enough to Raspberry Pi to receive power, startup and drive /KILL high (if I decide to go through the elegant solution road)?
In my experience, yes, it is. In my early experiments I had an external pull-up on /KILL to either the 3.3VRpi or 3.3V LDO output. Ever since I changed to a GPIO that defaults to pull-high I've been able to do without any other pull-up. I have 4 systems running with this configuration of LTC2951-1 for several months, turned on and off at least once per day. In that time I've not encountered an instance of unexpected shutdown during boot because /KILL was low.
guischall wrote: any help will be welcome.
thx.
Your welcome!
sparkyPi

Return to “Other projects”