Skip to main content

Patch Firmware (PX-41CX)

px-41cx
px-41cx

Introduction #

The PX-41CX allows the user to update the firmware patched versions using the enclosed USB serial connection cable. For details I suggest you download the PX-41CX documentation from Pierre Houbert’s hompage. The documentation describes how to update the firmware and patch using Python and Microsoft windows. For macOS and Linux you slight variations.

Preparation #

In addition to python you need and the script below you need the DxCore Tools and PX41CX Utilities . Easiest way to get them is to use git to clone them into the directory containing UPD_PX41CX_krischik.command

macOS #

On macOS you can use the following commands.

brew install"	\
    "wget"	\
    "python3"

pip3 install --break-system-packages	\
    "intelhex"				\
    "pyedbglib"				\
    "pymcuprog"				\
    "pyserial"				\
    "pyyaml"

git clone https://github.com/SpenceKonde/DxCore.git
git clone https://github.com/diemheych/px41cx-utility
Download Install.command

Using git clone #

Alternatively you can clone git clone Calculator-Scripts project with it’s sub modules which will set up everything with correct directory structure:

git clone https://git.code.sf.net/p/calculator-scripts/code calculator-scripts
cd calculator-scripts
git checkout --track master
git submodule init
git submodule update
Utilities/Install.command
cd PX-41CX/Firmware

On Linux use the your package manager

Personalisation #

First you need to make copy of UPD_PX41CX_krischik.command replacing „krischik“ with your own name. Making a copy ensures you have the original to compare if something goes wrong. Then you edit the file to adjust to your personal needs. Edit the file to change the file to your liking.

Changing splash screen #

The splash screen is set by changing the Splash_File file name. There are a example splash screen with the PX41CX Utilities. Just change the path the plash screen your like the best.

typeset Splash_File="../px41cx-utility/Splash_Images/px41cx.bmp"

Changing the info message #

The info message is changed with the -u1 to -u4. I only change the middle two lines hence I only set -u2 and -u3.

    python3 "${Utility_Path}/px41cx_utility.py"	\
	-u2 "| Built by: Martin Krischik!  |"	\
	-u3 "| Found: martin@krischik.com  |"	\
	-b "${Splash_File}"			\
	"${Image_File}"				\
	"${Custom_File}"

Changing the ROMS #

There are 12 user configurable ROM images to be included with the Firmware. To do so you add them to the px41cx_utility.py call. For details see the PX41CX Utilities README.

    python3 "${Utility_Path}/px41cx_utility.py"	\
	-06 PPCL.ROM c 1 0 10			\
	-07 PPCU.ROM d 1 0 10			\
	-u2 "| Built by: Martin Krischik!  |"	\
	-u3 "| Found: martin@krischik.com  |"	\
	-b "${Splash_File}"			\
	"${Image_File}"				\
	"${Custom_File}"
    python3 "${Utility_Path}/px41cx_utility.py"	\
	-m					\
	-16 FORTH4.ROM 4 1 0 12			\
	-17 FORTH5.ROM e 1 0 12			\
	-u2 "| Built by: Martin Krischik!  |"	\
	-u3 "| Found: martin@krischik.com  |"	\
	-b "${Splash_File}"			\
	"${Image_File}"				\
	"${Custom_File}"

Usage #

The finished script works just like UPD_PX41CX_krischik.command command only that it patches the firmware before flashing. The advantage of having a individual script is that you can just call the script again with a new version number to flash the newest version when it comes out. The script will even perform the download if needed.

>./UPD_PX41CX_krischik.command
Version to install (0901, 0902, …)? 0902
No ROM changes
SerialUPDI
UPDI programming for Arduino using a serial adapter
Based on pymcuprog, with significant modifications
By Quentin Bolsee and Spence Konde
Version 1.3.0.3 - Jul 2023
Using serial port /dev/tty.usbserial-14440 at 115200 baud.
Target: avr128da28
Set fuses: ['5:0b11001001', '6:0x04', '7:0x00', '8:0x00']
Action: write
File: px41cx_V0902_krischik.hex
pymcuprog.programmer - INFO - Setting up programming session for 'avr128da28'
pymcuprog.deviceinfo.deviceinfo - INFO - Looking for device avr128da28
pymcuprog.serialupdi.physical - INFO - Opening port '/dev/tty.usbserial-14440' at '115200' baud


pymcuprog.serialupdi.physical - INFO - Closing port '/dev/tty.usbserial-14440'

Source #

The script is written for macOS and ZShell but should work on any Linux system as well.

#!/bin/zsh

setopt Err_Exit

# Set device parameter either from setup file or by trying to guess the device
# name. This will only work on macOS and Linux user should change the next
# three lines.
#
typeset USB_Serial_Device="${USB_Serial_Device-$(echo /dev/tty.usbserial-14*)}"
typeset USB_Serial_Speed="${USB_Serial_Speed-115200}"
typeset Python_Packages="$(python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))")"
typeset DxCore_Path="$(pwd)/DxCore/megaavr/tools/"
typeset Utility_Path="$(pwd)/px41cx-utility"

# Read version number of Firmware to install.
#
read  "Num_Version?Version to install (0901, 0902, …)? "

typeset Image_File="px41cx_V${Num_Version}.hex"
typeset Custom_File="px41cx_V${Num_Version}_krischik.hex"
typeset Splash_File="${Utility_Path}/Splash_Images/px41cx.bmp"

# check if file is available and if not tries to download file.
#
if test ! -e "px41cx_v${Num_Version}/${Image_File}"; then
    typeset Zip_File="px41cx_v${Num_Version}.zip"

    echo "File «${Image_File}» not found."
    echo "Trying to download «${Zip_File}» from https://paxer.net."

    wget "https://paxer.net/px41cx/downloads/${Zip_File}"

    unzip "${Zip_File}" -x '__MACOSX/*'
fi

pushd "px41cx_v${Num_Version}"
    python3 "${Utility_Path}/px41cx_utility.py"	\
	-u2 "| Built by: Martin Krischik!  |"	\
	-u3 "| Found: martin@krischik.com  |"	\
	-b "${Splash_File}"			\
	"${Image_File}"				\
	"${Custom_File}"

    # Flash the firmware using the prog tool from DxCore
    #
    python3 -u "${DxCore_Path}/prog.py"				\
	-t "uart"						\
	-u "${USB_Serial_Device}"				\
	-b "${USB_Serial_Speed}"				\
	-d "avr128da28"						\
	--fuses "5:0b11001001" "6:0x04" "7:0x00" "8:0x00"	\
	-f "${Custom_File}"					\
	-a write						\
	-v
popd
Download UPD_PX41CX_krischik.command