Initial multiplatform support

This commit is contained in:
Mark Qvist 2022-01-09 23:40:30 +01:00
parent e1df8a2c75
commit 3e0536b272
7 changed files with 415 additions and 131 deletions

View File

@ -4,20 +4,30 @@
#define CONFIG_H #define CONFIG_H
#define MAJ_VERS 0x01 #define MAJ_VERS 0x01
#define MIN_VERS 0x12 #define MIN_VERS 0x13
#define PLATFORM_AVR 0x90
#define PLATFORM_ESP32 0x80
#define MCU_1284P 0x91 #define MCU_1284P 0x91
#define MCU_2560 0x92 #define MCU_2560 0x92
#define MCU_ESP32 0x81
#define MODE_HOST 0x11 #define MODE_HOST 0x11
#define MODE_TNC 0x12 #define MODE_TNC 0x12
#if defined(__AVR_ATmega1284P__) #if defined(__AVR_ATmega1284P__)
#define PLATFORM PLATFORM_AVR
#define MCU_VARIANT MCU_1284P #define MCU_VARIANT MCU_1284P
#warning "Firmware is being compiled for atmega1284p based boards" #warning "Firmware is being compiled for atmega1284p based boards"
#elif defined(__AVR_ATmega2560__) #elif defined(__AVR_ATmega2560__)
#define PLATFORM PLATFORM_AVR
#define MCU_VARIANT MCU_2560 #define MCU_VARIANT MCU_2560
#warning "Firmware is being compiled for atmega2560 based boards" #warning "Firmware is being compiled for atmega2560 based boards"
#elif defined(ESP32)
#define PLATFORM PLATFORM_ESP32
#define MCU_VARIANT MCU_ESP32
#warning "Firmware is being compiled for ESP32 based boards"
#else #else
#error "The firmware cannot be compiled for the selected MCU variant" #error "The firmware cannot be compiled for the selected MCU variant"
#endif #endif
@ -38,29 +48,40 @@
const int pin_led_rx = 12; const int pin_led_rx = 12;
const int pin_led_tx = 13; const int pin_led_tx = 13;
// TODO: Reset
#define CONFIG_UART_BUFFER_SIZE 6144 #define CONFIG_UART_BUFFER_SIZE 6144
#define CONFIG_QUEUE_SIZE 6144 #define CONFIG_QUEUE_SIZE 6144
#define CONFIG_QUEUE_MAX_LENGTH 250 #define CONFIG_QUEUE_MAX_LENGTH 250
#define EEPROM_SIZE 4096 #define EEPROM_SIZE 4096
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
#endif
#if MCU_VARIANT == MCU_2560 #elif MCU_VARIANT == MCU_2560
const int pin_cs = 10; const int pin_cs = 10;
const int pin_reset = 9; const int pin_reset = 9;
const int pin_dio = 2; const int pin_dio = 2;
const int pin_led_rx = 12; const int pin_led_rx = 12;
const int pin_led_tx = 13; const int pin_led_tx = 13;
// TODO: Reset
#define CONFIG_UART_BUFFER_SIZE 2048 #define CONFIG_UART_BUFFER_SIZE 2048
#define CONFIG_QUEUE_SIZE 2048 #define CONFIG_QUEUE_SIZE 2048
#define CONFIG_QUEUE_MAX_LENGTH 250 #define CONFIG_QUEUE_MAX_LENGTH 80
#define EEPROM_SIZE 4096 #define EEPROM_SIZE 4096
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
#elif MCU_VARIANT == MCU_ESP32
const int pin_cs = 18;
const int pin_reset = 23;
const int pin_dio = 26;
const int pin_led_rx = 2;
const int pin_led_tx = 4;
#define CONFIG_UART_BUFFER_SIZE 6144
#define CONFIG_QUEUE_SIZE 6144
#define CONFIG_QUEUE_MAX_LENGTH 250
#define EEPROM_SIZE 1024
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
#endif #endif
#define eeprom_addr(a) (a+EEPROM_OFFSET) #define eeprom_addr(a) (a+EEPROM_OFFSET)

View File

