Compare commits

..

No commits in common. "master" and "1.73" have entirely different histories.
master ... 1.73

88 changed files with 4344 additions and 6208 deletions

View File

@ -1,39 +0,0 @@
---
name: "\U0001F41B Bug Report"
about: Report a reproducible bug
title: ''
labels: ''
assignees: ''
---
**Read the Contribution Guidelines**
Before creating a bug report on this issue tracker, you **must** read the [Contribution Guidelines](https://github.com/markqvist/Reticulum/blob/master/Contributing.md). Issues that do not follow the contribution guidelines **will be deleted without comment**.
- The issue tracker is used by developers of this project. **Do not use it to ask general questions, or for support requests**.
- Ideas and feature requests can be made on the [Discussions](https://github.com/markqvist/Reticulum/discussions). **Only** feature requests accepted by maintainers and developers are tracked and included on the issue tracker. **Do not post feature requests here**.
- After reading the [Contribution Guidelines](https://github.com/markqvist/Reticulum/blob/master/Contributing.md), delete this section from your bug report.
**Describe the Bug**
First of all: Is this really a bug? Is it reproducible?
If this is a request for help because something is not working as you expected, stop right here, and go to the [discussions](https://github.com/markqvist/Reticulum/discussions) instead, where you can post your questions and get help from other users.
If this really is a bug or issue with the software, remove this section of the template, and provide **a clear and concise description of what the bug is**.
**To Reproduce**
Describe in detail how to reproduce the bug.
**Expected Behavior**
A clear and concise description of what you expected to happen.
**Logs & Screenshots**
Please include any relevant log output. If applicable, also add screenshots to help explain your problem. In most cases, without any relevant log output, we will not be able to determine the cause of the bug, or reproduce it.
**System Information**
- OS and version
- Python version
- Program version
**Additional context**
Add any other context about the problem here.

1
.gitignore vendored
View File

@ -7,4 +7,3 @@ Release/*.zip
Release/*.json
Console/build
build/*
.vscode

View File

@ -1,4 +1,4 @@
// Copyright (C) 2024, Mark Qvist
// Copyright (C) 2023, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -22,22 +22,19 @@
#elif HAS_BLE == true
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "src/ble/BLESerial.h"
BLESerial SerialBT;
// TODO: Remove
#define SerialBT Serial
#endif
#elif MCU_VARIANT == MCU_NRF52
#include <bluefruit.h>
#include <math.h>
#define BLE_RX_BUF 6144
BLEUart SerialBT(BLE_RX_BUF);
BLEUart SerialBT;
BLEDis bledis;
BLEBas blebas;
bool SerialBT_init = false;
#endif
#define BT_PAIRING_TIMEOUT 35000
#define BLE_FLUSH_TIMEOUT 20
uint32_t bt_pairing_started = 0;
#define BT_DEV_ADDR_LEN 6
@ -61,7 +58,6 @@ char bt_devname[11];
}
void bt_stop() {
display_unblank();
if (bt_state != BT_STATE_OFF) {
SerialBT.end();
bt_allow_pairing = false;
@ -70,7 +66,6 @@ char bt_devname[11];
}
void bt_start() {
display_unblank();
if (bt_state == BT_STATE_OFF) {
SerialBT.begin(bt_devname);
bt_state = BT_STATE_ON;
@ -78,7 +73,6 @@ char bt_devname[11];
}
void bt_enable_pairing() {
display_unblank();
if (bt_state == BT_STATE_OFF) bt_start();
bt_allow_pairing = true;
bt_pairing_started = millis();
@ -86,14 +80,12 @@ char bt_devname[11];
}
void bt_disable_pairing() {
display_unblank();
bt_allow_pairing = false;
bt_ssp_pin = 0;
bt_state = BT_STATE_ON;
}
void bt_pairing_complete(boolean success) {
display_unblank();
if (success) {
bt_disable_pairing();
} else {
@ -101,8 +93,7 @@ char bt_devname[11];
}
}
void bt_connection_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
display_unblank();
void bt_connection_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){
if(event == ESP_SPP_SRV_OPEN_EVT) {
bt_state = BT_STATE_CONNECTED;
cable_state = CABLE_STATE_DISCONNECTED;
@ -165,122 +156,25 @@ char bt_devname[11];
}
#elif HAS_BLE == true
BLESecurity *ble_security = new BLESecurity();
bool ble_authenticated = false;
uint32_t pairing_pin = 0;
void bt_flush() { if (bt_state == BT_STATE_CONNECTED) { SerialBT.flush(); } }
void bt_stop() {
if (bt_state != BT_STATE_OFF) {
bt_allow_pairing = false;
bt_state = BT_STATE_OFF;
}
}
void bt_disable_pairing() {
display_unblank();
bt_allow_pairing = false;
bt_ssp_pin = 0;
bt_state = BT_STATE_ON;
}
void bt_passkey_notify_callback(uint32_t passkey) {
// Serial.printf("Got passkey notification: %d\n", passkey);
bt_ssp_pin = passkey;
bt_state = BT_STATE_PAIRING;
bt_allow_pairing = true;
bt_pairing_started = millis();
kiss_indicate_btpin();
}
bool bt_confirm_pin_callback(uint32_t pin) {
// Serial.printf("Confirm PIN callback: %d\n", pin);
return true;
}
void bt_debond_all() {
// Serial.println("Debonding all");
int dev_num = esp_ble_get_bond_device_num();
esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num);
esp_ble_get_bond_device_list(&dev_num, dev_list);
for (int i = 0; i < dev_num; i++) { esp_ble_remove_bond_device(dev_list[i].bd_addr); }
free(dev_list);
}
void bt_update_passkey() {
// Serial.println("Updating passkey");
pairing_pin = random(899999)+100000;
bt_ssp_pin = pairing_pin;
}
uint32_t bt_passkey_callback() {
// Serial.println("API passkey request");
if (pairing_pin == 0) { bt_update_passkey(); }
return pairing_pin;
}
bool bt_client_authenticated() {
return ble_authenticated;
}
void bt_security_setup() {
uint32_t passkey = bt_passkey_callback();
// Serial.printf("Executing BT security setup, passkey is %d\n", passkey);
uint8_t key_size = 16;
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND;
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE;
uint8_t oob_support = ESP_BLE_OOB_DISABLE;
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_OOB_SUPPORT, &oob_support, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
}
bool bt_security_request_callback() {
if (bt_allow_pairing) {
// Serial.println("Accepting security request");
return true;
} else {
// Serial.println("Rejecting security request");
return false;
}
}
void bt_authentication_complete_callback(esp_ble_auth_cmpl_t auth_result) {
if (auth_result.success == true) {
// Serial.println("Authentication success");
ble_authenticated = true;
bt_state = BT_STATE_CONNECTED;
} else {
// Serial.println("Authentication fail");
ble_authenticated = false;
bt_state = BT_STATE_ON;
bt_security_setup();
}
bt_allow_pairing = false;
bt_ssp_pin = 0;
}
void bt_connect_callback(BLEServer *server) {
// uint16_t conn_id = server->getConnId();
// Serial.printf("Connected: %d\n", conn_id);
display_unblank();
ble_authenticated = false;
void bt_connect_callback(uint16_t conn_handle) {
bt_state = BT_STATE_CONNECTED;
cable_state = CABLE_STATE_DISCONNECTED;
}
void bt_disconnect_callback(BLEServer *server) {
// uint16_t conn_id = server->getConnId();
// Serial.printf("Disconnected: %d\n", conn_id);
display_unblank();
ble_authenticated = false;
void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
bt_state = BT_STATE_ON;
}
@ -305,8 +199,8 @@ char bt_devname[11];
sprintf(bt_devname, "RNode %02X%02X", bt_dh[14], bt_dh[15]);
free(data);
bt_security_setup();
// TODO: Implement GAP & GATT for RNode comms over BLE
bt_ready = true;
return true;
@ -317,20 +211,9 @@ char bt_devname[11];
}
void bt_start() {
display_unblank();
if (bt_state == BT_STATE_OFF) {
bt_state = BT_STATE_ON;
SerialBT.begin(bt_devname);
SerialBT.setTimeout(10);
}
}
void bt_stop() {
display_unblank();
if (bt_state != BT_STATE_OFF) {
bt_allow_pairing = false;
bt_state = BT_STATE_OFF;
SerialBT.end();
// TODO: Implement
}
}
@ -345,13 +228,7 @@ char bt_devname[11];
}
void bt_enable_pairing() {
display_unblank();
if (bt_state == BT_STATE_OFF) bt_start();
bt_security_setup();
//bt_debond_all();
//bt_update_passkey();
bt_allow_pairing = true;
bt_pairing_started = millis();
bt_state = BT_STATE_PAIRING;
@ -361,193 +238,123 @@ char bt_devname[11];
if (bt_allow_pairing && millis()-bt_pairing_started >= BT_PAIRING_TIMEOUT) {
bt_disable_pairing();
}
if (bt_state == BT_STATE_CONNECTED && millis()-SerialBT.lastFlushTime >= BLE_FLUSH_TIMEOUT) {
if (SerialBT.transmitBufferLength > 0) {
bt_flush();
}
}
}
#endif
#elif MCU_VARIANT == MCU_NRF52
uint32_t pairing_pin = 0;
uint8_t eeprom_read(uint32_t mapped_addr);
uint8_t eeprom_read(uint32_t mapped_addr);
void bt_stop() {
if (bt_state != BT_STATE_OFF) {
bt_allow_pairing = false;
bt_state = BT_STATE_OFF;
}
}
void bt_disable_pairing() {
void bt_stop() {
if (bt_state != BT_STATE_OFF) {
bt_allow_pairing = false;
bt_ssp_pin = 0;
bt_state = BT_STATE_ON;
bt_state = BT_STATE_OFF;
}
}
void bt_flush() { if (bt_state == BT_STATE_CONNECTED) { SerialBT.flushTXD(); } }
void bt_disable_pairing() {
bt_allow_pairing = false;
bt_ssp_pin = 0;
bt_state = BT_STATE_ON;
}
void bt_pairing_complete(uint16_t conn_handle, uint8_t auth_status) {
void bt_pairing_complete(uint16_t conn_handle, uint8_t auth_status) {
if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
BLEConnection* connection = Bluefruit.Connection(conn_handle);
ble_gap_conn_sec_mode_t security = connection->getSecureMode();
// On the NRF52 it is not possible with the Arduino library to reject
// requests from devices with no IO capabilities, which would allow
// bypassing pin entry through pairing using the "just works" mode.
// Therefore, we must check the security level of the connection after
// pairing to ensure "just works" has not been used. If it has, we need
// to disconnect, unpair and delete any bonding information immediately.
// Settings on the SerialBT service should prevent unauthorised access to
// the serial port anyway, but this is still wise to do regardless.
//
// Note: It may be nice to have this done in the BLESecurity class in the
// future, but as it stands right now I'd have to fork the BSP to do
// that, which I don't fancy doing. Impact on security is likely minimal.
// Requires investigation.
if (security.sm == 1 && security.lv >= 3) {
bt_state = BT_STATE_CONNECTED;
cable_state = CABLE_STATE_DISCONNECTED;
bt_disable_pairing();
} else {
if (connection->bonded()) {
connection->removeBondKey();
}
connection->disconnect();
}
bt_state = BT_STATE_CONNECTED;
cable_state = CABLE_STATE_DISCONNECTED;
bt_disable_pairing();
} else {
bt_ssp_pin = 0;
}
}
}
bool bt_passkey_callback(uint16_t conn_handle, uint8_t const passkey[6], bool match_request) {
if (bt_allow_pairing) {
return true;
bool bt_passkey_callback(uint16_t conn_handle, uint8_t const passkey[6], bool match_request) {
for (int i = 0; i < 6; i++) {
// multiply by tens however many times needed to make numbers appear in order
bt_ssp_pin += ((int)passkey[i] - 48) * pow(10, 5-i);
}
kiss_indicate_btpin();
if (match_request) {
if (bt_allow_pairing) {
return true;
}
}
return false;
}
}
void bt_connect_callback(uint16_t conn_handle) {
bt_state = BT_STATE_CONNECTED;
cable_state = CABLE_STATE_DISCONNECTED;
void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
bt_state = BT_STATE_ON;
}
BLEConnection* conn = Bluefruit.Connection(conn_handle);
conn->requestPHY(BLE_GAP_PHY_2MBPS);
conn->requestMtuExchange(512+3);
conn->requestDataLengthUpdate();
}
void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
if (reason != BLE_GAP_SEC_STATUS_SUCCESS) {
bt_state = BT_STATE_ON;
bool bt_setup_hw() {
if (!bt_ready) {
#if HAS_EEPROM
if (EEPROM.read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) {
#else
if (eeprom_read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) {
#endif
bt_enabled = true;
} else {
bt_enabled = false;
}
}
void bt_update_passkey() {
pairing_pin = random(899999)+100000;
bt_ssp_pin = pairing_pin;
}
uint32_t bt_get_passkey() {
// Serial.println("API passkey request");
if (pairing_pin == 0) { bt_update_passkey(); }
return pairing_pin;
}
bool bt_setup_hw() {
if (!bt_ready) {
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
Bluefruit.autoConnLed(false);
if (Bluefruit.begin()) {
Bluefruit.setTxPower(8); // Check bluefruit.h for supported values
Bluefruit.Security.setIOCaps(true, true, false);
Bluefruit.Security.setPairPasskeyCallback(bt_passkey_callback);
Bluefruit.Periph.setDisconnectCallback(bt_disconnect_callback);
Bluefruit.Security.setPairCompleteCallback(bt_pairing_complete);
const ble_gap_addr_t gap_addr = Bluefruit.getAddr();
char *data = (char*)malloc(BT_DEV_ADDR_LEN+1);
for (int i = 0; i < BT_DEV_ADDR_LEN; i++) {
data[i] = gap_addr.addr[i];
}
#if HAS_EEPROM
if (EEPROM.read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) {
data[BT_DEV_ADDR_LEN] = EEPROM.read(eeprom_addr(ADDR_SIGNATURE));
#else
if (eeprom_read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) {
data[BT_DEV_ADDR_LEN] = eeprom_read(eeprom_addr(ADDR_SIGNATURE));
#endif
bt_enabled = true;
} else {
bt_enabled = false;
}
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
Bluefruit.autoConnLed(false);
if (Bluefruit.begin()) {
uint32_t pin = bt_get_passkey();
char pin_char[6];
sprintf(pin_char,"%lu", pin);
unsigned char *hash = MD5::make_hash(data, BT_DEV_ADDR_LEN);
memcpy(bt_dh, hash, BT_DEV_HASH_LEN);
sprintf(bt_devname, "RNode %02X%02X", bt_dh[14], bt_dh[15]);
free(data);
Bluefruit.setTxPower(8); // Check bluefruit.h for supported values
Bluefruit.Security.setIOCaps(true, false, false); // display, yes; yes / no, no; keyboard, no
// This device is indeed capable of yes / no through the pairing mode
// being set, but I have chosen to set it thus to force the input of the
// pin on the device initiating the pairing.
bt_ready = true;
return true;
Bluefruit.Security.setMITM(true);
Bluefruit.Security.setPairPasskeyCallback(bt_passkey_callback);
Bluefruit.Security.setSecuredCallback(bt_connect_callback);
Bluefruit.Security.setPIN(pin_char);
Bluefruit.Periph.setDisconnectCallback(bt_disconnect_callback);
Bluefruit.Security.setPairCompleteCallback(bt_pairing_complete);
Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms
const ble_gap_addr_t gap_addr = Bluefruit.getAddr();
char *data = (char*)malloc(BT_DEV_ADDR_LEN+1);
for (int i = 0; i < BT_DEV_ADDR_LEN; i++) {
data[i] = gap_addr.addr[i];
}
#if HAS_EEPROM
data[BT_DEV_ADDR_LEN] = EEPROM.read(eeprom_addr(ADDR_SIGNATURE));
#else
data[BT_DEV_ADDR_LEN] = eeprom_read(eeprom_addr(ADDR_SIGNATURE));
#endif
unsigned char *hash = MD5::make_hash(data, BT_DEV_ADDR_LEN);
memcpy(bt_dh, hash, BT_DEV_HASH_LEN);
sprintf(bt_devname, "RNode %02X%02X", bt_dh[14], bt_dh[15]);
free(data);
bt_ready = true;
return true;
} else { return false; }
} else { return false; }
}
} else { return false; }
}
void bt_start() {
if (bt_state == BT_STATE_OFF) {
Bluefruit.setName(bt_devname);
bledis.setManufacturer(BLE_MANUFACTURER);
bledis.setModel(BLE_MODEL);
// start device information service
bledis.begin();
void bt_start() {
if (bt_state == BT_STATE_OFF) {
Bluefruit.setName(bt_devname);
bledis.setManufacturer(BLE_MANUFACTURER);
bledis.setModel(BLE_MODEL);
// start device information service
bledis.begin();
// Guard to ensure SerialBT service is not duplicated through BT being power cycled
if (!SerialBT_init) {
SerialBT.bufferTXD(true); // enable buffering
SerialBT.begin();
SerialBT.setPermission(SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM); // enable encryption for BLE serial
SerialBT.begin();
SerialBT_init = true;
}
blebas.begin();
blebas.begin();
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
// Include bleuart 128-bit uuid
Bluefruit.Advertising.addService(SerialBT);
// Include bleuart 128-bit uuid
Bluefruit.Advertising.addService(SerialBT);
// There is no room for Name in Advertising packet
// Use Scan response for Name
Bluefruit.ScanResponse.addName();
// There is no room for Name in Advertising packet
// Use Scan response for Name
Bluefruit.ScanResponse.addName();
Bluefruit.Advertising.start(0);
Bluefruit.Advertising.start(0);
bt_state = BT_STATE_ON;
}
}
bt_state = BT_STATE_ON;
}
}
bool bt_init() {
bool bt_init() {
bt_state = BT_STATE_OFF;
if (bt_setup_hw()) {
if (bt_enabled && !console_active) bt_start();
@ -555,19 +362,18 @@ char bt_devname[11];
} else {
return false;
}
}
}
void bt_enable_pairing() {
if (bt_state == BT_STATE_OFF) bt_start();
bt_allow_pairing = true;
bt_pairing_started = millis();
bt_state = BT_STATE_PAIRING;
kiss_indicate_btpin();
}
void bt_enable_pairing() {
if (bt_state == BT_STATE_OFF) bt_start();
bt_allow_pairing = true;
bt_pairing_started = millis();
bt_state = BT_STATE_PAIRING;
}
void update_bt() {
if (bt_allow_pairing && millis()-bt_pairing_started >= BT_PAIRING_TIMEOUT) {
bt_disable_pairing();
}
void update_bt() {
if (bt_allow_pairing && millis()-bt_pairing_started >= BT_PAIRING_TIMEOUT) {
bt_disable_pairing();
}
}
#endif

843
Boards.h

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Copyright (C) 2024, Mark Qvist
// Copyright (C) 2023, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
#define CONFIG_H
#define MAJ_VERS 0x01
#define MIN_VERS 0x4a
#define MIN_VERS 0x49
#define MODE_HOST 0x11
#define MODE_TNC 0x12
@ -28,8 +28,6 @@
#define CABLE_STATE_DISCONNECTED 0x00
#define CABLE_STATE_CONNECTED 0x01
uint8_t cable_state = CABLE_STATE_DISCONNECTED;
#define MAX_INTERFACES 12
#define BT_STATE_NA 0xff
#define BT_STATE_OFF 0x00
@ -65,6 +63,12 @@
// packet RSSI register
const int rssi_offset = 157;
// Default LoRa settings
const int lora_rx_turnaround_ms = 66;
const int lora_post_tx_yield_slots = 6;
#define LORA_CAD_SYMBOLS 3
// Operational variables
bool community_fw = true;
bool hw_ready = false;
@ -72,25 +76,17 @@
bool pmu_ready = false;
bool promisc = false;
bool implicit = false;
bool memory_low = false;
uint8_t implicit_l = 0;
uint8_t op_mode = MODE_HOST;
uint8_t model = 0x00;
uint8_t hwrev = 0x00;
int current_rssi = -292;
int last_rssi = -292;
uint8_t last_rssi_raw = 0x00;
uint8_t last_snr_raw = 0x80;
uint8_t seq[INTERFACE_COUNT];
uint16_t read_len[INTERFACE_COUNT];
bool serial_in_frame = false;
FIFOBuffer packet_rdy_interfaces;
uint8_t packet_rdy_interfaces_buf[MAX_INTERFACES];
uint8_t seq = 0xFF;
uint16_t read_len = 0;
// Incoming packet buffer
uint8_t pbuf[MTU];
@ -104,27 +100,13 @@
uint32_t stat_rx = 0;
uint32_t stat_tx = 0;
bool stat_signal_detected = false;
bool stat_signal_synced = false;
bool stat_rx_ongoing = false;
bool dcd = false;
bool dcd_led = false;
bool dcd_waiting = false;
long dcd_wait_until = 0;
uint16_t dcd_count = 0;
uint16_t dcd_threshold = 2;
uint32_t last_status_update = 0;
uint32_t last_dcd = 0;
uint32_t last_rx = 0;
uint32_t last_tx = 0;
unsigned long last_tx = 0;
unsigned long last_rx = 0;
// Power management
#define BATTERY_STATE_UNKNOWN 0x00
#define BATTERY_STATE_DISCHARGING 0x01
#define BATTERY_STATE_CHARGING 0x02
#define BATTERY_STATE_CHARGED 0x03
#define BATTERY_STATE_CHARGING 0x02
#define BATTERY_STATE_CHARGED 0x03
bool battery_installed = false;
bool battery_indeterminate = false;
bool external_power = false;
@ -134,8 +116,6 @@
uint8_t battery_state = 0x00;
uint8_t display_intensity = 0xFF;
uint8_t display_addr = 0xFF;
volatile bool display_updating = false;
bool display_blanking_enabled = false;
bool display_diagnostics = true;
bool device_init_done = false;
bool eeprom_ok = false;
@ -143,9 +123,9 @@
// Boot flags
#define START_FROM_BOOTLOADER 0x01
#define START_FROM_POWERON 0x02
#define START_FROM_BROWNOUT 0x03
#define START_FROM_JTAG 0x04
#define START_FROM_POWERON 0x02
#define START_FROM_BROWNOUT 0x03
#define START_FROM_JTAG 0x04
// Subinterfaces
// select interface 0 by default

View File

@ -1,4 +1,4 @@
// Copyright (C) 2024, Mark Qvist
// Copyright (C) 2023, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,5 @@
# These paths will have to be changed according to where you store these directories on your system
PATH_RETICULUM_WEBSITE=../../sites/reticulum.network
PATH_PACKAGES=../../../rns_build
PATH_PACKAGES=../../dist_archive
clean:
@echo Cleaning...
@ -15,14 +14,14 @@ dirs:
@mkdir -p ./build/images
pages:
python3 ./build.py
python ./build.py
pages-debug:
python3 ./build.py --no-gz --no-remap
python ./build.py --no-gz --no-remap
sourcepack:
@echo Packing firmware sources...
cd .. && zip -r Console/build/pkg/rnode_firmware.zip * -x Builds/\* Console/\* Documentation/images/\* Documentation/RNode_v1_Manual.pdf Documentation/rnfw_1.jpg Graphics/\* Python\ Module/\* Release/\* build/\* partition_hashes
zip --junk-paths -r build/pkg/rnode_firmware.zip ../arduino-cli.yaml ../Bluetooth.h ../Boards.h ../Config.h ../Console.h ../Device.h ../Display.h ../Framing.h ../Graphics.h ../Input.h ../LICENSE ../Makefile ../MD5.cpp ../MD5.h ../Modem.h ../partition_hashes ../Power.h ../README.md ../release_hashes.py ../RNode_Firmware_CE.ino ../ROM.h ../sx126x.cpp ../sx126x.h ../sx127x.cpp ../sx127x.h ../sx128x.cpp ../sx128x.h ../Utilities.h
data:
@echo Including assets...
@ -30,7 +29,7 @@ data:
@cp assets/gfx/* build/gfx/
@cp assets/images/* build/images/
@cp assets/stl/* build/3d/
# @cp assets/pkg/* build/pkg/
#@cp assets/pkg/* build/pkg/
# @cp assets/scripts/* build/scripts/
# @cp -r ../../Reticulum/docs/manual/* build/reticulum_manual/
# @cp -r ../../Reticulum/docs/Reticulum\ Manual.pdf build/reticulum_manual/
@ -45,4 +44,4 @@ site: clean external dirs data sourcepack pages
local: clean external dirs data sourcepack pages-debug
serve:
python3 -m http.server 7777 --bind 127.0.0.1 --directory ./build
python -m http.server 7777 --bind 127.0.0.1 --directory ./build

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -4,20 +4,17 @@ import sys
import shutil
packages = {
"rns": "rns-0.9.1-py3-none-any.whl",
"nomadnet": "nomadnet-0.6.0-py3-none-any.whl",
"lxmf": "lxmf-0.6.2-py3-none-any.whl",
"rnsh": "rnsh-0.1.5-py3-none-any.whl",
"rns": "rns-0.7.5-py3-none-any.whl",
"nomadnet": "nomadnet-0.4.9-py3-none-any.whl",
"lxmf": "lxmf-0.4.3-py3-none-any.whl",
"rnsh": "rnsh-0.1.4-py3-none-any.whl",
}
DEFAULT_TITLE = "RNode Bootstrap Console"
SOURCES_PATH="./source"
BUILD_PATH="./build"
# These paths may have to be changed depending on where you store these directories on your system
PACKAGES_PATH = "../../../rns_build"
PACKAGES_PATH = "../../dist_archive"
RNS_SOURCE_PATH = "../../Reticulum"
INPUT_ENCODING="utf-8"
OUTPUT_ENCODING="utf-8"
@ -177,34 +174,26 @@ mf.write(help_redirect)
mf.close()
def optimise_manual(path):
pm = 45
pm = 110
scale_imgs = [
("_images/board_rnodev2.png", pm),
("_images/board_rnode.png", pm),
("_images/board_heltec32v20.png", pm),
("_images/board_heltec32v30.png", pm),
("_images/board_heltec32.png", pm),
("_images/board_t3v21.png", pm),
("_images/board_t3v20.png", pm),
("_images/board_t3v10.png", pm),
("_images/board_t3s3.png", pm),
("_images/board_tbeam.png", pm),
("_images/board_tdeck.png", pm),
("_images/board_rak4631.png", pm),
("_images/board_tbeam_supreme.png", pm),
("_images/sideband_devices.webp", pm),
("_images/board_tbeam.png", pm),
("_images/nomadnet_3.png", pm),
("_images/meshchat_1.webp", pm),
("_images/radio_is5ac.png", pm),
("_images/radio_rblhg5.png", pm),
("_static/rns_logo_512.png", 256),
("../images/bg_h_1.webp", pm),
]
import subprocess
import shlex
for i,s in scale_imgs:
fp = path+"/"+i
resize = "convert "+fp+" -quality 25 -resize "+str(s)+" "+fp
resize = "convert "+fp+" -resize "+str(s)+" "+fp
print(resize)
subprocess.call(shlex.split(resize), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
@ -216,7 +205,6 @@ def optimise_manual(path):
"_static/scripts/furo.js.map",
"_static/jquery-3.6.0.js",
"_static/jquery.js",
"static/underscore-1.13.1.js",
"_static/_sphinx_javascript_frameworks_compat.js",
"_static/scripts/furo.js.LICENSE.txt",
"_static/styles/furo-extensions.css.map",

View File

@ -2,6 +2,7 @@
[title]: <> (How To Make Your Own RNodes)
[image]: <> (images/g3p.webp)
[excerpt]: <> (This article will outline the general process, and provide the information you need, for building your own RNode from a few basic modules. The RNode will be functionally identical to a commercially purchased board.)
<div class="article_date">{DATE}</div>
# How To Make Your Own RNodes
This article will outline the general process, and provide the information you need, for building your own RNode from a few basic modules. The RNode will be functionally identical to a purchased device.
@ -30,9 +31,10 @@ Currently, the RNode firmware supports a variety of different microcontrollers,
Regarding the LoRa transceiver module, there is going to be an almost overwhelming amount of options to choose from. To narrow it down, here are the essential characteristics to look for:
- The RNode firmware needs a module based on the **Semtech SX1276**, **Semtech SX1278**, **SX1262**, **SX1268** and **SX1280** LoRa transceiver ICs. These come in several different variants, for all frequency bands from about 150 MHz to 2500 MHz.
- The RNode firmware needs a module based on the **Semtech SX1276** or **Semtech SX1278** LoRa transceiver IC. These come in several different variants, for all frequency bands from about 150 MHz to about 1100 MHz.
- Support for **SX1262**, **SX1268** and **SX1280**-based modules is coming soon, but until that is released, only **SX1276** and **SX1278** modules will work.
- The module *must* expose the direct SPI bus to the transceiver chip. UART based modules that add their own communications layer will not work.
- The module must also expose the *reset* line of the chip, and provide the **DIO0** (or other relevant) interrupt signal *from* the chip.
- The module must also expose the *reset* line of the chip, and provide the **DIO0** interrupt signal *from* the chip.
- As mentioned above, the module must be logic-level compatible with the microcontroller you are using, unless you want to add a level-shifter. Resistor divider arrays will most likely not work here, due to the bus speeds required.
Keeping those things in mind, you should be able to select a suitable combination of microcontroller board and transceiver module.
@ -54,17 +56,12 @@ In the photo above I used an Adafruit Feather ESP32 board and a ModTronix inAir4
9. Connect the *DIO0* pin of the transceiver module to the *DIO0 interrupt pin* of the microcontroller board.
10. You can optionally connect transmit and receiver LEDs to the corresponding pins of the microcontroller board.
The pin layouts of your transceiver module and microcontroller board will vary, but you can look up the correct pin assignments for your processor type and board layout in the [Config.h](https://github.com/markqvist/RNode_Firmware/blob/master/Config.h) file of the [RNode Firmware](https://unsigned.io/rnode_firmware).
The pin layouts of your transceiver module and microcontroller board will vary, but you can look up the correct pin assignments for your processor type and board layout in the `Config.h` file of the [RNode Firmware]({ASSET_PATH}pkg/rnode_firmware.zip).
### Loading the Firmware
Once the hardware is assembled, you are ready to load the firmware onto the board and configure the configuration parameters in the boards EEPROM. Luckily, this process is completely automated by the [RNode Configuration Utility](https://markqvist.github.io/Reticulum/manual/using.html#the-rnodeconf-utility). To prepare for loading the firmware, make sure that `python` and `pip` is installed on your system, then install the `rns` package (which includes the `rnodeconf` program) by issuing the command:
## Loading the Firmware
Once the hardware is assembled, you are ready to load the firmware onto the board and configure the configuration parameters in the boards EEPROM. Luckily, this process is completely automated by the [RNode Configuration Utility]({ASSET_PATH}m/using.html#the-rnodeconf-utility).
```txt
pip install rns
```
If installation goes well, you can now move on to the next step.
The `rnodeconf` program is included in the `rns` package. Please read [these instructions]({ASSET_PATH}s_rns.html) for more information on how to install it from this repository, or from the Internet. If installation goes well, you can now move on to the next step.
> *Take Care*: A LoRa transceiver module **must** be connected to the board for the firmware to start and accept commands. If the firmware does not verify that the correct transceiver is available on the SPI bus, execution is stopped, and the board will not accept commands. If you find the board unresponsive after installing the firmware, or EEPROM configuration fails, double-check your transceiver module wiring!
@ -76,6 +73,24 @@ rnodeconf --autoinstall
The installer will now ask you to insert the device you want to set up, scan for connected serial ports, and ask you a number of questions regarding the device. When it has the information it needs, it will install the correct firmware and configure the necessary parameters in the device EEPROM for it to function properly.
> **Please Note!** If you are connected to the Internet while installing, the autoinstaller will automatically download any needed firmware files to a local cache before installing.
> If you do not have an active Internet connection while installing, you can extract and use the firmware from this device instead. This will **only** work if you are building the same type of RNode as the device you are extracting from, as the firmware has to match the targeted board and hardware configuration.
If you need to extract the firmware from an existing RNode, run the following command:
```
rnodeconf --extract
```
If `rnodeconf` finds a working RNode, it will extract and save the firmware from the device for later use. You can then run the auto-installer with the `--use-extracted` option to use the locally extracted file:
```
rnodeconf --autoinstall --use-extracted
```
This also works for updating the firmware on existing RNodes, so you can extract a newer firmware from one RNode, and deploy it onto other RNodes using the same method. Just use the `--update` option instead of `--autoinstall`.
If the install goes well, you will be greated with a success message telling you that your device is now ready. To confirm everything is OK, you can query the device info with:
```txt

View File

@ -1,4 +1,4 @@
// Copyright (C) 2024, Mark Qvist
// Copyright (C) 2023, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -36,8 +36,6 @@
#define APPLICATION_START 0x26000
#define USER_DATA_START 0xED000
#define IMG_SIZE_START 0xFF008
#endif
#endif
@ -143,13 +141,6 @@ void device_save_firmware_hash() {
}
#if MCU_VARIANT == MCU_NRF52
uint32_t retrieve_application_size() {
uint8_t bytes[4];
memcpy(bytes, (const void*)IMG_SIZE_START, 4);
uint32_t fw_len = bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24;
return fw_len;
}
void calculate_region_hash(unsigned long long start, unsigned long long end, uint8_t* return_hash) {
// this function calculates the hash digest of a region of memory,
// currently it is only designed to work for the application region
@ -161,12 +152,16 @@ void calculate_region_hash(unsigned long long start, unsigned long long end, uin
hash.begin(CRYS_HASH_SHA256_mode);
bool finish = false;
uint8_t size;
bool application = true;
int end_count = 0;
unsigned long length = 0;
while (start < end ) {
while (start < end - 1 ) {
const void* src = (const void*)start;
if (start + CHUNK_SIZE >= end) {
size = end - start;
size = (end - 1) - start;
}
else {
size = CHUNK_SIZE;
@ -174,9 +169,74 @@ void calculate_region_hash(unsigned long long start, unsigned long long end, uin
memcpy(chunk, src, CHUNK_SIZE);
hash.update(chunk, size);
// check if we've reached the end of the program
// if we're checking the application region
if (application) {
for (int i = 0; i < CHUNK_SIZE; i++) {
if (chunk[i] == 0xFF) {
bool matched = true;
end_count = 1;
// check if rest of chunk is FFs as well, only if FF is not
// at the end of chunk
if (i < CHUNK_SIZE - 1) {
for (int x = 0; x < CHUNK_SIZE - i; x++) {
if (chunk[i+x] != 0xFF) {
matched = false;
break;
}
end_count++;
}
}
if (matched) {
while (end_count < END_SECTION_SIZE) {
// check if bytes in next chunk up to total
// required are also FFs
for (int x = 1; x <= ceil(END_SECTION_SIZE / CHUNK_SIZE); x++) {
const void* src_next = (const void*)start + CHUNK_SIZE*x;
if ((END_SECTION_SIZE - end_count) > CHUNK_SIZE) {
size = CHUNK_SIZE;
} else {
size = END_SECTION_SIZE - end_count;
}
memcpy(chunk_next, src_next, size);
for (int y = 0; y < size; y++) {
if (chunk_next[y] != 0xFF) {
matched = false;
break;
}
end_count++;
}
if (!matched) {
break;
}
}
if (!matched) {
break;
}
}
if (matched) {
finish = true;
size = i;
break;
}
}
}
}
}
if (finish) {
hash.update(chunk, size);
length += size;
break;
} else {
hash.update(chunk, size);
}
start += CHUNK_SIZE;
length += CHUNK_SIZE;
}
hash.end(return_hash);
}
@ -197,14 +257,16 @@ void device_validate_partitions() {
esp_partition_get_sha256(esp_ota_get_running_partition(), dev_firmware_hash);
#elif MCU_VARIANT == MCU_NRF52
// todo, add bootloader, partition table, or softdevice?
calculate_region_hash(APPLICATION_START, APPLICATION_START+retrieve_application_size(), dev_firmware_hash);
calculate_region_hash(APPLICATION_START, USER_DATA_START, dev_firmware_hash);
#endif
#if VALIDATE_FIRMWARE
for (uint8_t i = 0; i < DEV_HASH_LEN; i++) {
if (dev_firmware_hash_target[i] != dev_firmware_hash[i]) {
fw_signature_validated = false;
break;
}
}
#endif
}
bool device_firmware_ok() {
@ -213,7 +275,6 @@ bool device_firmware_ok() {
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
bool device_init() {
#if VALIDATE_FIRMWARE
if (bt_ready) {
#if MCU_VARIANT == MCU_ESP32
for (uint8_t i=0; i<EEPROM_SIG_LEN; i++){dev_eeprom_signature[i]=EEPROM.read(eeprom_addr(ADDR_SIGNATURE+i));}
@ -249,9 +310,9 @@ bool device_init() {
hash.end(dev_hash);
#endif
device_load_signature();
device_validate_signature();
device_validate_partitions();
#if MCU_VARIANT == MCU_NRF52
@ -262,10 +323,5 @@ bool device_init() {
} else {
return false;
}
#else
// Skip hash comparison and checking BT
device_init_done = true;
return device_init_done;
#endif
}
#endif

1361
Display.h

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
# Building
## Prerequisites
The build system of this repository is based on GNU Make. The `Makefile` is in the base of the repository. Please ensure you have `arduino-cli`, `python3` and `make` installed before proceeding.
The build system of this repository is based on Make. The `Makefile` is in the base of the repository. Please ensure you have `arduino-cli` installed before proceeding.
Firstly, figure out which MCU platform your supported board is based on. The table below can help you.
@ -54,60 +54,6 @@ Ensure you replace [target] with the target you selected. For example:
`make upload-rak4631`
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`
After flashing a custom board, you will also need to provision the EEPROM before use:
`rnodeconf /dev/ttyACM0 -r --platform ESP32 --model a9 --product f0 --hwrev 3`
- platform must either be AVR, ESP32 or NRF52
- hwrev is required (any integer between 1 and 255)
- model should be something from the list below without the leading `0x` and in lowercase (example `e8`):
```
0x11: [430000000, 510000000, 22, "430 - 510 MHz", "rnode_firmware_rak4631.zip", "SX1262"],
0x12: [779000000, 928000000, 22, "779 - 928 MHz", "rnode_firmware_rak4631.zip", "SX1262"],
0xA4: [410000000, 525000000, 14, "410 - 525 MHz", "rnode_firmware.hex", "SX1278"],
0xA9: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware.hex", "SX1276"],
0xA1: [410000000, 525000000, 22, "410 - 525 MHz", "rnode_firmware_t3s3.zip", "SX1268"],
0xA6: [820000000, 1020000000, 22, "820 - 960 MHz", "rnode_firmware_t3s3.zip", "SX1262"],
0xA2: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_ng21.zip", "SX1278"],
0xA7: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware_ng21.zip", "SX1276"],
0xA3: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_ng20.zip", "SX1278"],
0xA8: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware_ng20.zip", "SX1276"],
0xB3: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v20.zip", "SX1278"],
0xB8: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v20.zip", "SX1276"],
0xB4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v21.zip", "SX1278"],
0xB9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v21.zip", "SX1276"],
0x04: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v21_tcxo.zip", "SX1278"],
0x09: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v21_tcxo.zip", "SX1276"],
0xBA: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v10.zip", "SX1278"],
0xBB: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v10.zip", "SX1276"],
0xC4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_heltec32v2.zip", "SX1278"],
0xC9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_heltec32v2.zip", "SX1276"],
0xC5: [470000000, 510000000, 21, "470 - 510 MHz", "rnode_firmware_heltec32v3.zip", "SX1262"],
0xCA: [863000000, 928000000, 21, "863 - 928 MHz", "rnode_firmware_heltec32v3.zip", "SX1262"],
0xE4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_tbeam.zip", "SX1278"],
0xE9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_tbeam.zip", "SX1276"],
0xE3: [420000000, 520000000, 22, "420 - 520 MHz", "rnode_firmware_tbeam_sx1262.zip", "SX1268"],
0xE8: [850000000, 950000000, 22, "850 - 950 MHz", "rnode_firmware_tbeam_sx1262.zip", "SX1262"],
0xFE: [100000000, 1100000000, 17, "(Band capabilities unknown)", None, "Unknown"],
0xFF: [100000000, 1100000000, 14, "(Band capabilities unknown)", None, "Unknown"],
```
- product should be a code from the following list below without the leading `0x` and in lowercase (example `f0`):
```
PRODUCT_RAK4631 = 0x10
PRODUCT_RNODE = 0x03
PRODUCT_T32_10 = 0xB2
PRODUCT_T32_20 = 0xB0
PRODUCT_T32_21 = 0xB1
PRODUCT_H32_V2 = 0xC0
PRODUCT_H32_V3 = 0xC1
PRODUCT_TBEAM = 0xE0
PRODUCT_HMBRW = 0xF0
```
**Please note**, you must re-compile the firmware each time you make changes **before** you flash it, else you will just be flashing the previous version of the firmware without the new changes!
These commands can also be run as a one liner. For example:

View File

@ -1,77 +1,47 @@
# Board support
If you wish to add support for a specific board to the project, all you have to do (if it's ESP32 or nRF52), is write an additional entry for `Boards.h` and `Utilities.h` and the `Makefile` .
If you wish to add support for a specific board to the project, all you have to do (if it's ESP32 or nRF52), is write an additional entry for `Boards.h`.
### Boards.h
This entry in `Boards.h` should include, at a minimum, the following:
This entry should include, at a minimum, the following:
* whether the device has bluetooth / BLE
* whether the device has a PMU
* whether the device has an EEPROM (false in all cases for nRF52, true for ESP32)
* pin mappings for SPI NSS, SCLK, MOSI, MISO, modem reset and dio0
* the type of modem on the board
* the number of interfaces (modems)
* the type of modem on the board (if undefined it defaults to SX127x)
* whether the modem has a busy pin
* RX and TX leds (preferably LEDs of different colours)
You should also define a unique name for your board (with a unique value), for
example:
```
#define BOARD_MY_WICKED_BOARD 0x3B
```
**Check your chosen value is not in use** in `Boards.h` first!
The board definition should look as follows:
# Check this area...
see https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-spi.h#L39
Effectively, there are multiple SPI buses we can map to pins on these
devices (including the hardware SPI bus)
An example of a minimal entry can be seen below:
```
#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD
#define HAS_BLUETOOTH false
#define HAS_CONSOLE true
#define HAS_EEPROM true
#define INTERFACE_COUNT 1
const int pin_led_rx = 9;
const int pin_led_tx = 8;
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX127X
{
true, // DEFAULT_SPI
false, // HAS_TCXO
false // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX127X
{
7, // pin_ss
4, // pin_sclk
6, // pin_mosi
5, // pin_miso
-1, // pin_busy
2, // pin_dio
3, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
#define HAS_BLUETOOTH true
#define HAS_PMU true
#define HAS_EEPROM true
#define EEPROM_SIZE 296 // minimum EEPROM size
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
const int pin_cs = 20;
const int pin_reset = 19;
// const int pin_cs = 1; not needed here
// const int pin_sclk = 2; not needed here
// const int pin_mosi = 3; not needed here
// const int pin_miso = 4; not needed here
const int pin_dio = 18;
// const int pin_busy = 0; not present
const int pin_led_rx = 5;
const int pin_led_tx = 6;
```
Note, this will have to be pasted in the section according to the MCU variant,
e.g. nRF52 or ESP32. Find the section by searching for the comparison where
`MCU_VARIANT` is checked for your MCU variant. **Do not change the order of the
pins or options in any of the interface_cfg or interface_pins arrays.** You
have been warned.
[There are multiple SPI
buses](https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-spi.h#L39)
we can map to pins on these devices (including the hardware SPI bus).
In some cases the SPI pins will not be required, as they will be the default pins for the SPI library supporting the board anyway, and therefore do not need overriding in the config.
If the SX1262 is being used the following should also be considered:
* the modem busy pin
* whether DIO2 should be used as the RF switch (DIO2_AS_RF_SWITCH)
* whether an RF on/off switch also has to be operated (through the pin pin_rxen)
* whether a TCXO is connected to the modem (HAS_TCXO and pin_tcxo_enable to enable the TCXO if present)
* whether the SPI pins are the default used by the SPI library
* whether an rf on/off switch also has to be operated (through the pin pin_rxen)
* whether a TCXO is connected to the modem (HAS_TCXO)
* the enable pin for the TCXO (if present)
An example of an entry using the SX1262 modem can be seen below:
```
@ -81,34 +51,22 @@ An example of an entry using the SX1262 modem can be seen below:
#define HAS_EEPROM true
#define EEPROM_SIZE 296 // minimum EEPROM size
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
#define MODEM SX1262
#define DIO2_AS_RF_SWITCH true
#define HAS_TCXO true
#define HAS_BUSY true
const int pin_cs = 20;
const int pin_reset = 19;
const int pin_rxen = 10;
// const int pin_cs = 1; not needed here
// const int pin_sclk = 2; not needed here
// const int pin_mosi = 3; not needed here
// const int pin_miso = 4; not needed here
const int pin_dio = 18;
const int pin_busy = 7;
const int pin_tcxo_enable = -1;
const int pin_led_rx = 5;
const int pin_led_tx = 6;
#define INTERFACE_COUNT 1
const uint8_t interfaces[INTERFACE_COUNT] = {SX126X};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1262
{
false, // DEFAULT_SPI
true, // HAS_TCXO
true // DIO2_AS_RF_SWITCH
}
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1262
{
42, // pin_ss
43, // pin_sclk
44, // pin_mosi
45, // pin_miso
46, // pin_busy
47, // pin_dio
38, // pin_reset
-1, // pin_txen
37, // pin_rxen
-1 // pin_tcxo_enable
}
};
```
If the SX1280 is being used, the following should also be added:
@ -122,116 +80,24 @@ An example of an entry using the SX1280 modem can be seen below:
#define HAS_EEPROM true
#define EEPROM_SIZE 296 // minimum EEPROM size
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
#define MODEM SX1280
#define HAS_BUSY true
#define HAS_RF_SWITCH_RX_TX true
const int pin_cs = 20;
const int pin_reset = 19;
const int pin_rxen = 10;
const int pin_txen = 11;
// const int pin_cs = 1; not needed here
// const int pin_sclk = 2; not needed here
// const int pin_mosi = 3; not needed here
// const int pin_miso = 4; not needed here
const int pin_dio = 18;
const int pin_busy = 7;
const int pin_tcxo_enable = -1;
const int pin_led_rx = 5;
const int pin_led_tx = 6;
#define INTERFACE_COUNT 1
const uint8_t interfaces[INTERFACE_COUNT] = {SX128X};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1280
{
true, // DEFAULT_SPI
false,// HAS_TCXO
false // DIO2_AS_RF_SWITCH
}
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1280
{
24, // pin_ss
3, // pin_sclk
30, // pin_mosi
29, // pin_miso
25, // pin_busy
15, // pin_dio
16, // pin_reset
20, // pin_txen
19, // pin_rxen
-1 // pin_tcxo_enable
}
};
```
#### INTERFACE_SPI (nRF52 only)
If you are using non-default SPI pins on an nRF52 MCU variant, you **must** ensure that you add this section to the bottom of your board config:
```
// Required because on nRF52, non-default SPI pins must be initialised when class is declared.
const SPIClass interface_spi[1] = {
// SX1262
SPIClass(
NRF_SPIM2,
interface_pins[0][3],
interface_pins[0][1],
interface_pins[0][2]
)
};
```
This will ensure the pins are set correctly in the SPI class.
### Utilities.h
You should add something similar to the following to drive the LEDs depending on your configuration:
```
#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD
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); }
```
Note: this will again have to be pasted in the correct section according to
your MCU variant. Please search for the other definitions of `led_rx_on()` to
find the correct section, then find the final section by searching for the
comparison where `MCU_VARIANT` is checked for your MCU variant.
### Makefile
You can add the example target below to the makefile for your board, but **you must replace the FQBN** in the arduino-cli command with the correct one for your board.
```
firmware-wicked_esp32:
arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\""
```
Pay attention the the DBOARD_MODEL= value as you must insert the one you chose earlier here.
Another entry to upload to the board. Again substitute your FQBN, and you may have to experiment with the commands to get it to flash:
#### ESP32
```
upload-wicked_esp32:
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32c3
@sleep 1
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --chip esp32c3 --port /dev/ttyACM0 --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
```
#### nRF52
```
upload-wicked_nrf52:
arduino-cli upload -p /dev/ttyACM0 --fqbn rakwireless:nrf52:WisCoreRAK4631Board
unzip -o build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.zip -d build/rakwireless.nrf52.WisCoreRAK4631Board
rnodeconf /dev/ttyACM0 --firmware-hash $$(sha256sum ./build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.bin | grep -o '^\S*')
```
And one final entry to make a release for the firmware:
#### ESP32
```
release-wicked_esp32:
arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_wicked_esp32.boot_app0
cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bin build/rnode_firmware_wicked_esp32.bin
cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_wicked_esp32.bootloader
cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_wicked_esp32.partitions
zip --junk-paths ./Release/rnode_firmware_wicked_esp32.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_wicked_esp32.boot_app0 build/rnode_firmware_wicked_esp32.bin build/rnode_firmware_wicked_esp32.bootloader build/rnode_firmware_wicked_esp32.partitions
rm -r build
```
#### nRF52
```
release-wicked_nrf52:
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\""
cp build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.hex build/rnode_firmware_wicked_nrf52.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/rnode_firmware_wicked_nrf52.hex Release/rnode_firmware_wicked_nrf52.zip
```
Don't forget to add this entry to the `release-all` target!
```
release-all: console-site spiffs-image release-tbeam release-tbeam_sx1262 release-lora32_v10 release-lora32_v20 release-lora32_v21 release-lora32_v10_extled release-lora32_v20_extled release-lora32_v21_extled release-lora32_v21_tcxo release-featheresp32 release-genericesp32 ***release-wicked_esp32*** release-heltec32_v2 release-heltec32_v3 release-heltec32_v2_extled release-rnode_ng_20 release-rnode_ng_21 release-t3s3 release-hashes
```
You can of course replace the ESP32 target with the nRF52 target, if you are building for that MCU variant, as seen in previous instructions.
Please submit this, and any other support in different areas of the project your board may require, as a PR for my consideration.
# Feature request

View File

@ -1,4 +1,4 @@
// Copyright (C) 2024, Mark Qvist
// Copyright (C) 2023, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -44,7 +44,6 @@
#define CMD_STAT_CHTM 0x25
#define CMD_STAT_PHYPRM 0x26
#define CMD_STAT_BAT 0x27
#define CMD_STAT_CSMA 0x28
#define CMD_BLINK 0x30
#define CMD_RANDOM 0x40
@ -52,16 +51,10 @@
#define CMD_FB_READ 0x42
#define CMD_FB_WRITE 0x43
#define CMD_FB_READL 0x44
#define CMD_DISP_READ 0x66
#define CMD_DISP_INT 0x45
#define CMD_DISP_ADDR 0x63
#define CMD_DISP_BLNK 0x64
#define CMD_DISP_ROT 0x67
#define CMD_DISP_RCND 0x68
#define CMD_NP_INT 0x65
#define CMD_BT_CTRL 0x46
#define CMD_BT_PIN 0x62
#define CMD_DIS_IA 0x69
#define CMD_BOARD 0x47
#define CMD_PLATFORM 0x48
@ -82,10 +75,32 @@
#define CMD_RESET_BYTE 0xF8
#define CMD_INTERFACES 0x64
#define CMD_DATA 0x00
#define CMD_SEL_INT 0x1F
#define CMD_INT0_DATA 0x00
#define CMD_INT1_DATA 0x10
#define CMD_INT2_DATA 0x20
#define CMD_INT3_DATA 0x70
#define CMD_INT4_DATA 0x80
#define CMD_INT5_DATA 0x90
#define CMD_INT6_DATA 0xA0
#define CMD_INT7_DATA 0xB0
#define CMD_INT8_DATA 0xC0
#define CMD_INT9_DATA 0xD0
#define CMD_INT10_DATA 0xE0
#define CMD_INT11_DATA 0xF0
#define CMD_SEL_INT0 0x1E
#define CMD_SEL_INT1 0x1F
#define CMD_SEL_INT2 0x2F
#define CMD_SEL_INT3 0x7F
#define CMD_SEL_INT4 0x8F
#define CMD_SEL_INT5 0x9F
#define CMD_SEL_INT6 0xAF
#define CMD_SEL_INT7 0xBF
#define CMD_SEL_INT8 0xCF
#define CMD_SEL_INT9 0xDF
#define CMD_SEL_INT10 0xEF
#define CMD_SEL_INT11 0xFF
#define DETECT_REQ 0x73
#define DETECT_RESP 0x46
@ -103,21 +118,6 @@
#define ERROR_TXFAILED 0x02
#define ERROR_EEPROM_LOCKED 0x03
#define ERROR_QUEUE_FULL 0x04
#define ERROR_MEMORY_LOW 0x05
#define ERROR_MODEM_TIMEOUT 0x06
#define CMD_GPS 0xA0
#define GPS_CMD_LAT 0x00
#define GPS_CMD_LNG 0x01
// Serial logging
#define LOG_MSG 0x2F
#define MSG_INFO 0x01
#define MSG_ERR 0x02
#define MSG_DBG 0x03
#define MSG_TRACE 0x04
// Serial framing variables
size_t frame_len;

1773
Graphics.h

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,7 @@
#define SX1276 0x00
#define SX1278 0x01
#define SX1261 0x10
#define SX127X 0x00
#define SX1276 0x01
#define SX1278 0x02
#define SX126X 0x10
#define SX1262 0x11
#define SX1268 0x12
#define SX1280 0x20
#define SX128X 0x20
#define SX1280 0x21

502
Makefile
View File

@ -1,4 +1,4 @@
# Copyright (C) 2024, Mark Qvist
# Copyright (C) 2023, Mark Qvist
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -13,520 +13,364 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Version 2.0.17 of the Arduino ESP core is based on ESP-IDF v4.4.7
ARDUINO_ESP_CORE_VER = 2.0.17
V ?= 0
VFLAG =
ifeq "$(V)" "1"
VFLAG =-v
endif
COMMON_BUILD_FLAGS = $(VFLAG) -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152"
COMMON_ESP_UPLOAD_FLAGS = $(VFLAG) --chip esp32 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000
ESP_IDF_VER = 2.0.17
all: release
clean:
-rm -rf ./build
-rm -f ./Release/rnode_firmware*
-rm -r ./build
-rm ./Release/rnode_firmware*
prep: prep-esp32 prep-nrf
prep: prep-avr prep-esp32 prep-samd
prep-index:
prep-avr:
arduino-cli core update-index --config-file arduino-cli.yaml
arduino-cli core install arduino:avr --config-file arduino-cli.yaml
arduino-cli core install unsignedio:avr --config-file arduino-cli.yaml
prep-esp32:
arduino-cli core install esp32:esp32@$(ARDUINO_ESP_CORE_VER) --config-file arduino-cli.yaml
arduino-cli core update-index --config-file arduino-cli.yaml
arduino-cli core install esp32:esp32@2.0.17 --config-file arduino-cli.yaml
arduino-cli lib install "Adafruit SSD1306"
arduino-cli lib install "Adafruit SH110X"
arduino-cli lib install "Adafruit ST7735 and ST7789 Library"
arduino-cli lib install "Adafruit NeoPixel"
arduino-cli lib install "XPowersLib"
arduino-cli lib install "Crypto"
arduino-cli lib install "Adafruit NeoPixel"
pip install pyserial rns --upgrade --user --break-system-packages # This looks scary, but it's actually just telling pip to install packages as a user instead of trying to install them systemwide, which bypasses the "externally managed environment" error.
prep-samd:
arduino-cli core update-index --config-file arduino-cli.yaml
arduino-cli core install adafruit:samd --config-file arduino-cli.yaml
prep-nrf:
arduino-cli core install adafruit:nrf52 --config-file arduino-cli.yaml
arduino-cli core update-index --config-file arduino-cli.yaml
arduino-cli core install rakwireless:nrf52 --config-file arduino-cli.yaml
arduino-cli core install Heltec_nRF52:Heltec_nRF52 --config-file arduino-cli.yaml
arduino-cli lib install "Crypto"
arduino-cli lib install "Adafruit GFX Library"
arduino-cli lib install "GxEPD2"
arduino-cli lib install "TinyGPSPlus"
arduino-cli config set library.enable_unsafe_install true
arduino-cli lib install --git-url https://github.com/liamcottle/esp8266-oled-ssd1306#e16cee124fe26490cb14880c679321ad8ac89c95
pip install pyserial rns --upgrade --user --break-system-packages # This looks scary, but it's actually just telling pip to install packages as a user instead of trying to install them systemwide, which bypasses the "externally managed environment" error.
pip install adafruit-nrfutil --upgrade --user --break-system-packages # This looks scary, but it's actually just telling pip to install packages as a user instead of trying to install them systemwide, which bypasses the "externally managed environment" error.
pip install adafruit-nrfutil --upgrade
console-site:
make -C Console clean site
spiffs: console-site spiffs-image
spiffs: console-site spiffs-image
spiffs-image:
python3 Release/esptool/spiffsgen.py 1966080 ./Console/build Release/console_image.bin
python Release/esptool/spiffsgen.py 1966080 ./Console/build Release/console_image.bin
upload-spiffs:
@echo Deploying SPIFFS image...
python ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyACM0) $(COMMON_UPLOAD_FLAGS) ./Release/console_image.bin
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --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
firmware: $(shell grep ^firmware- Makefile | cut -d: -f1)
firmware:
arduino-cli compile --fqbn unsignedio:avr:rnode
check_bt_buffers:
@./esp32_btbufs.py ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/libraries/BluetoothSerial/src/BluetoothSerial.cpp
firmware-mega2560:
arduino-cli compile --fqbn arduino:avr:mega
firmware-tbeam: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:t-beam $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\" \"-DBOARD_VARIANT=0xE4\""
firmware-tbeam:
arduino-cli compile --fqbn esp32:esp32:t-beam -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\""
firmware-tbeam_sx1262: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:t-beam $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\" \"-DBOARD_VARIANT=0xE8\""
firmware-techo:
arduino-cli compile --fqbn adafruit:nrf52:pca10056 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x44\""
firmware-tbeam_sx126x:
arduino-cli compile --fqbn esp32:esp32:t-beam -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\" \"-DMODEM=0x03\""
firmware-t3s3:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xAB\""
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\""
firmware-t3s3_sx126x:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xA1\""
firmware-lora32_v10:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x39\""
firmware-t3s3_sx1280_pa:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xAC\""
firmware-lora32_v10_extled:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x39\" \"-DEXTERNAL_LEDS=true\""
firmware-e22_esp32:
arduino-cli compile --fqbn esp32:esp32:esp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x45\" \"-DEXTERNAL_LEDS=true\""
firmware-lora32_v20:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x36\" \"-DEXTERNAL_LEDS=true\""
firmware-lora32_v10: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x39\""
firmware-lora32_v21:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\""
firmware-lora32_v10_extled: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x39\" \"-DEXTERNAL_LEDS=true\""
firmware-lora32_v21_extled:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\" \"-DEXTERNAL_LEDS=true\""
firmware-lora32_v20: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x36\" \"-DEXTERNAL_LEDS=true\""
firmware-lora32_v21_tcxo:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\" \"-DENABLE_TCXO=true\""
firmware-lora32_v21: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\""
firmware-heltec32_v2:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V2 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x38\""
firmware-lora32_v21_extled: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\" \"-DEXTERNAL_LEDS=true\""
firmware-lora32_v21_tcxo: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\" \"-DENABLE_TCXO=true\""
firmware-heltec32_v2: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V2 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x38\""
firmware-heltec32_v2_extled: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V2 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x38\" \"-DEXTERNAL_LEDS=true\""
firmware-heltec32_v2_extled:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V2 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x38\" \"-DEXTERNAL_LEDS=true\""
firmware-heltec32_v3:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V3 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3A\""
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V3 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3A\""
firmware-heltec_w_paper:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V3 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3E\""
firmware-rnode_ng_20:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x40\""
firmware-xiao_esp32s3:
arduino-cli compile --fqbn esp32:esp32:XIAO_ESP32S3 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3E\""
firmware-rnode_ng_21:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x41\""
firmware-rnode_ng_20: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x40\""
firmware-featheresp32:
arduino-cli compile --fqbn esp32:esp32:featheresp32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x34\""
firmware-rnode_ng_21: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x41\""
firmware-featheresp32: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:featheresp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x34\""
firmware-genericesp32: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:esp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x35\""
firmware-genericesp32:
arduino-cli compile --fqbn esp32:esp32:esp32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x35\""
firmware-rak4631:
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x51\" \"-DBOARD_VARIANT=0x12\""
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x51\""
firmware-rak4631_sx1280:
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x51\" \"-DBOARD_VARIANT=0x14\""
upload:
arduino-cli upload -p /dev/ttyUSB0 --fqbn unsignedio:avr:rnode
firmware-opencom-xl:
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x52\" \"-DBOARD_VARIANT=0x21\""
firmware-heltec_t114:
arduino-cli compile --log --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\""
firmware-heltec_t114_gps:
arduino-cli compile --log --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\" \"-DBOARD_VARIANT=0xCB\""
upload-mega2560:
arduino-cli upload -p /dev/ttyACM0 --fqbn arduino:avr:mega
upload-tbeam:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:t-beam
@sleep 1
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyACM0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
upload-tbeam_sx1262:
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:t-beam
@sleep 1
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.bin)
#@sleep 3
#python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --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
@sleep 3
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --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
upload-lora32_v10:
arduino-cli upload -p $(or $(port), /dev/ttyUSB0) --fqbn esp32:esp32:ttgo-lora32
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:ttgo-lora32
@sleep 1
rnodeconf $(or $(port), /dev/ttyUSB0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyUSB0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyUSB0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --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
upload-lora32_v20:
arduino-cli upload -p $(or $(port), /dev/ttyUSB0) --fqbn esp32:esp32:ttgo-lora32
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:ttgo-lora32
@sleep 1
rnodeconf $(or $(port), /dev/ttyUSB0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyUSB0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyUSB0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --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
upload-lora32_v21:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:ttgo-lora32
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:ttgo-lora32
@sleep 1
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyACM0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --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
upload-heltec32_v2:
arduino-cli upload -p $(or $(port), /dev/ttyUSB0) --fqbn esp32:esp32:heltec_wifi_lora_32_V2
arduino-cli upload -p /dev/ttyUSB1 --fqbn esp32:esp32:heltec_wifi_lora_32_V2
@sleep 1
rnodeconf $(or $(port), /dev/ttyUSB0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyUSB1 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyUSB0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB1 --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
upload-heltec_w_paper upload-heltec32_v3:
arduino-cli upload -p $(or $(port), /dev/ttyUSB0) --fqbn esp32:esp32:heltec_wifi_lora_32_V3
upload-heltec32_v3:
arduino-cli upload -p /dev/ttyUSB1 --fqbn esp32:esp32:heltec_wifi_lora_32_V3
@sleep 1
rnodeconf $(or $(port), /dev/ttyUSB0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyUSB1 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyUSB0) --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
upload-xiao_esp32s3:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:XIAO_ESP32S3
@sleep 1
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.XIAO_ESP32S3/RNode_Firmware_CE.ino.bin)
@sleep 3
python ./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 8MB 0x210000 ./Release/console_image.bin
upload-tdeck:
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
python ./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
upload-tbeam_supreme:
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
python ./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
python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyUSB1 --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
upload-rnode_ng_20:
arduino-cli upload -p $(or $(port), /dev/ttyUSB0) --fqbn esp32:esp32:ttgo-lora32
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:ttgo-lora32
@sleep 1
rnodeconf $(or $(port), /dev/ttyUSB0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyUSB0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyUSB0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --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
upload-rnode_ng_21:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:ttgo-lora32
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:ttgo-lora32
@sleep 1
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyACM0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --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
upload-t3s3:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:esp32s3
@echo
@echo Put board into flashing mode by holding BOOT button while momentarily pressing the RESET button. Hit enter when done.
@read
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32s3
@sleep 2
python ./Release/esptool/esptool.py --chip esp32s3 --port /dev/ttyACM0 --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
@echo
@echo Press the RESET button on the board now, and hit enter
@read
@sleep 1
python ./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
@sleep 3
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin)
upload-featheresp32:
arduino-cli upload -p $(or $(port), /dev/ttyUSB0) --fqbn esp32:esp32:featheresp32
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:featheresp32
@sleep 1
rnodeconf $(or $(port), /dev/ttyUSB0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.featheresp32/RNode_Firmware_CE.ino.bin)
rnodeconf /dev/ttyUSB0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.featheresp32/RNode_Firmware_CE.ino.bin)
@sleep 3
python ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyUSB0) $(COMMON_UPLOAD_FLAGS) ./Release/console_image.bin
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --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
upload-opencom-xl upload-rak4631:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn rakwireless:nrf52:WisCoreRAK4631Board
upload-rak4631:
arduino-cli upload -p /dev/ttyACM0 --fqbn rakwireless:nrf52:WisCoreRAK4631Board
unzip -o build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.zip -d build/rakwireless.nrf52.WisCoreRAK4631Board
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(sha256sum ./build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.bin | grep -o '^\S*')
rnodeconf /dev/ttyACM0 --firmware-hash $$(sha256sum ./build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.bin | grep -o '^\S*')
upload-e22_esp32:
arduino-cli upload -p $(or $(port), /dev/ttyUSB0) --fqbn esp32:esp32:esp32
@sleep 1
rnodeconf $(or $(port), /dev/ttyUSB0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyUSB0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
upload-heltec_t114:
arduino-cli upload -p /dev/ttyACM0 --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262
@sleep 1
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes from_device /dev/ttyACM0)
upload-techo:
arduino-cli upload -p /dev/ttyACM0 --fqbn adafruit:nrf52:pca10056
@sleep 6
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes from_device /dev/ttyACM0)
release: release-all
release: console-site spiffs-image $(shell grep ^release- Makefile | cut -d: -f1)
release-all: console-site spiffs-image release-tbeam release-tbeam_sx1262 release-lora32_v10 release-lora32_v20 release-lora32_v21 release-lora32_v10_extled release-lora32_v20_extled release-lora32_v21_extled release-lora32_v21_tcxo release-featheresp32 release-genericesp32 release-heltec32_v2 release-heltec32_v3 release-heltec32_v2_extled release-rnode_ng_20 release-rnode_ng_21 release-t3s3 release-hashes
release-hashes:
python3 ./release_hashes.py > ./Release/release.json
python ./release_hashes.py > ./Release/release.json
release-tbeam: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:t-beam $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\" \"-DBOARD_VARIANT=0xE4\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_tbeam.boot_app0
release-tbeam:
arduino-cli compile --fqbn esp32:esp32:t-beam -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_tbeam.boot_app0
cp build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.bin build/rnode_firmware_tbeam.bin
cp build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_tbeam.bootloader
cp build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_tbeam.partitions
zip --junk-paths ./Release/rnode_firmware_tbeam.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_tbeam.boot_app0 build/rnode_firmware_tbeam.bin build/rnode_firmware_tbeam.bootloader build/rnode_firmware_tbeam.partitions
rm -r build
release-tbeam_sx1262: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:t-beam $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\" \"-DBOARD_VARIANT=0xE8\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_tbeam_sx1262.boot_app0
release-tbeam_sx1262:
arduino-cli compile --fqbn esp32:esp32:t-beam -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\" \"-DMODEM=0x03\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_tbeam_sx1262.boot_app0
cp build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.bin build/rnode_firmware_tbeam_sx1262.bin
cp build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_tbeam_sx1262.bootloader
cp build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_tbeam_sx1262.partitions
zip --junk-paths ./Release/rnode_firmware_tbeam_sx1262.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_tbeam_sx1262.boot_app0 build/rnode_firmware_tbeam_sx1262.bin build/rnode_firmware_tbeam_sx1262.bootloader build/rnode_firmware_tbeam_sx1262.partitions
rm -r build
release-lora32_v10: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x39\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v10.boot_app0
release-lora32_v10:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x39\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v10.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_lora32v10.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_lora32v10.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_lora32v10.partitions
zip --junk-paths ./Release/rnode_firmware_lora32v10.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_lora32v10.boot_app0 build/rnode_firmware_lora32v10.bin build/rnode_firmware_lora32v10.bootloader build/rnode_firmware_lora32v10.partitions
rm -r build
release-lora32_v20: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x36\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v20.boot_app0
release-lora32_v20:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x36\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v20.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_lora32v20.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_lora32v20.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_lora32v20.partitions
zip --junk-paths ./Release/rnode_firmware_lora32v20.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_lora32v20.boot_app0 build/rnode_firmware_lora32v20.bin build/rnode_firmware_lora32v20.bootloader build/rnode_firmware_lora32v20.partitions
rm -r build
release-lora32_v21: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v21.boot_app0
release-lora32_v21:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v21.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_lora32v21.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_lora32v21.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_lora32v21.partitions
zip --junk-paths ./Release/rnode_firmware_lora32v21.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_lora32v21.boot_app0 build/rnode_firmware_lora32v21.bin build/rnode_firmware_lora32v21.bootloader build/rnode_firmware_lora32v21.partitions
rm -r build
release-lora32_v10_extled: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x39\" \"-DEXTERNAL_LEDS=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v10.boot_app0
release-lora32_v10_extled:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x39\" \"-DEXTERNAL_LEDS=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v10.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_lora32v10.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_lora32v10.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_lora32v10.partitions
zip --junk-paths ./Release/rnode_firmware_lora32v10.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_lora32v10.boot_app0 build/rnode_firmware_lora32v10.bin build/rnode_firmware_lora32v10.bootloader build/rnode_firmware_lora32v10.partitions
rm -r build
release-lora32_v20_extled: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x36\" \"-DEXTERNAL_LEDS=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v20.boot_app0
release-lora32_v20_extled:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x36\" \"-DEXTERNAL_LEDS=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v20.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_lora32v20.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_lora32v20.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_lora32v20.partitions
zip --junk-paths ./Release/rnode_firmware_lora32v20_extled.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_lora32v20.boot_app0 build/rnode_firmware_lora32v20.bin build/rnode_firmware_lora32v20.bootloader build/rnode_firmware_lora32v20.partitions
rm -r build
release-lora32_v21_extled: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\" \"-DEXTERNAL_LEDS=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v21.boot_app0
release-lora32_v21_extled:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\" \"-DEXTERNAL_LEDS=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v21.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_lora32v21.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_lora32v21.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_lora32v21.partitions
zip --junk-paths ./Release/rnode_firmware_lora32v21_extled.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_lora32v21.boot_app0 build/rnode_firmware_lora32v21.bin build/rnode_firmware_lora32v21.bootloader build/rnode_firmware_lora32v21.partitions
rm -r build
release-lora32_v21_tcxo: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\" \"-DENABLE_TCXO=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v21_tcxo.boot_app0
release-lora32_v21_tcxo:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x37\" \"-DENABLE_TCXO=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_lora32v21_tcxo.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_lora32v21_tcxo.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_lora32v21_tcxo.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_lora32v21_tcxo.partitions
zip --junk-paths ./Release/rnode_firmware_lora32v21_tcxo.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_lora32v21_tcxo.boot_app0 build/rnode_firmware_lora32v21_tcxo.bin build/rnode_firmware_lora32v21_tcxo.bootloader build/rnode_firmware_lora32v21_tcxo.partitions
rm -r build
release-heltec32_v2: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V2 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x38\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_heltec32v2.boot_app0
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.bin build/rnode_firmware_heltec32v2.bin
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_heltec32v2.bootloader
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_heltec32v2.partitions
release-heltec32_v3:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V3 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3A\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_heltec32v3.boot_app0
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.bin build/rnode_firmware_heltec32v3.bin
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_heltec32v3.bootloader
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_heltec32v3.partitions
zip --junk-paths ./Release/rnode_firmware_heltec32v3.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_heltec32v3.boot_app0 build/rnode_firmware_heltec32v3.bin build/rnode_firmware_heltec32v3.bootloader build/rnode_firmware_heltec32v3.partitions
rm -r build
release-heltec_w_paper:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V3 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3E\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_heltecwpaper.boot_app0
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.bin build/rnode_firmware_heltecwpaper.bin
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_heltecwpaper.bootloader
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_heltecwpaper.partitions
zip --junk-paths ./Release/rnode_firmware_heltecwpaper.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_heltecwpaper.boot_app0 build/rnode_firmware_heltecwpaper.bin build/rnode_firmware_heltecwpaper.bootloader build/rnode_firmware_heltecwpaper.partitions
rm -r build
release-xiao_esp32s3:
arduino-cli compile --fqbn esp32:esp32:XIAO_ESP32S3 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3E\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_xiao_esp32s3.boot_app0
cp build/esp32.esp32.XIAO_ESP32S3/RNode_Firmware_CE.ino.bin build/rnode_firmware_xiao_esp32s3.bin
cp build/esp32.esp32.XIAO_ESP32S3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_xiao_esp32s3.bootloader
cp build/esp32.esp32.XIAO_ESP32S3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_xiao_esp32s3.partitions
zip --junk-paths ./Release/rnode_firmware_xiao_esp32s3.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_xiao_esp32s3.boot_app0 build/rnode_firmware_xiao_esp32s3.bin build/rnode_firmware_xiao_esp32s3.bootloader build/rnode_firmware_xiao_esp32s3.partitions
rm -r build
release-heltec32_v2_extled: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V2 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x38\" \"-DEXTERNAL_LEDS=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_heltec32v2.boot_app0
release-heltec32_v2:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V2 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x38\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_heltec32v2.boot_app0
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.bin build/rnode_firmware_heltec32v2.bin
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_heltec32v2.bootloader
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_heltec32v2.partitions
zip --junk-paths ./Release/rnode_firmware_heltec32v2.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_heltec32v2.boot_app0 build/rnode_firmware_heltec32v2.bin build/rnode_firmware_heltec32v2.bootloader build/rnode_firmware_heltec32v2.partitions
rm -r build
release-rnode_ng_20: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x40\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_ng20.boot_app0
release-heltec32_v3:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V3 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3A\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_heltec32v3.boot_app0
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.bin build/rnode_firmware_heltec32v3.bin
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_heltec32v3.bootloader
cp build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_heltec32v3.partitions
zip --junk-paths ./Release/rnode_firmware_heltec32v3.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_heltec32v3.boot_app0 build/rnode_firmware_heltec32v3.bin build/rnode_firmware_heltec32v3.bootloader build/rnode_firmware_heltec32v3.partitions
rm -r build
release-heltec32_v2_extled:
arduino-cli compile --fqbn esp32:esp32:heltec_wifi_lora_32_V2 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x38\" \"-DEXTERNAL_LEDS=true\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_heltec32v2.boot_app0
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.bin build/rnode_firmware_heltec32v2.bin
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_heltec32v2.bootloader
cp build/esp32.esp32.heltec_wifi_lora_32_V2/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_heltec32v2.partitions
zip --junk-paths ./Release/rnode_firmware_heltec32v2.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_heltec32v2.boot_app0 build/rnode_firmware_heltec32v2.bin build/rnode_firmware_heltec32v2.bootloader build/rnode_firmware_heltec32v2.partitions
rm -r build
release-rnode_ng_20:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x40\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_ng20.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_ng20.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_ng20.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_ng20.partitions
zip --junk-paths ./Release/rnode_firmware_ng20.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_ng20.boot_app0 build/rnode_firmware_ng20.bin build/rnode_firmware_ng20.bootloader build/rnode_firmware_ng20.partitions
rm -r build
release-rnode_ng_21: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x41\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_ng21.boot_app0
release-rnode_ng_21:
arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x41\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_ng21.boot_app0
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin build/rnode_firmware_ng21.bin
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_ng21.bootloader
cp build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_ng21.partitions
zip --junk-paths ./Release/rnode_firmware_ng21.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_ng21.boot_app0 build/rnode_firmware_ng21.bin build/rnode_firmware_ng21.bootloader build/rnode_firmware_ng21.partitions
rm -r build
release-techo:
arduino-cli compile --fqbn adafruit:nrf52:pca10056 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x44\""
cp build/adafruit.nrf52.pca10056/RNode_Firmware_CE.ino.hex build/rnode_firmware_techo.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/rnode_firmware_techo.hex Release/rnode_firmware_techo.zip
rm -r build
release-t3s3:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xA1\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3_sx126x.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3_sx126x.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3_sx126x.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3_sx126x.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3_sx126x.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx126x.boot_app0 build/rnode_firmware_t3s3_sx126x.bin build/rnode_firmware_t3s3_sx126x.bootloader build/rnode_firmware_t3s3_sx126x.partitions
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3.boot_app0 build/rnode_firmware_t3s3.bin build/rnode_firmware_t3s3.bootloader build/rnode_firmware_t3s3.partitions
rm -r build
release-t3s3_sx127x:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xA5\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3_sx127x.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3_sx127x.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3_sx127x.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3_sx127x.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3_sx127x.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx127x.boot_app0 build/rnode_firmware_t3s3_sx127x.bin build/rnode_firmware_t3s3_sx127x.bootloader build/rnode_firmware_t3s3_sx127x.partitions
rm -r build
release-t3s3_sx1280_pa:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xAC\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3_sx1280_pa.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3_sx1280_pa.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3_sx1280_pa.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3_sx1280_pa.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3_sx1280_pa.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx1280_pa.boot_app0 build/rnode_firmware_t3s3_sx1280_pa.bin build/rnode_firmware_t3s3_sx1280_pa.bootloader build/rnode_firmware_t3s3_sx1280_pa.partitions
rm -r build
release-e22_esp32:
arduino-cli compile --fqbn esp32:esp32:esp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x45\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_esp32_e22.boot_app0
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bin build/rnode_firmware_esp32_e22.bin
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_esp32_e22.bootloader
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_esp32_e22.partitions
zip --junk-paths ./Release/rnode_firmware_esp32_e22.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_esp32_e22.boot_app0 build/rnode_firmware_esp32_e22.bin build/rnode_firmware_esp32_e22.bootloader build/rnode_firmware_esp32_e22.partitions
rm -r build
release-tdeck:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_tdeck.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_tdeck.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_tdeck.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_tdeck.partitions
zip --junk-paths ./Release/rnode_firmware_tdeck.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_tdeck.boot_app0 build/rnode_firmware_tdeck.bin build/rnode_firmware_tdeck.bootloader build/rnode_firmware_tdeck.partitions
rm -r build
release-tbeam_supreme:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3D\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_tbeam_supreme.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_tbeam_supreme.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_tbeam_supreme.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_tbeam_supreme.partitions
zip --junk-paths ./Release/rnode_firmware_tbeam_supreme.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_tbeam_supreme.boot_app0 build/rnode_firmware_tbeam_supreme.bin build/rnode_firmware_tbeam_supreme.bootloader build/rnode_firmware_tbeam_supreme.partitions
rm -r build
release-featheresp32: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:featheresp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x34\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_featheresp32.boot_app0
release-featheresp32:
arduino-cli compile --fqbn esp32:esp32:featheresp32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x34\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_featheresp32.boot_app0
cp build/esp32.esp32.featheresp32/RNode_Firmware_CE.ino.bin build/rnode_firmware_featheresp32.bin
cp build/esp32.esp32.featheresp32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_featheresp32.bootloader
cp build/esp32.esp32.featheresp32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_featheresp32.partitions
zip --junk-paths ./Release/rnode_firmware_featheresp32.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_featheresp32.boot_app0 build/rnode_firmware_featheresp32.bin build/rnode_firmware_featheresp32.bootloader build/rnode_firmware_featheresp32.partitions
rm -r build
release-genericesp32: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:esp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x35\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_esp32_generic.boot_app0
release-genericesp32:
arduino-cli compile --fqbn esp32:esp32:esp32 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x35\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_esp32_generic.boot_app0
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bin build/rnode_firmware_esp32_generic.bin
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_esp32_generic.bootloader
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_esp32_generic.partitions
zip --junk-paths ./Release/rnode_firmware_esp32_generic.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_esp32_generic.boot_app0 build/rnode_firmware_esp32_generic.bin build/rnode_firmware_esp32_generic.bootloader build/rnode_firmware_esp32_generic.partitions
rm -r build
release-mega2560:
arduino-cli compile --fqbn arduino:avr:mega -e --build-property "compiler.cpp.extra_flags=\"-DMODEM=0x01\""
cp build/arduino.avr.mega/RNode_Firmware_CE.ino.hex Release/rnode_firmware_m2560.hex
rm -r build
release-rak4631:
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x51\" \"-DBOARD_VARIANT=0x12\""
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x51\""
cp build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.hex build/rnode_firmware_rak4631.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/rnode_firmware_rak4631.hex Release/rnode_firmware_rak4631.zip
rm -r build
release-rak4631_sx1280:
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x51\" \"-DBOARD_VARIANT=0x14\""
cp build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.hex build/rnode_firmware_rak4631_sx1280.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/rnode_firmware_rak4631_sx1280.hex Release/rnode_firmware_rak4631_sx1280.zip
rm -r build
release-opencom-xl:
arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x52\" \"-DBOARD_VARIANT=0x21\""
cp build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.hex build/rnode_firmware_opencom_xl.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/rnode_firmware_opencom_xl.hex Release/rnode_firmware_opencom_xl.zip
rm -r build
release-heltec_t114:
arduino-cli compile --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\""
cp build/Heltec_nRF52.Heltec_nRF52.HT-n5262/RNode_Firmware_CE.ino.hex build/rnode_firmware_heltec_t114.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/rnode_firmware_heltec_t114.hex Release/rnode_firmware_heltec_t114.zip
rm -r build

323
Power.h
View File

@ -1,28 +1,9 @@
// Copyright (C) 2024, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#if BOARD_MODEL == BOARD_TBEAM || BOARD_MODEL == BOARD_TBEAM_S_V1
#if BOARD_MODEL == BOARD_TBEAM
#include <XPowersLib.h>
XPowersLibInterface* PMU = NULL;
#ifndef PMU_WIRE_PORT
#if BOARD_MODEL == BOARD_TBEAM_S_V1
#define PMU_WIRE_PORT Wire1
#else
#define PMU_WIRE_PORT Wire
#endif
#define PMU_WIRE_PORT Wire
#endif
#define BAT_V_MIN 3.15
@ -47,6 +28,8 @@
pmuInterrupt = true;
}
#elif BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1
#define BAT_C_SAMPLES 7
#define BAT_D_SAMPLES 2
#define BAT_V_MIN 3.15
#define BAT_V_MAX 4.3
#define BAT_V_CHG 4.48
@ -61,109 +44,26 @@
int bat_charged_samples = 0;
bool bat_voltage_dropping = false;
float bat_delay_v = 0;
float bat_state_change_v = 0;
#elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL
#include "nrfx_power.h"
#define BAT_C_SAMPLES 7
#define BAT_D_SAMPLES 2
#define BAT_V_MIN 2.75
#define BAT_V_MAX 4.2
#define BAT_V_FLOAT 4.22
#define BAT_SAMPLES 5
#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12 - bit ADC resolution = 3000mV / 4096
#define VBAT_DIVIDER_COMP (1.73) // Compensation factor for the VBAT divider
#define VBAT_MV_PER_LSB_FIN (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#define PIN_VBAT WB_A0
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;
#elif BOARD_MODEL == BOARD_T3S3
#define BAT_V_MIN 3.15
#define BAT_V_MAX 4.217
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 5
const uint8_t pin_vbat = 1;
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;
#elif BOARD_MODEL == BOARD_TDECK
#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 = 4;
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;
#elif BOARD_MODEL == BOARD_HELTEC32_V3
#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 7
const uint8_t pin_vbat = 1;
const uint8_t pin_ctrl = 37;
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;
#elif BOARD_MODEL == BOARD_HELTEC_T114
#define BAT_V_MIN 3.15
#define BAT_V_MAX 4.165
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 7
const uint8_t pin_vbat = 4;
const uint8_t pin_ctrl = 6;
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;
#elif BOARD_MODEL == BOARD_TECHO
#define BAT_V_MIN 3.15
#define BAT_V_MAX 4.16
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 7
const uint8_t pin_vbat = 4;
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;
#elif BOARD_MODEL == BOARD_RAK4631
#include "nrfx_power.h"
#define BAT_C_SAMPLES 7
#define BAT_D_SAMPLES 2
#define BAT_V_MIN 2.75
#define BAT_V_MAX 4.2
#define BAT_V_FLOAT 4.22
#define BAT_SAMPLES 5
#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12 - bit ADC resolution = 3000mV / 4096
#define VBAT_DIVIDER_COMP (1.73) // Compensation factor for the VBAT divider
#define VBAT_MV_PER_LSB_FIN (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#define PIN_VBAT WB_A0
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;
#endif
uint32_t last_pmu_update = 0;
@ -174,23 +74,10 @@ uint8_t pmu_rc = 0;
void kiss_indicate_battery();
void measure_battery() {
#if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1 || BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_TDECK || BOARD_MODEL == BOARD_T3S3 || BOARD_MODEL == BOARD_HELTEC_T114 || BOARD_MODEL == BOARD_TECHO
#if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1
battery_installed = true;
battery_indeterminate = true;
#if BOARD_MODEL == BOARD_HELTEC32_V3
float battery_measurement = (float)(analogRead(pin_vbat)) * 0.0041;
#elif BOARD_MODEL == BOARD_T3S3
float battery_measurement = (float)(analogRead(pin_vbat)) / 4095.0*6.7828;
#elif BOARD_MODEL == BOARD_HELTEC_T114
float battery_measurement = (float)(analogRead(pin_vbat)) * 0.017165;
#elif BOARD_MODEL == BOARD_TECHO
float battery_measurement = (float)(analogRead(pin_vbat)) * 0.007067;
#else
float battery_measurement = (float)(analogRead(pin_vbat)) / 4095.0*7.26;
#endif
bat_v_samples[bat_samples_count%BAT_SAMPLES] = battery_measurement;
bat_v_samples[bat_samples_count%BAT_SAMPLES] = (float)(analogRead(pin_vbat)) / 4095*2*3.3*1.1;
bat_p_samples[bat_samples_count%BAT_SAMPLES] = ((battery_voltage-BAT_V_MIN) / (BAT_V_MAX-BAT_V_MIN))*100.0;
bat_samples_count++;
@ -213,61 +100,41 @@ void measure_battery() {
battery_voltage = battery_voltage/BAT_SAMPLES;
if (bat_delay_v == 0) bat_delay_v = battery_voltage;
if (bat_state_change_v == 0) bat_state_change_v = battery_voltage;
if (battery_percent > 100.0) battery_percent = 100.0;
if (battery_percent < 0.0) battery_percent = 0.0;
if (bat_samples_count%BAT_SAMPLES == 0) {
float bat_delay_diff = bat_state_change_v-battery_voltage;
if (bat_delay_diff < 0) { bat_delay_diff *= -1; }
if (battery_voltage < bat_delay_v && battery_voltage < BAT_V_FLOAT) {
if (bat_voltage_dropping == false) {
if (bat_delay_diff > 0.008) {
bat_voltage_dropping = true;
bat_state_change_v = battery_voltage;
// SerialBT.printf("STATE CHANGE to DISCHARGE at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v);
}
}
bat_voltage_dropping = true;
} else {
if (bat_voltage_dropping == true) {
if (bat_delay_diff > 0.01) {
bat_voltage_dropping = false;
bat_state_change_v = battery_voltage;
// SerialBT.printf("STATE CHANGE to CHARGE at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v);
}
}
bat_voltage_dropping = false;
}
bat_samples_count = 0;
bat_delay_v = battery_voltage;
}
if (bat_voltage_dropping && battery_voltage < BAT_V_FLOAT) {
battery_state = BATTERY_STATE_DISCHARGING;
} else {
if (battery_percent < 100.0) {
#if BOARD_MODEL == BOARD_RNODE_NG_21
battery_state = BATTERY_STATE_CHARGING;
} else {
battery_state = BATTERY_STATE_CHARGED;
}
#else
battery_state = BATTERY_STATE_DISCHARGING;
#endif
}
#if MCU_VARIANT == MCU_NRF52
if (bt_state != BT_STATE_OFF) { blebas.write(battery_percent); }
#endif
// if (bt_state == BT_STATE_CONNECTED) {
// SerialBT.printf("Bus voltage %.3fv. Unfiltered %.3fv.", battery_voltage, bat_v_samples[BAT_SAMPLES-1]);
// if (bat_voltage_dropping) { SerialBT.printf(" Voltage is dropping. Percentage %.1f%%.", battery_percent); }
// else { SerialBT.printf(" Voltage is not dropping. Percentage %.1f%%.", battery_percent); }
// if (battery_state == BATTERY_STATE_DISCHARGING) { SerialBT.printf(" Battery discharging. delay_v %.3fv", bat_delay_v); }
// if (battery_state == BATTERY_STATE_CHARGING) { SerialBT.printf(" Battery charging. delay_v %.3fv", bat_delay_v); }
// if (battery_state == BATTERY_STATE_CHARGED) { SerialBT.print(" Battery is charged."); }
// SerialBT.print("\n");
// if (bat_voltage_dropping) {
// SerialBT.printf(" Voltage is dropping. Percentage %.1f%%.\n", battery_percent);
// } else {
// SerialBT.print(" Voltage is not dropping.\n");
// }
// }
}
#elif BOARD_MODEL == BOARD_TBEAM || BOARD_MODEL == BOARD_TBEAM_S_V1
#elif BOARD_MODEL == BOARD_TBEAM
if (PMU) {
float discharge_current = 0;
float charge_current = 0;
@ -305,7 +172,7 @@ void measure_battery() {
}
}
} else {
battery_state = BATTERY_STATE_UNKNOWN;
battery_state = BATTERY_STATE_DISCHARGING;
battery_percent = 0.0;
battery_voltage = 0.0;
}
@ -347,7 +214,7 @@ void measure_battery() {
battery_ready = false;
}
#elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL
#elif BOARD_MODEL == BOARD_RAK4631
battery_installed = true;
battery_indeterminate = false;
@ -406,16 +273,6 @@ void measure_battery() {
if (battery_percent >= 98) {
battery_state = BATTERY_STATE_CHARGED;
}
#if HAS_BLE
if ((bt_state == BT_STATE_ON) || bt_state == BT_STATE_CONNECTED) {
if (battery_state != BATTERY_STATE_CHARGING) {
blebas.write(battery_percent);
} else {
blebas.write(100);
}
}
#endif
#endif
if (battery_ready) {
@ -434,33 +291,31 @@ void update_pmu() {
}
bool init_pmu() {
#if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1 || BOARD_MODEL == BOARD_TDECK || BOARD_MODEL == BOARD_T3S3 || BOARD_MODEL == BOARD_TECHO
#if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1
pinMode(pin_vbat, INPUT);
return true;
#elif BOARD_MODEL == BOARD_HELTEC32_V3
pinMode(pin_ctrl,OUTPUT);
digitalWrite(pin_ctrl, LOW);
return true;
#elif BOARD_MODEL == BOARD_HELTEC_T114
pinMode(pin_ctrl,OUTPUT);
digitalWrite(pin_ctrl, HIGH);
return true;
#elif BOARD_MODEL == BOARD_TBEAM
Wire.begin(I2C_SDA, I2C_SCL);
if (!PMU) {
PMU = new XPowersAXP2101(PMU_WIRE_PORT);
if (!PMU->init()) {
Serial.println("Warning: Failed to find AXP2101 power management");
delete PMU;
PMU = NULL;
} else {
Serial.println("AXP2101 PMU init succeeded, using AXP2101 PMU");
}
}
if (!PMU) {
PMU = new XPowersAXP192(PMU_WIRE_PORT);
if (!PMU->init()) {
Serial.println("Warning: Failed to find AXP192 power management");
delete PMU;
PMU = NULL;
} else {
Serial.println("AXP192 PMU init succeeded, using AXP192 PMU");
}
}
@ -566,7 +421,7 @@ bool init_pmu() {
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
return true;
#elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL
#elif BOARD_MODEL == BOARD_RAK4631
// board doesn't have PMU but we can measure batt voltage
// prep ADC for reading battery level
@ -581,86 +436,6 @@ bool init_pmu() {
// Get a single ADC sample and throw it away
float raw = analogRead(PIN_VBAT);
return true;
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
Wire1.begin(I2C_SDA, I2C_SCL);
if (!PMU) {
PMU = new XPowersAXP2101(PMU_WIRE_PORT);
if (!PMU->init()) {
delete PMU;
PMU = NULL;
}
}
if (!PMU) {
return false;
}
/**
* gnss module power channel
* The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during
* initialization
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO4);
// lora radio power channel
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
// m.2 interface
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
PMU->enablePowerOutput(XPOWERS_DCDC3);
/**
* ALDO2 cannot be turned off.
* It is a necessary condition for sensor communication.
* It must be turned on to properly access the sensor and screen
* It is also responsible for the power supply of PCF8563
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2);
// 6-axis , magnetometer ,bme280 , oled screen power channel
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO1);
// sdcard power channle
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
PMU->enablePowerOutput(XPOWERS_BLDO1);
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
// PMU->enablePowerOutput(XPOWERS_DCDC4);
// not use channel
PMU->disablePowerOutput(XPOWERS_DCDC2); // not elicited
PMU->disablePowerOutput(XPOWERS_DCDC5); // not elicited
PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_VBACKUP);
// Configure charging
PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
// TODO: Reset
PMU->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
// Set the time of pressing the button to turn off
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
PMU->setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
// disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
PMU->clearIrqStatus();
// It is necessary to disable the detection function of the TS pin on the board
// without the battery temperature detection function, otherwise it will cause abnormal charging
PMU->disableTSPinMeasure();
PMU->enableVbusVoltageMeasure();
PMU->enableBattVoltageMeasure();
return true;
#else
return false;
#endif

View File

@ -14,17 +14,15 @@ The RNode system is primarily software, which *transforms* different kinds of av
## Latest Release
The latest release, installable through `rnodeconf`, is version `1.73`. This release brings the following changes:
The latest release, installable through `rnodeconf`, is version `1.72`. This release brings the following changes:
- Added multiple interface support - for supported boards you may now use more than one radio modem at once! Currently the only supported board is the RAK4631 with the right hardware.
- Fixes for various issues with the SX1280 - data rates are now at expected speeds overall.
- Added PA calculations for the LoRa1280F27 - this allows for the TX power to be set accurately for this modem.
- Fixes for OLED compilation errors as a result of commit 055083f.
- Added switching graphics to the display - shows statistics from up to 2 modems simultaneously.
- Fix TNC EEPROM settings not being saved - courtesy of @attermann
- Fix ESP32 linker errors - BSP version is now fixed at 2.0.17, using the older crosstool-ng linker from previous versions (2021r1)
- Added support for flashing T3S3 boards
- Added deep sleep support on T3S3
- Various quality updates for nRF / RAK4631
- Fixed a bug with antenna switch utilisation on RAK4631
- Updated console image to include latest packages
You must have at least version `2.1.3` of `rnodeconf` installed to update your RNode Firmware install to version `1.73`. Get it by updating the `rns` package to at least version `0.6.4`.
You must have at least version `2.1.3` of `rnodeconf` installed to update the RNode Firmware to version `1.72`. Get it by updating the `rns` package to at least version `0.6.4`.
## Supported products and boards
@ -32,28 +30,21 @@ You must have at least version `2.1.3` of `rnodeconf` installed to update your R
| Name | Manufacturer | Link | Transceiver | MCU | Description |
| :---: | :---: | :---: | :---: | :---: | :---: |
| Handheld v2.x RNodes | [Mark Qvist](https://unsigned.io) | [Buy here](https://unsigned.io/shop/product/handheld-rnode) | SX1276 | ESP32 |
| openCom XL | [Liberated Embedded Systems](https://liberatedsystems.co.uk) | [Buy here](https://store.liberatedsystems.co.uk/product/opencom-xl/) | SX1262 & SX1280 | nRF52 | Supports utilisation of both modems at once |
### Homebrew devices
| Board name | Link | Transceiver | MCU | Description |
| :--- | :---: | :---: | :---: | :---: |
| RAK4631 | [Buy here](https://store.rakwireless.com/products/rak4631-lpwan-node?m=5&h=wisblock-core) | SX1262 | nRF52 |
| LilyGO T-BEAM v1.1 | [Buy here](https://www.lilygo.cc/products/t-beam-v1-1-esp32-lora-module) | SX1276/8 or SX1262 | ESP32 |
| LilyGO T-Beam Supreme | [Buy here](https://lilygo.cc/products/t-beam-supreme) | SX1262 | ESP32-S3 |
| LilyGO LoRa32 v1.0 | [Buy here](https://www.lilygo.cc/products/lora32-v1-0) | SX1276/8 | ESP32 |
| LilyGO LoRa32 v2.0 | No link | SX1276/8 | ESP32 | Discontinued? |
| LilyGO LoRa32 v2.1 | [Buy here](https://www.lilygo.cc/products/lora3) | SX1276/8 | ESP32 | With and without TCXO |
| Heltec LoRa32 v2 | No link | SX1276/8 | ESP32 | Discontinued? |
| Heltec LoRa32 v3 | [Buy here](https://heltec.org/project/wifi-lora-32-v3/) | SX1262 | ESP32 |
| LilyGo T3S3 v1.0 | [Buy here](https://lilygo.cc/products/t3s3-v1-0) | SX1262 or SX1276 or SX1280 | ESP32-S3 |
| Heltec T114 | [Buy here](https://heltec.org/project/mesh-node-t114/) | SX1262 | nRF52 |
| Homebrew ESP32 boards | | Any supported | ESP32 | This can be any board with an Adafruit Feather (or generic) ESP32 chip |
It's easy to create your own RNodes from one of the supported development boards and devices. If a device or board you want to use is not yet supported, you are welcome to [join the effort](Documentation/CONTRIBUTING.md) and help create a board definition and pin mapping for it!
<!--| LilyGO T-Deck | [Buy here](https://lilygo.cc/products/t-deck) | SX1262 | ESP32-S3 |-->
<!--| Heltec Wireless Paper | [Buy here](https://heltec.org/project/wireless-paper/) | SX1262 | ESP32-S3 | -->
<!--<img src="Documentation/images/devboards_1.webp" width="100%"/>-->
## Supported Transceiver Modules
@ -63,7 +54,7 @@ The RNode Firmware supports all transceiver modules based on the following chips
* Semtech SX1278
* Semtech SX1280
These also must have an **SPI interface** and **DIO_0 (sometimes called DIO_1)** pin connected to the MCU directly.
These also must have an **SPI interface** and **DIO_0** pin connected to the MCU directly.
## One Tool, Many Uses
@ -114,8 +105,6 @@ pip install rns --upgrade
rnodeconf --autoinstall
```
For most of the supported device types, it is also possible to use [Liam Cottle's Web-based RNode Flasher](https://liamcottle.github.io/rnode-flasher/). This option may be easier if you're not familiar with using a command line interface.
For more detailed instruction and in-depth guides, you can have a look at some of these resources:
- Create a [basic RNode from readily available development boards](https://unsigned.io/guides/2022_01_25_installing-rnode-firmware-on-supported-devices.html)
@ -164,7 +153,7 @@ The source code includes an SX1276 driver that is released under MIT License, an
You can obtain the source code from [my business Git instance](https://git.liberatedsystems.co.uk/jacob.eva/RNode_Firmware_CE) or [GitHub](https://github.com/liberatedsystems/RNode_Firmware_CE).
Every RNode which supports the console functionality also includes an internal copy of it's own firmware source code, that can be downloaded through the [RNode Bootstrap Console](https://unsigned.io/rnode_bootstrap_console), by putting the RNode into Console Mode (which can be activated by holding the user button for 10 seconds and releasing it).
Every RNode which supports the console functionality also includes an internal copy of it's own firmware source code, that can be downloaded through the [RNode Bootstrap Console](https://unsigned.io/rnode_bootstrap_console), by putting the RNode into Console Mode (which can be activated by pressing the reset button two times within two seconds).
The RNode Ecosystem is free and non-proprietary, and actively seeks to distribute it's ownership and control. If you want to build RNodes for commercial purposes, including selling them, you must do so adhering to the Open Source licenses that the various parts of the RNode project is released under, and under your own responsibility.

File diff suppressed because it is too large Load Diff

98
ROM.h
View File

@ -1,4 +1,4 @@
// Copyright (C) 2024, Mark Qvist
// Copyright (C) 2023, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -14,45 +14,71 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#ifndef ROM_H
#define ROM_H
#define CHECKSUMMED_SIZE 0x0B
#define ROM_H
// ROM address map ///////////////
#define ADDR_PRODUCT 0x00
#define ADDR_MODEL 0x01
#define ADDR_HW_REV 0x02
#define ADDR_SERIAL 0x03
#define ADDR_MADE 0x07
#define ADDR_CHKSUM 0x0B
#define ADDR_SIGNATURE 0x1B
#define ADDR_INFO_LOCK 0x9B
#define CHECKSUMMED_SIZE 0x0B
#define ADDR_CONF_SF 0x9C
#define ADDR_CONF_CR 0x9D
#define ADDR_CONF_TXP 0x9E
#define ADDR_CONF_BW 0x9F
#define ADDR_CONF_FREQ 0xA3
#define ADDR_CONF_OK 0xA7
#define PRODUCT_RNODE 0x03
#define PRODUCT_HMBRW 0xF0
#define PRODUCT_TBEAM 0xE0
#define PRODUCT_T32_10 0xB2
#define PRODUCT_T32_20 0xB0
#define PRODUCT_T32_21 0xB1
#define PRODUCT_H32_V2 0xC0
#define PRODUCT_H32_V3 0xC1
#define PRODUCT_RAK4631 0x10
#define MODEL_11 0x11
#define MODEL_12 0x12
#define MODEL_A1 0xA1
#define MODEL_A6 0xA6
#define MODEL_A4 0xA4
#define MODEL_A9 0xA9
#define MODEL_A3 0xA3
#define MODEL_A8 0xA8
#define MODEL_A2 0xA2
#define MODEL_A7 0xA7
#define MODEL_B3 0xB3
#define MODEL_B8 0xB8
#define MODEL_B4 0xB4
#define MODEL_B9 0xB9
#define MODEL_BA 0xBA
#define MODEL_BB 0xBB
#define MODEL_C4 0xC4
#define MODEL_C9 0xC9
#define MODEL_C5 0xC5
#define MODEL_CA 0xCA
#define MODEL_E4 0xE4
#define MODEL_E9 0xE9
#define MODEL_E3 0xE3
#define MODEL_E8 0xE8
#define MODEL_FE 0xFE
#define MODEL_FF 0xFF
#define ADDR_CONF_BT 0xB0
#define ADDR_CONF_DSET 0xB1
#define ADDR_CONF_DINT 0xB2
#define ADDR_CONF_DADR 0xB3
#define ADDR_CONF_DBLK 0xB4
#define ADDR_CONF_PSET 0xB5
#define ADDR_CONF_PINT 0xB6
#define ADDR_CONF_BSET 0xB7
#define ADDR_CONF_DROT 0xB8
#define ADDR_CONF_PSET 0xB5
#define ADDR_CONF_PINT 0xB6
#define ADDR_CONF_BSET 0xB7
#define ADDR_CONF_DIA 0xB9
#define ADDR_PRODUCT 0x00
#define ADDR_MODEL 0x01
#define ADDR_HW_REV 0x02
#define ADDR_SERIAL 0x03
#define ADDR_MADE 0x07
#define ADDR_CHKSUM 0x0B
#define ADDR_SIGNATURE 0x1B
#define ADDR_INFO_LOCK 0x9B
#define INFO_LOCK_BYTE 0x73
#define CONF_OK_BYTE 0x73
#define BT_ENABLE_BYTE 0x73
#define ADDR_CONF_SF 0x9C
#define ADDR_CONF_CR 0x9D
#define ADDR_CONF_TXP 0x9E
#define ADDR_CONF_BW 0x9F
#define ADDR_CONF_FREQ 0xA3
#define ADDR_CONF_OK 0xA7
#define ADDR_CONF_BT 0xB0
#define ADDR_CONF_DSET 0xB1
#define ADDR_CONF_DINT 0xB2
#define ADDR_CONF_DADR 0xB3
#define EEPROM_RESERVED 200
//////////////////////////////////
#define INFO_LOCK_BYTE 0x73
#define CONF_OK_BYTE 0x73
#define BT_ENABLE_BYTE 0x73
#define EEPROM_RESERVED 200
#endif

1073
Radio.cpp

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license.
// Modifications and additions copyright 2024 by Mark Qvist & Jacob Eva
// Modifications and additions copyright 2023 by Mark Qvist & Jacob Eva
// Obviously still under the MIT license.
#ifndef RADIO_H
@ -11,7 +11,6 @@
#include <SPI.h>
#include "Interfaces.h"
#include "Boards.h"
#include "src/misc/FIFOBuffer.h"
#define MAX_PKT_LENGTH 255
@ -19,15 +18,6 @@
#define PA_OUTPUT_RFO_PIN 0
#define PA_OUTPUT_PA_BOOST_PIN 1
// Default LoRa settings
#define PHY_HEADER_LORA_SYMBOLS 20
#define PHY_CRC_LORA_BITS 16
#define LORA_PREAMBLE_SYMBOLS_MIN 18
#define LORA_PREAMBLE_TARGET_MS 24
#define LORA_PREAMBLE_FAST_DELTA 18
#define LORA_FAST_THRESHOLD_BPS 30E3
#define LORA_LIMIT_THRESHOLD_BPS 60E3
// DCD
#define STATUS_INTERVAL_MS 3
#define DCD_SAMPLES 2500
@ -38,31 +28,20 @@
#define AIRTIME_BINLEN_MS (STATUS_INTERVAL_MS*DCD_SAMPLES)
#define AIRTIME_BINS ((AIRTIME_LONGTERM*1000)/AIRTIME_BINLEN_MS)
#define current_airtime_bin(void) (millis()%AIRTIME_LONGTERM_MS)/AIRTIME_BINLEN_MS
// CSMA Parameters
#define CSMA_SIFS_MS 0
#define CSMA_POST_TX_YIELD_SLOTS 3
#define CSMA_SLOT_MAX_MS 100
#define CSMA_SLOT_MIN_MS 24
#define CSMA_SLOT_MIN_FAST_DELTA 18
#define CSMA_SLOT_SYMBOLS 12
#define CSMA_CW_BANDS 4
#define CSMA_CW_MIN 0
#define CSMA_CW_PER_BAND_WINDOWS 15
#define CSMA_BAND_1_MAX_AIRTIME 7
#define CSMA_BAND_N_MIN_AIRTIME 85
#define CSMA_INFR_THRESHOLD_DB 12
#define LED_ID_TRIG 16
#define NOISE_FLOOR_SAMPLES 64
#define DCD_THRESHOLD 2
#define DCD_LED_STEP_D 3
#define LORA_PREAMBLE_SYMBOLS_HW 4
#define LORA_PREAMBLE_SYMBOLS_MIN 18
#define LORA_PREAMBLE_TARGET_MS 15
#define LORA_PREAMBLE_FAST_TARGET_MS 1
#define LORA_FAST_BITRATE_THRESHOLD 40000
#define RSSI_OFFSET 157
#define PHY_HEADER_LORA_SYMBOLS 8
#define MODEM_TIMEOUT_MULT 1.5
#define _e 2.71828183
#define _S 10.0
// Status flags
const uint8_t SIG_DETECT = 0x01;
@ -71,13 +50,9 @@ const uint8_t RX_ONGOING = 0x04;
// forward declare Utilities.h LED functions
void led_rx_on();
void led_rx_off();
void led_id_on();
void led_id_off();
void led_indicate_airtime_lock();
void kiss_indicate_channel_stats(uint8_t index);
void kiss_indicate_csma_stats(uint8_t index);
void led_rx_off();
void led_indicate_airtime_lock();
#if PLATFORM == PLATFORM_ESP32
// get update_lock for ESP32
@ -87,28 +62,25 @@ extern portMUX_TYPE update_lock;
class RadioInterface : public Stream {
public:
// todo: in the future define _spiModem and _spiSettings from here for inheritence by child classes
RadioInterface(uint8_t index) : _index(index), _sf(0x07), _radio_locked(false),
RadioInterface(uint8_t index) : _index(index), _radio_locked(false),
_radio_online(false), _st_airtime_limit(0.0), _lt_airtime_limit(0.0),
_airtime_lock(false), _airtime(0.0), _longterm_airtime(0.0), _last_packet_cost(0.0),
_airtime_lock(false), _airtime(0.0), _longterm_airtime(0.0),
_local_channel_util(0.0), _total_channel_util(0.0),
_longterm_channel_util(0.0), _last_status_update(0),
_stat_signal_detected(false), _stat_signal_synced(false),_stat_rx_ongoing(false), _last_dcd(0),
_dcd_count(0), _dcd(false), _dcd_led(false),
_dcd_waiting(false), _dcd_sample(0),
_csma_slot_ms(CSMA_SLOT_MIN_MS),
_preambleLength(LORA_PREAMBLE_SYMBOLS_MIN), _lora_symbol_time_ms(0.0),
_lora_preamble_time_ms(0), _lora_header_time_ms(0), _lora_symbol_rate(0.0), _lora_us_per_byte(0.0), _bitrate(0),
_packet{0}, _onReceive(NULL), _txp(0), _ldro(false), _limit_rate(false), _interference_detected(false), _avoid_interference(true), _difs_ms(CSMA_SIFS_MS + 2 * _csma_slot_ms), _difs_wait_start(0), _cw_wait_start(0), _cw_wait_target(0), _cw_wait_passed(0), _csma_cw(-1), _cw_band(1), _cw_min(0), _cw_max(CSMA_CW_PER_BAND_WINDOWS), _noise_floor_sampled(false), _noise_floor_sample(0), _noise_floor_buffer({0}), _noise_floor(-292), _led_id_filter(0), _preamble_detected_at(0) {};
virtual void reset() = 0;
_dcd_waiting(false), _dcd_wait_until(0), _dcd_sample(0),
_post_tx_yield_timeout(0), _csma_slot_ms(50), _csma_p_min(0.1),
_csma_p_max(0.8), _preambleLength(6), _lora_symbol_time_ms(0.0),
_lora_symbol_rate(0.0), _lora_us_per_byte(0.0), _bitrate(0),
_packet{0}, _onReceive(NULL) {};
virtual int begin() = 0;
virtual void end() = 0;
virtual int beginPacket(int implicitHeader = false) = 0;
virtual int endPacket() = 0;
virtual int packetRssi(uint8_t pkt_snr_raw = 0xFF) = 0;
virtual int packetRssi() = 0;
virtual int currentRssi() = 0;
virtual uint8_t packetRssiRaw() = 0;
virtual uint8_t currentRssiRaw() = 0;
@ -133,7 +105,7 @@ public:
virtual void sleep() = 0;
virtual bool preInit() = 0;
virtual int8_t getTxPower() = 0;
virtual uint8_t getTxPower() = 0;
virtual void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN) = 0;
virtual uint32_t getFrequency() = 0;
virtual void setFrequency(uint32_t frequency) = 0;
@ -144,49 +116,19 @@ public:
virtual void setCodingRate4(int denominator) = 0;
virtual uint8_t getCodingRate4() = 0;
virtual void setPreambleLength(long length) = 0;
virtual bool dcd() = 0;
virtual uint8_t modemStatus() = 0;
virtual void enableCrc() = 0;
virtual void disableCrc() = 0;
virtual void enableTCXO() = 0;
virtual void disableTCXO() = 0;
virtual uint8_t random() = 0;
virtual byte random() = 0;
virtual void setSPIFrequency(uint32_t frequency) = 0;
void updateBitrate() {
if (!_radio_online) { _bitrate = 0; }
else {
_lora_symbol_rate = (float)getSignalBandwidth()/(float)(pow(2, _sf));
_lora_symbol_time_ms = (1.0/_lora_symbol_rate)*1000.0;
_bitrate = (uint32_t)(_sf * ( (4.0/(float)getCodingRate4()) / ((float)(pow(2, _sf))/((float)getSignalBandwidth()/1000.0)) ) * 1000.0);
_lora_us_per_byte = 1000000.0/((float)_bitrate/8.0);
bool fast_rate = _bitrate > LORA_FAST_THRESHOLD_BPS;
_limit_rate = _bitrate > LORA_LIMIT_THRESHOLD_BPS;
int csma_slot_min_ms = CSMA_SLOT_MIN_MS;
float lora_preamble_target_ms = LORA_PREAMBLE_TARGET_MS;
if (fast_rate) { csma_slot_min_ms -= CSMA_SLOT_MIN_FAST_DELTA;
lora_preamble_target_ms -= LORA_PREAMBLE_FAST_DELTA; }
_csma_slot_ms = _lora_symbol_time_ms*CSMA_SLOT_SYMBOLS;
if (_csma_slot_ms > CSMA_SLOT_MAX_MS) { _csma_slot_ms = CSMA_SLOT_MAX_MS; }
if (_csma_slot_ms < CSMA_SLOT_MIN_MS) { _csma_slot_ms = csma_slot_min_ms; }
_difs_ms = CSMA_SIFS_MS + 2*_csma_slot_ms;
float target_preamble_symbols = lora_preamble_target_ms/_lora_symbol_time_ms;
if (target_preamble_symbols < LORA_PREAMBLE_SYMBOLS_MIN) { target_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN; }
else { target_preamble_symbols = (ceil)(target_preamble_symbols); }
setPreambleLength(target_preamble_symbols);
_lora_preamble_time_ms = (ceil)(_preambleLength * _lora_symbol_time_ms);
_lora_header_time_ms = (ceil)(PHY_HEADER_LORA_SYMBOLS * _lora_symbol_time_ms);
}
}
virtual void updateBitrate() = 0;
virtual void handleDio0Rise() = 0;
virtual bool getPacketValidity() = 0;
virtual void clearIRQStatus() = 0;
uint32_t getBitrate() { return _bitrate; };
uint8_t getIndex() { return _index; };
void setRadioLock(bool lock) { _radio_locked = lock; };
@ -226,182 +168,131 @@ public:
}
_longterm_channel_util = (float)longterm_channel_util_sum/(float)AIRTIME_BINS;
updateCSMAParameters();
kiss_indicate_channel_stats(_index);
updateCSMAp();
//kiss_indicate_channel_stats(); // todo: enable me!
};
float getAirtime(uint16_t written) {
float lora_symbols = 0;
void addAirtime(uint16_t written) {
float packet_cost_ms = 0.0;
if (interfaces[_index] == SX1276 || interfaces[_index] == SX1278) {
lora_symbols += (8*written + PHY_CRC_LORA_BITS - 4*_sf + 8 + PHY_HEADER_LORA_SYMBOLS);
lora_symbols /= 4*(_sf-2*_ldro);
lora_symbols *= getCodingRate4();
lora_symbols += _preambleLength + 0.25 + 8;
packet_cost_ms += lora_symbols * _lora_symbol_time_ms;
}
else if (interfaces[_index] == SX1262 || interfaces[_index] == SX1280) {
if (_sf < 7) {
lora_symbols += (8*written + PHY_CRC_LORA_BITS - 4*_sf + PHY_HEADER_LORA_SYMBOLS);
lora_symbols /= 4*_sf;
lora_symbols *= getCodingRate4();
lora_symbols += _preambleLength + 2.25 + 8;
packet_cost_ms += lora_symbols * _lora_symbol_time_ms;
} else {
lora_symbols += (8*written + PHY_CRC_LORA_BITS - 4*_sf + 8 + PHY_HEADER_LORA_SYMBOLS);
lora_symbols /= 4*(_sf-2*_ldro);
lora_symbols *= getCodingRate4();
lora_symbols += _preambleLength + 0.25 + 8;
packet_cost_ms += lora_symbols * _lora_symbol_time_ms;
}
}
_last_packet_cost = packet_cost_ms;
return packet_cost_ms;
}
void addAirtime() {
float payload_cost_ms = ((float)written * _lora_us_per_byte)/1000.0;
packet_cost_ms += payload_cost_ms;
packet_cost_ms += (_preambleLength+4.25)*_lora_symbol_time_ms;
packet_cost_ms += PHY_HEADER_LORA_SYMBOLS * _lora_symbol_time_ms;
uint16_t cb = current_airtime_bin();
uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
_airtime_bins[cb] += _last_packet_cost;
_airtime_bins[cb] += packet_cost_ms;
_airtime_bins[nb] = 0;
};
void updateModemStatus() {
#if MCU_VARIANT == MCU_ESP32
portENTER_CRITICAL(&update_lock);
#elif MCU_VARIANT == MCU_NRF52
portENTER_CRITICAL();
#endif
bool carrier_detected = dcd();
int current_rssi = currentRssi();
_last_status_update = millis();
#if MCU_VARIANT == MCU_ESP32
portEXIT_CRITICAL(&update_lock);
#elif MCU_VARIANT == MCU_NRF52
portEXIT_CRITICAL();
#endif
_interference_detected = !carrier_detected && (current_rssi > (_noise_floor+CSMA_INFR_THRESHOLD_DB));
if (_interference_detected) { if (_led_id_filter < LED_ID_TRIG) { _led_id_filter += 1; } }
else { if (_led_id_filter > 0) {_led_id_filter -= 1; } }
if (carrier_detected) { _dcd = true; } else { _dcd = false; }
_dcd_led = _dcd;
if (_dcd_led) { led_rx_on(); }
else {
if (_interference_detected) {
if (_led_id_filter >= LED_ID_TRIG && _noise_floor_sampled) { led_id_on(); }
} else {
if (_airtime_lock) { led_indicate_airtime_lock(); }
else { led_rx_off(); led_id_off(); }
}
}
}
void updateNoiseFloor() {
int current_rssi = currentRssi();
if (!_dcd) {
if (!_noise_floor_sampled || current_rssi < _noise_floor + CSMA_INFR_THRESHOLD_DB) {
_noise_floor_buffer[_noise_floor_sample] = current_rssi;
_noise_floor_sample = _noise_floor_sample+1;
if (_noise_floor_sample >= NOISE_FLOOR_SAMPLES) {
_noise_floor_sample %= NOISE_FLOOR_SAMPLES;
_noise_floor_sampled = true;
}
if (_noise_floor_sampled) {
_noise_floor = 0;
for (int ni = 0; ni < NOISE_FLOOR_SAMPLES; ni++) { _noise_floor += _noise_floor_buffer[ni]; }
_noise_floor /= NOISE_FLOOR_SAMPLES;
}
}
}
}
void checkModemStatus() {
if (millis()-_last_status_update >= STATUS_INTERVAL_MS) {
updateModemStatus();
updateNoiseFloor();
_util_samples[_dcd_sample] = _dcd;
_dcd_sample = (_dcd_sample+1)%DCD_SAMPLES;
if (_dcd_sample % UTIL_UPDATE_INTERVAL == 0) {
_util_samples[_dcd_sample] = _dcd;
_dcd_sample = (_dcd_sample+1)%DCD_SAMPLES;
if (_dcd_sample % UTIL_UPDATE_INTERVAL == 0) {
int util_count = 0;
for (int ui = 0; ui < DCD_SAMPLES; ui++) {
if (_util_samples[ui]) util_count++;
if (_util_samples[ui]) util_count++;
}
_local_channel_util = (float)util_count / (float)DCD_SAMPLES;
_total_channel_util = _local_channel_util + _airtime;
if (_total_channel_util > 1.0) _total_channel_util = 1.0;
int16_t cb = current_airtime_bin();
uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
if (_total_channel_util > _longterm_bins[cb]) _longterm_bins[cb] = _total_channel_util;
_longterm_bins[nb] = 0.0;
updateAirtime();
}
}
}
};
void updateCSMAParameters() {
int airtime_pct = (int)(_airtime*100);
int new_cw_band = _cw_band;
void updateModemStatus() {
#if PLATFORM == PLATFORM_ESP32
portENTER_CRITICAL(&update_lock);
#elif PLATFORM == PLATFORM_NRF52
portENTER_CRITICAL();
#endif
uint8_t status = modemStatus();
_last_status_update = millis();
#if PLATFORM == PLATFORM_ESP32
portEXIT_CRITICAL(&update_lock);
#elif PLATFORM == PLATFORM_NRF52
portEXIT_CRITICAL();
#endif
if ((status & SIG_DETECT) == SIG_DETECT) { _stat_signal_detected = true; } else { _stat_signal_detected = false; }
if ((status & SIG_SYNCED) == SIG_SYNCED) { _stat_signal_synced = true; } else { _stat_signal_synced = false; }
if ((status & RX_ONGOING) == RX_ONGOING) { _stat_rx_ongoing = true; } else { _stat_rx_ongoing = false; }
// if (stat_signal_detected || stat_signal_synced || stat_rx_ongoing) {
if (_stat_signal_detected || _stat_signal_synced) {
if (_stat_rx_ongoing) {
if (_dcd_count < DCD_THRESHOLD) {
_dcd_count++;
} else {
_last_dcd = _last_status_update;
_dcd_led = true;
_dcd = true;
}
}
} else {
if (_dcd_count == 0) {
_dcd_led = false;
} else if (_dcd_count > DCD_LED_STEP_D) {
_dcd_count -= DCD_LED_STEP_D;
} else {
_dcd_count = 0;
}
if (_last_status_update > _last_dcd+_csma_slot_ms) {
_dcd = false;
_dcd_led = false;
_dcd_count = 0;
}
}
if (airtime_pct <= CSMA_BAND_1_MAX_AIRTIME) { new_cw_band = 1; }
else {
int at = airtime_pct + CSMA_BAND_1_MAX_AIRTIME;
new_cw_band = map(at, CSMA_BAND_1_MAX_AIRTIME, CSMA_BAND_N_MIN_AIRTIME, 2, CSMA_CW_BANDS);
}
if (new_cw_band > CSMA_CW_BANDS) { new_cw_band = CSMA_CW_BANDS; }
if (new_cw_band != _cw_band) {
_cw_band = (uint8_t)(new_cw_band);
_cw_min = (_cw_band-1) * CSMA_CW_PER_BAND_WINDOWS;
_cw_max = (_cw_band) * CSMA_CW_PER_BAND_WINDOWS - 1;
kiss_indicate_csma_stats(_index);
}
}
if (_dcd_led) {
led_rx_on();
} else {
if (_airtime_lock) {
led_indicate_airtime_lock();
} else {
led_rx_off();
}
}
};
void setPostTxYieldTimeout(uint32_t timeout) { _post_tx_yield_timeout = timeout; };
uint32_t getPostTxYieldTimeout() { return _post_tx_yield_timeout; };
void setDCD(bool dcd) { _dcd = dcd; };
bool getDCD() { return _dcd; };
void setDCDWaiting(bool dcd_waiting) { _dcd_waiting = dcd_waiting; };
bool getDCDWaiting() { return _dcd_waiting; };
void setDCDWaitUntil(uint32_t dcd_wait_until) { _dcd_wait_until = dcd_wait_until; };
bool getDCDWaitUntil() { return _dcd_wait_until; };
float getAirtime() { return _airtime; };
float getLongtermAirtime() { return _longterm_airtime; };
float getTotalChannelUtil() { return _total_channel_util; };
float getLongtermChannelUtil() { return _longterm_channel_util; };
float CSMASlope(float u) { return (pow(_e,_S*u-_S/2.0))/(pow(_e,_S*u-_S/2.0)+1.0); };
void updateCSMAp() {
_csma_p = (uint8_t)((1.0-(_csma_p_min+(_csma_p_max-_csma_p_min)*CSMASlope(_airtime)))*255.0);
};
uint8_t getCSMAp() { return _csma_p; };
void setCSMASlotMS(int slot_size) { _csma_slot_ms = slot_size; };
int getCSMASlotMS() { return _csma_slot_ms; };
float getSymbolTime() { return _lora_symbol_time_ms; };
float getSymbolRate() { return _lora_symbol_rate; };
long getPreambleLength() { return _preambleLength; };
void setAvdInterference(bool cfg) { _avoid_interference = cfg; };
bool getAvdInterference() { return _avoid_interference; };
bool getInterference() { return _interference_detected; };
int getNoiseFloor() { return _noise_floor; };
unsigned long getDifsMS() { return _difs_ms; };
uint8_t getCWBand() { return _cw_band; };
uint8_t getCWMin() { return _cw_min; };
uint8_t getCWMax() { return _cw_max; };
uint8_t getCW() { return _csma_cw; };
void setCW(uint8_t cw) { _csma_cw = cw; };
void setCWWaitTarget(unsigned long target) { _cw_wait_target = target; };
unsigned long getCWWaitTarget() { return _cw_wait_target; };
unsigned long getDifsWaitStart() { return _difs_wait_start; };
void setDifsWaitStart(unsigned long start) { _difs_wait_start = start; };
unsigned long getCWWaitStart() { return _cw_wait_start; };
void setCWWaitStart(unsigned long start) { _cw_wait_start = start; };
void addCWWaitPassed(unsigned long start) { _cw_wait_passed += start; };
void resetCWWaitPassed() { _cw_wait_passed = 0; };
bool getCWWaitStatus() { return _cw_wait_passed < _cw_wait_target; };
bool getLimitRate() { return _limit_rate; };
protected:
virtual void explicitHeaderMode() = 0;
virtual void implicitHeaderMode() = 0;
uint8_t _index;
uint32_t _bitrate;
int8_t _txp;
uint8_t _sf;
bool _radio_locked;
bool _radio_online;
float _st_airtime_limit;
@ -411,7 +302,6 @@ protected:
uint16_t _longterm_bins[AIRTIME_BINS] = {0};
float _airtime;
float _longterm_airtime;
float _last_packet_cost;
float _local_channel_util;
float _total_channel_util;
float _longterm_channel_util;
@ -424,53 +314,35 @@ protected:
bool _dcd;
bool _dcd_led;
bool _dcd_waiting;
long _dcd_wait_until;
bool _util_samples[DCD_SAMPLES] = {false};
int _dcd_sample;
uint32_t _post_tx_yield_timeout;
uint8_t _csma_p;
int _csma_slot_ms;
float _csma_p_min;
float _csma_p_max;
long _preambleLength;
float _lora_symbol_time_ms;
float _lora_symbol_rate;
float _lora_us_per_byte;
long _lora_preamble_time_ms;
long _lora_header_time_ms;
bool _ldro;
bool _limit_rate;
bool _interference_detected;
bool _avoid_interference;
int _csma_slot_ms;
unsigned long _difs_ms;
unsigned long _difs_wait_start;
unsigned long _cw_wait_start;
unsigned long _cw_wait_target;
unsigned long _cw_wait_passed;
int _csma_cw;
uint8_t _cw_band;
uint8_t _cw_min;
uint8_t _cw_max;
bool _noise_floor_sampled;
int _noise_floor_sample;
int _noise_floor_buffer[NOISE_FLOOR_SAMPLES];
int _noise_floor;
uint8_t _led_id_filter;
unsigned long _preamble_detected_at;
uint8_t _packet[255];
uint32_t _bitrate;
uint8_t _packet[255];
void (*_onReceive)(uint8_t, int);
};
class sx126x : public RadioInterface {
public:
sx126x(uint8_t index, SPIClass* spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int
sx126x(uint8_t index, SPIClass spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int
dio0, int busy, int rxen);
void reset();
int begin();
void end();
int beginPacket(int implicitHeader = false);
int endPacket();
int packetRssi(uint8_t pkt_snr_raw = 0xFF);
int packetRssi();
int currentRssi();
uint8_t packetRssiRaw();
uint8_t currentRssiRaw();
@ -495,7 +367,7 @@ public:
void sleep();
bool preInit();
int8_t getTxPower();
uint8_t getTxPower();
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
uint32_t getFrequency();
void setFrequency(uint32_t frequency);
@ -506,7 +378,7 @@ public:
void setCodingRate4(int denominator);
uint8_t getCodingRate4();
void setPreambleLength(long length);
bool dcd();
uint8_t modemStatus();
void enableCrc();
void disableCrc();
void enableTCXO();
@ -519,6 +391,8 @@ public:
void dumpRegisters(Stream& out);
void updateBitrate();
void handleDio0Rise();
private:
void writeBuffer(const uint8_t* buffer, size_t size);
@ -544,13 +418,14 @@ private:
void handleLowDataRate();
void optimizeModemSensitivity();
void reset(void);
void calibrate(void);
void calibrate_image(uint32_t frequency);
bool getPacketValidity();
void clearIRQStatus();
private:
SPISettings _spiSettings;
SPIClass* _spiModem;
SPIClass _spiModem;
int _ss;
int _sclk;
int _mosi;
@ -560,8 +435,11 @@ private:
int _rxen;
int _busy;
uint32_t _frequency;
int _txp;
uint8_t _sf;
uint8_t _bw;
uint8_t _cr;
uint8_t _ldro;
int _packetIndex;
int _implicitHeaderMode;
int _payloadLength;
@ -569,15 +447,14 @@ private:
int _fifo_tx_addr_ptr;
int _fifo_rx_addr_ptr;
bool _preinit_done;
uint8_t _index;
bool _tcxo;
bool _dio2_as_rf_switch;
};
class sx127x : public RadioInterface {
public:
sx127x(uint8_t index, SPIClass* spi, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy);
void reset();
sx127x(uint8_t index, SPIClass spi, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy);
int begin();
void end();
@ -585,7 +462,6 @@ public:
int beginPacket(int implicitHeader = false);
int endPacket();
int packetRssi(uint8_t pkt_snr_raw = 0xFF);
int packetRssi();
int currentRssi();
uint8_t packetRssiRaw();
@ -611,7 +487,7 @@ public:
void sleep();
bool preInit();
int8_t getTxPower();
uint8_t getTxPower();
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
uint32_t getFrequency();
void setFrequency(uint32_t frequency);
@ -622,7 +498,7 @@ public:
void setCodingRate4(int denominator);
uint8_t getCodingRate4();
void setPreambleLength(long length);
bool dcd();
uint8_t modemStatus();
void enableCrc();
void disableCrc();
void enableTCXO();
@ -632,8 +508,10 @@ public:
void setSPIFrequency(uint32_t frequency);
void updateBitrate();
void handleDio0Rise();
bool getPacketValidity();
void clearIRQStatus();
private:
void setSyncWord(uint8_t sw);
void explicitHeaderMode();
@ -651,7 +529,7 @@ private:
private:
SPISettings _spiSettings;
SPIClass* _spiModem;
SPIClass _spiModem;
int _ss;
int _sclk;
int _mosi;
@ -663,15 +541,14 @@ private:
int _packetIndex;
int _implicitHeaderMode;
bool _preinit_done;
uint8_t _index;
uint8_t _sf;
uint8_t _cr;
uint32_t _bw;
};
class sx128x : public RadioInterface {
public:
sx128x(uint8_t index, SPIClass* spi, bool tcxo, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen, int txen);
void reset();
sx128x(uint8_t index, SPIClass spi, bool tcxo, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen, int txen);
int begin();
void end();
@ -679,7 +556,7 @@ public:
int beginPacket(int implicitHeader = false);
int endPacket();
int packetRssi(uint8_t pkt_snr_raw = 0xFF);
int packetRssi();
int currentRssi();
uint8_t packetRssiRaw();
uint8_t currentRssiRaw();
@ -704,7 +581,7 @@ public:
void sleep();
bool preInit();
int8_t getTxPower();
uint8_t getTxPower();
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
uint32_t getFrequency();
void setFrequency(uint32_t frequency);
@ -715,7 +592,7 @@ public:
void setCodingRate4(int denominator);
uint8_t getCodingRate4();
void setPreambleLength(long length);
bool dcd();
uint8_t modemStatus();
void enableCrc();
void disableCrc();
void enableTCXO();
@ -727,10 +604,11 @@ public:
void dumpRegisters(Stream& out);
void updateBitrate();
void handleDio0Rise();
bool getPacketValidity();
void clearIRQStatus();
private:
void writeBuffer(const uint8_t* buffer, size_t size);
void readBuffer(uint8_t* buffer, size_t size);
@ -758,7 +636,7 @@ private:
private:
SPISettings _spiSettings;
SPIClass* _spiModem;
SPIClass _spiModem;
int _ss;
int _sclk;
int _mosi;
@ -770,6 +648,8 @@ private:
int _busy;
int _modem;
uint32_t _frequency;
int _txp;
uint8_t _sf;
uint8_t _bw;
uint8_t _cr;
int _packetIndex;
@ -780,9 +660,7 @@ private:
int _fifo_rx_addr_ptr;
bool _preinit_done;
int _rxPacketLength;
uint8_t _index;
bool _tcxo;
uint8_t _preamble_e;
uint8_t _preamble_m;
uint32_t _last_preamble;
};
#endif

View File

@ -1,5 +1,5 @@
# Precompiled Firmware
The firmware is now handled and installed to RNodes directly through `rnodeconf`, which is inclueded in the `rns` package. It can be installed via `pip`:
You can download and flash the firmware to supported boards using the [RNode Config Utility](https://github.com/markqvist/rnodeconfigutil). All firmware releases are now handled and installed directly through `rnodeconf`, which is inclueded in the `rns` package. It can be installed via `pip`:
```
# Install rnodeconf via rns package

Binary file not shown.

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton, Espressif Systems (Shanghai) CO LTD, other contributors as noted.
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
#
# ESP32 partition table generation tool
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
#
# spiffsgen is a tool used to generate a spiffs image from a directory
#

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
board_manager:
additional_urls:
- https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
- https://liberatedsystems.co.uk/rnode-firmware-ce/esp-custom-package.json
- https://raw.githubusercontent.com/RAKwireless/RAKwireless-Arduino-BSP-Index/main/package_rakwireless_index.json
- https://github.com/HelTecAutomation/Heltec_nRF52/releases/download/1.7.0/package_heltec_nrf_index.json
- http://unsigned.io/arduino/package_unsignedio_UnsignedBoards_index.json

View File

@ -1,47 +0,0 @@
#!/usr/bin/env python3
import sys
try:
target_path = sys.argv[1]
rxbuf_size = 0; rxbuf_minsize = 6144
txbuf_size = 0; txbuf_minsize = 384
line_index = 0
rx_line_index = 0
tx_line_index = 0
with open(target_path) as sf:
for line in sf:
line_index += 1
if line.startswith("#define RX_QUEUE_SIZE"):
ents = line.split(" ")
try:
rxbuf_size = int(ents[2])
rx_line_index = line_index
except Exception as e:
print(f"Could not parse Bluetooth RX_QUEUE_SIZE: {e}")
if line.startswith("#define TX_QUEUE_SIZE"):
ents = line.split(" ")
try:
txbuf_size = int(ents[2])
tx_line_index = line_index
except Exception as e:
print(f"Could not parse Bluetooth RX_QUEUE_SIZE: {e}")
if rxbuf_size != 0 and txbuf_size != 0:
break
if rxbuf_size < rxbuf_minsize:
print(f"Error: The configured ESP32 Bluetooth RX buffer size is too small, please set it to at least {rxbuf_minsize} and try compiling again.")
print(f"The buffer configuration can be modified in line {rx_line_index} of: {target_path}")
exit(1)
if txbuf_size < txbuf_minsize:
print(f"Error: The configured ESP32 Bluetooth TX buffer size is too small, please set it to at least {txbuf_minsize} and try compiling again.")
print(f"The buffer configuration can be modified in line {tx_line_index} of: {target_path}")
exit(1)
exit(0)
except Exception as e:
print(f"Could not determine ESP32 Bluetooth buffer configuration: {e}")
print("Please fix this error and try again")

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# Copyright (C) 2024, Mark Qvist
# Copyright (C) 2023, Mark Qvist
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -20,7 +20,6 @@ import sys
import RNS
import json
import hashlib
import subprocess
major_version = None
minor_version = None
@ -28,23 +27,9 @@ target_version = None
target_file = os.path.join(sys.argv[1])
if sys.argv[1] == "from_device":
from_device = True
else:
from_device = False
firmware_data = open(target_file, "rb").read()
calc_hash = hashlib.sha256(firmware_data[0:-32]).digest()
part_hash = firmware_data[-32:]
if not from_device:
firmware_data = open(target_file, "rb").read()
calc_hash = hashlib.sha256(firmware_data[0:-32]).digest()
part_hash = firmware_data[-32:]
if calc_hash == part_hash:
print(RNS.hexrep(part_hash, delimit=False))
else:
try:
cmdresult = subprocess.run(["rnodeconf", sys.argv[2], "-L"], stdout=subprocess.PIPE).stdout.decode('utf-8')
part_hash = cmdresult.split("The actual firmware hash is: ")[1].replace("\n", "")
print(part_hash)
except Exception as e:
print("Could not get partition hash from device: "+str(e))
if calc_hash == part_hash:
print(RNS.hexrep(part_hash, delimit=False))

View File

@ -1,6 +1,6 @@
#!/bin/python3
#!/bin/python
# Copyright (C) 2024, Mark Qvist
# Copyright (C) 2023, Mark Qvist
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -47,4 +47,4 @@ for filename in files:
"version": target_version
}
print(json.dumps(release_hashes))
print(json.dumps(release_hashes))

View File

@ -1,153 +0,0 @@
// Copyright (C) 2024, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <Arduino.h>
#include "../../Boards.h"
#if PLATFORM != PLATFORM_NRF52
#if HAS_BLE
#include "BLESerial.h"
uint32_t bt_passkey_callback();
void bt_passkey_notify_callback(uint32_t passkey);
bool bt_security_request_callback();
void bt_authentication_complete_callback(esp_ble_auth_cmpl_t auth_result);
bool bt_confirm_pin_callback(uint32_t pin);
void bt_connect_callback(BLEServer *server);
void bt_disconnect_callback(BLEServer *server);
bool bt_client_authenticated();
uint32_t BLESerial::onPassKeyRequest() { return bt_passkey_callback(); }
void BLESerial::onPassKeyNotify(uint32_t passkey) { bt_passkey_notify_callback(passkey); }
bool BLESerial::onSecurityRequest() { return bt_security_request_callback(); }
void BLESerial::onAuthenticationComplete(esp_ble_auth_cmpl_t auth_result) { bt_authentication_complete_callback(auth_result); }
void BLESerial::onConnect(BLEServer *server) { bt_connect_callback(server); }
void BLESerial::onDisconnect(BLEServer *server) { bt_disconnect_callback(server); ble_server->startAdvertising(); }
bool BLESerial::onConfirmPIN(uint32_t pin) { return bt_confirm_pin_callback(pin); };
bool BLESerial::connected() { return ble_server->getConnectedCount() > 0; }
int BLESerial::read() {
int result = this->rx_buffer.pop();
if (result == '\n') { this->numAvailableLines--; }
return result;
}
size_t BLESerial::readBytes(uint8_t *buffer, size_t bufferSize) {
int i = 0;
while (i < bufferSize && available()) { buffer[i] = (uint8_t)this->rx_buffer.pop(); i++; }
return i;
}
int BLESerial::peek() {
if (this->rx_buffer.getLength() == 0) return -1;
return this->rx_buffer.get(0);
}
int BLESerial::available() { return this->rx_buffer.getLength(); }
size_t BLESerial::print(const char *str) {
if (ble_server->getConnectedCount() <= 0) return 0;
size_t written = 0; for (size_t i = 0; str[i] != '\0'; i++) { written += this->write(str[i]); }
flush();
return written;
}
size_t BLESerial::write(const uint8_t *buffer, size_t bufferSize) {
if (ble_server->getConnectedCount() <= 0) { return 0; } else {
size_t written = 0; for (int i = 0; i < bufferSize; i++) { written += this->write(buffer[i]); }
flush();
return written;
}
}
size_t BLESerial::write(uint8_t byte) {
if (bt_client_authenticated()) {
if (ble_server->getConnectedCount() <= 0) { return 0; } else {
this->transmitBuffer[this->transmitBufferLength] = byte;
this->transmitBufferLength++;
if (this->transmitBufferLength == maxTransferSize) { flush(); }
return 1;
}
} else {
return 0;
}
}
void BLESerial::flush() {
if (this->transmitBufferLength > 0) {
TxCharacteristic->setValue(this->transmitBuffer, this->transmitBufferLength);
this->transmitBufferLength = 0;
this->lastFlushTime = millis();
TxCharacteristic->notify(true);
}
}
void BLESerial::begin(const char *name) {
ConnectedDeviceCount = 0;
BLEDevice::init(name);
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9);
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9);
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_SCAN ,ESP_PWR_LVL_P9);
ble_server = BLEDevice::createServer();
ble_server->setCallbacks(this);
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_MITM);
BLEDevice::setSecurityCallbacks(this);
SetupSerialService();
ble_adv = BLEDevice::getAdvertising();
ble_adv->addServiceUUID(BLE_SERIAL_SERVICE_UUID);
ble_adv->setMinPreferred(0x20);
ble_adv->setMaxPreferred(0x40);
ble_adv->setScanResponse(true);
ble_adv->start();
}
void BLESerial::end() { BLEDevice::deinit(); }
void BLESerial::onWrite(BLECharacteristic *characteristic) {
if (characteristic->getUUID().toString() == BLE_RX_UUID) {
auto value = characteristic->getValue();
for (int i = 0; i < value.length(); i++) { rx_buffer.push(value[i]); }
}
}
void BLESerial::SetupSerialService() {
SerialService = ble_server->createService(BLE_SERIAL_SERVICE_UUID);
RxCharacteristic = SerialService->createCharacteristic(BLE_RX_UUID, BLECharacteristic::PROPERTY_WRITE);
RxCharacteristic->setAccessPermissions(ESP_GATT_PERM_WRITE_ENC_MITM);
RxCharacteristic->addDescriptor(new BLE2902());
RxCharacteristic->setWriteProperty(true);
RxCharacteristic->setCallbacks(this);
TxCharacteristic = SerialService->createCharacteristic(BLE_TX_UUID, BLECharacteristic::PROPERTY_NOTIFY);
TxCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENC_MITM);
TxCharacteristic->addDescriptor(new BLE2902());
TxCharacteristic->setNotifyProperty(true);
TxCharacteristic->setReadProperty(true);
SerialService->start();
}
BLESerial::BLESerial() { }
#endif
#endif

View File

@ -1,133 +0,0 @@
// Copyright (C) 2024, Mark Qvist
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "../../Boards.h"
#if PLATFORM != PLATFORM_NRF52
#if HAS_BLE
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
template <size_t n>
class BLEFIFO {
private:
uint8_t buffer[n];
int head = 0;
int tail = 0;
public:
void push(uint8_t value) {
buffer[head] = value;
head = (head + 1) % n;
if (head == tail) { tail = (tail + 1) % n; }
}
int pop() {
if (head == tail) {
return -1;
} else {
uint8_t value = buffer[tail];
tail = (tail + 1) % n;
return value;
}
}
void clear() { head = 0; tail = 0; }
int get(size_t index) {
if (index >= this->getLength()) {
return -1;
} else {
return buffer[(tail + index) % n];
}
}
size_t getLength() {
if (head >= tail) {
return head - tail;
} else {
return n - tail + head;
}
}
};
#define RX_BUFFER_SIZE 6144
#define BLE_BUFFER_SIZE 512 // Must fit in max GATT attribute length
#define MIN_MTU 50
class BLESerial : public BLECharacteristicCallbacks, public BLEServerCallbacks, public BLESecurityCallbacks, public Stream {
public:
BLESerial();
void begin(const char *name);
void end();
void onWrite(BLECharacteristic *characteristic);
int available();
int peek();
int read();
size_t readBytes(uint8_t *buffer, size_t bufferSize);
size_t write(uint8_t byte);
size_t write(const uint8_t *buffer, size_t bufferSize);
size_t print(const char *value);
void flush();
void onConnect(BLEServer *server);
void onDisconnect(BLEServer *server);
uint32_t onPassKeyRequest();
void onPassKeyNotify(uint32_t passkey);
bool onSecurityRequest();
void onAuthenticationComplete(esp_ble_auth_cmpl_t);
bool onConfirmPIN(uint32_t pin);
bool connected();
BLEServer *ble_server;
BLEAdvertising *ble_adv;
BLEService *SerialService;
BLECharacteristic *TxCharacteristic;
BLECharacteristic *RxCharacteristic;
size_t transmitBufferLength;
unsigned long long lastFlushTime;
private:
BLESerial(BLESerial const &other) = delete;
void operator=(BLESerial const &other) = delete;
BLEFIFO<RX_BUFFER_SIZE> rx_buffer;
size_t numAvailableLines;
uint8_t transmitBuffer[BLE_BUFFER_SIZE];
int ConnectedDeviceCount;
void SetupSerialService();
uint16_t peerMTU;
uint16_t maxTransferSize = BLE_BUFFER_SIZE;
bool checkMTU();
const char *BLE_SERIAL_SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
const char *BLE_RX_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
const char *BLE_TX_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
bool started = false;
};
#endif
#endif

View File

@ -1,440 +0,0 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
* Copyright (c) 2018 by Fabrice Weinberg
* Copyright (c) 2024 by Heltec AutoMation
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* ThingPulse invests considerable time and money to develop these open source libraries.
* Please support us by buying our products (and not the clones) from
* https://thingpulse.com
*
*/
#ifndef ST7789Spi_h
#define ST7789Spi_h
#include "OLEDDisplay.h"
#include <SPI.h>
#define ST_CMD_DELAY 0x80 // special signifier for command lists
#define ST77XX_NOP 0x00
#define ST77XX_SWRESET 0x01
#define ST77XX_RDDID 0x04
#define ST77XX_RDDST 0x09
#define ST77XX_SLPIN 0x10
#define ST77XX_SLPOUT 0x11
#define ST77XX_PTLON 0x12
#define ST77XX_NORON 0x13
#define ST77XX_INVOFF 0x20
#define ST77XX_INVON 0x21
#define ST77XX_DISPOFF 0x28
#define ST77XX_DISPON 0x29
#define ST77XX_CASET 0x2A
#define ST77XX_RASET 0x2B
#define ST77XX_RAMWR 0x2C
#define ST77XX_RAMRD 0x2E
#define ST77XX_PTLAR 0x30
#define ST77XX_TEOFF 0x34
#define ST77XX_TEON 0x35
#define ST77XX_MADCTL 0x36
#define ST77XX_COLMOD 0x3A
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_RDID1 0xDA
#define ST77XX_RDID2 0xDB
#define ST77XX_RDID3 0xDC
#define ST77XX_RDID4 0xDD
// Some ready-made 16-bit ('565') color settings:
#define ST77XX_BLACK 0x0000
#define ST77XX_WHITE 0xFFFF
#define ST77XX_RED 0xF800
#define ST77XX_GREEN 0x07E0
#define ST77XX_BLUE 0x001F
#define ST77XX_CYAN 0x07FF
#define ST77XX_MAGENTA 0xF81F
#define ST77XX_YELLOW 0xFFE0
#define ST77XX_ORANGE 0xFC00
#define LED_A_ON LOW
#ifdef ESP_PLATFORM
#undef LED_A_ON
#define LED_A_ON HIGH
#define rtos_free free
#define rtos_malloc malloc
//SPIClass SPI1(HSPI);
#endif
class ST7789Spi : public OLEDDisplay {
private:
uint8_t _rst;
uint8_t _dc;
uint8_t _cs;
uint8_t _ledA;
int _miso;
int _mosi;
int _clk;
SPIClass * _spi;
SPISettings _spiSettings;
uint16_t _RGB=0xFFFF;
uint8_t _buffheight;
public:
/* pass _cs as -1 to indicate "do not use CS pin", for cases where it is hard wired low */
ST7789Spi(SPIClass *spiClass,uint8_t _rst, uint8_t _dc, uint8_t _cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_RAWMODE,uint16_t width=240,uint16_t height=320,int mosi=-1,int miso=-1,int clk=-1) {
this->_spi = spiClass;
this->_rst = _rst;
this->_dc = _dc;
this->_cs = _cs;
this->_mosi=mosi;
this->_miso=miso;
this->_clk=clk;
//this->_ledA = _ledA;
_spiSettings = SPISettings(40000000, MSBFIRST, SPI_MODE0);
setGeometry(g,width,height);
}
bool connect(){
this->_buffheight=displayHeight / 8;
this->_buffheight+=displayHeight % 8 ? 1:0;
pinMode(_cs, OUTPUT);
pinMode(_dc, OUTPUT);
//pinMode(_ledA, OUTPUT);
if (_cs != (uint8_t) -1) {
pinMode(_cs, OUTPUT);
}
pinMode(_rst, OUTPUT);
#ifdef ESP_PLATFORM
_spi->begin(_clk,_miso,_mosi,-1);
#else
_spi->begin();
#endif
_spi->setClockDivider (SPI_CLOCK_DIV2);
// Pulse Reset low for 10ms
digitalWrite(_rst, HIGH);
delay(1);
digitalWrite(_rst, LOW);
delay(10);
digitalWrite(_rst, HIGH);
_spi->begin ();
//digitalWrite(_ledA, LED_A_ON);
return true;
}
void display(void) {
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
uint16_t minBoundY = UINT16_MAX;
uint16_t maxBoundY = 0;
uint16_t minBoundX = UINT16_MAX;
uint16_t maxBoundX = 0;
uint16_t x, y;
// Calculate the Y bounding box of changes
// and copy buffer[pos] to buffer_back[pos];
for (y = 0; y < _buffheight; y++) {
for (x = 0; x < displayWidth; x++) {
//Serial.printf("x %d y %d\r\n",x,y);
uint16_t pos = x + y * displayWidth;
if (buffer[pos] != buffer_back[pos]) {
minBoundY = min(minBoundY, y);
maxBoundY = max(maxBoundY, y);
minBoundX = min(minBoundX, x);
maxBoundX = max(maxBoundX, x);
}
buffer_back[pos] = buffer[pos];
}
yield();
}
// If the minBoundY wasn't updated
// we can savely assume that buffer_back[pos] == buffer[pos]
// holdes true for all values of pos
if (minBoundY == UINT16_MAX) return;
set_CS(LOW);
_spi->beginTransaction(_spiSettings);
for (y = minBoundY; y <= maxBoundY; y++)
{
for(int temp = 0; temp<8;temp++)
{
//setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1);
setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1);
//setAddrWindow(y*8+temp,minBoundX,1,maxBoundX-minBoundX+1);
uint32_t const pixbufcount = maxBoundX-minBoundX+1;
uint16_t *pixbuf = (uint16_t *)rtos_malloc(2 * pixbufcount);
for (x = minBoundX; x <= maxBoundX; x++)
{
pixbuf[x-minBoundX] = ((buffer[x + y * displayWidth]>>temp)&0x01)==1?_RGB:0;
}
#ifdef ESP_PLATFORM
_spi->transferBytes((uint8_t *)pixbuf, NULL, 2 * pixbufcount);
#else
_spi->transfer(pixbuf, NULL, 2 * pixbufcount);
#endif
rtos_free(pixbuf);
}
}
_spi->endTransaction();
set_CS(HIGH);
#else
set_CS(LOW);
_spi->beginTransaction(_spiSettings);
uint8_t x, y;
for (y = 0; y < _buffheight; y++)
{
for(int temp = 0; temp<8;temp++)
{
//setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1);
//setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1);
setAddrWindow(y*8+temp,0,1,displayWidth);
uint32_t const pixbufcount = displayWidth;
uint16_t *pixbuf = (uint16_t *)rtos_malloc(2 * pixbufcount);
for (x = 0; x < displayWidth; x++)
{
pixbuf[x] = ((buffer[x + y * displayWidth]>>temp)&0x01)==1?_RGB:0;
}
#ifdef ESP_PLATFORM
_spi->transferBytes((uint8_t *)pixbuf, NULL, 2 * pixbufcount);
#else
_spi->transfer(pixbuf, NULL, 2 * pixbufcount);
#endif
rtos_free(pixbuf);
}
}
_spi->endTransaction();
set_CS(HIGH);
#endif
}
virtual void resetOrientation() {
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MX;
sendCommand(ST77XX_MADCTL);
WriteData(madctl);
delay(10);
}
virtual void flipScreenVertically() {
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MY;
sendCommand(ST77XX_MADCTL);
WriteData(madctl);
delay(10);
}
virtual void mirrorScreen() {
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MX|ST77XX_MADCTL_MY;
sendCommand(ST77XX_MADCTL);
WriteData(madctl);
delay(10);
}
virtual void setRotation(uint8_t r) {
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MX;
if (r == 1) { madctl = 0xC0; }
if (r == 2) { madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MY; }
if (r == 3) { madctl = 0x00; }
sendCommand(ST77XX_MADCTL);
WriteData(madctl);
delay(10);
}
void setRGB(uint16_t c)
{
this->_RGB=0x00|c>>8|c<<8&0xFF00;
}
void displayOn(void) {
//sendCommand(DISPLAYON);
}
void displayOff(void) {
//sendCommand(DISPLAYOFF);
}
//#define ST77XX_MADCTL_MY 0x80
//#define ST77XX_MADCTL_MX 0x40
//#define ST77XX_MADCTL_MV 0x20
//#define ST77XX_MADCTL_ML 0x10
protected:
// Send all the init commands
virtual void sendInitCommands()
{
sendCommand(ST77XX_SWRESET); // 1: Software reset, no args, w/delay
delay(150);
sendCommand(ST77XX_SLPOUT); // 2: Out of sleep mode, no args, w/delay
delay(10);
sendCommand(ST77XX_COLMOD); // 3: Set color mode, 16-bit color
WriteData(0x55);
delay(10);
sendCommand(ST77XX_MADCTL); // 4: Mem access ctrl (directions), Row/col addr, bottom-top refresh
WriteData(0x08);
sendCommand(ST77XX_CASET); // 5: Column addr set,
WriteData(0x00);
WriteData(0x00); // XSTART = 0
WriteData(0x00);
WriteData(240); // XEND = 240
sendCommand(ST77XX_RASET); // 6: Row addr set,
WriteData(0x00);
WriteData(0x00); // YSTART = 0
WriteData(320>>8);
WriteData(320&0xFF); // YSTART = 320
sendCommand(ST77XX_SLPOUT); // 7: hack
delay(10);
sendCommand(ST77XX_NORON); // 8: Normal display on, no args, w/delay
delay(10);
sendCommand(ST77XX_DISPON); // 9: Main screen turn on, no args, delay
delay(10);
sendCommand(ST77XX_INVON); // 10: invert
delay(10);
//uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MX;
uint8_t madctl = ST77XX_MADCTL_RGB|ST77XX_MADCTL_MV|ST77XX_MADCTL_MX;
sendCommand(ST77XX_MADCTL);
WriteData(madctl);
delay(10);
setRGB(ST77XX_GREEN);
}
private:
void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
x += (320-displayWidth)/2;
y += (240-displayHeight)/2;
uint32_t xa = ((uint32_t)x << 16) | (x + w - 1);
uint32_t ya = ((uint32_t)y << 16) | (y + h - 1);
writeCommand(ST77XX_CASET); // Column addr set
SPI_WRITE32(xa);
writeCommand(ST77XX_RASET); // Row addr set
SPI_WRITE32(ya);
writeCommand(ST77XX_RAMWR); // write to RAM
}
int getBufferOffset(void) {
return 0;
}
inline void set_CS(bool level) {
if (_cs != (uint8_t) -1) {
digitalWrite(_cs, level);
}
};
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
set_CS(HIGH);
digitalWrite(_dc, LOW);
set_CS(LOW);
_spi->beginTransaction(_spiSettings);
_spi->transfer(com);
_spi->endTransaction();
set_CS(HIGH);
digitalWrite(_dc, HIGH);
}
inline void WriteData(uint8_t data) __attribute__((always_inline)){
digitalWrite(_cs, LOW);
_spi->beginTransaction(_spiSettings);
_spi->transfer(data);
_spi->endTransaction();
digitalWrite(_cs, HIGH);
}
void SPI_WRITE32(uint32_t l)
{
_spi->transfer(l >> 24);
_spi->transfer(l >> 16);
_spi->transfer(l >> 8);
_spi->transfer(l);
}
void writeCommand(uint8_t cmd) {
digitalWrite(_dc, LOW);
_spi->transfer(cmd);
digitalWrite(_dc, HIGH);
}
// Private functions
void setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width, uint16_t height) {
this->geometry = g;
switch (g) {
case GEOMETRY_128_128:
this->displayWidth = 128;
this->displayHeight = 128;
break;
case GEOMETRY_128_64:
this->displayWidth = 128;
this->displayHeight = 64;
break;
case GEOMETRY_128_32:
this->displayWidth = 128;
this->displayHeight = 32;
break;
case GEOMETRY_64_48:
this->displayWidth = 64;
this->displayHeight = 48;
break;
case GEOMETRY_64_32:
this->displayWidth = 64;
this->displayHeight = 32;
break;
case GEOMETRY_RAWMODE:
this->displayWidth = width > 0 ? width : 128;
this->displayHeight = height > 0 ? height : 64;
break;
}
uint8_t tmp=displayHeight % 8;
uint8_t _buffheight=displayHeight / 8;
if(tmp!=0)
_buffheight++;
this->displayBufferSize = displayWidth * _buffheight ;
}
};
#endif

