5

I have an SMBUS (I2C, SMART Battery/charger) communication connected to the RPi:

Pin 3 GPIO2 SMBUS SDA Pin 5 GPIO3 SMBUS SCL

When pin 5 is connected, the system will wake up after approx 5-20 secs again after sudo shutdown -h now. If I disconnect pin 5, the system never boots unless I power cycle.

I suspect the wake-from-halt function is related to this. How can I prevent the Pi from booting again?

I have tried different varieties of shutting down; sudo halt, sudo shutdown -h now, sudo shutdown -h -H now. All display the same behaviour.

Links to the board/battery connected on pin 3/5:

8
  • Presumably this is because when the clock signal stops the battery takes it as a motive to act. You cannot prevent the pi from rebooting if the power is cycled by the supply or GPIO 5 is pulled low. You may be able to prevent the latter by altering firmware, but if it is the former you are out of luck.
    – goldilocks
    Commented Nov 22, 2016 at 17:22
  • Welcome to the Raspberry Pi flavoured corner of the Stack Exchange network. I'm trying to get my head around your set up. You have effectively a UPS system but when you tell the RPi to shutdown it reboots after a short while, which is not what you expect. Don't forget that the I2C bus pins on the RPi have a 1K8 pull-up to the RPi 3V3 power supply so if that goes down it will drag the I2C bus lines down as well - which, as they are normally driven as "open-collector" lines by all slave devices might be upsetting the (presumably slave) device that is the battery control system.
    – SlySven
    Commented Nov 22, 2016 at 18:09
  • @SlySven thanks for your reply. I'm mostly trying to understand what's happening. This might not be a problem in the long run, but during development I want to be able to shut down the RPi properly to prevent SD card corruption. Later I will put the SD in read only, as the system will be designed to handle that the battery runs out of power. My suspicion right now is that the PMM240 board acts as both i2c slave and master (it can communicate with the battery, as well). There is a way to configure the PMM240 board to act as slave only.
    – fkarlsson
    Commented Nov 23, 2016 at 8:46
  • @goldilocks thanks for your reply, and thanks for confirming that there is no (simple) way to disable wake-from-halt. I will see if I can reconfigure the PMM240 board in some way to prevent this unwanted behaviour.
    – fkarlsson
    Commented Nov 23, 2016 at 9:15
  • 1
    @ppumkin yes that's exactly what it means! Opens up for a lot of possibilities and in my case some problems. :)
    – fkarlsson
    Commented Jan 11, 2017 at 14:19

3 Answers 3

5

Yes there is a way to disable GPIO3 (physical pin 5) pulled low to boot.

In /boot/config.txt add the line

dtoverlay=gpio-poweroff

See the documentation for overlays in /boot/overlays/README. The entry for gpio-poweroff states:

Name:   gpio-poweroff
Info:   Drives a GPIO high or low on poweroff (including halt). Enabling 
        this overlay will prevent the ability to boot by driving GPIO3 low.
Load:   dtoverlay=gpio-poweroff,<param>=<val>
Params: gpiopin             GPIO for signalling (default 26)

        active_low          Set if the power control device requires a
                            high->low transition to trigger a power-down.
                            Note that this will require the support of a
                            custom dt-blob.bin to prevent a power-down
                            during the boot process, and that a reboot
                            will also cause the pin to go low.
        input               Set if the gpio pin should be configured as
                            an input.
        export              Set to export the configured pin to sysfs

Disabling GPIO3 boot behaviour is a documented side effect of enabling gpio-poweroff. Best check you are not using GPIO 26 for anything, else you will need to change the default poweroff pin.

I am using this 'feature' on a RPi3 running Raspbian STRETCH.

I was experiencing similar issues of I2C devices triggering unwanted restarts once the Pi was in halt.

1
  • That's great news! Thanks, marking your reply as the new answer.
    – fkarlsson
    Commented Nov 5, 2018 at 15:55
2

Courtesy of @goldilocks and @SlySven it has been confirmed that there is no way to disable the wake-from-halt feature (= Pulling GPIO5 low causes RPi to boot).

The RRC2040 has a builtin feature which allows it to act as an I2C master in order to send updates to Smart Chargers and an SMBus Host. This subsequently also causes the RPi to boot if the I2C SCLK is connected. The battery can be configured to act as slave only but that kind of defeats the whole purpose of using a "Smart Battery".

My solution will be to configure the RPi in such a way that turning off power without first shutting down the OS will not cause problems. This will have additional benefits, either way.

0

[Edit:] This solution doesn't work, since the RRC Battery switches on Alarm_Mode every 60 seconds if it doesn't get reset according to the documentation:

The ALARM_MODE bit is automatically cleared by the Smart Battery electronics every 60 seconds so that any accidental activation of this mode will not be persistent. A SMBus Host which does not want the Smart Battery to be a master on the SMBus must therefore continually set this bit at least once per 45 seconds to keep the ALARM_MODE bit set.

But maybe someone finds this helpful:

The RRC2040 Smart Battery Pack per default is configured to regularly send charge information and alarm messages (for example low battery status). The battery switches from beeing a slave device to the master role to send these messages (it sends without beeing asked). In your case (and mine, too) these messages cause the Raspberry to boot.

According to the documentation (Page 20) you can switch off these status messages. You have to disable ALARM_MODE and CHARGER_MODE (0 enables, 1 disables).

In Python3 this can be achieved by:

import smbus2
bus = smbus2.SMBus(1)

def set_bit(value, bit):
    return value | (1<<bit)

BatteryMode = bus.read_word_data(0xb, 0x03)

BatteryMode = set_bit(BatteryMode, 13)  # disable ALARM_MODE
BatteryMode = set_bit(BatteryMode, 14)  # disable CHARGER_MODE

bus.write_word_data(0xb, 0x03, BatteryMode) # Write BatteryMode

You can re-enable the broadcast messages with:

import smbus2
bus = smbus2.SMBus(1)

def clear_bit(value, bit):
    return value & ~(1<<bit)

BatteryMode = bus.read_word_data(0xb, 0x03)

BatteryMode = clear_bit(BatteryMode, 13)  # enable ALARM_MODE
BatteryMode = clear_bit(BatteryMode, 14)  # enable CHARGER_MODE

bus.write_word_data(0xb, 0x03, BatteryMode) # Write BatteryMode

0xb is the default address of the RRC Smart Battery.

Of course other devices could still wake the Raspberry, but for the RRC Battery this should solve the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.