Custom firmware upload without reboot


I’m using the GrovePi+ on a Raspberry Pi 4 with Ubuntu Server (arm64) and components that are not supported in the default Firmware, so I implemented a custom one.

I use avrdude 6.2 for arm64 with gpio to upload the firmware with the following commands:

avrdude -c linuxgpio -p m328p -U lfuse:w:0xFF:m
avrdude -c linuxgpio -p m328p -U hfuse:w:0xDA:m
avrdude -c linuxgpio -p m328p -U efuse:w:0x05:m
avrdude -c linuxgpio -p m328p -U flash:w:firmware.hex

This works fine and all fuses are ok, but when I now run i2cdetect -y 1 it does not find the GrovePi+ at 0x04 anymore and I need to reboot the Pi. After the reboot it detects it again and I can use the firmware and all components are working.

Can I do something after uploading the firmware to “reset” the GrovePi+ without the need to reboot the whole Pi?

1 Like

I finally found a solution to solve this issue:

After uploading the custom firmware the GrovePi+ was not reset by avrdude and running avrdude -c linuxgpio -p m328p did not help too.

I also tried to use WiringPi but it was not able to access the GPIO, the solution is to use sysfs to do the reset, I use this small script (which has to be run as root):

echo "8" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio8/direction
echo "1" > /sys/class/gpio/gpio8/value
echo "8" > /sys/class/gpio/unexport

After running the script i2cdetect -y 1 finds the GrovePi+ at 0x04 again!

Hope this may help someone who has the same issue.



You talk about gettin’ down-and-dirty? I’ve done some bare-metal coding in my past but NOTHING like this.

What changes did you implement? How did you change them?

How did you even RIP the original software - which is what I am assuming you did.

You have my curiosity perked up!

You gotta’ BIGGER SET than I do - my ears are still smoking!

1 Like

@mitch.kremm, will this work with the GoPiGo3 when I have I2C failure?

Is the any possibility It would harm my GoPiGo3?

1 Like

The port numbers for the i2c interface may be different, but other than that, I can’t see how it could hurt things.

What you really need is a watchdog for the i2c interface that would kick it up the bum if it detects a data transfer failure.

1 Like

Let me check with the team and @cleoqc. I really have no idea!


What you REALLY need is an i2c buffer chip on the GPG controller board that takes the “custom” i2c implementation on the Pi and translates, (both ways), into the normal and expected i2c signals.

That done, problem is solved!

1 Like

Actually it needs a little bit more than that - ability to cycle a slave’s power to the I2C connector.

The forum reports folks seeing these I2C failures and needing to power cycle the slave devices before communication can be restored.

I also want the addressable power switch feature so I use power hungry sensors only when I need to them.

1 Like

I strongly suspect that the issue with the slaves is that they get a malformed data-stream from the Pi, go all pear-shaped, and choke.

The way to keep the slave devices from choking is to avoid them going all pear-shaped, and the way to avoid that is to not send them malformed data streams.


Active power-switching is an entirely different subject.

The simplest active power switch is a power MOSFET pair, connected between VCC and ground - with the power lead to the device connected to the center point of the MOSFET pair. If you tie the two gates together and bring them out to a pin, (through a suitable isolating resistor), driving the pin one way will turn power on to the device. Driving the pin the other way will disconnect it from VCC and tie the device’s VCC input to ground, preventing it from being damaged because VCC was left floating. The problem with this is that it assumes you have enough GPIO pins available to switch every device you want to control.

There are pre-packaged MOSFET pairs with a certain number of pairs per chip, kind of like the 7400 series IC’s with six inverters or four op-amps in them.

The design is simple bordering on trivial. Implementation won’t be because a standard single or double sided board will be huge unless you get fancy with multiple layers and ground/power planes within the PCB itself.

Take a look at DigiKey or Mouser, they might have this as a complete assembly.


Another issue is where you will put it? Even if it’s small, it won’t be tiny, and spare space on a GoPiGo is at a premium. Not to mention that you will have to cut interface cables and hard-wire the device to the Grove connector cable and whatever GPIO pin you were using to control it.


One thought would be to make it an in-line device, one switch per device and using the “alternate” data pin on the Grove connector to control the switch. Unfortunately, this would only work on an A/D connector. Switching power to any connector being used for i2c would require the switch to be hard-wired.

No, what I want is a tiny I2C distribution board that itself has an I2C address used to turn the power and bus extension to individual I2C ports on/off.


1 Like

I don’t know if you ever watched the series Firefly. One of my favorite lines (by the character Jayne) was “If wishes were horses, we’d all be eating steak” :robot:



What’s that?

Then your addressable power board would go sideways on the next malformed I2c packet. :wink:



To be honest, that shouldn’t be too difficult.

A micro controller, maybe a decoder chip, and some wild-donky software and you’re in!

It’s the software that would be the tough part.

1 Like

I basically use a complete custom firmware, I’m using the 4 - Channel SPDT Relay, some single Relays, Temperature&Humidity Sensor Pro(DHT22), Water Atomization and Electricity sensor. Some of them not supported by the default firmware.

On the Raspberry Pi I switched from Ubuntu Server (arm64) to a custom system that I develop using buildroot, because Ubuntu had too many things installed that I don’t need and I also want to use Rauc to install OTA updates on the device. I also uses the 7" touchscreen and vc4-fkms-v3d did not work with Qt Qml eglfs either.

When the prototype is finished I will open source the project and when I have the time, write some blog posts how I did it because I barely found any good informations on the internet how to accomplish something like that. Also thinking of commercializing it when it works well for me so people who need something similar but aren’t able to build it on their own can buy the whole system, but that will be a longer way from now as I’ll have a full time job as a software engineer and only work on it in my spare time right now.


I guess you did it incorrectly. The code snippet below should temporarily reset it:

import wiringpi
import time

def reset_grovepi_mcu():    
    wiringpi.pinMode(8, 1)
    wiringpi.digitalWrite(8, 0)        # Pull nRESET pin low
    wiringpi.digitalWrite(8, 1)        # Release it

1 Like

Good find and thanks for sharing!