Skip to content

Instantly share code, notes, and snippets.

@benlye
Last active February 8, 2023 08:43
Show Gist options
  • Save benlye/1b33b6c2bbf9883f52fbdf81148105d7 to your computer and use it in GitHub Desktop.
Save benlye/1b33b6c2bbf9883f52fbdf81148105d7 to your computer and use it in GitHub Desktop.
Script to build multiple MULTI-Module firmware binaries in WSLv2
#!/bin/bash
# Get the command line options
while getopts ":dh" opt; do
case $opt in
d) BOARDSUFFIX="-devel"
;;
h) printf "$USAGE"; exit 1
;;
esac
done
# Path to the firmware source
SRCPATH=/mnt/c/Users/ben/GitHub/DIY-Multiprotocol-TX-Module/Multiprotocol
# Global ID to set on each module
GLOBALID=0x12345678
# Path to sed - needed for the option functions
SED=$(which gsed || which sed)
# Function to enable a firmware option
optenable() {
for opt in "$@" ; do
eval "${SED} -i 's/\/\{2,\}[[:blank:]]*\(#define[[:blank:]]*\b${opt}\b\)/\1/g' $SRCPATH/_Config.h"
done
}
# Function to disable a firmware option
optdisable() {
for opt in "$@" ; do
eval "${SED} -i 's/^\([[:blank:]]*\)\(#define[[:blank:]]*\b${opt}\b\)/\1\/\/\2/g' $SRCPATH/_Config.h"
done
}
# Function to set a firmware option
optset() {
eval "${SED} -i 's/\(#define \b${1}\b\).*$/\1 ${2}/g' $SRCPATH/_Config.h"
}
# Function to add a firmware option
optadd() {
eval "echo \"#define ${1} ${2}\" >>$SRCPATH/_Config.h"
}
# Function to build the firmware
buildMulti() { exitcode=0; BUILDCMD="arduino-cli compile -b $BOARD $SRCPATH/Multiprotocol.ino --output-dir /tmp/build/"; echo $BUILDCMD; $BUILDCMD; if [ $? -ne 0 ]; then exitcode=1; fi; echo; return $exitcode; }
# Get all the protocol names
A7105_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_A7105_INO\)\(.*\)/\1/p' $SRCPATH/_Config.h)
CC2500_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CC2500_INO\)\(.*\)/\1/p' $SRCPATH/_Config.h)
CYRF6936_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CYRF6936_INO\)\(.*\)/\1/p' $SRCPATH/_Config.h)
NRF24L01_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_NRF24L01_INO\)\(.*\)/\1/p' $SRCPATH/_Config.h)
CCNRF_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CCNRF_INO\)\(.*\)/\1/p' $SRCPATH/_Config.h)
SX1276_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_SX1276_INO\)\(.*\)/\1/p' $SRCPATH/_Config.h)
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS $CCNRF_PROTOCOLS $SX1276_PROTOCOLS);
# Get the firmware version number
MAJOR_VERSION=$(grep "VERSION_MAJOR" "$SRCPATH/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
MINOR_VERSION=$(grep "VERSION_MINOR" "$SRCPATH/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
REVISION_VERSION=$(grep "VERSION_REVISION" "$SRCPATH//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
PATCH_VERSION=$(grep "VERSION_PATCH" "$SRCPATH//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
MULTI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$REVISION_VERSION.$PATCH_VERSION
# Add arduino-cli to the path
export PATH=$PATH:$HOME/arduino-cli
# Install arduino-cli if it's missing
which arduino-cli > /dev/null
if [[ $? -ne 0 ]]; then
printf "\n\e[93marduino-cli not found - installing in ~/arduino-cli\e[0m\n\n"
mkdir ~/arduino-cli
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/arduino-cli sh;
fi
# Make sure we have arduino-cli
which arduino-cli > /dev/null
if [[ $? -ne 0 ]]; then
printf "\n\e[91marduino-cli not found!\e[0m\n\n"
fi
# Configure the Arduino CLI
arduino-cli config init --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json,https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/devel/source/package_multi_4in1_board_devel_index.json --overwrite
arduino-cli core update-index
arduino-cli core install arduino:avr
# Install release boards
arduino-cli core install multi4in1:avr
arduino-cli core install multi4in1:STM32F1
# Install devel boards
arduino-cli core install multi4in1-devel:avr
arduino-cli core install multi4in1-devel:STM32F1
# Make sure _Config.h file is unmodified
git -C $SRCPATH checkout $SRCPATH/_Config.h
# Make a backup copy of _Config.h
cp $SRCPATH/_Config.h $SRCPATH/_Config.h.bak
# Create a version-specific folder for the binary files
OUTPUT_DIR=./firmware/v${MULTI_VERSION}${BOARDSUFFIX}
if [ ! -d "$OUTPUT_DIR" ]
then
mkdir $OUTPUT_DIR
fi
# Build counters
TOTAL_BUILDS=10
BUILD_NUM=0
# Set the board for the 128KB STM32 builds
BOARD="multi4in1$BOARDSUFFIX:STM32F1:multistm32f103cb:debug_option=none"
### Generic build of the default configuration for STM32 ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION with default configuration for any STM32 module\e[0m\n\n"
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-stm-default-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
### Generic build for OpenTX ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION with fixed IDs and no tuning for any STM32 module\e[0m\n\n"
# Disable PPM
optdisable ENABLE_PPM
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
# Set a global CYRF ID
optenable FORCE_CYRF_ID
optset FORCE_CYRF_ID '"\\x01\\x02\\x03\\x04\\x05\\x06"'
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-stm-forceid-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
### Build for the Jumper JP4IN-SE for OpenTX ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION for Jumper JP4IN-SE\e[0m\n\n"
# Forced CC2500 tuning for CC2500
optenable FORCE_FRSKYD_TUNING
optset FORCE_FRSKYD_TUNING -6
optenable FORCE_FRSKYX_TUNING
optset FORCE_FRSKYX_TUNING -6
# Disable PPM
optdisable ENABLE_PPM
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
# Set a global CYRF ID
optenable FORCE_CYRF_ID
optset FORCE_CYRF_ID '"\\x01\\x02\\x03\\x04\\x05\\x06"'
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-jp4inse-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
### Build for the Radioboss JP4IN1 for OpenTX ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION for Radioboss 4IN1 \e[0m\n\n"
# Forced CC2500 tuning for CC2500
optenable FORCE_FRSKYD_TUNING
optset FORCE_FRSKYD_TUNING 0
optenable FORCE_FRSKYX_TUNING
optset FORCE_FRSKYX_TUNING 0
# Disable PPM
optdisable ENABLE_PPM
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
# Set a global CYRF ID
optenable FORCE_CYRF_ID
optset FORCE_CYRF_ID '"\\x01\\x02\\x03\\x04\\x05\\x06"'
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-rb4in1-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
### Build for the iRangeX IRX4 for OpenTX ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION for iRangeX IRX4\e[0m\n\n"
# Forced CC2500 tuning for CC2500
optenable FORCE_FRSKYD_TUNING
optset FORCE_FRSKYD_TUNING -8
optenable FORCE_FRSKYX_TUNING
optset FORCE_FRSKYX_TUNING -8
# Disable PPM
optdisable ENABLE_PPM
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
# Set a global CYRF ID
optenable FORCE_CYRF_ID
optset FORCE_CYRF_ID '"\\x01\\x02\\x03\\x04\\x05\\x06"'
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-irx4-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
### Build for the Radiomaster TX16S internal module ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION for the RadioMaster TX16S Internal module\e[0m\n\n"
# Forced CC2500 tuning for CC2500
optenable FORCE_FRSKYD_TUNING
optset FORCE_FRSKYD_TUNING 5
optenable FORCE_FRSKYX_TUNING
optset FORCE_FRSKYX_TUNING 5
# Disable PPM
optdisable ENABLE_PPM
# Disable INVERT_TELEMETRY
optdisable INVERT_TELEMETRY
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
# Set a global CYRF ID
optenable FORCE_CYRF_ID
optset FORCE_CYRF_ID '"\\x01\\x02\\x03\\x04\\x05\\x06"'
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-tx16sint-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
### Build for RadioMaster TX12 ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION for the RadioMaster TX12 CC2500 Internal module\e[0m\n\n"
# Disable PPM
optdisable ENABLE_PPM
# Disable INVERT_TELEMETRY
optdisable INVERT_TELEMETRY
# Disable RF modules
optdisable A7105_INSTALLED
optdisable CYRF6936_INSTALLED
optdisable NRF24L01_INSTALLED
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-tx12-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
# Set the board for the 64KB STM32 builds
BOARD="multi4in1$BOARDSUFFIX:STM32F1:multistm32f103c8:debug_option=none"
### Build for the URUAV TMX5 64KB module ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION for the URUAV TMX5 Module\e[0m\n\n"
# Forced CC2500 tuning for CC2500
#optenable FORCE_FRSKYD_TUNING
#optset FORCE_FRSKYD_TUNING -51
#optenable FORCE_FRSKYX_TUNING
#optset FORCE_FRSKYX_TUNING -51
# Disable PPM
optdisable ENABLE_PPM
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
# Set a global CYRF ID
optenable FORCE_CYRF_ID
optset FORCE_CYRF_ID '"\\x01\\x02\\x03\\x04\\x05\\x06"'
# Disable all the protocols
optdisable $ALL_PROTOCOLS
# Enable selected protocols
optenable AFHDS2A_A7105_INO
optenable DSM_CYRF6936_INO
optenable FLYSKY_A7105_INO
optenable FRSKYD_CC2500_INO
optenable FRSKYX_CC2500_INO
optenable FRSKY_RX_CC2500_INO
optenable MJXQ_CCNRF_INO
optenable H8_3D_NRF24L01_INO
optenable SCANNER_CC2500_INO
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-tmx5-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
# Set the board for the T18 5-in-1 build
BOARD="multi4in1$BOARDSUFFIX:STM32F1:multi5in1t18int"
### Build for the T18 Pro internal 5in1 module ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION for T18 Pro Internal 5in1 module\e[0m\n\n"
# Forced CC2500 tuning for CC2500
optenable FORCE_FRSKYD_TUNING
optset FORCE_FRSKYD_TUNING -12
optenable FORCE_FRSKYX_TUNING
optset FORCE_FRSKYX_TUNING -12
# Disable PPM
optdisable ENABLE_PPM
# Disable INVERT_TELEMETRY
optdisable INVERT_TELEMETRY
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
# Set a global CYRF ID
optenable FORCE_CYRF_ID
optset FORCE_CYRF_ID '"\\x01\\x02\\x03\\x04\\x05\\x06"'
# Enable the SX1276 RF module
optenable SX1276_INSTALLED
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-t18int-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
# Set the board for the Atmega AVR build
BOARD="multi4in1$BOARDSUFFIX:avr:multiatmega328p:bootloader=optiboot"
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
### Build for the Banggood AVR module ###
((BUILD_NUM=BUILD_NUM+1))
printf "\n\e[92m[$BUILD_NUM/$TOTAL_BUILDS] Building firmware v$MULTI_VERSION for the Banggood AVR module for OpenTX\e[0m\n\n"
# Forced CC2500 tuning for CC2500
optenable FORCE_FRSKYD_TUNING
optset FORCE_FRSKYD_TUNING -51
optenable FORCE_FRSKYX_TUNING
optset FORCE_FRSKYX_TUNING -51
# Disable PPM
optdisable ENABLE_PPM
# Force the same global ID as other modules
optenable FORCE_GLOBAL_ID
optset FORCE_GLOBAL_ID $GLOBALID
# Set a global CYRF ID
optenable FORCE_CYRF_ID
optset FORCE_CYRF_ID '"\\x01\\x02\\x03\\x04\\x05\\x06"'
# Disable all the protocols
optdisable $ALL_PROTOCOLS
# Enable selected protocols
optenable DSM_CYRF6936_INO
optenable FLYSKY_A7105_INO
optenable FRSKYD_CC2500_INO
optenable FRSKYX_CC2500_INO
optenable MJXQ_NRF24L01_INO
optenable H8_3D_NRF24L01_INO
optenable SCANNER_CC2500_INO
buildMulti
# If everything went OK, copy the binary
if [ $? -eq 0 ]; then
cp /tmp/build/Multiprotocol.ino.bin ${OUTPUT_DIR}/multi-avr-${MULTI_VERSION}.bin
else
printf "\n\e[91mAn error occured while compiling the firmware.\e[0m\n\n"
fi
# Restore _Config.h
cp $SRCPATH/_Config.h.bak $SRCPATH/_Config.h
# Clean up
rm $SRCPATH/_Config.h.bak
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment