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:

Greenonline
  • 2,969
  • 5
  • 27
  • 38
fkarlsson
  • 73
  • 7

3 Answers3

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.

Greenonline
  • 2,969
  • 5
  • 27
  • 38
Philip Cook
  • 66
  • 1
  • 1
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.

fkarlsson
  • 73
  • 7
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.

nnn
  • 156
  • 5