11 KiB
How to compile the rnode firmware yourself
Dependencies
Make sure 'git', 'make', 'python' and 'pip' are instaled. Most like;y these are already availble on your system. Otherwise do:
$ sudo apt install git
$ sudo apt install make
$ sudo apt install pip
$ sudo apt install python
Download arduino-cli
$ cd
$ curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
Add arduino-cli to path by editing ~/.bashrc
$ nano ~/.bashrc
add 'export PATH=~/bin:$PATH' to end of file
Clone git repo
$ git clone https://github.com/liberatedsystems/RNode_Firmware_CE.git
Prepare
Install the required BSP and libraries for the ESP32 system.
$ cd RNode_Firmware_CE/
$ make prep-esp32
This command stalled. I stopped the command by hiting CTRL-C and restarted it.
Add rns software to path:
$ nano ~/.bashrc
add 'export PATH=~/.local/bin:$PATH' to the end of the file.
Test
To test if you can compile the firmware try it:
$ make firmware-heltec32_v3
Fingers crossed!
Define new board, the theory
In order to build custom firmware for a new board it has to be defined in several files.
Makefile
BOARD_MODEL defines the target board. It is a unique 8 bit number. BOARD_VARIANT defines the variant of the board. A board could come with different LoRa transceivers, for example. It is also a unique 8 bit number.
Every target board has a section 'firmware-<board_name>', 'upload-' and 'release-'
boards.h
Both BOARD_MODEL and BOARD_VARIANT are #defines in this file. They are used to define the pinout of the SPI port and if it has certain perifirals such as a screen BLE etc.
Let's see an example:
#elif BOARD_MODEL == BOARD_HELTEC32_V3
#define IS_ESP32S3 true
#define HAS_DISPLAY true
#define DISPLAY OLED
#define HAS_BLUETOOTH false
#define HAS_BLE true
#define HAS_PMU true
#define HAS_CONSOLE true
#define HAS_EEPROM true
#define HAS_INPUT true
#define HAS_SLEEP true
#define PIN_WAKEUP GPIO_NUM_0
#define WAKEUP_LEVEL 0
#define INTERFACE_COUNT 1
#define OCP_TUNED 0x38
const int pin_btn_usr1 = 0;
#if defined(EXTERNAL_LEDS)
const int pin_led_rx = 13;
const int pin_led_tx = 14;
#else
const int pin_led_rx = 35;
const int pin_led_tx = 35;
#endif
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1262
{
true, // DEFAULT_SPI
true, // HAS_TCXO
true // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1262
{
8, // pin_ss
9, // pin_sclk
10, // pin_mosi
11, // pin_miso
13, // pin_busy
14, // pin_dio
12, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
If we want to add support for a new board we have to add a new section for this board. Here we define all the features it has or not has.
Define new board for real
Let's say we want to add support for the Waveshare ESP32-S3 Pico with an SX1278 LoRa transceiver. First we have to make define both BOARD_MODEL and BOARD_VARIANT. Let's define BOARD_MODEL as 0x61 and BOARD_VARIANT as 0x31 as these numbers are not used yet. Here the 0x31 indicates the use of a SX1278 LoRa transceiver. In the future we can define more transceivers for this board. Then we make entries in the Makefile.
# Added board from Mees Electronics
firmware-waveshare-esp32-s3-pico: check_bt_buffers
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\""
# Added board from Mees Electronics
upload-waveshare-esp32-s3-pico:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:esp32s3
@sleep 1
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyACM0) --chip esp32-s3 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
release-waveshare-esp32-s3-pico:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\" \"-DBOARD_VARIANT=0x31\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_waveshare-esp32-s3-pico.boot_app0
cp build/esp32.esp32.waveshare-esp32-s3-pico/RNode_Firmware_CE.ino.bin build/rnode_firmware_waveshare-esp32-s3-pico.bin
cp build/esp32.esp32.waveshare-esp32-s3-pico/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_waveshare-esp32-s3-pico.bootloader
cp build/esp32.esp32.waveshare-esp32-s3-pico/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_waveshare-esp32-s3-pico.partitions
zip --junk-paths ./Release/rnode_firmware_waveshare-esp32-s3-pico.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx126xrnode_firmware_waveshare-esp32-s3-pico.boot_app0 build/rnode_firmware_waveshare-esp32-s3-pico.bin build/rnode_firmware_waveshare-esp32-s3-pico.bootloader build/rnode_firmware_waveshare-esp32-s3-pico.partitions
rm -r build
In the file Boards.h make an entry for the new board inside the '#if MCU_VARIANT == MCU_ESP32':
// Board definition added by Mees Electronics
#elif BOARD_MODEL == BOARD_WAVESHARE_ESP32_S3_PICO
#define IS_ESP32S3 true
#define HAS_DISPLAY false
#define HAS_BLUETOOTH false
#define HAS_BLE true
#define HAS_PMU true
#define HAS_CONSOLE true
#define HAS_EEPROM true
#define INTERFACE_COUNT 1
#define HAS_NP true
const int pin_np = 21;
#if HAS_NP == false
#if defined(EXTERNAL_LEDS)
const int pin_led_rx = 16;
const int pin_led_tx = 17;
#else
const int pin_led_rx = 21;
const int pin_led_tx = 21;
#endif
#endif
const uint8_t interfaces[INTERFACE_COUNT] = {SX1278};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1278
{
false, // DEFAULT_SPI
false, // HAS_TCXO
false // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1278
{
10, // pin_ss
12, // pin_sclk
11, // pin_mosi
13, // pin_miso
-1, // pin_busy
15, // pin_dio
14, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
Also, in the file Utilities.h add entry. Again, inside the '#if MCU_VARIANT == MCU_ESP32'.
#elif BOARD_MODEL == BOARD_WAVESHARE_ESP32_S3_PICO
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
void led_id_on() { }
void led_id_off() { }
In Utilities.h the functions led_indicate_info(), led_indicate_standby() and led_indicate_not_ready() is also defined for the different boards. If the new board has a NeoPixel, nothing has to be added her.
In Utilities.h the function bool eeprom_model_valid() also has some board specific definitions. Make sure these are set correctly to prevent an EEPROM error during startup:
// Added by Mees Electronics
#elif BOARD_MODEL == BOARD_WAVESHARE_ESP32_S3_PICO
if (model == MODEL_A4) {
In Utilities.h the function void setTXPower() defines the LoRa power setting per Lora module/board pair. Add the new board here:
// Added by Mees Electronics
if (model == MODEL_A4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
The file display.h also has a board definition section. If the new board has a display, make sure there is a proper entry for it. Again, inside the '#if MCU_VARIANT == MCU_ESP32'. If the board does not have a display, don't define this section.
#elif BOARD_MODEL == BOARD_WAVESHARE_ESP32_S3_PICO
disp_mode = DISP_MODE_LANDSCAPE;
display.setRotation(0);
The file Power.h must also have a board definition. And also proper definitions in void measure_battery() and bool init_pmu(). These are more elaborate and not yet fully understood, but probably used when the board has a battery installed. If the new board does not have a battery, do not define anything here!
#elif BOARD_MODEL == BOARD_WAVESHARE_ESP32_S3_PICO
#define BAT_V_MIN 3.15
#define BAT_V_MAX 4.3
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 5
const uint8_t pin_vbat = 35;
float bat_p_samples[BAT_SAMPLES];
float bat_v_samples[BAT_SAMPLES];
uint8_t bat_samples_count = 0;
int bat_discharging_samples = 0;
int bat_charging_samples = 0;
int bat_charged_samples = 0;
bool bat_voltage_dropping = false;
float bat_delay_v = 0;
float bat_state_change_v = 0;
Flashing the board
Make shure you are in the dialout group. If not:
$ sudo usermod -aG dialout <username>
If you are flashing a custom board, you will need to generate a signing key in rnodeconf prior to flashing if you do not already have one by running:
$ rnodeconf -k
Than flash the firmware.
$ make upload-waveshare-esp32-s3-pico
This will end with error 'This device has not been provisioned yet, cannot set firmware hash'. But fear not. After flashing a custom board, you will also need to provision the EEPROM before use:
$ rnodeconf /dev/ttyACM0 -r --platform ESP32 --model a4 --product f0 --hwrev 3
Sometimes the board give error whule flashing. Try flashing the board via the other serial interface (ttyACM1). Don't know why, but it works.
Migrating to a other system
When the rnode is flashed, it is signed with a key. If you connect the rnode to another system, this key cannot be validated. It is possible to write a new key to the rnode by erasing the eeprom and writing the local key to it.
$ rnodeconf /dev/ttyACM0 --eeprom-wipe
$ rnodeconf /dev/ttyACM0 -r --platform ESP32 --model a4 --product f0 --hwrev 3