@ -27,6 +27,8 @@
#define CMD_BLINK 0x30 #define CMD_BLINK 0x30
#define CMD_RANDOM 0x40 #define CMD_RANDOM 0x40
#define CMD_PLATFORM 0x48
#define CMD_MCU 0x49
#define CMD_FW_VERSION 0x50 #define CMD_FW_VERSION 0x50
#define CMD_ROM_READ 0x51 #define CMD_ROM_READ 0x51
#define CMD_ROM_WRITE 0x52 #define CMD_ROM_WRITE 0x52
@ -34,6 +36,9 @@
#define CMD_CONF_DELETE 0x54 #define CMD_CONF_DELETE 0x54
#define CMD_UNLOCK_ROM 0x59 #define CMD_UNLOCK_ROM 0x59
#define ROM_UNLOCK_BYTE 0xF8 #define ROM_UNLOCK_BYTE 0xF8
#define CMD_RESET 0x55
#define CMD_RESET_BYTE 0xF8
#define DETECT_REQ 0x73 #define DETECT_REQ 0x73
#define DETECT_RESP 0x46 #define DETECT_RESP 0x46

View File

@ -449,6 +449,8 @@ long LoRaClass::getSignalBandwidth()
case 8: return 250E3; case 8: return 250E3;
case 9: return 500E3; case 9: return 500E3;
} }
return 0;
} }
void LoRaClass::handleLowDataRate(){ void LoRaClass::handleLowDataRate(){

View File

@ -1,6 +1,29 @@
prep:
arduino-cli core update-index --config-file arduino-cli.yaml
arduino-cli core install unsignedio:avr
firmware: firmware:
arduino-cli compile --fqbn unsignedio:avr:rnode arduino-cli compile --fqbn unsignedio:avr:rnode
release:
arduino-cli compile --fqbn unsignedio:avr:rnode -e
cp build/unsignedio.avr.rnode/RNode_Firmware.ino.hex Precompiled/rnode_firmware_latest.hex
rm -r build
upload: upload:
arduino-cli upload -p /dev/ttyUSB0 --fqbn unsignedio:avr:rnode arduino-cli upload -p /dev/ttyUSB0 --fqbn unsignedio:avr:rnode
prep-tbeam:
arduino-cli core update-index --config-file arduino-cli.yaml
arduino-cli core install esp32:esp32
firmware-tbeam:
arduino-cli compile --fqbn esp32:esp32:t-beam
upload-tbeam:
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:t-beam
release-tbeam:
arduino-cli compile --fqbn esp32:esp32:t-beam -e
cp build/esp32.esp32.t-beam/RNode_Firmware.ino.bin Precompiled/rnode_firmware_latest_tbeam.bin
rm -r build

View File

@ -22,6 +22,12 @@ volatile bool serial_buffering = false;
char sbuf[128]; char sbuf[128];
void setup() { void setup() {
#if MCU_VARIANT == MCU_ESP32
delay(1500);
EEPROM.begin(EEPROM_SIZE);
Serial.setRxBufferSize(CONFIG_UART_BUFFER_SIZE);
#endif
// Seed the PRNG // Seed the PRNG
randomSeed(analogRead(0)); randomSeed(analogRead(0));
@ -54,6 +60,12 @@ void setup() {
// pins for the LoRa module // pins for the LoRa module
LoRa.setPins(pin_cs, pin_reset, pin_dio); LoRa.setPins(pin_cs, pin_reset, pin_dio);
#if MCU_VARIANT == MCU_ESP32
radio_locked = true;
radio_online = false;
hw_ready = false;
#endif
// Validate board health, EEPROM and config // Validate board health, EEPROM and config
validateStatus(); validateStatus();
} }
@ -76,6 +88,7 @@ bool startRadio() {
// serial port and with the onboard LEDs // serial port and with the onboard LEDs
kiss_indicate_error(ERROR_INITRADIO); kiss_indicate_error(ERROR_INITRADIO);
led_indicate_error(0); led_indicate_error(0);
return false;
} else { } else {
radio_online = true; radio_online = true;
@ -86,13 +99,17 @@ bool startRadio() {
getFrequency(); getFrequency();
LoRa.enableCrc(); LoRa.enableCrc();
LoRa.onReceive(receiveCallback);
#if MCU_VARIANT != MCU_ESP32
LoRa.onReceive(receive_callback);
#endif
lora_receive(); lora_receive();
// Flash an info pattern to indicate // Flash an info pattern to indicate
// that the radio is now on // that the radio is now on
led_indicate_info(3); led_indicate_info(3);
return true;
} }
} else { } else {
@ -100,10 +117,12 @@ bool startRadio() {
// that the radio was locked, and thus // that the radio was locked, and thus
// not started // not started
led_indicate_warning(3); led_indicate_warning(3);
return false;
} }
} else { } else {
// If radio is already on, we silently // If radio is already on, we silently
// ignore the request. // ignore the request.
return true;
} }
} }
@ -120,7 +139,7 @@ void update_radio_lock() {
} }
} }
void receiveCallback(int packet_size) { void receive_callback(int packet_size) {
if (!promisc) { if (!promisc) {
// The standard operating mode allows large // The standard operating mode allows large
// packets with a payload up to 500 bytes, // packets with a payload up to 500 bytes,
@ -197,7 +216,7 @@ void receiveCallback(int packet_size) {
} }
} else { } else {
// In promiscuous mode, raw packets are // In promiscuous mode, raw packets are
// output directly over to the host // output directly to the host
read_len = 0; read_len = 0;
last_rssi = LoRa.packetRssi(); last_rssi = LoRa.packetRssi();
last_snr_raw = LoRa.packetSnrRaw(); last_snr_raw = LoRa.packetSnrRaw();
@ -232,7 +251,13 @@ void flushQueue(void) {
queue_flushing = true; queue_flushing = true;
size_t processed = 0; size_t processed = 0;
#if MCU_VARIANT == MCU_ESP32
while (!fifo16_isempty(&packet_starts)) {
#else
while (!fifo16_isempty_locked(&packet_starts)) { while (!fifo16_isempty_locked(&packet_starts)) {
#endif
size_t start = fifo16_pop(&packet_starts); size_t start = fifo16_pop(&packet_starts);
size_t length = fifo16_pop(&packet_lengths); size_t length = fifo16_pop(&packet_lengths);
@ -497,6 +522,10 @@ void serialCallback(uint8_t sbyte) {
if (sbyte == ROM_UNLOCK_BYTE) { if (sbyte == ROM_UNLOCK_BYTE) {
unlock_rom(); unlock_rom();
} }
} else if (command == CMD_RESET) {
if (sbyte == CMD_RESET_BYTE) {
hard_reset();
}
} else if (command == CMD_ROM_READ) { } else if (command == CMD_ROM_READ) {
kiss_dump_eeprom(); kiss_dump_eeprom();
} else if (command == CMD_ROM_WRITE) { } else if (command == CMD_ROM_WRITE) {
@ -516,6 +545,10 @@ void serialCallback(uint8_t sbyte) {
} }
} else if (command == CMD_FW_VERSION) { } else if (command == CMD_FW_VERSION) {
kiss_indicate_version(); kiss_indicate_version();
} else if (command == CMD_PLATFORM) {
kiss_indicate_platform();
} else if (command == CMD_MCU) {
kiss_indicate_mcu();
} else if (command == CMD_CONF_SAVE) { } else if (command == CMD_CONF_SAVE) {
eeprom_conf_save(); eeprom_conf_save();
} else if (command == CMD_CONF_DELETE) { } else if (command == CMD_CONF_DELETE) {
@ -562,18 +595,31 @@ void checkModemStatus() {
} }
void validateStatus() { void validateStatus() {
if (OPTIBOOT_MCUSR & (1<<PORF)) { #if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
uint8_t boot_flags = OPTIBOOT_MCUSR;
uint8_t F_POR = PORF;
uint8_t F_BOR = BORF;
uint8_t F_WDR = WDRF;
#elif MCU_VARIANT == MCU_ESP32
// TODO: Get ESP32 boot flags
uint8_t boot_flags = 0x02;
uint8_t F_POR = 0x00;
uint8_t F_BOR = 0x00;
uint8_t F_WDR = 0x01;
#endif
if (boot_flags & (1<<F_POR)) {
boot_vector = START_FROM_POWERON; boot_vector = START_FROM_POWERON;
} else if (OPTIBOOT_MCUSR & (1<<BORF)) { } else if (boot_flags & (1<<F_BOR)) {
boot_vector = START_FROM_BROWNOUT; boot_vector = START_FROM_BROWNOUT;
} else if (OPTIBOOT_MCUSR & (1<<WDRF)) { } else if (boot_flags & (1<<F_WDR)) {
boot_vector = START_FROM_BOOTLOADER; boot_vector = START_FROM_BOOTLOADER;
} else { } else {
Serial.write("Error, indeterminate boot vector\r\n"); Serial.write("Error, indeterminate boot vector\r\n");
led_indicate_boot_error(); led_indicate_boot_error();
} }
if (boot_vector == START_FROM_BOOTLOADER) { if (boot_vector == START_FROM_BOOTLOADER || boot_vector == START_FROM_POWERON) {
if (eeprom_lock_set()) { if (eeprom_lock_set()) {
if (eeprom_product_valid() && eeprom_model_valid() && eeprom_hwrev_valid()) { if (eeprom_product_valid() && eeprom_model_valid() && eeprom_hwrev_valid()) {
if (eeprom_checksum_valid()) { if (eeprom_checksum_valid()) {
@ -602,6 +648,13 @@ void loop() {
if (radio_online) { if (radio_online) {
checkModemStatus(); checkModemStatus();
#if MCU_VARIANT == MCU_ESP32
int packet_size = LoRa.parsePacket();
if (packet_size) {
receive_callback(packet_size);
}
#endif
if (queue_height > 0) { if (queue_height > 0) {
if (!dcd_waiting) updateModemStatus(); if (!dcd_waiting) updateModemStatus();
@ -630,14 +683,26 @@ void loop() {
} }
} }
#if MCU_VARIANT == MCU_ESP32
buffer_serial();
#endif
#if MCU_VARIANT != MCU_ESP32
if (!fifo_isempty_locked(&serialFIFO)) serial_poll(); if (!fifo_isempty_locked(&serialFIFO)) serial_poll();
#else
if (!fifo_isempty(&serialFIFO)) serial_poll();
#endif
} }
volatile bool serial_polling = false; volatile bool serial_polling = false;
void serial_poll() { void serial_poll() {
serial_polling = true; serial_polling = true;
#if MCU_VARIANT != MCU_ESP32
while (!fifo_isempty_locked(&serialFIFO)) { while (!fifo_isempty_locked(&serialFIFO)) {
#else
while (!fifo_isempty(&serialFIFO)) {
#endif
char sbyte = fifo_pop(&serialFIFO); char sbyte = fifo_pop(&serialFIFO);
serialCallback(sbyte); serialCallback(sbyte);
} }
@ -645,6 +710,7 @@ void serial_poll() {
serial_polling = false; serial_polling = false;
} }
#define MAX_CYCLES 20 #define MAX_CYCLES 20
void buffer_serial() { void buffer_serial() {
if (!serial_buffering) { if (!serial_buffering) {
@ -654,9 +720,15 @@ void buffer_serial() {
while (c < MAX_CYCLES && Serial.available()) { while (c < MAX_CYCLES && Serial.available()) {
c++; c++;
#if MCU_VARIANT != MCU_ESP32
if (!fifo_isfull_locked(&serialFIFO)) { if (!fifo_isfull_locked(&serialFIFO)) {
fifo_push_locked(&serialFIFO, Serial.read()); fifo_push_locked(&serialFIFO, Serial.read());
} }
#else
if (!fifo_isfull(&serialFIFO)) {
fifo_push(&serialFIFO, Serial.read());
}
#endif
} }
serial_buffering = false; serial_buffering = false;
@ -664,6 +736,7 @@ void buffer_serial() {
} }
void serial_interrupt_init() { void serial_interrupt_init() {
#if MCU_VARIANT == MCU_1284P
TCCR3A = 0; TCCR3A = 0;
TCCR3B = _BV(CS10) | TCCR3B = _BV(CS10) |
_BV(WGM33)| _BV(WGM33)|
@ -673,8 +746,29 @@ void serial_interrupt_init() {
ICR3 = 16000; ICR3 = 16000;
TIMSK3 = _BV(ICIE3); TIMSK3 = _BV(ICIE3);
#elif MCU_VARIANT == MCU_2560
// TODO: This should probably be updated for
// atmega2560 support. Might be source of
// reported issues from snh.
TCCR3A = 0;
TCCR3B = _BV(CS10) |
_BV(WGM33)|
_BV(WGM32);
// Buffer incoming frames every 1ms
ICR3 = 16000;
TIMSK3 = _BV(ICIE3);
#elif MCU_VARIANT == MCU_ESP32
// No interrupt-based polling on ESP32
#endif
} }
ISR(TIMER3_CAPT_vect) { #if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
ISR(TIMER3_CAPT_vect) {
buffer_serial(); buffer_serial();
} }
#endif

5
ROM.h
View File

@ -4,8 +4,13 @@
#define CHECKSUMMED_SIZE 0x0B #define CHECKSUMMED_SIZE 0x0B
#define PRODUCT_RNODE 0x03 #define PRODUCT_RNODE 0x03
#define PRODUCT_HMBRW 0xF0
#define PRODUCT_TBEAM 0xE0
#define MODEL_A4 0xA4 #define MODEL_A4 0xA4
#define MODEL_A9 0xA9 #define MODEL_A9 0xA9
#define MODEL_E4 0xE4
#define MODEL_E9 0xE9
#define MODEL_FF 0xFF
#define ADDR_PRODUCT 0x00 #define ADDR_PRODUCT 0x00
#define ADDR_MODEL 0x01 #define ADDR_MODEL 0x01

View File

@ -1,23 +1,52 @@
#include <EEPROM.h> #include <EEPROM.h>
#include <stddef.h> #include <stddef.h>
#include <util/atomic.h>
#include "LoRa.h" #include "LoRa.h"
#include "ROM.h" #include "ROM.h"
#include "Config.h" #include "Config.h"
#include "Framing.h" #include "Framing.h"
#include "MD5.h" #include "MD5.h"
uint8_t boot_vector = 0x00; #if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
uint8_t OPTIBOOT_MCUSR __attribute__ ((section(".noinit"))); #include <avr/wdt.h>
void resetFlagsInit(void) __attribute__ ((naked)) __attribute__ ((used)) __attribute__ ((section (".init0"))); #include <util/atomic.h>
void resetFlagsInit(void) { #elif MCU_VARIANT == MCU_ESP32
__asm__ __volatile__ ("sts %0, r2\n" : "=m" (OPTIBOOT_MCUSR) :); // TODO: Hard reset on ESP32
} #endif
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); } uint8_t boot_vector = 0x00;
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); } #if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
void led_tx_off() { digitalWrite(pin_led_tx, LOW); } uint8_t OPTIBOOT_MCUSR __attribute__ ((section(".noinit")));
void resetFlagsInit(void) __attribute__ ((naked)) __attribute__ ((used)) __attribute__ ((section (".init0")));
void resetFlagsInit(void) {
__asm__ __volatile__ ("sts %0, r2\n" : "=m" (OPTIBOOT_MCUSR) :);
}
#elif MCU_VARIANT == MCU_ESP32
// TODO: Get ESP32 boot flags
#endif
#if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
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); }
#elif MCU_VARIANT == MCU_ESP32
void led_rx_on() { digitalWrite(pin_led_rx, LOW); }
void led_rx_off() { digitalWrite(pin_led_rx, HIGH); }
void led_tx_on() { digitalWrite(pin_led_tx, LOW); }
void led_tx_off() { digitalWrite(pin_led_tx, HIGH); }
#endif
void hard_reset(void) {
#if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
wdt_enable(WDTO_15MS);
while(true) {
led_tx_on(); led_rx_off();
}
#elif MCU_VARIANT == MCU_ESP32
ESP.restart();
#endif
}
void led_indicate_error(int cycles) { void led_indicate_error(int cycles) {
bool forever = (cycles == 0) ? true : false; bool forever = (cycles == 0) ? true : false;
@ -31,8 +60,8 @@ void led_indicate_error(int cycles) {
delay(100); delay(100);
if (!forever) cycles--; if (!forever) cycles--;
} }
digitalWrite(pin_led_rx, LOW); led_rx_off();
digitalWrite(pin_led_tx, LOW); led_tx_off();
} }
void led_indicate_boot_error() { void led_indicate_boot_error() {
@ -51,35 +80,65 @@ void led_indicate_warning(int cycles) {
cycles = forever ? 1 : cycles; cycles = forever ? 1 : cycles;
digitalWrite(pin_led_tx, HIGH); digitalWrite(pin_led_tx, HIGH);
while(cycles > 0) { while(cycles > 0) {
digitalWrite(pin_led_tx, LOW); led_tx_off();
delay(100); delay(100);
digitalWrite(pin_led_tx, HIGH); led_tx_on();
delay(100); delay(100);
if (!forever) cycles--; if (!forever) cycles--;
} }
digitalWrite(pin_led_tx, LOW); led_tx_off();
} }
void led_indicate_info(int cycles) { #if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
void led_indicate_info(int cycles) {
bool forever = (cycles == 0) ? true : false; bool forever = (cycles == 0) ? true : false;
cycles = forever ? 1 : cycles; cycles = forever ? 1 : cycles;
while(cycles > 0) { while(cycles > 0) {
digitalWrite(pin_led_rx, LOW); led_rx_off();
delay(100); delay(100);
digitalWrite(pin_led_rx, HIGH); led_rx_on();
delay(100); delay(100);
if (!forever) cycles--; if (!forever) cycles--;
} }
digitalWrite(pin_led_rx, LOW); led_rx_off();
} }
#elif MCU_VARIANT == MCU_ESP32
void led_indicate_info(int cycles) {
bool forever = (cycles == 0) ? true : false;
cycles = forever ? 1 : cycles;
while(cycles > 0) {
led_tx_off();
delay(100);
led_tx_on();
delay(100);
if (!forever) cycles--;
}
led_tx_off();
}
#endif
uint8_t led_standby_min = 1;
uint8_t led_standby_max = 40; unsigned long led_standby_ticks = 0;
#if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
uint8_t led_standby_min = 1;
uint8_t led_standby_max = 40;
unsigned long led_standby_wait = 11000;
#elif MCU_VARIANT == MCU_ESP32
uint8_t led_standby_min = 200;
uint8_t led_standby_max = 255;
uint8_t led_notready_min = 0;
uint8_t led_notready_max = 255;
uint8_t led_notready_value = led_notready_min;
int8_t led_notready_direction = 0;
unsigned long led_notready_ticks = 0;
unsigned long led_standby_wait = 4000;
unsigned long led_notready_wait = 150;
#endif
uint8_t led_standby_value = led_standby_min; uint8_t led_standby_value = led_standby_min;
int8_t led_standby_direction = 0; int8_t led_standby_direction = 0;
unsigned long led_standby_ticks = 0;
unsigned long led_standby_wait = 11000; #if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
void led_indicate_standby() { void led_indicate_standby() {
led_standby_ticks++; led_standby_ticks++;
if (led_standby_ticks > led_standby_wait) { if (led_standby_ticks > led_standby_wait) {
led_standby_ticks = 0; led_standby_ticks = 0;
@ -90,11 +149,11 @@ void led_indicate_standby() {
} }
led_standby_value += led_standby_direction; led_standby_value += led_standby_direction;
analogWrite(pin_led_rx, led_standby_value); analogWrite(pin_led_rx, led_standby_value);
digitalWrite(pin_led_tx, 0); led_tx_off();
} }
} }
#elif MCU_VARIANT == MCU_ESP32
void led_indicate_not_ready() { void led_indicate_standby() {
led_standby_ticks++; led_standby_ticks++;
if (led_standby_ticks > led_standby_wait) { if (led_standby_ticks > led_standby_wait) {
led_standby_ticks = 0; led_standby_ticks = 0;
@ -105,9 +164,47 @@ void led_indicate_not_ready() {
} }
led_standby_value += led_standby_direction; led_standby_value += led_standby_direction;
analogWrite(pin_led_tx, led_standby_value); analogWrite(pin_led_tx, led_standby_value);
digitalWrite(pin_led_rx, 0); led_rx_off();
} }
} }
#endif
#if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
void led_indicate_not_ready() {
led_standby_ticks++;
if (led_standby_ticks > led_standby_wait) {
led_standby_ticks = 0;
if (led_standby_value <= led_standby_min) {
led_standby_direction = 1;
} else if (led_standby_value >= led_standby_max) {
led_standby_direction = -1;
}
led_standby_value += led_standby_direction;
analogWrite(pin_led_tx, led_standby_value);
led_rx_off();
}
}
#elif MCU_VARIANT == MCU_ESP32
void led_indicate_not_ready() {
led_notready_ticks++;
if (led_notready_ticks > led_notready_wait) {
led_notready_ticks = 0;
if (led_notready_value <= led_notready_min) {
led_notready_direction = 1;
} else if (led_notready_value >= led_notready_max) {
led_notready_direction = -1;
}
led_notready_value += led_notready_direction;
if (led_notready_value > 128) {
led_tx_on();
} else {
led_tx_off();
}
led_rx_off();
}
}
#endif
void escapedSerialWrite(uint8_t byte) { void escapedSerialWrite(uint8_t byte) {
if (byte == FEND) { Serial.write(FESC); byte = TFEND; } if (byte == FEND) { Serial.write(FESC); byte = TFEND; }
@ -266,6 +363,20 @@ void kiss_indicate_version() {
Serial.write(FEND); Serial.write(FEND);
} }
void kiss_indicate_platform() {
Serial.write(FEND);
Serial.write(CMD_PLATFORM);
Serial.write(PLATFORM);
Serial.write(FEND);
}
void kiss_indicate_mcu() {
Serial.write(FEND);
Serial.write(CMD_MCU);
Serial.write(MCU_VARIANT);
Serial.write(FEND);
}
bool isSplitPacket(uint8_t header) { bool isSplitPacket(uint8_t header) {
return (header & FLAG_SPLIT); return (header & FLAG_SPLIT);
} }
@ -384,9 +495,21 @@ void kiss_dump_eeprom() {
Serial.write(FEND); Serial.write(FEND);
} }
void eeprom_update(int mapped_addr, uint8_t byte) {
#if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
EEPROM.update(mapped_addr, byte);
#elif MCU_VARIANT == MCU_ESP32
if (EEPROM.read(mapped_addr) != byte) {
EEPROM.write(mapped_addr, byte);
EEPROM.commit();
}
#endif
}
void eeprom_write(uint8_t addr, uint8_t byte) { void eeprom_write(uint8_t addr, uint8_t byte) {
if (!eeprom_info_locked() && addr >= 0 && addr < EEPROM_RESERVED) { if (!eeprom_info_locked() && addr >= 0 && addr < EEPROM_RESERVED) {
EEPROM.update(eeprom_addr(addr), byte); eeprom_update(eeprom_addr(addr), byte);
} else { } else {
kiss_indicate_error(ERROR_EEPROM_LOCKED); kiss_indicate_error(ERROR_EEPROM_LOCKED);
} }
@ -394,9 +517,9 @@ void eeprom_write(uint8_t addr, uint8_t byte) {
void eeprom_erase() { void eeprom_erase() {
for (int addr = 0; addr < EEPROM_RESERVED; addr++) { for (int addr = 0; addr < EEPROM_RESERVED; addr++) {
EEPROM.update(eeprom_addr(addr), 0xFF); eeprom_update(eeprom_addr(addr), 0xFF);
} }
while (true) { led_tx_on(); led_rx_off(); } hard_reset();
} }
bool eeprom_lock_set() { bool eeprom_lock_set() {
@ -408,7 +531,8 @@ bool eeprom_lock_set() {
} }
bool eeprom_product_valid() { bool eeprom_product_valid() {
if (EEPROM.read(eeprom_addr(ADDR_PRODUCT)) == PRODUCT_RNODE) { uint8_t rval = EEPROM.read(eeprom_addr(ADDR_PRODUCT));
if (rval == PRODUCT_RNODE || rval == PRODUCT_HMBRW || rval == PRODUCT_TBEAM) {
return true; return true;
} else { } else {
return false; return false;
@ -417,7 +541,7 @@ bool eeprom_product_valid() {
bool eeprom_model_valid() { bool eeprom_model_valid() {
model = EEPROM.read(eeprom_addr(ADDR_MODEL)); model = EEPROM.read(eeprom_addr(ADDR_MODEL));
if (model == MODEL_A4 || model == MODEL_A9) { if (model == MODEL_A4 || model == MODEL_A9 || model == MODEL_FF || model == MODEL_E4 || model == MODEL_E9) {
return true; return true;
} else { } else {
return false; return false;
@ -475,21 +599,21 @@ void eeprom_conf_load() {
void eeprom_conf_save() { void eeprom_conf_save() {
if (hw_ready && radio_online) { if (hw_ready && radio_online) {
EEPROM.update(eeprom_addr(ADDR_CONF_SF), lora_sf); eeprom_update(eeprom_addr(ADDR_CONF_SF), lora_sf);
EEPROM.update(eeprom_addr(ADDR_CONF_CR), lora_cr); eeprom_update(eeprom_addr(ADDR_CONF_CR), lora_cr);
EEPROM.update(eeprom_addr(ADDR_CONF_TXP), lora_txp); eeprom_update(eeprom_addr(ADDR_CONF_TXP), lora_txp);
EEPROM.update(eeprom_addr(ADDR_CONF_BW)+0x00, lora_bw>>24); eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x00, lora_bw>>24);
EEPROM.update(eeprom_addr(ADDR_CONF_BW)+0x01, lora_bw>>16); eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x01, lora_bw>>16);
EEPROM.update(eeprom_addr(ADDR_CONF_BW)+0x02, lora_bw>>8); eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x02, lora_bw>>8);
EEPROM.update(eeprom_addr(ADDR_CONF_BW)+0x03, lora_bw); eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x03, lora_bw);
EEPROM.update(eeprom_addr(ADDR_CONF_FREQ)+0x00, lora_freq>>24); eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x00, lora_freq>>24);
EEPROM.update(eeprom_addr(ADDR_CONF_FREQ)+0x01, lora_freq>>16); eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x01, lora_freq>>16);
EEPROM.update(eeprom_addr(ADDR_CONF_FREQ)+0x02, lora_freq>>8); eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x02, lora_freq>>8);
EEPROM.update(eeprom_addr(ADDR_CONF_FREQ)+0x03, lora_freq); eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x03, lora_freq);
EEPROM.update(eeprom_addr(ADDR_CONF_OK), CONF_OK_BYTE); eeprom_update(eeprom_addr(ADDR_CONF_OK), CONF_OK_BYTE);
led_indicate_info(10); led_indicate_info(10);
} else { } else {
led_indicate_warning(10); led_indicate_warning(10);
@ -497,7 +621,7 @@ void eeprom_conf_save() {
} }
void eeprom_conf_delete() { void eeprom_conf_delete() {
EEPROM.update(eeprom_addr(ADDR_CONF_OK), 0x00); eeprom_update(eeprom_addr(ADDR_CONF_OK), 0x00);
} }
void unlock_rom() { void unlock_rom() {
@ -544,28 +668,31 @@ inline void fifo_flush(FIFOBuffer *f) {
f->head = f->tail; f->head = f->tail;
} }
static inline bool fifo_isempty_locked(const FIFOBuffer *f) { #if MCU_VARIANT != MCU_ESP32
static inline bool fifo_isempty_locked(const FIFOBuffer *f) {
bool result; bool result;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
result = fifo_isempty(f); result = fifo_isempty(f);
} }
return result; return result;
} }
static inline bool fifo_isfull_locked(const FIFOBuffer *f) { static inline bool fifo_isfull_locked(const FIFOBuffer *f) {
bool result; bool result;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
result = fifo_isfull(f); result = fifo_isfull(f);
} }
return result; return result;
} }
static inline void fifo_push_locked(FIFOBuffer *f, unsigned char c) { static inline void fifo_push_locked(FIFOBuffer *f, unsigned char c) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
fifo_push(f, c); fifo_push(f, c);
} }
} }
#endif
/*
static inline unsigned char fifo_pop_locked(FIFOBuffer *f) { static inline unsigned char fifo_pop_locked(FIFOBuffer *f) {
unsigned char c; unsigned char c;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
@ -573,6 +700,7 @@ static inline unsigned char fifo_pop_locked(FIFOBuffer *f) {
} }
return c; return c;
} }
*/
inline void fifo_init(FIFOBuffer *f, unsigned char *buffer, size_t size) { inline void fifo_init(FIFOBuffer *f, unsigned char *buffer, size_t size) {
f->head = f->tail = f->begin = buffer; f->head = f->tail = f->begin = buffer;
@ -622,14 +750,18 @@ inline void fifo16_flush(FIFOBuffer16 *f) {
f->head = f->tail; f->head = f->tail;
} }
static inline bool fifo16_isempty_locked(const FIFOBuffer16 *f) { #if MCU_VARIANT != MCU_ESP32
static inline bool fifo16_isempty_locked(const FIFOBuffer16 *f) {
bool result; bool result;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
result = fifo16_isempty(f); result = fifo16_isempty(f);
} }
return result;
}
return result;
}
#endif
/*
static inline bool fifo16_isfull_locked(const FIFOBuffer16 *f) { static inline bool fifo16_isfull_locked(const FIFOBuffer16 *f) {
bool result; bool result;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
@ -638,6 +770,7 @@ static inline bool fifo16_isfull_locked(const FIFOBuffer16 *f) {
return result; return result;
} }
static inline void fifo16_push_locked(FIFOBuffer16 *f, size_t c) { static inline void fifo16_push_locked(FIFOBuffer16 *f, size_t c) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
fifo16_push(f, c); fifo16_push(f, c);
@ -651,6 +784,7 @@ static inline size_t fifo16_pop_locked(FIFOBuffer16 *f) {
} }
return c; return c;
} }
*/
inline void fifo16_init(FIFOBuffer16 *f, size_t *buffer, size_t size) { inline void fifo16_init(FIFOBuffer16 *f, size_t *buffer, size_t size) {
f->head = f->tail = f->begin = buffer; f->head = f->tail = f->begin = buffer;