pi3hat firmware release 2025-09-20

It has been a minute since there has been a pi3hat firmware release, but we have a new one out now, that fixes a longtime usability issue with the pi3hat as well as improves its ability to drive busses with many devices. The release, 2025-09-20 can be found on github with the source and firmware elf. If you’re not running into problems, there is no real need to upgrade, but read on to see if it is something you might be interested in.

The problem

Ever since the pi3hat was released there has been a usability issue with respect to sending frames to non-existent devices. As a bit of background, the pi3hat has 5 CAN-FD ports, which are driven by 3 separate STM32G4 microcontrollers. JC1 and JC2 share a controller, JC3 and JC4 share one and JC5 shares one with the IMU. If you ever attempt to communicate with a servo on a bus that has nothing connected, the firmware on that microcontroller effectively becomes unable to send any other CAN frames, even on the other port it controls. This can happen if you get the --pi3hat-cfg configuration temporarily incorrect and once it is triggered the only resolution is to power cycle the pi3hat.

The resolution to this issue is basically the same as the recent mjcanfd-usb-1x firmware release, in that frame transmissions are cancelled 50ms after the last frame was submitted to the hardware queue. With that fix, all the CAN ports remain usable even when sending frames to disconnected ports.

Queue size increase

Also matching the mjcanfd-usb-1x release, the internal software transmit and receive queue for the pi3hat is increased from 6 frames to 32 frames per port. This lets the pi3hat drive much longer chains in pipelined mode at a high rate.

Upgrading

The pi3hat does not have a bootloader and thus can only be flashed using the SWD port on each of the 3 microcontrollers. To upgrade, use the flash.py script from the pi3hat repository and the .elf file from the github release page with an STM32 programmer like the one at mjbots.com. On Ubuntu or Debian you can install OpenOCD with:

sudo apt install openocd

then run the following command once while the SWD cable is connected to each of the three ZH6 connectors in turn.

pi3hat$ ./flash.py 20250920-pi3hat-6dbff7f7a56fb55af755793e66748f4bbb84bc46.elf

And that’s all!