View File

@ -1,95 +0,0 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "FIFOBuffer.h"
#ifdef __cplusplus
extern "C" {
#endif
bool fifo_isempty(const FIFOBuffer *f) {
return f->head == f->tail;
}
bool fifo_isfull(const FIFOBuffer *f) {
return ((f->head == f->begin) && (f->tail == f->end)) || (f->tail == f->head - 1);
}
void fifo_push(FIFOBuffer *f, unsigned char c) {
*(f->tail) = c;
if (f->tail == f->end) {
f->tail = f->begin;
} else {
f->tail++;
}
}
unsigned char fifo_pop(FIFOBuffer *f) {
if(f->head == f->end) {
f->head = f->begin;
return *(f->end);
} else {
return *(f->head++);
}
}
void fifo_flush(FIFOBuffer *f) {
f->head = f->tail;
}
void fifo_init(FIFOBuffer *f, unsigned char *buffer, size_t size) {
f->head = f->tail = f->begin = buffer;
f->end = buffer + size;
}
// todo, fix this so it actually displays the amount of data in the fifo
// buffer, not just the size allocated for the buffer
size_t fifo_len(FIFOBuffer *f) {
return f->end - f->begin;
}
bool fifo16_isempty(const FIFOBuffer16 *f) {
return f->head == f->tail;
}
bool fifo16_isfull(const FIFOBuffer16 *f) {
return ((f->head == f->begin) && (f->tail == f->end)) || (f->tail == f->head - 1);
}
void fifo16_push(FIFOBuffer16 *f, uint16_t c) {
*(f->tail) = c;
if (f->tail == f->end) {
f->tail = f->begin;
} else {
f->tail++;
}
}
uint16_t fifo16_pop(FIFOBuffer16 *f) {
if(f->head == f->end) {
f->head = f->begin;
return *(f->end);
} else {
return *(f->head++);
}
}
void fifo16_flush(FIFOBuffer16 *f) {
f->head = f->tail;
}
void fifo16_init(FIFOBuffer16 *f, uint16_t *buffer, uint16_t size) {
f->head = f->tail = f->begin = buffer;
f->end = buffer + size;
}
uint16_t fifo16_len(FIFOBuffer16 *f) {
return (f->end - f->begin);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,59 +0,0 @@
#ifndef FIFOBUFFER_H
#define FIFOBUFFER_H
#ifdef __cplusplus
extern "C" {
#endif
/* An 8 bit FIFO buffer implementation */
typedef struct FIFOBuffer
{
unsigned char *begin;
unsigned char *end;
unsigned char * volatile head;
unsigned char * volatile tail;
} FIFOBuffer;
bool fifo_isempty(const FIFOBuffer *f);
bool fifo_isfull(const FIFOBuffer *f);
void fifo_push(FIFOBuffer *f, unsigned char c);
unsigned char fifo_pop(FIFOBuffer *f);
void fifo_flush(FIFOBuffer *f);
void fifo_init(FIFOBuffer *f, unsigned char *buffer, size_t size);
size_t fifo_len(FIFOBuffer *f);
/* A 16-bit implementation of the same FIFO buffer. */
typedef struct FIFOBuffer16
{
uint16_t *begin;
uint16_t *end;
uint16_t * volatile head;
uint16_t * volatile tail;
} FIFOBuffer16;
bool fifo16_isempty(const FIFOBuffer16 *f);
bool fifo16_isfull(const FIFOBuffer16 *f);
void fifo16_push(FIFOBuffer16 *f, uint16_t c);
uint16_t fifo16_pop(FIFOBuffer16 *f);
void fifo16_flush(FIFOBuffer16 *f);
void fifo16_init(FIFOBuffer16 *f, uint16_t *buffer, uint16_t size);
uint16_t fifo16_len(FIFOBuffer16 *f);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,45 +0,0 @@
extern RadioInterface* interface_obj[INTERFACE_COUNT];
void (*onIntRise[INTERFACE_COUNT]) (void);
#if INTERFACE_COUNT == 1
void onInt0Rise() {
if (interfaces[0] == SX1280) {
// On the SX1280, there is a bug which can cause the busy line
// to remain high if a high amount of packets are received when
// in continuous RX mode. This is documented as Errata 16.1 in
// the SX1280 datasheet v3.2 (page 149)
// Therefore, the modem is set into receive mode each time a packet is received.
interface_obj[0]->receive();
}
if (interface_obj[0]->getPacketValidity()) {
interface_obj[0]->handleDio0Rise();
}
}
void setup_interfaces() {
onIntRise[0] = onInt0Rise;
}
#elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL
void onInt0Rise() {
if (interface_obj[0]->getPacketValidity()) {
interface_obj[0]->handleDio0Rise();
}
}
void onInt1Rise() {
// On the SX1280, there is a bug which can cause the busy line
// to remain high if a high amount of packets are received when
// in continuous RX mode. This is documented as Errata 16.1 in
// the SX1280 datasheet v3.2 (page 149)
// Therefore, the modem is set into receive mode each time a packet is received.
interface_obj[1]->receive();
if (interface_obj[1]->getPacketValidity()) {
interface_obj[1]->handleDio0Rise();
}
}
void setup_interfaces() {
onIntRise[0] = onInt0Rise;
onIntRise[1] = onInt1Rise;
}
#endif

View File

@ -1,8 +0,0 @@
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#define GPS_INTERVAL 5000 // ms
unsigned long last_gps = 0;
TinyGPSPlus gps;
SoftwareSerial gps_s(PIN_GPS_RX, PIN_GPS_TX);