1.75 release (incorporate upstream changes)
This commit is contained in:
parent
211dffac12
commit
a5d35c35e5
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1,3 +0,0 @@
|
||||
Radio.cpp merge=ours
|
||||
Radio.hpp merge=ours
|
||||
opencom_xl_firmware.ino merge=ours
|
278
Bluetooth.h
278
Bluetooth.h
@ -29,12 +29,11 @@
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
#include <bluefruit.h>
|
||||
#include <math.h>
|
||||
#define BLE_MTU 512+3
|
||||
BLEUart SerialBT(BLE_MTU);
|
||||
#define BLE_RX_BUF 6144
|
||||
BLEUart SerialBT(BLE_RX_BUF);
|
||||
BLEDis bledis;
|
||||
BLEBas blebas;
|
||||
bool SerialBT_init = false;
|
||||
extern void led_indicate_info(int);
|
||||
#endif
|
||||
|
||||
#define BT_PAIRING_TIMEOUT 35000
|
||||
@ -48,6 +47,8 @@ char bt_da[BT_DEV_ADDR_LEN];
|
||||
char bt_dh[BT_DEV_HASH_LEN];
|
||||
char bt_devname[11];
|
||||
|
||||
extern void led_indicate_info(int);
|
||||
|
||||
#if MCU_VARIANT == MCU_ESP32
|
||||
#if HAS_BLUETOOTH == true
|
||||
|
||||
@ -62,7 +63,7 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
void bt_stop() {
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
if (bt_state != BT_STATE_OFF) {
|
||||
SerialBT.end();
|
||||
bt_allow_pairing = false;
|
||||
@ -71,7 +72,7 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
void bt_start() {
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
if (bt_state == BT_STATE_OFF) {
|
||||
SerialBT.begin(bt_devname);
|
||||
bt_state = BT_STATE_ON;
|
||||
@ -79,7 +80,7 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
void bt_enable_pairing() {
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
if (bt_state == BT_STATE_OFF) bt_start();
|
||||
bt_allow_pairing = true;
|
||||
bt_pairing_started = millis();
|
||||
@ -87,14 +88,14 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
void bt_disable_pairing() {
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
bt_allow_pairing = false;
|
||||
bt_ssp_pin = 0;
|
||||
bt_state = BT_STATE_ON;
|
||||
}
|
||||
|
||||
void bt_pairing_complete(boolean success) {
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
if (success) {
|
||||
bt_disable_pairing();
|
||||
} else {
|
||||
@ -103,7 +104,7 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
void bt_connection_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
if(event == ESP_SPP_SRV_OPEN_EVT) {
|
||||
bt_state = BT_STATE_CONNECTED;
|
||||
cable_state = CABLE_STATE_DISCONNECTED;
|
||||
@ -166,31 +167,42 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
#elif HAS_BLE == true
|
||||
bool bt_setup_hw(); void bt_security_setup();
|
||||
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_disable_pairing() {
|
||||
//display_unblank();
|
||||
bt_allow_pairing = false;
|
||||
bt_ssp_pin = 0;
|
||||
void bt_start() {
|
||||
// Serial.println("BT start");
|
||||
display_unblank();
|
||||
if (bt_state == BT_STATE_OFF) {
|
||||
bt_state = BT_STATE_ON;
|
||||
SerialBT.begin(bt_devname);
|
||||
SerialBT.setTimeout(10);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
void bt_stop() {
|
||||
// Serial.println("BT stop");
|
||||
display_unblank();
|
||||
if (bt_state != BT_STATE_OFF) {
|
||||
bt_allow_pairing = false;
|
||||
bt_state = BT_STATE_OFF;
|
||||
SerialBT.end();
|
||||
}
|
||||
}
|
||||
|
||||
bool bt_confirm_pin_callback(uint32_t pin) {
|
||||
// Serial.printf("Confirm PIN callback: %d\n", pin);
|
||||
bool bt_init() {
|
||||
// Serial.println("BT init");
|
||||
bt_state = BT_STATE_OFF;
|
||||
if (bt_setup_hw()) {
|
||||
if (bt_enabled && !console_active) bt_start();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void bt_debond_all() {
|
||||
@ -202,6 +214,44 @@ char bt_devname[11];
|
||||
free(dev_list);
|
||||
}
|
||||
|
||||
void bt_enable_pairing() {
|
||||
// Serial.println("BT enable pairing");
|
||||
display_unblank();
|
||||
if (bt_state == BT_STATE_OFF) bt_start();
|
||||
|
||||
bt_security_setup();
|
||||
|
||||
bt_allow_pairing = true;
|
||||
bt_pairing_started = millis();
|
||||
bt_state = BT_STATE_PAIRING;
|
||||
bt_ssp_pin = pairing_pin;
|
||||
}
|
||||
|
||||
void bt_disable_pairing() {
|
||||
// Serial.println("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);
|
||||
if (bt_allow_pairing) {
|
||||
bt_ssp_pin = passkey;
|
||||
bt_pairing_started = millis();
|
||||
kiss_indicate_btpin();
|
||||
} else {
|
||||
// Serial.println("Pairing not allowed, re-init");
|
||||
SerialBT.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
bool bt_confirm_pin_callback(uint32_t pin) {
|
||||
// Serial.printf("Confirm PIN callback: %d\n", pin);
|
||||
return true;
|
||||
}
|
||||
|
||||
void bt_update_passkey() {
|
||||
// Serial.println("Updating passkey");
|
||||
pairing_pin = random(899999)+100000;
|
||||
@ -218,31 +268,6 @@ char bt_devname[11];
|
||||
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");
|
||||
@ -257,11 +282,15 @@ char bt_devname[11];
|
||||
if (auth_result.success == true) {
|
||||
// Serial.println("Authentication success");
|
||||
ble_authenticated = true;
|
||||
bt_state = BT_STATE_CONNECTED;
|
||||
if (bt_state == BT_STATE_PAIRING) {
|
||||
// Serial.println("Pairing complete, disconnecting");
|
||||
delay(2000); SerialBT.disconnect();
|
||||
} else { bt_state = BT_STATE_CONNECTED; }
|
||||
} else {
|
||||
// Serial.println("Authentication fail");
|
||||
ble_authenticated = false;
|
||||
bt_state = BT_STATE_ON;
|
||||
bt_update_passkey();
|
||||
bt_security_setup();
|
||||
}
|
||||
bt_allow_pairing = false;
|
||||
@ -269,23 +298,24 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
void bt_connect_callback(BLEServer *server) {
|
||||
// uint16_t conn_id = server->getConnId();
|
||||
uint16_t conn_id = server->getConnId();
|
||||
// Serial.printf("Connected: %d\n", conn_id);
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
ble_authenticated = false;
|
||||
bt_state = BT_STATE_CONNECTED;
|
||||
if (bt_state != BT_STATE_PAIRING) { bt_state = BT_STATE_CONNECTED; }
|
||||
cable_state = CABLE_STATE_DISCONNECTED;
|
||||
}
|
||||
|
||||
void bt_disconnect_callback(BLEServer *server) {
|
||||
// uint16_t conn_id = server->getConnId();
|
||||
uint16_t conn_id = server->getConnId();
|
||||
// Serial.printf("Disconnected: %d\n", conn_id);
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
ble_authenticated = false;
|
||||
bt_state = BT_STATE_ON;
|
||||
}
|
||||
|
||||
bool bt_setup_hw() {
|
||||
// Serial.println("BT setup hw");
|
||||
if (!bt_ready) {
|
||||
if (EEPROM.read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) {
|
||||
bt_enabled = true;
|
||||
@ -317,45 +347,30 @@ char bt_devname[11];
|
||||
} else { return false; }
|
||||
}
|
||||
|
||||
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_security_setup() {
|
||||
// Serial.println("Executing BT security setup");
|
||||
if (pairing_pin == 0) { bt_update_passkey(); }
|
||||
uint32_t passkey = pairing_pin;
|
||||
// Serial.printf("Passkey is %d\n", passkey);
|
||||
|
||||
void bt_stop() {
|
||||
//display_unblank();
|
||||
if (bt_state != BT_STATE_OFF) {
|
||||
bt_allow_pairing = false;
|
||||
bt_state = BT_STATE_OFF;
|
||||
SerialBT.end();
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
bool bt_init() {
|
||||
bt_state = BT_STATE_OFF;
|
||||
if (bt_setup_hw()) {
|
||||
if (bt_enabled && !console_active) bt_start();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
void bt_enable_pairing() {
|
||||
//display_unblank();
|
||||
if (bt_state == BT_STATE_OFF) bt_start();
|
||||
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;
|
||||
|
||||
bt_security_setup();
|
||||
//bt_debond_all();
|
||||
//bt_update_passkey();
|
||||
|
||||
bt_allow_pairing = true;
|
||||
bt_pairing_started = millis();
|
||||
bt_state = BT_STATE_PAIRING;
|
||||
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));
|
||||
}
|
||||
|
||||
void update_bt() {
|
||||
@ -371,15 +386,12 @@ char bt_devname[11];
|
||||
#endif
|
||||
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
uint32_t pairing_pin = 0;
|
||||
|
||||
uint8_t eeprom_read(uint32_t mapped_addr);
|
||||
|
||||
void bt_bond_wipe() {
|
||||
// Delete all bonding data
|
||||
Bluefruit.Periph.clearBonds();
|
||||
led_indicate_info(2);
|
||||
}
|
||||
|
||||
void bt_stop() {
|
||||
// Serial.println("BT Stop");
|
||||
if (bt_state != BT_STATE_OFF) {
|
||||
bt_allow_pairing = false;
|
||||
bt_state = BT_STATE_OFF;
|
||||
@ -387,16 +399,21 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
void bt_disable_pairing() {
|
||||
// Serial.println("BT Disable pairing");
|
||||
bt_allow_pairing = false;
|
||||
pairing_pin = 0;
|
||||
bt_ssp_pin = 0;
|
||||
bt_state = BT_STATE_ON;
|
||||
}
|
||||
|
||||
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);
|
||||
void bt_flush() { if (bt_state == BT_STATE_CONNECTED) { SerialBT.flushTXD(); } }
|
||||
|
||||
void bt_pairing_complete(uint16_t conn_handle, uint8_t auth_status) {
|
||||
// Serial.println("BT pairing complete");
|
||||
BLEConnection* connection = Bluefruit.Connection(conn_handle);
|
||||
if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
|
||||
ble_gap_conn_sec_mode_t security = connection->getSecureMode();
|
||||
// Serial.println("Bonding success");
|
||||
|
||||
// On the NRF52 it is not possible with the Arduino library to reject
|
||||
// requests from devices with no IO capabilities, which would allow
|
||||
@ -413,26 +430,26 @@ char bt_devname[11];
|
||||
// Requires investigation.
|
||||
|
||||
if (security.sm == 1 && security.lv >= 3) {
|
||||
// Serial.println("Auth level success");
|
||||
bt_state = BT_STATE_CONNECTED;
|
||||
cable_state = CABLE_STATE_DISCONNECTED;
|
||||
connection->disconnect();
|
||||
bt_disable_pairing();
|
||||
} else {
|
||||
if (connection->bonded()) {
|
||||
connection->removeBondKey();
|
||||
}
|
||||
// Serial.println("Auth level failure, debonding");
|
||||
if (connection->bonded()) { connection->removeBondKey(); }
|
||||
connection->disconnect();
|
||||
bt_disable_pairing();
|
||||
}
|
||||
} else {
|
||||
bt_ssp_pin = 0;
|
||||
// Serial.println("Bonding failure");
|
||||
connection->disconnect();
|
||||
bt_disable_pairing();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
// Serial.println("Passkey callback");
|
||||
if (bt_allow_pairing) {
|
||||
return true;
|
||||
}
|
||||
@ -440,21 +457,37 @@ char bt_devname[11];
|
||||
}
|
||||
|
||||
void bt_connect_callback(uint16_t conn_handle) {
|
||||
// Serial.println("Connect callback");
|
||||
bt_state = BT_STATE_CONNECTED;
|
||||
cable_state = CABLE_STATE_DISCONNECTED;
|
||||
|
||||
BLEConnection* conn = Bluefruit.Connection(conn_handle);
|
||||
conn->requestPHY(BLE_GAP_PHY_2MBPS);
|
||||
conn->requestMtuExchange(BLE_MTU);
|
||||
conn->requestMtuExchange(512+3);
|
||||
conn->requestDataLengthUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||
void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||
// Serial.println("Disconnect callback");
|
||||
if (reason != BLE_GAP_SEC_STATUS_SUCCESS) {
|
||||
bt_state = BT_STATE_ON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bt_update_passkey() {
|
||||
// Serial.println("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() {
|
||||
// Serial.println("Setup HW");
|
||||
if (!bt_ready) {
|
||||
#if HAS_EEPROM
|
||||
if (EEPROM.read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) {
|
||||
@ -468,6 +501,10 @@ void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||
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);
|
||||
|
||||
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
|
||||
@ -477,6 +514,7 @@ void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||
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
|
||||
@ -504,23 +542,24 @@ void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||
}
|
||||
|
||||
void bt_start() {
|
||||
// Serial.println("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();
|
||||
blebas.begin();
|
||||
|
||||
// Guard to ensure SerialBT service is not duplicated through BT being power cycled
|
||||
if (!SerialBT_init) {
|
||||
SerialBT.bufferTXD(true); // enable buffering
|
||||
|
||||
SerialBT.setPermission(SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM); // enable encryption for BLE serial
|
||||
SerialBT.begin();
|
||||
SerialBT_init = true;
|
||||
}
|
||||
|
||||
blebas.begin();
|
||||
|
||||
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
|
||||
Bluefruit.Advertising.addTxPower();
|
||||
|
||||
@ -538,6 +577,7 @@ void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||
}
|
||||
|
||||
bool bt_init() {
|
||||
// Serial.println("BT init");
|
||||
bt_state = BT_STATE_OFF;
|
||||
if (bt_setup_hw()) {
|
||||
if (bt_enabled && !console_active) bt_start();
|
||||
@ -548,10 +588,24 @@ void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||
}
|
||||
|
||||
void bt_enable_pairing() {
|
||||
// Serial.println("BT enable pairing");
|
||||
if (bt_state == BT_STATE_OFF) bt_start();
|
||||
|
||||
uint32_t pin = bt_get_passkey();
|
||||
char pin_char[6];
|
||||
sprintf(pin_char,"%lu", pin);
|
||||
Bluefruit.Security.setPIN(pin_char);
|
||||
|
||||
bt_allow_pairing = true;
|
||||
bt_pairing_started = millis();
|
||||
bt_state = BT_STATE_PAIRING;
|
||||
kiss_indicate_btpin();
|
||||
}
|
||||
|
||||
void bt_debond_all() {
|
||||
// Delete all bonding data
|
||||
Bluefruit.Periph.clearBonds();
|
||||
led_indicate_info(2);
|
||||
}
|
||||
|
||||
void update_bt() {
|
||||
|
518
Boards.h
518
Boards.h
@ -73,47 +73,50 @@
|
||||
#define MODEL_B3 0xB3 // LilyGO T3 v2.0, 433 MHz
|
||||
#define MODEL_B8 0xB8 // LilyGO T3 v2.0, 868 MHz
|
||||
|
||||
#define PRODUCT_T32_21 0xB1 // T3 v2.1 - sold by LilyGO
|
||||
#define PRODUCT_T32_21 0xB1
|
||||
#define BOARD_LORA32_V2_1 0x37
|
||||
#define MODEL_B4 0xB4 // LilyGO T3 v2.1, 433 MHz
|
||||
#define MODEL_B9 0xB9 // LilyGO T3 v2.1, 868 MHz
|
||||
|
||||
#define BOARD_T3S3 0x42 // T3S3 - sold by LilyGO
|
||||
#define MODEL_A1 0xA1 // T3S3 SX1262 868/915 MHz
|
||||
#define MODEL_AB 0xAB // T3S3 SX1276 868/915 MHz
|
||||
#define MODEL_A5 0xA5 // T3S3 SX1278 433 MHz
|
||||
#define MODEL_AC 0xAC // T3S3 SX1280 2.4 GHz w/ PA
|
||||
|
||||
#define PRODUCT_TECHO 0x15 // LilyGO T-Echo devices
|
||||
#define BOARD_TECHO 0x43
|
||||
#define MODEL_16 0x16 // T-Echo 433 MHz
|
||||
#define MODEL_17 0x17 // T-Echo 868/915 MHz
|
||||
|
||||
|
||||
#define PRODUCT_H32_V2 0xC0 // LoRa32 v2 - sold by Heltec
|
||||
#define PRODUCT_H32_V2 0xC0 // Board code 0x38
|
||||
#define BOARD_HELTEC32_V2 0x38
|
||||
#define MODEL_C4 0xC4 // Heltec Lora32 v2, 433 MHz
|
||||
#define MODEL_C9 0xC9 // Heltec Lora32 v2, 868 MHz
|
||||
|
||||
#define PRODUCT_H32_V3 0xC1 // LoRa32 v3 - sold by Heltec
|
||||
#define PRODUCT_H32_V3 0xC1
|
||||
#define BOARD_HELTEC32_V3 0x3A
|
||||
#define MODEL_C5 0xC5 // Heltec Lora32 v3, 433 MHz
|
||||
#define MODEL_CA 0xCA // Heltec Lora32 v3, 868 MHz
|
||||
|
||||
#define PRODUCT_H_W_PAPER 0xC3
|
||||
#define BOARD_H_W_PAPER 0x3F
|
||||
#define MODEL_C8 0xC8
|
||||
|
||||
#define PRODUCT_RAK4631 0x10 // RAK4631 - sold by RAKWireless
|
||||
#define BOARD_RAK4631 0x51
|
||||
#define MODEL_11 0x11 // RAK4631, 433 MHz
|
||||
#define MODEL_12 0x12 // RAK4631, 868 MHz
|
||||
#define MODEL_13 0x13 // RAK4631, 433MHz with WisBlock SX1280 module (LIBSYS002)
|
||||
#define MODEL_14 0x14 // RAK4631, 868/915 MHz with WisBlock SX1280 module (LIBSYS002)
|
||||
#define MODEL_13 0x13 // RAK4631, 433MHz with WisBlock SX1280 module (LIBSYS002 rev 1.3)
|
||||
#define MODEL_14 0x14 // RAK4631, 868/915 MHz with WisBlock SX1280 module (LIBSYS002 rev 1.3)
|
||||
|
||||
#define PRODUCT_OPENCOM_XL 0x20 // openCom XL - sold by Liberated Embedded Systems
|
||||
#define BOARD_OPENCOM_XL 0x52
|
||||
#define MODEL_21 0x21 // openCom XL, 868/915 MHz
|
||||
#define MODEL_21 0x21 // openCom XL v1, 868/915 MHz
|
||||
|
||||
#define BOARD_E22_ESP32 0x44 // Custom Ebyte E22 board design for meshtastic, source:
|
||||
#define BOARD_E22_ESP32 0x45 // Custom Ebyte E22 board design for meshtastic, source:
|
||||
// https://github.com/NanoVHF/Meshtastic-DIY/blob/main/Schematics/E-Byte_E22/Mesh_Ebyte_E22-XXXM30S.pdf
|
||||
|
||||
#define PRODUCT_HELTEC_T114 0xC2 // Heltec Mesh Node T114
|
||||
#define BOARD_HELTEC_T114 0x3C
|
||||
#define MODEL_C6 0xC6 // Heltec Mesh Node T114, 470-510 MHz
|
||||
#define MODEL_C7 0xC7 // Heltec Mesh Node T114, 863-928 MHz
|
||||
#define MODEL_CB 0xCB // Heltec Mesh Node T114, 863-928 MHz + GPS
|
||||
|
||||
#define PRODUCT_TECHO 0x15 // LilyGO T-Echo devices
|
||||
#define BOARD_TECHO 0x44
|
||||
#define MODEL_16 0x16 // T-Echo 433 MHz
|
||||
#define MODEL_17 0x17 // T-Echo 868/915 MHz
|
||||
|
||||
#define PRODUCT_HMBRW 0xF0
|
||||
#define BOARD_HMBRW 0x32
|
||||
#define BOARD_HUZZAH32 0x34
|
||||
@ -155,11 +158,9 @@
|
||||
#endif
|
||||
|
||||
#if MCU_VARIANT == MCU_ESP32
|
||||
|
||||
// Board models for ESP32 based builds are
|
||||
// defined by the build target in the makefile.
|
||||
// If you are not using make to compile this
|
||||
// firmware, you can manually define model here.
|
||||
// Board models for ESP32 based builds are defined by the build target in
|
||||
// the makefile. If you are not using make to compile this firmware, you
|
||||
// can manually define the model here.
|
||||
//
|
||||
// #define BOARD_MODEL BOARD_GENERIC_ESP32
|
||||
#define CONFIG_UART_BUFFER_SIZE 6144
|
||||
@ -180,7 +181,7 @@
|
||||
#define INTERFACE_COUNT 1
|
||||
const int pin_led_rx = 14;
|
||||
const int pin_led_tx = 32;
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX127X
|
||||
{
|
||||
@ -223,7 +224,7 @@
|
||||
const int pin_led_tx = 4;
|
||||
|
||||
#if BOARD_VARIANT == MODEL_E4 || BOARD_VARIANT == MODEL_E9
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX127X
|
||||
{
|
||||
@ -249,7 +250,8 @@
|
||||
};
|
||||
|
||||
#elif BOARD_VARIANT == MODEL_E3 || BOARD_VARIANT == MODEL_E8
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX126X};
|
||||
#define OCP_TUNED 0x38
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
@ -283,7 +285,7 @@
|
||||
const int pin_led_rx = 14;
|
||||
const int pin_led_tx = 32;
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX127X
|
||||
{
|
||||
@ -293,7 +295,7 @@
|
||||
},
|
||||
};
|
||||
const int8_t interface_pins[INTERFACE_COUNT][10] = {
|
||||
// SX1262
|
||||
// SX127X
|
||||
{
|
||||
4, // pin_ss
|
||||
-1, // pin_sclk
|
||||
@ -370,7 +372,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX127X
|
||||
{
|
||||
@ -400,11 +402,14 @@
|
||||
#define DISPLAY OLED
|
||||
#define HAS_BLUETOOTH true
|
||||
#define HAS_PMU true
|
||||
#define HAS_NP true
|
||||
#define HAS_CONSOLE true
|
||||
#define HAS_EEPROM true
|
||||
#define INTERFACE_COUNT 1
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
|
||||
const int pin_np = 12;
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
|
||||
#if HAS_TCXO == true
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX127X
|
||||
@ -487,7 +492,7 @@
|
||||
const int pin_led_tx = 25;
|
||||
#endif
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX127X
|
||||
{
|
||||
@ -515,6 +520,7 @@
|
||||
#elif BOARD_MODEL == BOARD_HELTEC32_V3
|
||||
#define IS_ESP32S3 true
|
||||
#define HAS_DISPLAY true
|
||||
#define DISPLAY OLED
|
||||
#define HAS_BLUETOOTH false
|
||||
#define HAS_BLE true
|
||||
#define HAS_PMU true
|
||||
@ -525,6 +531,7 @@
|
||||
#define PIN_WAKEUP GPIO_NUM_0
|
||||
#define WAKEUP_LEVEL 0
|
||||
#define INTERFACE_COUNT 1
|
||||
#define OCP_TUNED 0x38
|
||||
|
||||
const int pin_btn_usr1 = 0;
|
||||
|
||||
@ -636,8 +643,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX127X
|
||||
{
|
||||
@ -666,7 +672,7 @@
|
||||
#define IS_ESP32S3 true
|
||||
#define HAS_DISPLAY true
|
||||
#define DISPLAY OLED
|
||||
#define HAS_CONSOLE false
|
||||
#define HAS_CONSOLE true
|
||||
#define HAS_BLUETOOTH false
|
||||
#define HAS_BLE true
|
||||
#define HAS_PMU true
|
||||
@ -754,11 +760,168 @@
|
||||
};
|
||||
#endif
|
||||
|
||||
const int pin_np = 38;
|
||||
const int pin_dac = 25;
|
||||
const int pin_adc = 1;
|
||||
|
||||
const int SD_MISO = 2;
|
||||
const int SD_MOSI = 11;
|
||||
const int SD_CLK = 14;
|
||||
const int SD_CS = 13;
|
||||
|
||||
#if HAS_NP == false
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
const int pin_led_rx = 37;
|
||||
const int pin_led_tx = 37;
|
||||
#else
|
||||
const int pin_led_rx = 37;
|
||||
const int pin_led_tx = 37;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif BOARD_MODEL == BOARD_TDECK
|
||||
#define IS_ESP32S3 true
|
||||
#define HAS_DISPLAY false
|
||||
#define DISPLAY TFT // to be tested...
|
||||
#define HAS_CONSOLE false
|
||||
#define HAS_BLUETOOTH false
|
||||
#define HAS_BLE true
|
||||
#define HAS_PMU true
|
||||
#define HAS_NP false
|
||||
#define HAS_SD false
|
||||
#define HAS_EEPROM true
|
||||
|
||||
#define HAS_INPUT true
|
||||
#define HAS_SLEEP true
|
||||
#define PIN_WAKEUP GPIO_NUM_0
|
||||
#define WAKEUP_LEVEL 0
|
||||
|
||||
const int pin_poweron = 10;
|
||||
const int pin_btn_usr1 = 0;
|
||||
|
||||
const int SD_MISO = 38;
|
||||
const int SD_MOSI = 41;
|
||||
const int SD_CLK = 40;
|
||||
const int SD_CS = 39;
|
||||
|
||||
const int DISPLAY_DC = 11;
|
||||
const int DISPLAY_CS = 12;
|
||||
const int DISPLAY_MISO = 38;
|
||||
const int DISPLAY_MOSI = 41;
|
||||
const int DISPLAY_CLK = 40;
|
||||
const int DISPLAY_BL_PIN = 42;
|
||||
|
||||
#define INTERFACE_COUNT 1
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
false, // DEFAULT_SPI
|
||||
true, // HAS_TCXO
|
||||
true // DIO2_AS_RF_SWITCH
|
||||
},
|
||||
};
|
||||
const uint8_t interface_pins[INTERFACE_COUNT][10] = {
|
||||
// SX1262
|
||||
{
|
||||
9, // pin_ss
|
||||
40, // pin_sclk
|
||||
41, // pin_mosi
|
||||
38, // pin_miso
|
||||
13, // pin_busy
|
||||
45, // pin_dio
|
||||
17, // pin_reset
|
||||
-1, // pin_txen
|
||||
-1, // pin_rxen
|
||||
-1 // pin_tcxo_enable
|
||||
}
|
||||
};
|
||||
|
||||
#if HAS_NP == false
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
const int pin_led_rx = 43;
|
||||
const int pin_led_tx = 43;
|
||||
#else
|
||||
const int pin_led_rx = 43;
|
||||
const int pin_led_tx = 43;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
#define IS_ESP32S3 true
|
||||
#define OCP_TUNED 0x38
|
||||
|
||||
#define HAS_DISPLAY true
|
||||
#define DISPLAY MONO_OLED
|
||||
#define HAS_CONSOLE true
|
||||
#define HAS_BLUETOOTH false
|
||||
#define HAS_BLE true
|
||||
#define HAS_PMU true
|
||||
#define HAS_NP false
|
||||
#define HAS_SD false
|
||||
#define HAS_EEPROM true
|
||||
|
||||
#define HAS_INPUT true
|
||||
#define HAS_SLEEP false
|
||||
|
||||
#define PMU_IRQ 40
|
||||
#define I2C_SCL 41
|
||||
#define I2C_SDA 42
|
||||
|
||||
const int pin_btn_usr1 = 0;
|
||||
|
||||
const int SD_MISO = 37;
|
||||
const int SD_MOSI = 35;
|
||||
const int SD_CLK = 36;
|
||||
const int SD_CS = 47;
|
||||
|
||||
const int IMU_CS = 34;
|
||||
|
||||
#define INTERFACE_COUNT 1
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
false, // DEFAULT_SPI
|
||||
true, // HAS_TCXO
|
||||
true // DIO2_AS_RF_SWITCH
|
||||
},
|
||||
};
|
||||
const uint8_t interface_pins[INTERFACE_COUNT][10] = {
|
||||
// SX1262
|
||||
{
|
||||
10, // pin_ss
|
||||
12, // pin_sclk
|
||||
11, // pin_mosi
|
||||
13, // pin_miso
|
||||
4, // pin_busy
|
||||
1, // pin_dio
|
||||
5, // pin_reset
|
||||
-1, // pin_txen
|
||||
-1, // pin_rxen
|
||||
-1 // pin_tcxo_enable
|
||||
}
|
||||
};
|
||||
|
||||
#if HAS_NP == false
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
const int pin_led_rx = 43;
|
||||
const int pin_led_tx = 43;
|
||||
#else
|
||||
const int pin_led_rx = 43;
|
||||
const int pin_led_tx = 43;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif BOARD_MODEL == BOARD_E22_ESP32
|
||||
#define HAS_DISPLAY true
|
||||
#define DISPLAY OLED
|
||||
// currently there is only support for using one Bluetooth type,
|
||||
// Bluetooth has been chosen over BLE as it is less experimental
|
||||
#define HAS_BLUETOOTH true
|
||||
#define HAS_BLE true
|
||||
//#define HAS_BLE true
|
||||
#define HAS_CONSOLE true
|
||||
#define HAS_SD false
|
||||
#define HAS_EEPROM true
|
||||
@ -772,7 +935,7 @@
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
true, // DEFAULT_SPI
|
||||
false, // DEFAULT_SPI
|
||||
true, // HAS_TCXO
|
||||
true // DIO2_AS_RF_SWITCH
|
||||
},
|
||||
@ -792,144 +955,113 @@
|
||||
-1 // pin_tcxo_enable
|
||||
}
|
||||
};
|
||||
|
||||
#elif BOARD_MODEL == BOARD_TDECK
|
||||
#elif BOARD_MODEL == BOARD_XIAO_S3
|
||||
#define IS_ESP32S3 true
|
||||
#define MODEM SX1262
|
||||
#define DIO2_AS_RF_SWITCH true
|
||||
#define HAS_BUSY true
|
||||
#define HAS_TCXO true
|
||||
|
||||
#define HAS_DISPLAY false
|
||||
#define HAS_CONSOLE false
|
||||
#define HAS_DISPLAY true
|
||||
#define DISPLAY OLED
|
||||
//#define HAS_CONSOLE true
|
||||
#define HAS_BLUETOOTH false
|
||||
#define HAS_BLE true
|
||||
#define HAS_PMU true
|
||||
//#define HAS_PMU true
|
||||
#define HAS_NP false
|
||||
#define HAS_SD false
|
||||
#define HAS_EEPROM true
|
||||
|
||||
#define HAS_INPUT true
|
||||
#define HAS_SLEEP true
|
||||
#define PIN_WAKEUP GPIO_NUM_0
|
||||
#define PIN_WAKEUP GPIO_NUM_21
|
||||
#define WAKEUP_LEVEL 0
|
||||
|
||||
const int pin_poweron = 10;
|
||||
const int pin_btn_usr1 = 0;
|
||||
#define INTERFACE_COUNT 1
|
||||
|
||||
const int pin_cs = 9;
|
||||
const int pin_reset = 17;
|
||||
const int pin_sclk = 40;
|
||||
const int pin_mosi = 41;
|
||||
const int pin_miso = 38;
|
||||
const int pin_tcxo_enable = -1;
|
||||
const int pin_dio = 45;
|
||||
const int pin_busy = 13;
|
||||
// #define PMU_IRQ 40
|
||||
// #define I2C_SCL 41
|
||||
// #define I2C_SDA 42
|
||||
|
||||
const int SD_MISO = 38;
|
||||
const int SD_MOSI = 41;
|
||||
const int SD_CLK = 40;
|
||||
const int SD_CS = 39;
|
||||
// Wio-SX1262 button pulls down GPIO21
|
||||
// THis is shared with the Yellow LED
|
||||
// on the ESP32S3 (also active Low)
|
||||
const int pin_btn_usr1 = 21;
|
||||
|
||||
const int DISPLAY_DC = 11;
|
||||
const int DISPLAY_CS = 12;
|
||||
const int DISPLAY_MISO = 38;
|
||||
const int DISPLAY_MOSI = 41;
|
||||
const int DISPLAY_CLK = 40;
|
||||
const int DISPLAY_BL_PIN = 42;
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
true, // DEFAULT_SPI
|
||||
true, // HAS_TCXO
|
||||
true // DIO2_AS_RF_SWITCH
|
||||
},
|
||||
};
|
||||
const int8_t interface_pins[INTERFACE_COUNT][10] = {
|
||||
// SX1262
|
||||
{
|
||||
41, // pin_ss
|
||||
7, // pin_sclk
|
||||
9, // pin_mosi
|
||||
8, // pin_miso
|
||||
40, // pin_busy
|
||||
39, // pin_dio
|
||||
42, // pin_reset
|
||||
-1, // pin_txen
|
||||
-1, // pin_rxen
|
||||
-1 // pin_tcxo_enable
|
||||
}
|
||||
};
|
||||
|
||||
// const int SD_MISO = 37;
|
||||
// const int SD_MOSI = 35;
|
||||
// const int SD_CLK = 36;
|
||||
// const int SD_CS = 47;
|
||||
|
||||
// const int IMU_CS = 34;
|
||||
|
||||
// HAS LED/tx on Wio board - 48 Hi/ON
|
||||
// LED 21 on ESP board - Lo/ON/Yellow
|
||||
// shared with button input.
|
||||
#if HAS_NP == false
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
const int pin_led_rx = 43;
|
||||
const int pin_led_tx = 43;
|
||||
const int pin_led_rx = 48;
|
||||
const int pin_led_tx = 48; //47;
|
||||
#else
|
||||
const int pin_led_rx = 43;
|
||||
const int pin_led_tx = 43;
|
||||
const int pin_led_rx = 48;
|
||||
const int pin_led_tx = 48; //47;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
#define IS_ESP32S3 true
|
||||
#define MODEM SX1262
|
||||
#define DIO2_AS_RF_SWITCH true
|
||||
#define HAS_BUSY true
|
||||
#define HAS_TCXO true
|
||||
|
||||
#define HAS_DISPLAY true
|
||||
#define HAS_CONSOLE true
|
||||
#define HAS_BLUETOOTH false
|
||||
#define HAS_BLE true
|
||||
#define HAS_PMU true
|
||||
#define HAS_NP false
|
||||
#define HAS_SD false
|
||||
#define HAS_EEPROM true
|
||||
|
||||
#define HAS_INPUT true
|
||||
#define HAS_SLEEP false
|
||||
|
||||
#define PMU_IRQ 40
|
||||
#define I2C_SCL 41
|
||||
#define I2C_SDA 42
|
||||
|
||||
const int pin_btn_usr1 = 0;
|
||||
|
||||
const int pin_cs = 10;
|
||||
const int pin_reset = 5;
|
||||
const int pin_sclk = 12;
|
||||
const int pin_mosi = 11;
|
||||
const int pin_miso = 13;
|
||||
const int pin_tcxo_enable = -1;
|
||||
const int pin_dio = 1;
|
||||
const int pin_busy = 4;
|
||||
|
||||
const int SD_MISO = 37;
|
||||
const int SD_MOSI = 35;
|
||||
const int SD_CLK = 36;
|
||||
const int SD_CS = 47;
|
||||
|
||||
const int IMU_CS = 34;
|
||||
|
||||
#if HAS_NP == false
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
const int pin_led_rx = 43;
|
||||
const int pin_led_tx = 43;
|
||||
#else
|
||||
const int pin_led_rx = 43;
|
||||
const int pin_led_tx = 43;
|
||||
#error An unsupported ESP32 board was selected. Cannot compile RNode firmware.
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
#define CONFIG_UART_BUFFER_SIZE 6144
|
||||
#define CONFIG_QUEUE_0_SIZE 6144
|
||||
#define CONFIG_QUEUE_MAX_LENGTH 200
|
||||
|
||||
#if BOARD_MODEL == BOARD_TECHO
|
||||
#define VALIDATE_FIRMWARE false
|
||||
#define _PINNUM(port, pin) ((port) * 32 + (pin))
|
||||
#define HAS_INPUT true
|
||||
//#define GPS_BAUD_RATE 115200
|
||||
//#define PIN_GPS_TX 41
|
||||
//#define PIN_GPS_RX 40
|
||||
#define EEPROM_SIZE 296
|
||||
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
|
||||
//#define HAS_EEPROM true
|
||||
//#define HAS_SD true
|
||||
#define HAS_EEPROM false
|
||||
#define HAS_SD false
|
||||
#define HAS_DISPLAY true
|
||||
#define DISPLAY EINK_BW
|
||||
#define DISPLAY_MODEL GxEPD2_154_D67
|
||||
//#define HAS_CONSOLE true
|
||||
//#define HAS_TXCO true
|
||||
//#define HAS_BLE true
|
||||
//#define HAS_PMU true
|
||||
#define CONFIG_UART_BUFFER_SIZE 40000
|
||||
#define BLE_MANUFACTURER "LilyGO"
|
||||
#define BLE_MODEL "T-Echo"
|
||||
#define HAS_CONSOLE false
|
||||
#define HAS_BLE true
|
||||
#define HAS_PMU true
|
||||
#define CONFIG_UART_BUFFER_SIZE 32768
|
||||
#define CONFIG_QUEUE_0_SIZE 6144
|
||||
#define CONFIG_QUEUE_MAX_LENGTH 200
|
||||
//#define BLE_MANUFACTURER "LilyGO"
|
||||
//#define BLE_MODEL "T-Echo"
|
||||
#define INTERFACE_COUNT 1
|
||||
//#define I2C_SDA 26
|
||||
//#define I2C_SCL 27
|
||||
#define CONFIG_QUEUE_1_SIZE 40000
|
||||
#define HAS_BACKLIGHT true
|
||||
// first interface in list is the primary
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX126X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
@ -1008,7 +1140,7 @@
|
||||
#define CONFIG_UART_BUFFER_SIZE 40000 // \todo, does it have to be this big?
|
||||
|
||||
// first interface in list is the primary
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX126X, SX128X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262, SX1280};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
@ -1061,9 +1193,121 @@
|
||||
const int pin_btn_usr1 = 9;
|
||||
const int pin_led_rx = LED_BLUE;
|
||||
const int pin_led_tx = LED_GREEN;
|
||||
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
#define HAS_EEPROM false
|
||||
#define HAS_DISPLAY true
|
||||
#define DISPLAY TFT
|
||||
#define DISPLAY_SCALE_OVERRIDE true
|
||||
#define DISPLAY_SCALE 2
|
||||
#define HAS_BLUETOOTH false
|
||||
#define HAS_BLE true
|
||||
#define HAS_CONSOLE false
|
||||
#define HAS_PMU true
|
||||
#define HAS_NP true
|
||||
#define HAS_SD false
|
||||
#define HAS_TCXO true
|
||||
#define HAS_BUSY true
|
||||
#define HAS_INPUT true
|
||||
#define HAS_SLEEP true
|
||||
#define CONFIG_UART_BUFFER_SIZE 6144
|
||||
#define CONFIG_QUEUE_SIZE 6144
|
||||
#define CONFIG_QUEUE_MAX_LENGTH 200
|
||||
#define EEPROM_SIZE 296
|
||||
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
|
||||
#define BLE_MANUFACTURER "Heltec"
|
||||
#define BLE_MODEL "T114"
|
||||
|
||||
#define PIN_T114_ADC_EN 6
|
||||
#define PIN_VEXT_EN 21
|
||||
|
||||
// LED
|
||||
#define LED_T114_GREEN 3
|
||||
#define PIN_T114_LED 14
|
||||
#define NP_M 1
|
||||
const int pin_np = PIN_T114_LED;
|
||||
|
||||
|
||||
// pins for buttons on Heltec T114
|
||||
const int pin_btn_usr1 = 42;
|
||||
|
||||
const int pin_led_rx = 35;
|
||||
const int pin_led_tx = 35;
|
||||
|
||||
#define PIN_T114_TFT_BLGT 15
|
||||
#define PIN_T114_TFT_EN 3
|
||||
|
||||
// pins for ST7789 display on Heltec T114
|
||||
const int DISPLAY_DC = 12;
|
||||
const int DISPLAY_CS = 11;
|
||||
const int DISPLAY_MISO = 11; // not connected
|
||||
const int DISPLAY_MOSI = 9;
|
||||
const int DISPLAY_CLK = 8;
|
||||
const int DISPLAY_BL_PIN = PIN_T114_TFT_BLGT;
|
||||
const int DISPLAY_RST = 2;
|
||||
|
||||
#define INTERFACE_COUNT 1
|
||||
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
|
||||
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
|
||||
{
|
||||
24, // pin_ss
|
||||
19, // pin_sclk
|
||||
22, // pin_mosi
|
||||
23, // pin_miso
|
||||
17, // pin_busy
|
||||
20, // pin_dio
|
||||
25, // pin_reset
|
||||
-1, // pin_txen
|
||||
-1, // pin_rxen
|
||||
-1 // pin_tcxo_enable
|
||||
}
|
||||
};
|
||||
|
||||
#if BOARD_VARIANT == MODEL_CB
|
||||
#define HAS_GPS true
|
||||
#define GPS_BAUD_RATE 9600
|
||||
#define PIN_GPS_RX 37
|
||||
#define PIN_GPS_TX 39
|
||||
#endif
|
||||
#else
|
||||
#error An unsupported nRF board was selected. Cannot compile RNode firmware.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_SCALE
|
||||
#define DISPLAY_SCALE 1
|
||||
#endif
|
||||
|
||||
#ifndef HAS_BUSY
|
||||
const int pin_busy = -1;
|
||||
#endif
|
||||
|
||||
#ifndef LED_ON
|
||||
#define LED_ON HIGH
|
||||
#endif
|
||||
|
||||
#ifndef LED_OFF
|
||||
#define LED_OFF LOW
|
||||
#endif
|
||||
|
||||
// Default OCP value if not specified
|
||||
// in board configuration
|
||||
#ifndef OCP_TUNED
|
||||
#define OCP_TUNED 0x38
|
||||
#endif
|
||||
|
||||
#ifndef NP_M
|
||||
#define NP_M 0.15
|
||||
#endif
|
||||
#endif
|
||||
|
21
Config.h
21
Config.h
@ -80,12 +80,11 @@
|
||||
bool memory_low = false;
|
||||
uint8_t implicit_l = 0;
|
||||
|
||||
uint8_t packet_interface = 0xFF;
|
||||
|
||||
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;
|
||||
@ -110,8 +109,21 @@
|
||||
uint32_t stat_rx = 0;
|
||||
uint32_t stat_tx = 0;
|
||||
|
||||
unsigned long last_tx = 0;
|
||||
unsigned long last_rx = 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;
|
||||
|
||||
// Power management
|
||||
#define BATTERY_STATE_UNKNOWN 0x00
|
||||
@ -127,6 +139,7 @@
|
||||
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;
|
||||
|
@ -21,7 +21,7 @@ pages-debug:
|
||||
|
||||
sourcepack:
|
||||
@echo Packing firmware sources...
|
||||
zip --junk-paths -r build/pkg/rnode_firmware.zip ../arduino-cli.yaml ../src/ble/BLESerial.cpp ../src/ble/BLESerial.h ../Bluetooth.h ../Boards.h ../Config.h ../Console.h ../Device.h ../Display.h ../Framing.h ../Graphics.h .../Input.h ../Interfaces.h ../LICENSE ../Makefile ../src/misc/FIFOBuffer.c ../src/misc/FIFOBuffer.h ../src/misc/MD5.cpp ../src/misc/MD5.h ../partition_hashes ../Power.h ../README.md ../release_hashes.py ../RNode_Firmware_CE.ino ../ROM.h ../Radio.cpp ../Radio.hpp ../Utilities.h ../esp32_btbufs.py
|
||||
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
|
||||
|
||||
data:
|
||||
@echo Including assets...
|
||||
@ -29,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/
|
||||
|
@ -4,17 +4,20 @@ import sys
|
||||
import shutil
|
||||
|
||||
packages = {
|
||||
"rns": "rns-0.8.2-py3-none-any.whl",
|
||||
"nomadnet": "nomadnet-0.5.4-py3-none-any.whl",
|
||||
"lxmf": "lxmf-0.5.5-py3-none-any.whl",
|
||||
"rnsh": "rnsh-0.1.4-py3-none-any.whl",
|
||||
"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",
|
||||
}
|
||||
|
||||
DEFAULT_TITLE = "RNode Bootstrap Console"
|
||||
SOURCES_PATH="./source"
|
||||
BUILD_PATH="./build"
|
||||
PACKAGES_PATH = "../../dist_archive"
|
||||
|
||||
# These paths may have to be changed depending on where you store these directories on your system
|
||||
PACKAGES_PATH = "../../../rns_build"
|
||||
RNS_SOURCE_PATH = "../../Reticulum"
|
||||
|
||||
INPUT_ENCODING="utf-8"
|
||||
OUTPUT_ENCODING="utf-8"
|
||||
|
||||
@ -174,7 +177,7 @@ mf.write(help_redirect)
|
||||
mf.close()
|
||||
|
||||
def optimise_manual(path):
|
||||
pm = 60
|
||||
pm = 45
|
||||
scale_imgs = [
|
||||
("_images/board_rnodev2.png", pm),
|
||||
("_images/board_rnode.png", pm),
|
||||
|
@ -2,7 +2,6 @@
|
||||
[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.
|
||||
@ -31,10 +30,9 @@ 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** 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 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 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** interrupt signal *from* the chip.
|
||||
- The module must also expose the *reset* line of the chip, and provide the **DIO0** (or other relevant) 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.
|
||||
@ -56,12 +54,17 @@ 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` file of the [RNode Firmware]({ASSET_PATH}pkg/rnode_firmware.zip).
|
||||
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).
|
||||
|
||||
## 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).
|
||||
### 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:
|
||||
|
||||
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.
|
||||
|
||||
```txt
|
||||
pip install rns
|
||||
```
|
||||
|
||||
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!
|
||||
|
||||
@ -73,24 +76,6 @@ 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
|
||||
|
54
Device.h
54
Device.h
@ -36,6 +36,8 @@
|
||||
#define APPLICATION_START 0x26000
|
||||
|
||||
#define USER_DATA_START 0xED000
|
||||
|
||||
#define IMG_SIZE_START 0xFF008
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -141,37 +143,12 @@ void device_save_firmware_hash() {
|
||||
}
|
||||
|
||||
#if MCU_VARIANT == MCU_NRF52
|
||||
#define FW_LENGTH_LEN 4
|
||||
|
||||
#if MCU_VARIANT == MCU_NRF52
|
||||
void set_fw_length(uint8_t* length_array) {
|
||||
fw_length_file.open(FW_LENGTH_FILE, FILE_O_WRITE);
|
||||
|
||||
fw_length_file.seek(0);
|
||||
|
||||
fw_length_file.write(length_array, FW_LENGTH_LEN);
|
||||
|
||||
fw_length_file.close();
|
||||
|
||||
hard_reset();
|
||||
}
|
||||
|
||||
unsigned long get_fw_length() {
|
||||
fw_length_file.open(FW_LENGTH_FILE, FILE_O_READ);
|
||||
|
||||
// If file doesn't exist yet
|
||||
if (!fw_length_file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t length_array[4];
|
||||
|
||||
fw_length_file.read(length_array, 4);
|
||||
|
||||
unsigned long length = (length_array[0] << 24) | (length_array[1] << 16) | (length_array[2] << 8) | length_array[3];
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
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,
|
||||
@ -184,13 +161,9 @@ 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 ) {
|
||||
const void* src = (const void*)start;
|
||||
if (start + CHUNK_SIZE >= end) {
|
||||
size = end - start;
|
||||
@ -201,15 +174,10 @@ void calculate_region_hash(unsigned long long start, unsigned long long end, uin
|
||||
|
||||
memcpy(chunk, src, CHUNK_SIZE);
|
||||
|
||||
if (application) {
|
||||
for (int i = 0; i < CHUNK_SIZE; i++) {
|
||||
// do nothing
|
||||
}
|
||||
hash.update(chunk, size);
|
||||
length += size;
|
||||
|
||||
start += CHUNK_SIZE;
|
||||
}
|
||||
}
|
||||
hash.end(return_hash);
|
||||
}
|
||||
#endif
|
||||
@ -229,7 +197,7 @@ 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+get_fw_length(), dev_firmware_hash);
|
||||
calculate_region_hash(APPLICATION_START, APPLICATION_START+retrieve_application_size(), dev_firmware_hash);
|
||||
#endif
|
||||
for (uint8_t i = 0; i < DEV_HASH_LEN; i++) {
|
||||
if (dev_firmware_hash_target[i] != dev_firmware_hash[i]) {
|
||||
|
281
Display.h
281
Display.h
@ -135,38 +135,41 @@ void busyCallback(const void* p) {
|
||||
|
||||
#include "Graphics.h"
|
||||
|
||||
#if BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL
|
||||
#if BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL || BOARD_MODEL == BOARD_H_W_PAPER
|
||||
#if DISPLAY == EINK_BW
|
||||
GxEPD2_BW<DISPLAY_MODEL, DISPLAY_MODEL::HEIGHT> display(DISPLAY_MODEL(pin_disp_cs, pin_disp_dc, pin_disp_reset, pin_disp_busy));
|
||||
float disp_target_fps = 0.2;
|
||||
float disp_target_fps = 0.5;
|
||||
uint32_t last_epd_refresh = 0;
|
||||
uint32_t last_epd_full_refresh = 0;
|
||||
#define REFRESH_PERIOD 300000 // 5 minutes in ms
|
||||
#elif DISPLAY == EINK_3C
|
||||
GxEPD2_3C<DISPLAY_MODEL, DISPLAY_MODEL::HEIGHT> display(DISPLAY_MODEL(pin_disp_cs, pin_disp_dc, pin_disp_reset, pin_disp_busy));
|
||||
float disp_target_fps = 0.05; // refresh usually takes longer on 3C, hence this is 4x the BW refresh period
|
||||
float disp_target_fps = 0.05; // refresh usually takes longer on 3C
|
||||
uint32_t last_epd_refresh = 0;
|
||||
uint32_t last_epd_full_refresh = 0;
|
||||
#define REFRESH_PERIOD 600000 // 10 minutes in ms
|
||||
#endif
|
||||
#elif BOARD_MODEL == BOARD_TECHO
|
||||
GxEPD2_BW<DISPLAY_MODEL, DISPLAY_MODEL::HEIGHT> display(DISPLAY_MODEL(pin_disp_cs, pin_disp_dc, pin_disp_reset, pin_disp_busy));
|
||||
float disp_target_fps = 0.2;
|
||||
uint32_t last_epd_refresh = 0;
|
||||
uint32_t last_epd_full_refresh = 0;
|
||||
#define REFRESH_PERIOD 300000 // 5 minutes in ms
|
||||
#else
|
||||
#if DISPLAY == OLED
|
||||
#if BOARD_MODEL == BOARD_TDECK
|
||||
Adafruit_SSD1306 display(DISP_W, DISP_H, &Wire, DISP_RST);
|
||||
#elif BOARD_MODEL == BOARD_TDECK
|
||||
Adafruit_ST7789 display = Adafruit_ST7789(DISPLAY_CS, DISPLAY_DC, -1);
|
||||
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
Adafruit_SH1106G display = Adafruit_SH1106G(DISP_W, DISP_H, &Wire, -1);
|
||||
#else
|
||||
Adafruit_SSD1306 display(DISP_W, DISP_H, &Wire, DISP_RST);
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
ST7789Spi display(&SPI1, DISPLAY_RST, DISPLAY_DC, DISPLAY_CS);
|
||||
#endif
|
||||
float disp_target_fps = 7;
|
||||
#define SCREENSAVER_TIME 500 // ms
|
||||
uint32_t last_screensaver = 0;
|
||||
#define SCREENSAVER_INTERVAL 600000 // 10 minutes in ms
|
||||
bool screensaver_enabled = false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DISP_MODE_UNKNOWN 0x00
|
||||
@ -178,9 +181,14 @@ uint8_t disp_mode = DISP_MODE_UNKNOWN;
|
||||
uint8_t disp_ext_fb = false;
|
||||
unsigned char fb[512];
|
||||
uint32_t last_disp_update = 0;
|
||||
bool display_tx = false;
|
||||
uint32_t last_unblank_event = 0;
|
||||
uint32_t display_blanking_timeout = DISPLAY_BLANKING_TIMEOUT;
|
||||
uint8_t display_unblank_intensity = display_intensity;
|
||||
bool display_blanked = false;
|
||||
bool display_tx[INTERFACE_COUNT] = {false};
|
||||
bool recondition_display = false;
|
||||
int disp_update_interval = 1000/disp_target_fps;
|
||||
|
||||
int epd_update_interval = 1000/disp_target_fps;
|
||||
uint32_t last_page_flip = 0;
|
||||
uint32_t last_interface_page_flip = 0;
|
||||
int page_interval = 4000;
|
||||
@ -238,7 +246,6 @@ void update_area_positions() {
|
||||
}
|
||||
|
||||
uint8_t display_contrast = 0x00;
|
||||
#if DISPLAY == OLED
|
||||
#if BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
void set_contrast(Adafruit_SH1106G *display, uint8_t value) {
|
||||
}
|
||||
@ -267,13 +274,15 @@ for (int i = 0; i < num; i++) {
|
||||
}
|
||||
level = value;
|
||||
}
|
||||
#elif BOARD_MODEL == BOARD_OPENCOM_XL || BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_H_W_PAPER
|
||||
// no backlight on these displays
|
||||
void set_contrast (void* display, uint8_t contrast) {};
|
||||
#else
|
||||
void set_contrast(Adafruit_SSD1306 *display, uint8_t contrast) {
|
||||
display->ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display->ssd1306_command(contrast);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool display_init() {
|
||||
#if HAS_DISPLAY
|
||||
@ -324,16 +333,39 @@ bool display_init() {
|
||||
display.init(0, true, 10, false, SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
display.setPartialWindow(0, 0, DISP_W, DISP_H);
|
||||
|
||||
// Because refreshing this display can take some time, sometimes serial
|
||||
// commands will be missed. Therefore, during periods where the device is
|
||||
// waiting for the display to update, it will poll the serial buffer to
|
||||
// check for any commands from the host.
|
||||
display.epd2.setBusyCallback(busyCallback);
|
||||
#endif
|
||||
#elif BOARD_MODEL == BOARD_H_W_PAPER
|
||||
pinMode(pin_disp_en, OUTPUT);
|
||||
digitalWrite(pin_disp_en, LOW);
|
||||
display.init(0, true, 10, false, SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
display.setPartialWindow(0, 0, DISP_W, DISP_H);
|
||||
|
||||
display.epd2.setBusyCallback(busyCallback);
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
pinMode(PIN_T114_TFT_EN, OUTPUT);
|
||||
digitalWrite(PIN_T114_TFT_EN, LOW);
|
||||
#elif BOARD_MODEL == BOARD_TECHO
|
||||
display.init(0, true, 10, false, displaySPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
display.setPartialWindow(0, 0, DISP_W, DISP_H);
|
||||
display.epd2.setBusyCallback(busyCallback);
|
||||
#if HAS_BACKLIGHT
|
||||
pinMode(pin_backlight, OUTPUT);
|
||||
analogWrite(pin_backlight, 0);
|
||||
#endif
|
||||
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
Wire.begin(SDA_OLED, SCL_OLED);
|
||||
#elif BOARD_MODEL == BOARD_XIAO_S3
|
||||
Wire.begin(SDA_OLED, SCL_OLED);
|
||||
#endif
|
||||
|
||||
#if HAS_EEPROM
|
||||
uint8_t display_rotation = EEPROM.read(eeprom_addr(ADDR_CONF_DROT));
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
uint8_t display_rotation = eeprom_read(eeprom_addr(ADDR_CONF_DROT));
|
||||
#endif
|
||||
if (display_rotation < 0 or display_rotation > 3) display_rotation = 0xFF;
|
||||
|
||||
#if DISP_CUSTOM_ADDR == true
|
||||
#if HAS_EEPROM
|
||||
uint8_t display_address = EEPROM.read(eeprom_addr(ADDR_CONF_DADR));
|
||||
@ -345,12 +377,37 @@ bool display_init() {
|
||||
uint8_t display_address = DISP_ADDR;
|
||||
#endif
|
||||
|
||||
#if HAS_EEPROM
|
||||
if (EEPROM.read(eeprom_addr(ADDR_CONF_BSET)) == CONF_OK_BYTE) {
|
||||
uint8_t db_timeout = EEPROM.read(eeprom_addr(ADDR_CONF_DBLK));
|
||||
if (db_timeout == 0x00) {
|
||||
display_blanking_enabled = false;
|
||||
} else {
|
||||
display_blanking_enabled = true;
|
||||
display_blanking_timeout = db_timeout*1000;
|
||||
}
|
||||
}
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
if (eeprom_read(eeprom_addr(ADDR_CONF_BSET)) == CONF_OK_BYTE) {
|
||||
uint8_t db_timeout = eeprom_read(eeprom_addr(ADDR_CONF_DBLK));
|
||||
if (db_timeout == 0x00) {
|
||||
display_blanking_enabled = false;
|
||||
} else {
|
||||
display_blanking_enabled = true;
|
||||
display_blanking_timeout = db_timeout*1000;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DISPLAY == EINK_BW || DISPLAY == EINK_3C
|
||||
// don't check if display is actually connected
|
||||
if(false) {
|
||||
#elif BOARD_MODEL == BOARD_TDECK
|
||||
display.init(240, 320);
|
||||
display.setSPISpeed(80e6);
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
display.init();
|
||||
// set white as default pixel colour for Heltec T114
|
||||
display.setRGB(COLOR565(0xFF, 0xFF, 0xFF));
|
||||
if (false) {
|
||||
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
if (!display.begin(display_address, true)) {
|
||||
@ -362,6 +419,11 @@ bool display_init() {
|
||||
#if DISPLAY == OLED
|
||||
set_contrast(&display, display_contrast);
|
||||
#endif
|
||||
if (display_rotation != 0xFF) {
|
||||
// hardcode to portrait for now as rotating display doesn't make sense on this platform
|
||||
disp_mode = DISP_MODE_PORTRAIT;
|
||||
display.setRotation(display_rotation);
|
||||
} else {
|
||||
#if BOARD_MODEL == BOARD_RNODE_NG_20
|
||||
disp_mode = DISP_MODE_PORTRAIT;
|
||||
display.setRotation(3);
|
||||
@ -407,25 +469,48 @@ bool display_init() {
|
||||
disp_mode = DISP_MODE_PORTRAIT;
|
||||
display.setRotation(3);
|
||||
#endif
|
||||
}
|
||||
|
||||
update_area_positions();
|
||||
for (int i = 0; i < INTERFACE_COUNT; i++) {
|
||||
for (int j = 0; j < WATERFALL_SIZE; j++) { waterfall[i][j] = 0; }
|
||||
}
|
||||
|
||||
last_page_flip = millis();
|
||||
|
||||
stat_area.cp437(true);
|
||||
disp_area.cp437(true);
|
||||
display.cp437(true);
|
||||
|
||||
#if MCU_VARIANT != MCU_NRF52
|
||||
#if BOARD_MODEL != BOARD_HELTEC_T114
|
||||
display.cp437(true);
|
||||
#endif
|
||||
|
||||
#if HAS_EEPROM
|
||||
display_intensity = EEPROM.read(eeprom_addr(ADDR_CONF_DINT));
|
||||
#else
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
display_intensity = eeprom_read(eeprom_addr(ADDR_CONF_DINT));
|
||||
#endif
|
||||
display_unblank_intensity = display_intensity;
|
||||
|
||||
#if BOARD_MODEL == BOARD_TECHO
|
||||
#if HAS_BACKLIGHT
|
||||
if (display_intensity == 0) { analogWrite(pin_backlight, 0); }
|
||||
else { analogWrite(pin_backlight, display_intensity); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BOARD_MODEL == BOARD_TDECK
|
||||
display.fillScreen(DISPLAY_BLACK);
|
||||
#endif
|
||||
|
||||
#if BOARD_MODEL == BOARD_HELTEC_T114
|
||||
// Enable backlight led (display is always black without this)
|
||||
fillRect(p_ad_x, p_ad_y, 128, 128, DISPLAY_BLACK);
|
||||
fillRect(p_as_x, p_as_y, 128, 128, DISPLAY_BLACK);
|
||||
pinMode(PIN_T114_TFT_BLGT, OUTPUT);
|
||||
digitalWrite(PIN_T114_TFT_BLGT, LOW);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
@ -691,8 +776,13 @@ void draw_quality_bars(int px, int py) {
|
||||
// Serial.printf("Last SNR: %.2f\n, quality: %.2f\n", snr, quality);
|
||||
}
|
||||
|
||||
#define S_RSSI_MIN -135.0
|
||||
#define S_RSSI_MAX -75.0
|
||||
#if MODEM == SX1280
|
||||
#define S_RSSI_MIN -105.0
|
||||
#define S_RSSI_MAX -65.0
|
||||
#else
|
||||
#define S_RSSI_MIN -135.0
|
||||
#define S_RSSI_MAX -75.0
|
||||
#endif
|
||||
#define S_RSSI_SPAN (S_RSSI_MAX-S_RSSI_MIN)
|
||||
void draw_signal_bars(int px, int py) {
|
||||
int rssi_val = last_rssi;
|
||||
@ -763,12 +853,12 @@ void draw_waterfall(int px, int py) {
|
||||
if (rssi_val < WF_RSSI_MIN) rssi_val = WF_RSSI_MIN;
|
||||
if (rssi_val > WF_RSSI_MAX) rssi_val = WF_RSSI_MAX;
|
||||
int rssi_normalised = ((rssi_val - WF_RSSI_MIN)*(1.0/WF_RSSI_SPAN))*WF_PIXEL_WIDTH;
|
||||
if (display_tx) {
|
||||
if (display_tx[interface_page]) {
|
||||
for (uint8_t i; i < WF_TX_SIZE; i++) {
|
||||
waterfall[interface_page][waterfall_head[interface_page]++] = -1;
|
||||
if (waterfall_head[interface_page] >= WATERFALL_SIZE) waterfall_head[interface_page] = 0;
|
||||
}
|
||||
display_tx = false;
|
||||
display_tx[interface_page] = false;
|
||||
} else {
|
||||
waterfall[interface_page][waterfall_head[interface_page]++] = rssi_normalised;
|
||||
if (waterfall_head[interface_page] >= WATERFALL_SIZE) waterfall_head[interface_page] = 0;
|
||||
@ -899,6 +989,9 @@ void update_stat_area() {
|
||||
}
|
||||
}
|
||||
|
||||
extern char bt_devname[11];
|
||||
extern char bt_dh[16];
|
||||
|
||||
void draw_disp_area() {
|
||||
if (!device_init_done || firmware_update_mode) {
|
||||
uint8_t p_by = 37;
|
||||
@ -1028,6 +1121,14 @@ void draw_disp_area() {
|
||||
disp_area.drawBitmap(32+2, 50, bm_hg_high, 5, 9, DISPLAY_BLACK, DISPLAY_WHITE);
|
||||
#endif
|
||||
|
||||
disp_area.setTextColor(DISPLAY_BLACK); disp_area.setTextSize(2);
|
||||
|
||||
// TODO, for some reason there is a weird artifact at the top of the screen if this line isn't here. Need to investigate.
|
||||
//disp_area.fillRect(0,0,disp_area.width(),8,DISPLAY_WHITE);
|
||||
|
||||
// display device ID on top bar
|
||||
disp_area.setCursor(3, 8); disp_area.printf("OC-XL %02X%02X", bt_dh[14], bt_dh[15]);
|
||||
|
||||
} else {
|
||||
if (device_signatures_ok()) {
|
||||
#if DISP_H == 122
|
||||
@ -1041,6 +1142,11 @@ void draw_disp_area() {
|
||||
#else
|
||||
disp_area.drawBitmap(0, 0, bm_def, disp_area.width(), 37, DISPLAY_WHITE, DISPLAY_BLACK);
|
||||
#endif
|
||||
|
||||
// display device ID beneath header
|
||||
disp_area.setFont(SMALL_FONT); disp_area.setTextWrap(false); disp_area.setCursor(15, 60); disp_area.setTextColor(DISPLAY_WHITE); disp_area.setTextSize(4);
|
||||
disp_area.printf("%02X%02X", bt_dh[14], bt_dh[15]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1187,60 +1293,133 @@ void update_disp_area() {
|
||||
}
|
||||
}
|
||||
|
||||
void do_screensaver(uint32_t current){
|
||||
void display_recondition() {
|
||||
#if DISPLAY == OLED
|
||||
// Invert display to protect against OLED screen burn in
|
||||
//TODO: Make this a option configurable through rnodeconf
|
||||
//TODO: Implement other ways to do the screensaver, such as scrolling the screen.
|
||||
if (screensaver_enabled) {
|
||||
if (current-last_screensaver >= SCREENSAVER_INTERVAL+SCREENSAVER_TIME) {
|
||||
display.invertDisplay(0);
|
||||
last_screensaver = current;
|
||||
screensaver_enabled = false;
|
||||
for (uint8_t iy = 0; iy < disp_area.height(); iy++) {
|
||||
unsigned char rand_seg [] = {random(0xFF),random(0xFF),random(0xFF),random(0xFF),random(0xFF),random(0xFF),random(0xFF),random(0xFF)};
|
||||
stat_area.drawBitmap(0, iy, rand_seg, 64, 1, DISPLAY_WHITE, DISPLAY_BLACK);
|
||||
disp_area.drawBitmap(0, iy, rand_seg, 64, 1, DISPLAY_WHITE, DISPLAY_BLACK);
|
||||
}
|
||||
}
|
||||
else if (current-last_screensaver >= SCREENSAVER_INTERVAL) {
|
||||
display.invertDisplay(1);
|
||||
screensaver_enabled = true;
|
||||
|
||||
display.drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), DISPLAY_WHITE, DISPLAY_BLACK);
|
||||
if (disp_mode == DISP_MODE_PORTRAIT) {
|
||||
display.drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), DISPLAY_WHITE, DISPLAY_BLACK);
|
||||
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
|
||||
display.drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), DISPLAY_WHITE, DISPLAY_BLACK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool epd_blanked = false;
|
||||
#if DISPLAY == EINK_3C || DISPLAY == EINK_BW
|
||||
void epd_blank(bool full_update = true) {
|
||||
display.setFullWindow();
|
||||
display.fillScreen(DISPLAY_WHITE);
|
||||
display.display(full_update);
|
||||
}
|
||||
|
||||
void epd_black(bool full_update = true) {
|
||||
display.setFullWindow();
|
||||
display.fillScreen(DISPLAY_BLACK);
|
||||
display.display(full_update);
|
||||
}
|
||||
#endif
|
||||
|
||||
void update_display(bool blank = false) {
|
||||
#if DISPLAY == OLED
|
||||
display_updating = true;
|
||||
if (blank == true) {
|
||||
last_disp_update = millis()-disp_update_interval-1;
|
||||
} else {
|
||||
if (display_blanking_enabled && millis()-last_unblank_event >= display_blanking_timeout) {
|
||||
blank = true;
|
||||
display_blanked = true;
|
||||
if (display_intensity != 0) {
|
||||
display_unblank_intensity = display_intensity;
|
||||
}
|
||||
display_intensity = 0;
|
||||
} else {
|
||||
display_blanked = false;
|
||||
if (display_unblank_intensity != 0x00) {
|
||||
display_intensity = display_unblank_intensity;
|
||||
display_unblank_intensity = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blank) {
|
||||
if (millis()-last_disp_update >= disp_update_interval) {
|
||||
if (display_contrast != display_intensity) {
|
||||
display_contrast = display_intensity;
|
||||
set_contrast(&display, display_contrast);
|
||||
}
|
||||
display.clearDisplay();
|
||||
|
||||
#if DISPLAY == EINK_3C || DISPLAY == EINK_BW
|
||||
if (!epd_blanked) {
|
||||
epd_blank();
|
||||
epd_blanked = true;
|
||||
}
|
||||
#endif
|
||||
if (blank) {
|
||||
|
||||
#if BOARD_MODEL == BOARD_HELTEC_T114
|
||||
display.clear();
|
||||
display.display();
|
||||
#elif BOARD_MODEL != BOARD_TDECK && DISPLAY != EINK_3C && DISPLAY != EINK_BW
|
||||
display.clearDisplay();
|
||||
display.display();
|
||||
#else
|
||||
// TODO: Clear screen
|
||||
#endif
|
||||
|
||||
last_disp_update = millis();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (millis()-last_disp_update >= disp_update_interval) {
|
||||
uint32_t current = millis();
|
||||
do_screensaver(current);
|
||||
if (display_contrast != display_intensity) {
|
||||
display_contrast = display_intensity;
|
||||
set_contrast(&display, display_contrast);
|
||||
}
|
||||
|
||||
#if BOARD_MODEL == BOARD_HELTEC_T114
|
||||
display.clear();
|
||||
#elif BOARD_MODEL != BOARD_TDECK && DISPLAY != EINK_3C && DISPLAY != EINK_BW
|
||||
display.clearDisplay();
|
||||
#endif
|
||||
|
||||
if (recondition_display) {
|
||||
disp_target_fps = 30;
|
||||
disp_update_interval = 1000/disp_target_fps;
|
||||
display_recondition();
|
||||
} else {
|
||||
#if DISPLAY == EINK_BW || DISPLAY == EINK_3C
|
||||
display.setFullWindow();
|
||||
display.fillScreen(DISPLAY_WHITE);
|
||||
#endif
|
||||
|
||||
update_stat_area();
|
||||
update_disp_area();
|
||||
#if DISPLAY == OLED
|
||||
}
|
||||
|
||||
#if DISPLAY == EINK_BW || DISPLAY == EINK_3C
|
||||
if (current-last_epd_refresh >= epd_update_interval) {
|
||||
if (current-last_epd_full_refresh >= REFRESH_PERIOD) { display.display(false); last_epd_full_refresh = millis(); }
|
||||
else { display.display(true); }
|
||||
last_epd_refresh = millis();
|
||||
epd_blanked = false;
|
||||
}
|
||||
#elif BOARD_MODEL != BOARD_TDECK
|
||||
display.display();
|
||||
#else
|
||||
if (current-last_epd_refresh >= REFRESH_PERIOD) {
|
||||
// Perform a full refresh after the correct time has elapsed
|
||||
display.display(false);
|
||||
last_epd_refresh = current;
|
||||
} else {
|
||||
// Only perform a partial refresh
|
||||
display.display(true);
|
||||
}
|
||||
#endif
|
||||
last_disp_update = current;
|
||||
|
||||
last_disp_update = millis();
|
||||
}
|
||||
}
|
||||
display_updating = false;
|
||||
}
|
||||
|
||||
void display_unblank() {
|
||||
last_unblank_event = millis();
|
||||
}
|
||||
|
||||
void ext_fb_enable() {
|
||||
|
50
Framing.h
50
Framing.h
@ -44,6 +44,7 @@
|
||||
#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
|
||||
|
||||
@ -51,12 +52,17 @@
|
||||
#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_UNPAIR 0x70
|
||||
#define CMD_BT_PIN 0x62
|
||||
#define CMD_DIS_IA 0x69
|
||||
|
||||
#define CMD_BOARD 0x47
|
||||
#define CMD_PLATFORM 0x48
|
||||
@ -75,35 +81,16 @@
|
||||
#define ROM_UNLOCK_BYTE 0xF8
|
||||
#define CMD_RESET 0x55
|
||||
#define CMD_RESET_BYTE 0xF8
|
||||
#define CMD_FW_LENGTH 0x65
|
||||
|
||||
#define CMD_INTERFACES 0x64
|
||||
|
||||
#define CMD_INT0_DATA 0x00
|
||||
#define CMD_INT1_DATA 0x10
|
||||
#define CMD_INT2_DATA 0x20
|
||||
#define CMD_INT3_DATA 0x70
|
||||
#define CMD_INT4_DATA 0x75
|
||||
#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_DATA 0x00
|
||||
|
||||
#define CMD_SEL_INT0 0x1E
|
||||
#define CMD_SEL_INT1 0x1F
|
||||
#define CMD_SEL_INT2 0x2F
|
||||
#define CMD_SEL_INT3 0x74
|
||||
#define CMD_SEL_INT4 0x7F
|
||||
#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 CMD_SEL_INT 0x1F
|
||||
#define CMD_LOG 0x80
|
||||
#define CMD_TIME 0x81
|
||||
#define CMD_MUX_CHAIN 0x82
|
||||
#define CMD_MUX_DSCVR 0x83
|
||||
|
||||
#define DETECT_REQ 0x73
|
||||
#define DETECT_RESP 0x46
|
||||
@ -124,6 +111,19 @@
|
||||
#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;
|
||||
bool IN_FRAME = false;
|
||||
|
142
Graphics.h
142
Graphics.h
@ -267,77 +267,77 @@ const unsigned char bm_version [] PROGMEM = {
|
||||
};
|
||||
|
||||
const unsigned char bm_def [] PROGMEM = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xcf, 0x70, 0x78, 0x0e, 0x0c, 0x03, 0x07, 0x80, 0x60, 0xff, 0x03, 0x01, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xcf, 0x20, 0x78, 0x0e, 0x0c, 0x07, 0x07, 0x80, 0xe0, 0xff, 0x87, 0x01, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xcf, 0x23, 0x98, 0x7f, 0x1c, 0xff, 0x39, 0x9f, 0xe7, 0x3f, 0xcf, 0x39, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xcf, 0x27, 0x98, 0x7f, 0x3c, 0xff, 0x39, 0x8f, 0xe7, 0x3f, 0xcf, 0x39, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xcf, 0x27, 0x9f, 0x8f, 0x3c, 0xc3, 0x39, 0x81, 0xe7, 0x3f, 0xcf, 0x39, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xce, 0x27, 0x9f, 0x07, 0x1c, 0x03, 0x39, 0x80, 0xe7, 0x3f, 0x87, 0x39, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xc0, 0x27, 0x98, 0x06, 0x0c, 0x03, 0x39, 0x80, 0x60, 0x33, 0x03, 0x01, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xe0, 0x77, 0xfc, 0x0e, 0x1e, 0x07, 0x7d, 0xc0, 0xe0, 0x3f, 0x87, 0x01, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xf0, 0x7c, 0x07, 0x83, 0xff, 0xc0, 0xff, 0xfc, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xf8, 0x7e, 0x0f, 0xc3, 0xff, 0xe1, 0xff, 0xfc, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xfc, 0x7f, 0x0f, 0xcf, 0xff, 0xf1, 0xff, 0xfc, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xfe, 0x7f, 0x8f, 0xcf, 0xff, 0xf9, 0xff, 0xfc, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x03, 0xf0, 0x7e, 0x7f, 0xff, 0xcf, 0xc1, 0xf9, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xf0, 0x7e, 0x7f, 0xff, 0xcf, 0xc1, 0xf9, 0xf8, 0x7f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xf8, 0x7f, 0xff, 0xcf, 0xc1, 0xf9, 0xf8, 0x3f, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xf8, 0x7f, 0xff, 0xcf, 0xc1, 0xf9, 0xf8, 0x3f, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xf8, 0x7e, 0xff, 0xcf, 0xc1, 0xf9, 0xf8, 0x3f, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xf8, 0x7e, 0x7f, 0xcf, 0xc1, 0xf9, 0xf8, 0x3f, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xf0, 0x7e, 0x7e, 0x3f, 0xcf, 0xc1, 0xf9, 0xf8, 0x7f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xe0, 0x7e, 0x7e, 0x1f, 0xcf, 0xc1, 0xf9, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xe0, 0x7e, 0x7e, 0x0f, 0xcf, 0xff, 0xf9, 0xff, 0xfc, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x03, 0xe0, 0x7e, 0x7e, 0x0f, 0xcf, 0xff, 0xf1, 0xff, 0xfc, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x03, 0xe0, 0x7e, 0x7e, 0x0f, 0xc3, 0xff, 0xe1, 0xff, 0xf0, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x03, 0xe0, 0x3c, 0x3c, 0x07, 0x83, 0xff, 0xc0, 0xff, 0xf0, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x33, 0x26, 0x66, 0x66, 0xcc, 0xcc, 0xd9, 0x99, 0x99, 0x33, 0x33, 0x26, 0x66, 0x66, 0xcc, 0x00,
|
||||
0x0c, 0x89, 0x99, 0x99, 0x33, 0x33, 0x26, 0x66, 0x64, 0x4c, 0xcc, 0xc9, 0x99, 0x99, 0x32, 0x00,
|
||||
0x0c, 0x89, 0x99, 0x99, 0x33, 0x33, 0x26, 0x66, 0x64, 0x4c, 0xcc, 0xc9, 0x99, 0x99, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x70, 0x20, 0x20, 0x81, 0x04, 0x10, 0x40, 0x82, 0x0f, 0x04, 0x04, 0x00,
|
||||
0x00, 0x00, 0x07, 0x80, 0xf0, 0x30, 0x61, 0x81, 0x86, 0x30, 0xc0, 0xc6, 0x1f, 0x86, 0x0c, 0x00,
|
||||
0x00, 0x00, 0x18, 0x41, 0x0c, 0x38, 0xe1, 0xe7, 0x86, 0x30, 0xf0, 0xc6, 0x06, 0x01, 0x10, 0x00,
|
||||
0x00, 0x00, 0x18, 0x41, 0x0c, 0x3c, 0xe1, 0xe7, 0x86, 0x30, 0xf0, 0xc6, 0x06, 0x01, 0x30, 0x00,
|
||||
0x00, 0x00, 0x18, 0x01, 0x0c, 0x33, 0x61, 0x99, 0x86, 0x30, 0xc8, 0xc6, 0x06, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x18, 0x01, 0x0c, 0x32, 0x21, 0x89, 0x86, 0x30, 0xcd, 0xc6, 0x06, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x18, 0x41, 0x0c, 0x30, 0x21, 0x81, 0x86, 0x30, 0xc3, 0xc6, 0x06, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x08, 0x41, 0x0c, 0x30, 0x21, 0x81, 0x86, 0x30, 0xc3, 0xc6, 0x06, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x07, 0x80, 0xf0, 0x30, 0x21, 0x81, 0x81, 0xc0, 0xc0, 0xc6, 0x06, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x70, 0x00, 0x20, 0x80, 0x01, 0xc0, 0x00, 0x82, 0x00, 0x00, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0f, 0xc3, 0x1f, 0x81, 0x81, 0x0c, 0x0c, 0x0e, 0x07, 0xe0, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0e, 0x03, 0x1c, 0x01, 0xc3, 0x0c, 0x0c, 0x00, 0x07, 0x00, 0xe0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x18, 0x61, 0xe7, 0x0c, 0xcc, 0x31, 0x86, 0x18, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0f, 0x83, 0x1f, 0x81, 0xdb, 0x0c, 0xcc, 0x3f, 0x87, 0xe0, 0xf8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0f, 0xc3, 0x1f, 0x81, 0x99, 0x0c, 0xcc, 0x3f, 0x87, 0xe0, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0e, 0x03, 0x1d, 0x81, 0x81, 0x0c, 0xcc, 0x31, 0x87, 0xe0, 0xe0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x19, 0x81, 0x81, 0x0c, 0xcc, 0x21, 0x86, 0x60, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x18, 0x61, 0x81, 0x03, 0x30, 0x21, 0x86, 0x10, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x08, 0x61, 0x81, 0x03, 0x30, 0x20, 0x86, 0x10, 0x7c, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0xff, 0xff, 0x87, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x78, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0xff, 0xff, 0x87, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x78, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0xff, 0xff, 0x87, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x78, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0xff, 0xff, 0x87, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x78, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0x80, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x78, 0x00, 0x00, 0x00,
|
||||
0x07, 0xff, 0xff, 0x87, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x78, 0x7f, 0xff, 0xf8, 0x00,
|
||||
0x07, 0xff, 0xff, 0x87, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x78, 0x7f, 0xff, 0xf8, 0x00,
|
||||
0x07, 0xff, 0xff, 0x87, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x78, 0x7f, 0xff, 0xf8, 0x00,
|
||||
0x07, 0xff, 0xff, 0x87, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x78, 0x7f, 0xff, 0xf8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x33, 0x26, 0x66, 0x66, 0xcc, 0xcc, 0xd9, 0x99, 0x99, 0x33, 0x33, 0x26, 0x66, 0x66, 0xcc, 0x00,
|
||||
0x0c, 0x89, 0x99, 0x99, 0x33, 0x33, 0x26, 0x66, 0x64, 0x4c, 0xcc, 0xc9, 0x99, 0x99, 0x32, 0x00,
|
||||
0x0c, 0x89, 0x99, 0x99, 0x33, 0x33, 0x26, 0x66, 0x64, 0x4c, 0xcc, 0xc9, 0x99, 0x99, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const unsigned char bm_def_lc [] PROGMEM = {
|
||||
|
BIN
Graphics/Bitmaps/bm_def.bmp
Normal file
BIN
Graphics/Bitmaps/bm_def.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
Graphics/Design/bm_def.xcf
Normal file
BIN
Graphics/Design/bm_def.xcf
Normal file
Binary file not shown.
11
Interfaces.h
11
Interfaces.h
@ -1,7 +1,6 @@
|
||||
#define SX127X 0x00
|
||||
#define SX1276 0x01
|
||||
#define SX1278 0x02
|
||||
#define SX126X 0x10
|
||||
#define SX1276 0x00
|
||||
#define SX1278 0x01
|
||||
#define SX1261 0x10
|
||||
#define SX1262 0x11
|
||||
#define SX128X 0x20
|
||||
#define SX1280 0x21
|
||||
#define SX1268 0x12
|
||||
#define SX1280 0x20
|
||||
|
5
ROM.h
5
ROM.h
@ -42,6 +42,11 @@
|
||||
#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 INFO_LOCK_BYTE 0x73
|
||||
#define CONF_OK_BYTE 0x73
|
||||
|
400
Radio.cpp
400
Radio.cpp
@ -5,6 +5,7 @@
|
||||
// Obviously still under the MIT license.
|
||||
|
||||
#include "Radio.hpp"
|
||||
#include "src/misc/ModemISR.h"
|
||||
|
||||
#if PLATFORM == PLATFORM_ESP32
|
||||
#if defined(ESP32) and !defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
@ -91,37 +92,12 @@
|
||||
extern FIFOBuffer packet_rdy_interfaces;
|
||||
extern RadioInterface* interface_obj[];
|
||||
|
||||
// ISRs cannot provide parameters to the functions they call. Since we have
|
||||
// multiple interfaces, we have to read each dio0 pin for each one and see
|
||||
// which one is high. We can then use the index of this pin in the 2D array to
|
||||
// signal the correct interface to the main loop
|
||||
void ISR_VECT onDio0Rise() {
|
||||
BaseType_t int_status = taskENTER_CRITICAL_FROM_ISR();
|
||||
for (int i = 0; i < INTERFACE_COUNT; i++) {
|
||||
if (digitalRead(interface_pins[i][5]) == HIGH) {
|
||||
if (interface_obj[i]->getPacketValidity()) {
|
||||
interface_obj[i]->handleDio0Rise();
|
||||
}
|
||||
if (interfaces[i] == SX128X) {
|
||||
// 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[i]->receive();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL_FROM_ISR(int_status);
|
||||
}
|
||||
|
||||
sx126x::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) :
|
||||
RadioInterface(index),
|
||||
_spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiModem(spi), _ss(ss),
|
||||
_sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0),
|
||||
_busy(busy), _rxen(rxen), _frequency(0), _sf(0x07), _bw(0x04),
|
||||
_cr(0x01), _ldro(0x00), _packetIndex(0), _implicitHeaderMode(0),
|
||||
_busy(busy), _rxen(rxen), _frequency(0), _bw(0x04),
|
||||
_cr(0x01), _packetIndex(0), _implicitHeaderMode(0),
|
||||
_payloadLength(255), _crcMode(1), _fifo_tx_addr_ptr(0),
|
||||
_fifo_rx_addr_ptr(0), _preinit_done(false), _tcxo(tcxo),
|
||||
_dio2_as_rf_switch(dio2_as_rf_switch)
|
||||
@ -217,12 +193,11 @@ void sx126x::loraMode() {
|
||||
|
||||
void sx126x::waitOnBusy() {
|
||||
unsigned long time = millis();
|
||||
if (_busy != -1) {
|
||||
while (digitalRead(_busy) == HIGH)
|
||||
{
|
||||
if (millis() >= (time + 100)) {
|
||||
break;
|
||||
if (millis() >= (time + 100)) { break; }
|
||||
}
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,11 +250,7 @@ void sx126x::writeBuffer(const uint8_t* buffer, size_t size)
|
||||
_spiModem->transfer(OP_FIFO_WRITE_6X);
|
||||
_spiModem->transfer(_fifo_tx_addr_ptr);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
_spiModem->transfer(buffer[i]);
|
||||
_fifo_tx_addr_ptr++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {_spiModem->transfer(buffer[i]); _fifo_tx_addr_ptr++;}
|
||||
|
||||
_spiModem->endTransaction();
|
||||
|
||||
@ -297,10 +268,7 @@ void sx126x::readBuffer(uint8_t* buffer, size_t size)
|
||||
_spiModem->transfer(_fifo_rx_addr_ptr);
|
||||
_spiModem->transfer(0x00);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
buffer[i] = _spiModem->transfer(0x00);
|
||||
}
|
||||
for (int i = 0; i < size; i++) {buffer[i] = _spiModem->transfer(0x00);}
|
||||
|
||||
_spiModem->endTransaction();
|
||||
|
||||
@ -308,7 +276,7 @@ void sx126x::readBuffer(uint8_t* buffer, size_t size)
|
||||
}
|
||||
|
||||
void sx126x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, int ldro) {
|
||||
// because there is no access to these registers on the sx1262, we have
|
||||
// Because there is no access to these registers on the sx1262, we have
|
||||
// to set all these parameters at once or not at all.
|
||||
uint8_t buf[8];
|
||||
|
||||
@ -327,7 +295,7 @@ void sx126x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, int ldro) {
|
||||
}
|
||||
|
||||
void sx126x::setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc) {
|
||||
// because there is no access to these registers on the sx1262, we have
|
||||
// Because there is no access to these registers on the sx1262, we have
|
||||
// to set all these parameters at once or not at all.
|
||||
uint8_t buf[9];
|
||||
|
||||
@ -374,27 +342,11 @@ void sx126x::calibrate(void) {
|
||||
void sx126x::calibrate_image(uint32_t frequency) {
|
||||
uint8_t image_freq[2] = {0};
|
||||
|
||||
if (frequency >= 430E6 && frequency <= 440E6) {
|
||||
image_freq[0] = 0x6B;
|
||||
image_freq[1] = 0x6F;
|
||||
}
|
||||
else if (frequency >= 470E6 && frequency <= 510E6) {
|
||||
image_freq[0] = 0x75;
|
||||
image_freq[1] = 0x81;
|
||||
}
|
||||
else if (frequency >= 779E6 && frequency <= 787E6) {
|
||||
image_freq[0] = 0xC1;
|
||||
image_freq[1] = 0xC5;
|
||||
}
|
||||
else if (frequency >= 863E6 && frequency <= 870E6) {
|
||||
image_freq[0] = 0xD7;
|
||||
image_freq[1] = 0xDB;
|
||||
}
|
||||
else if (frequency >= 902E6 && frequency <= 928E6) {
|
||||
image_freq[0] = 0xE1;
|
||||
image_freq[1] = 0xE9;
|
||||
}
|
||||
|
||||
if (frequency >= 430E6 && frequency <= 440E6) { image_freq[0] = 0x6B; image_freq[1] = 0x6F; }
|
||||
else if (frequency >= 470E6 && frequency <= 510E6) { image_freq[0] = 0x75; image_freq[1] = 0x81; }
|
||||
else if (frequency >= 779E6 && frequency <= 787E6) { image_freq[0] = 0xC1; image_freq[1] = 0xC5; }
|
||||
else if (frequency >= 863E6 && frequency <= 870E6) { image_freq[0] = 0xD7; image_freq[1] = 0xDB; }
|
||||
else if (frequency >= 902E6 && frequency <= 928E6) { image_freq[0] = 0xE1; image_freq[1] = 0xE9; }
|
||||
executeOpcode(OP_CALIBRATE_IMAGE_6X, image_freq, 2);
|
||||
waitOnBusy();
|
||||
}
|
||||
@ -403,9 +355,7 @@ int sx126x::begin()
|
||||
{
|
||||
reset();
|
||||
|
||||
if (_busy != -1) {
|
||||
pinMode(_busy, INPUT);
|
||||
}
|
||||
if (_busy != -1) { pinMode(_busy, INPUT); }
|
||||
|
||||
if (!_preinit_done) {
|
||||
if (!preInit()) {
|
||||
@ -413,9 +363,7 @@ int sx126x::begin()
|
||||
}
|
||||
}
|
||||
|
||||
if (_rxen != -1) {
|
||||
pinMode(_rxen, OUTPUT);
|
||||
}
|
||||
if (_rxen != -1) { pinMode(_rxen, OUTPUT); }
|
||||
|
||||
calibrate();
|
||||
calibrate_image(_frequency);
|
||||
@ -502,21 +450,25 @@ int sx126x::endPacket()
|
||||
|
||||
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2);
|
||||
|
||||
// wait for TX done
|
||||
while ((buf[1] & IRQ_TX_DONE_MASK_6X) == 0) {
|
||||
// Wait for TX done
|
||||
bool timed_out = false;
|
||||
uint32_t w_timeout = millis()+(calculateAirtime(_payloadLength)* MODEM_TIMEOUT_MULT);
|
||||
while ((millis() < w_timeout) && ((buf[1] & IRQ_TX_DONE_MASK_6X) == 0)) {
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x00;
|
||||
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2);
|
||||
yield();
|
||||
}
|
||||
|
||||
if (millis() > w_timeout) { timed_out = true; }
|
||||
|
||||
// clear IRQ's
|
||||
|
||||
uint8_t mask[2];
|
||||
mask[0] = 0x00;
|
||||
mask[1] = IRQ_TX_DONE_MASK_6X;
|
||||
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, mask, 2);
|
||||
return 1;
|
||||
return !timed_out;
|
||||
}
|
||||
|
||||
uint8_t sx126x::modemStatus() {
|
||||
@ -542,7 +494,6 @@ uint8_t sx126x::modemStatus() {
|
||||
return byte;
|
||||
}
|
||||
|
||||
|
||||
uint8_t sx126x::currentRssiRaw() {
|
||||
uint8_t byte = 0;
|
||||
executeOpcodeRead(OP_CURRENT_RSSI_6X, &byte, 1);
|
||||
@ -615,9 +566,7 @@ int ISR_VECT sx126x::available()
|
||||
|
||||
int ISR_VECT sx126x::read()
|
||||
{
|
||||
if (!available()) {
|
||||
return -1;
|
||||
}
|
||||
if (!available()) { return -1; }
|
||||
|
||||
// if received new packet
|
||||
if (_packetIndex == 0) {
|
||||
@ -689,9 +638,9 @@ void sx126x::onReceive(void(*callback)(uint8_t, int))
|
||||
_spiModem->usingInterrupt(digitalPinToInterrupt(_dio0));
|
||||
#endif
|
||||
// make function available
|
||||
extern void onDio0Rise();
|
||||
extern void (*onIntRise[INTERFACE_COUNT])(void);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(_dio0), onDio0Rise, RISING);
|
||||
attachInterrupt(digitalPinToInterrupt(_dio0), onIntRise[_index], RISING);
|
||||
} else {
|
||||
detachInterrupt(digitalPinToInterrupt(_dio0));
|
||||
#ifdef SPI_HAS_NOTUSINGINTERRUPT
|
||||
@ -927,7 +876,7 @@ void sx126x::setPreambleLength(long length)
|
||||
|
||||
void sx126x::setSyncWord(uint16_t sw)
|
||||
{
|
||||
// TODO: Fix
|
||||
// TODO: Why was this hardcoded instead of using the config value?
|
||||
// writeRegister(REG_SYNC_WORD_MSB_6X, (sw & 0xFF00) >> 8);
|
||||
// writeRegister(REG_SYNC_WORD_LSB_6X, sw & 0x00FF);
|
||||
writeRegister(REG_SYNC_WORD_MSB_6X, 0x14);
|
||||
@ -946,7 +895,7 @@ void sx126x::disableCrc()
|
||||
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
|
||||
}
|
||||
|
||||
byte sx126x::random()
|
||||
uint8_t sx126x::random()
|
||||
{
|
||||
return readRegister(REG_RANDOM_GEN_6X);
|
||||
}
|
||||
@ -1619,11 +1568,11 @@ sx128x::sx128x(uint8_t index, SPIClass* spi, bool tcxo, int ss, int sclk, int mo
|
||||
_spiSettings(8E6, MSBFIRST, SPI_MODE0),
|
||||
_spiModem(spi),
|
||||
_ss(ss), _sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0),
|
||||
_busy(busy), _rxen(rxen), _txen(txen), _frequency(0), _sf(0x05),
|
||||
_busy(busy), _rxen(rxen), _txen(txen), _frequency(0),
|
||||
_bw(0x34), _cr(0x01), _packetIndex(0), _implicitHeaderMode(0),
|
||||
_payloadLength(255), _crcMode(0), _fifo_tx_addr_ptr(0), _fifo_rx_addr_ptr(0),
|
||||
_rxPacketLength(0), _preinit_done(false),
|
||||
_tcxo(tcxo), _txp_dc(55)
|
||||
_tcxo(tcxo)
|
||||
{
|
||||
// overide Stream timeout value
|
||||
setTimeout(0);
|
||||
@ -1649,25 +1598,21 @@ bool sx128x::preInit() {
|
||||
_spiModem->begin();
|
||||
#endif
|
||||
|
||||
// check version (retry for up to 2 seconds)
|
||||
// check version (retry for up to 500 ms)
|
||||
long start = millis();
|
||||
|
||||
uint8_t version_msb;
|
||||
uint8_t version_lsb;
|
||||
|
||||
while (((millis() - start) < 2000) && (millis() >= start)) {
|
||||
while (((millis() - start) < 500) && (millis() >= start)) {
|
||||
|
||||
version_msb = readRegister(REG_FIRM_VER_MSB);
|
||||
version_lsb = readRegister(REG_FIRM_VER_LSB);
|
||||
|
||||
if ((version_msb == 0xB7 && version_lsb == 0xA9) || (version_msb == 0xB5 && version_lsb == 0xA9)) {
|
||||
break;
|
||||
}
|
||||
if ((version_msb == 0xB7 && version_lsb == 0xA9) || (version_msb == 0xB5 && version_lsb == 0xA9)) { break; }
|
||||
delay(100);
|
||||
}
|
||||
if ((version_msb != 0xB7 || version_lsb != 0xA9) && (version_msb != 0xB5 || version_lsb != 0xA9)) {
|
||||
return false;
|
||||
}
|
||||
if ((version_msb != 0xB7 || version_lsb != 0xA9) && (version_msb != 0xB5 || version_lsb != 0xA9)) { return false; }
|
||||
|
||||
_preinit_done = true;
|
||||
return true;
|
||||
@ -1695,9 +1640,7 @@ uint8_t ISR_VECT sx128x::singleTransfer(uint8_t opcode, uint16_t address, uint8_
|
||||
_spiModem->transfer(opcode);
|
||||
_spiModem->transfer((address & 0xFF00) >> 8);
|
||||
_spiModem->transfer(address & 0x00FF);
|
||||
if (opcode == OP_READ_REGISTER_8X) {
|
||||
_spiModem->transfer(0x00);
|
||||
}
|
||||
if (opcode == OP_READ_REGISTER_8X) { _spiModem->transfer(0x00); }
|
||||
response = _spiModem->transfer(value);
|
||||
_spiModem->endTransaction();
|
||||
|
||||
@ -1708,38 +1651,17 @@ uint8_t ISR_VECT sx128x::singleTransfer(uint8_t opcode, uint16_t address, uint8_
|
||||
|
||||
void sx128x::rxAntEnable()
|
||||
{
|
||||
if (_txen != -1) {
|
||||
#if BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_21
|
||||
analogWrite(_txen, 0);
|
||||
#else
|
||||
digitalWrite(_txen, LOW);
|
||||
#endif
|
||||
}
|
||||
if (_rxen != -1) {
|
||||
digitalWrite(_rxen, HIGH);
|
||||
}
|
||||
if (_txen != -1) { digitalWrite(_txen, LOW); }
|
||||
if (_rxen != -1) { digitalWrite(_rxen, HIGH); }
|
||||
}
|
||||
|
||||
void sx128x::txAntEnable()
|
||||
{
|
||||
if (_txen != -1) {
|
||||
#if BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_21
|
||||
// RAK4631 with WisBlock SX1280 module (LIBSYS002)
|
||||
// This board needs to use a PWM input in order to scale the power of
|
||||
// the PA output. Undocumented by NiceRF, they have been contacted for
|
||||
// comment. (March 2025)
|
||||
analogWrite(_txen, _txp_dc);
|
||||
#else
|
||||
digitalWrite(_txen, HIGH);
|
||||
#endif
|
||||
}
|
||||
if (_rxen != -1) {
|
||||
digitalWrite(_rxen, LOW);
|
||||
}
|
||||
if (_txen != -1) { digitalWrite(_txen, HIGH); }
|
||||
if (_rxen != -1) { digitalWrite(_rxen, LOW); }
|
||||
}
|
||||
|
||||
void sx128x::loraMode() {
|
||||
// enable lora mode on the SX1262 chip
|
||||
uint8_t mode = MODE_LONG_RANGE_MODE_8X;
|
||||
executeOpcode(OP_PACKET_TYPE_8X, &mode, 1);
|
||||
}
|
||||
@ -1748,10 +1670,7 @@ void sx128x::waitOnBusy() {
|
||||
unsigned long time = millis();
|
||||
while (digitalRead(_busy) == HIGH)
|
||||
{
|
||||
if (millis() >= (time + 100)) {
|
||||
break;
|
||||
}
|
||||
// do nothing
|
||||
if (millis() >= (time + 100)) { break; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1846,37 +1765,38 @@ void sx128x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr) {
|
||||
buf[2] = cr;
|
||||
executeOpcode(OP_MODULATION_PARAMS_8X, buf, 3);
|
||||
|
||||
if (sf <= 6) {
|
||||
writeRegister(0x925, 0x1E);
|
||||
} else if (sf <= 8) {
|
||||
writeRegister(0x925, 0x37);
|
||||
} else if (sf >= 9) {
|
||||
writeRegister(0x925, 0x32);
|
||||
}
|
||||
if (sf <= 6) { writeRegister(0x925, 0x1E); }
|
||||
else if (sf <= 8) { writeRegister(0x925, 0x37); }
|
||||
else if (sf >= 9) { writeRegister(0x925, 0x32); }
|
||||
writeRegister(0x093C, 0x1);
|
||||
}
|
||||
|
||||
void sx128x::setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc) {
|
||||
void sx128x::setPacketParams(uint32_t target_preamble, uint8_t headermode, uint8_t length, uint8_t crc) {
|
||||
// because there is no access to these registers on the sx1280, we have
|
||||
// to set all these parameters at once or not at all.
|
||||
uint8_t buf[7];
|
||||
uint32_t calc_preamble;
|
||||
|
||||
// Cap max preamble length
|
||||
if (target_preamble >= 0xF000) target_preamble = 0xF000;
|
||||
|
||||
if (_last_preamble != target_preamble) {
|
||||
_preamble_e = 1;
|
||||
_preamble_m = 1;
|
||||
// calculate exponent and mantissa values for modem
|
||||
uint8_t e = 1;
|
||||
uint8_t m = 1;
|
||||
uint32_t preamblelen;
|
||||
|
||||
while (e <= 15) {
|
||||
while (m <= 15) {
|
||||
preamblelen = m * (pow(2,e));
|
||||
if (preamblelen >= preamble) break;
|
||||
m++;
|
||||
while (_preamble_e <= 15) {
|
||||
while (_preamble_m <= 15) {
|
||||
calc_preamble = _preamble_m * (pow(2,_preamble_e));
|
||||
if (calc_preamble >= target_preamble - 4) break;
|
||||
_preamble_m++;
|
||||
}
|
||||
if (calc_preamble >= target_preamble - 4) break;
|
||||
_preamble_m = 1;
|
||||
_preamble_e++;
|
||||
}
|
||||
if (preamblelen >= preamble) break;
|
||||
m = 0;
|
||||
e++;
|
||||
}
|
||||
|
||||
buf[0] = (e << 4) | m;
|
||||
buf[0] = (_preamble_e << 4) | _preamble_m;
|
||||
buf[1] = headermode;
|
||||
buf[2] = length;
|
||||
buf[3] = crc;
|
||||
@ -1887,9 +1807,11 @@ void sx128x::setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t leng
|
||||
buf[6] = 0x00;
|
||||
|
||||
executeOpcode(OP_PACKET_PARAMS_8X, buf, 7);
|
||||
|
||||
_last_preamble = target_preamble;
|
||||
}
|
||||
|
||||
int sx128x::begin()
|
||||
void sx128x::reset()
|
||||
{
|
||||
if (_reset != -1) {
|
||||
pinMode(_reset, OUTPUT);
|
||||
@ -1900,6 +1822,11 @@ int sx128x::begin()
|
||||
digitalWrite(_reset, HIGH);
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
int sx128x::begin()
|
||||
{
|
||||
reset();
|
||||
|
||||
if (_rxen != -1) {
|
||||
pinMode(_rxen, OUTPUT);
|
||||
@ -1961,11 +1888,8 @@ int sx128x::beginPacket(int implicitHeader)
|
||||
// put in standby mode
|
||||
standby();
|
||||
|
||||
if (implicitHeader) {
|
||||
implicitHeaderMode();
|
||||
} else {
|
||||
explicitHeaderMode();
|
||||
}
|
||||
if (implicitHeader) { implicitHeaderMode(); }
|
||||
else { explicitHeaderMode(); }
|
||||
|
||||
_payloadLength = 0;
|
||||
_fifo_tx_addr_ptr = 0;
|
||||
@ -1991,14 +1915,17 @@ int sx128x::endPacket()
|
||||
|
||||
executeOpcodeRead(OP_GET_IRQ_STATUS_8X, buf, 2);
|
||||
|
||||
// wait for TX done
|
||||
while ((buf[1] & IRQ_TX_DONE_MASK_8X) == 0) {
|
||||
// Wait for TX done
|
||||
bool timed_out = false;
|
||||
uint32_t w_timeout = millis()+(calculateAirtime(_payloadLength)* MODEM_TIMEOUT_MULT);
|
||||
while ((millis() < w_timeout) && ((buf[1] & IRQ_TX_DONE_MASK_8X) == 0)) {
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x00;
|
||||
executeOpcodeRead(OP_GET_IRQ_STATUS_8X, buf, 2);
|
||||
yield();
|
||||
}
|
||||
|
||||
if (millis() > w_timeout) { timed_out = true; }
|
||||
|
||||
// clear IRQ's
|
||||
|
||||
@ -2006,7 +1933,7 @@ int sx128x::endPacket()
|
||||
mask[0] = 0x00;
|
||||
mask[1] = IRQ_TX_DONE_MASK_8X;
|
||||
executeOpcode(OP_CLEAR_IRQ_STATUS_8X, mask, 2);
|
||||
return 1;
|
||||
return !timed_out;
|
||||
}
|
||||
|
||||
uint8_t sx128x::modemStatus() {
|
||||
@ -2034,7 +1961,6 @@ uint8_t sx128x::modemStatus() {
|
||||
return byte;
|
||||
}
|
||||
|
||||
|
||||
uint8_t sx128x::currentRssiRaw() {
|
||||
uint8_t byte = 0;
|
||||
executeOpcodeRead(OP_CURRENT_RSSI_8X, &byte, 1);
|
||||
@ -2124,9 +2050,7 @@ int ISR_VECT sx128x::read()
|
||||
}
|
||||
_fifo_rx_addr_ptr = rxbuf[1];
|
||||
|
||||
if (size > 255) {
|
||||
size = 255;
|
||||
}
|
||||
if (size > 255) { size = 255; }
|
||||
|
||||
readBuffer(_packet, size);
|
||||
}
|
||||
@ -2138,9 +2062,7 @@ int ISR_VECT sx128x::read()
|
||||
|
||||
int sx128x::peek()
|
||||
{
|
||||
if (!available()) {
|
||||
return -1;
|
||||
}
|
||||
if (!available()) { return -1; }
|
||||
|
||||
uint8_t b = _packet[_packetIndex];
|
||||
return b;
|
||||
@ -2189,9 +2111,9 @@ void sx128x::onReceive(void(*callback)(uint8_t, int))
|
||||
#endif
|
||||
|
||||
// make function available
|
||||
extern void onDio0Rise();
|
||||
extern void (*onIntRise[INTERFACE_COUNT])(void);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(_dio0), onDio0Rise, RISING);
|
||||
attachInterrupt(digitalPinToInterrupt(_dio0), onIntRise[_index], RISING);
|
||||
} else {
|
||||
detachInterrupt(digitalPinToInterrupt(_dio0));
|
||||
#ifdef SPI_HAS_NOTUSINGINTERRUPT
|
||||
@ -2253,150 +2175,100 @@ void sx128x::disableTCXO() {
|
||||
|
||||
void sx128x::setTxPower(int level, int outputPin) {
|
||||
uint8_t tx_buf[2];
|
||||
#if BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_21
|
||||
// RAK4631 with WisBlock SX1280 module (LIBSYS002) The following duty cycle
|
||||
// values assume a battery is in use which has a maximum voltage supply of
|
||||
// 4.2v (each case assumes 3.7v, except 15-20dBm to ensure legal compliance
|
||||
// at all battery voltages), as per the specification for the RAK19001.
|
||||
// Higher voltage batteries may cause your device to operate illegally due
|
||||
// to the resulting increase in transmission power. Beware!
|
||||
|
||||
// TODO: in the future it may be possible to read the battery voltage and
|
||||
// compensate for the lower voltage causing a lower transmit power. Need to
|
||||
// look into this.
|
||||
|
||||
if (level > 25) {
|
||||
level = 25;
|
||||
} else if (level < 0) {
|
||||
level = 0;
|
||||
}
|
||||
#if BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_14 || BOARD_VARIANT == MODEL_21
|
||||
// RAK4631 with WisBlock SX1280 module (LIBSYS002 rev 1.3)
|
||||
// Power range on this model is roughly -6 dBm to 20 dBm
|
||||
if (level > 20) { level = 20; }
|
||||
else if (level < -6) { level = -6; }
|
||||
|
||||
_txp = level;
|
||||
|
||||
int reg_value;
|
||||
|
||||
switch (level) {
|
||||
case -6:
|
||||
reg_value = -18; // -6.3 dBm
|
||||
break;
|
||||
case -5:
|
||||
reg_value = -17; // -5.4 dBm
|
||||
break;
|
||||
case -4:
|
||||
reg_value = -16; // -3.9 dBm
|
||||
break;
|
||||
case -3:
|
||||
reg_value = -15; // -2.9 dBm
|
||||
break;
|
||||
case -2:
|
||||
reg_value = -14; // -2 dBm
|
||||
break;
|
||||
case -1:
|
||||
reg_value = -13; // CANNOT SET, BUG??
|
||||
break;
|
||||
case 0:
|
||||
reg_value = -18;
|
||||
_txp_dc = 131;
|
||||
reg_value = -12; // -0.4 dBm
|
||||
break;
|
||||
case 1:
|
||||
reg_value = -16;
|
||||
_txp_dc = 137;
|
||||
reg_value = -10; // 1.1 dBm
|
||||
break;
|
||||
case 2:
|
||||
reg_value = -15;
|
||||
_txp_dc = 142;
|
||||
reg_value = -9; // 2.4 dBm
|
||||
break;
|
||||
case 3:
|
||||
reg_value = -14;
|
||||
_txp_dc = 148;
|
||||
reg_value = -8; // 3 dBm
|
||||
break;
|
||||
case 4:
|
||||
reg_value = -13;
|
||||
_txp_dc = 154;
|
||||
reg_value = -7; // 4.1 dBm
|
||||
break;
|
||||
case 5:
|
||||
reg_value = -12;
|
||||
_txp_dc = 159;
|
||||
reg_value = -6; // 5.1 dBm
|
||||
break;
|
||||
case 6:
|
||||
reg_value = -11;
|
||||
_txp_dc = 163;
|
||||
reg_value = -5; // 6 dBm
|
||||
break;
|
||||
case 7:
|
||||
reg_value = -9;
|
||||
_txp_dc = 168;
|
||||
reg_value = -4; // 7.3 dBm
|
||||
break;
|
||||
case 8:
|
||||
reg_value = -8;
|
||||
_txp_dc = 174;
|
||||
reg_value = -3; // 8.3 dBm
|
||||
break;
|
||||
case 9:
|
||||
reg_value = -7;
|
||||
_txp_dc = 178;
|
||||
reg_value = -2; // 9.2 dBm
|
||||
break;
|
||||
case 10:
|
||||
reg_value = -6;
|
||||
_txp_dc = 184;
|
||||
reg_value = -1; // 10.3 dBm
|
||||
break;
|
||||
case 11:
|
||||
reg_value = -5;
|
||||
_txp_dc = 189;
|
||||
reg_value = 0; // 11.4 dBm
|
||||
break;
|
||||
case 12:
|
||||
reg_value = -4;
|
||||
_txp_dc = 194;
|
||||
reg_value = 1; // 12.4 dBm
|
||||
break;
|
||||
case 13:
|
||||
reg_value = -3;
|
||||
_txp_dc = 199;
|
||||
reg_value = 2; // 13.5 dBm
|
||||
break;
|
||||
case 14:
|
||||
reg_value = -2;
|
||||
_txp_dc = 199;
|
||||
reg_value = 2; // 13.5 dBm
|
||||
break;
|
||||
case 15:
|
||||
reg_value = -1;
|
||||
// Capped to ensure it doesn't exceed 15dBm
|
||||
_txp_dc = 202;
|
||||
reg_value = 3; // 14.3 dBm
|
||||
break;
|
||||
case 16:
|
||||
reg_value = 0;
|
||||
// Capped to ensure it doesn't exceed 16dBm
|
||||
_txp_dc = 208;
|
||||
reg_value = 5; // 16.4 dBm
|
||||
break;
|
||||
case 17:
|
||||
reg_value = 1;
|
||||
// Capped to ensure it doesn't exceed 17dBm
|
||||
_txp_dc = 214;
|
||||
reg_value = 6; // 17.1 dBm
|
||||
break;
|
||||
case 18:
|
||||
reg_value = 2;
|
||||
// Capped to ensure it doesn't exceed 18dBm
|
||||
_txp_dc = 222;
|
||||
reg_value = 8; // 18.5 dBm
|
||||
break;
|
||||
case 19:
|
||||
reg_value = 3;
|
||||
// Capped to ensure it doesn't exceed 19dBm
|
||||
_txp_dc = 228;
|
||||
reg_value = 10; // 19.2 dBm
|
||||
break;
|
||||
case 20:
|
||||
reg_value = 4;
|
||||
// Capped to ensure it doesn't exceed 20dBm
|
||||
_txp_dc = 234;
|
||||
break;
|
||||
case 21:
|
||||
reg_value = 5;
|
||||
_txp_dc = 247;
|
||||
break;
|
||||
case 22:
|
||||
reg_value = 6;
|
||||
_txp_dc = 254;
|
||||
break;
|
||||
case 23:
|
||||
reg_value = 7;
|
||||
_txp_dc = 255;
|
||||
break;
|
||||
case 24:
|
||||
reg_value = 8;
|
||||
_txp_dc = 255;
|
||||
break;
|
||||
case 25:
|
||||
reg_value = 9;
|
||||
_txp_dc = 255;
|
||||
break;
|
||||
case 26:
|
||||
reg_value = 12;
|
||||
_txp_dc = 255;
|
||||
break;
|
||||
case 27:
|
||||
reg_value = 13;
|
||||
_txp_dc = 255;
|
||||
reg_value = 13; // 20.1 dBm
|
||||
break;
|
||||
default:
|
||||
reg_value = -18;
|
||||
_txp_dc = 131;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2562,7 +2434,8 @@ uint32_t sx128x::getSignalBandwidth()
|
||||
}
|
||||
|
||||
void sx128x::handleLowDataRate(){
|
||||
// todo: do i need this??
|
||||
if (_sf > 10) { _ldro = true; }
|
||||
else { _ldro = false; }
|
||||
}
|
||||
|
||||
void sx128x::optimizeModemSensitivity(){
|
||||
@ -2571,15 +2444,10 @@ void sx128x::optimizeModemSensitivity(){
|
||||
|
||||
void sx128x::setSignalBandwidth(uint32_t sbw)
|
||||
{
|
||||
if (sbw <= 203.125E3) {
|
||||
_bw = 0x34;
|
||||
} else if (sbw <= 406.25E3) {
|
||||
_bw = 0x26;
|
||||
} else if (sbw <= 812.5E3) {
|
||||
_bw = 0x18;
|
||||
} else {
|
||||
_bw = 0x0A;
|
||||
}
|
||||
if (sbw <= 203.125E3) { _bw = 0x34; }
|
||||
else if (sbw <= 406.25E3) { _bw = 0x26; }
|
||||
else if (sbw <= 812.5E3) { _bw = 0x18; }
|
||||
else { _bw = 0x0A; }
|
||||
|
||||
setModulationParams(_sf, _bw, _cr);
|
||||
|
||||
@ -2587,8 +2455,8 @@ void sx128x::setSignalBandwidth(uint32_t sbw)
|
||||
optimizeModemSensitivity();
|
||||
}
|
||||
|
||||
void sx128x::setCodingRate4(int denominator)
|
||||
{
|
||||
void sx128x::setCodingRate4(int denominator) {
|
||||
// TODO: add support for new interleaving scheme, see page 117 of sx1280 datasheet
|
||||
if (denominator < 5) {
|
||||
denominator = 5;
|
||||
} else if (denominator > 8) {
|
||||
|
56
Radio.hpp
56
Radio.hpp
@ -19,6 +19,10 @@
|
||||
#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
|
||||
|
||||
// DCD
|
||||
#define STATUS_INTERVAL_MS 3
|
||||
#define DCD_SAMPLES 2500
|
||||
@ -46,6 +50,8 @@
|
||||
#define _e 2.71828183
|
||||
#define _S 12.5
|
||||
|
||||
#define MODEM_TIMEOUT_MULT 1.5
|
||||
|
||||
// Status flags
|
||||
const uint8_t SIG_DETECT = 0x01;
|
||||
const uint8_t SIG_SYNCED = 0x02;
|
||||
@ -71,7 +77,7 @@ public:
|
||||
// todo: in the future define _spiModem and _spiSettings from here for inheritence by child classes
|
||||
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),
|
||||
_airtime_lock(false), _airtime(0.0), _longterm_airtime(0.0), _last_packet_cost(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),
|
||||
@ -80,7 +86,7 @@ public:
|
||||
_post_tx_yield_timeout(0), _csma_slot_ms(50), _csma_p(85), _csma_p_min(0.15),
|
||||
_csma_p_max(0.333), _csma_b_speed(0.15), _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), _txp(0) {};
|
||||
_packet{0}, _onReceive(NULL), _txp(0), _sf(0x05), _ldro(0) {};
|
||||
virtual int begin() = 0;
|
||||
virtual void end() = 0;
|
||||
|
||||
@ -146,6 +152,36 @@ public:
|
||||
float getSTALock() { return _st_airtime_limit; };
|
||||
void setLTALock(float at) { _lt_airtime_limit = at; };
|
||||
float getLTALock() { return _lt_airtime_limit; };
|
||||
float calculateAirtime(uint16_t written) {
|
||||
float lora_symbols = 0;
|
||||
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;
|
||||
}
|
||||
bool calculateALock() {
|
||||
_airtime_lock = false;
|
||||
if (_st_airtime_limit != 0.0 && _airtime >= _st_airtime_limit) {
|
||||
@ -313,6 +349,7 @@ 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;
|
||||
@ -339,6 +376,8 @@ protected:
|
||||
float _lora_symbol_rate;
|
||||
float _lora_us_per_byte;
|
||||
uint32_t _bitrate;
|
||||
uint8_t _sf;
|
||||
uint8_t _ldro;
|
||||
uint8_t _packet[255];
|
||||
void (*_onReceive)(uint8_t, int);
|
||||
};
|
||||
@ -348,6 +387,8 @@ 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
|
||||
dio0, int busy, int rxen);
|
||||
|
||||
void reset();
|
||||
|
||||
int begin();
|
||||
void end();
|
||||
|
||||
@ -430,7 +471,6 @@ private:
|
||||
void handleLowDataRate();
|
||||
void optimizeModemSensitivity();
|
||||
|
||||
void reset(void);
|
||||
void calibrate(void);
|
||||
void calibrate_image(uint32_t frequency);
|
||||
bool getPacketValidity();
|
||||
@ -447,10 +487,8 @@ private:
|
||||
int _rxen;
|
||||
int _busy;
|
||||
uint32_t _frequency;
|
||||
uint8_t _sf;
|
||||
uint8_t _bw;
|
||||
uint8_t _cr;
|
||||
uint8_t _ldro;
|
||||
int _packetIndex;
|
||||
int _implicitHeaderMode;
|
||||
int _payloadLength;
|
||||
@ -551,7 +589,6 @@ private:
|
||||
int _packetIndex;
|
||||
int _implicitHeaderMode;
|
||||
bool _preinit_done;
|
||||
uint8_t _sf;
|
||||
uint8_t _cr;
|
||||
};
|
||||
|
||||
@ -562,6 +599,8 @@ public:
|
||||
int begin();
|
||||
void end();
|
||||
|
||||
void reset();
|
||||
|
||||
int beginPacket(int implicitHeader = false);
|
||||
int endPacket();
|
||||
|
||||
@ -658,7 +697,6 @@ private:
|
||||
int _busy;
|
||||
int _modem;
|
||||
uint32_t _frequency;
|
||||
uint8_t _sf;
|
||||
uint8_t _bw;
|
||||
uint8_t _cr;
|
||||
int _packetIndex;
|
||||
@ -670,6 +708,8 @@ private:
|
||||
bool _preinit_done;
|
||||
int _rxPacketLength;
|
||||
bool _tcxo;
|
||||
uint8_t _txp_dc;
|
||||
uint8_t _preamble_e;
|
||||
uint8_t _preamble_m;
|
||||
uint32_t _last_preamble;
|
||||
};
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Precompiled Firmware
|
||||
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`:
|
||||
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`:
|
||||
|
||||
```
|
||||
# Install rnodeconf via rns package
|
||||
|
456
Utilities.h
456
Utilities.h
@ -23,15 +23,14 @@
|
||||
#if HAS_EEPROM
|
||||
#include <EEPROM.h>
|
||||
#elif PLATFORM == PLATFORM_NRF52
|
||||
#include <hal/nrf_rng.h>
|
||||
#include <Adafruit_LittleFS.h>
|
||||
#include <InternalFileSystem.h>
|
||||
using namespace Adafruit_LittleFS_Namespace;
|
||||
#define EEPROM_FILE "eeprom"
|
||||
#define FW_LENGTH_FILE "fw_length"
|
||||
bool file_exists = false;
|
||||
int written_bytes = 4;
|
||||
File eeprom_file(InternalFS);
|
||||
File fw_length_file(InternalFS);
|
||||
File file(InternalFS);
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
|
||||
@ -92,10 +91,31 @@ uint8_t boot_vector = 0x00;
|
||||
// TODO: Get NRF52 boot flags
|
||||
#endif
|
||||
|
||||
#if MCU_VARIANT == MCU_NRF52
|
||||
unsigned long get_rng_seed() {
|
||||
nrf_rng_error_correction_enable(NRF_RNG);
|
||||
nrf_rng_shorts_disable(NRF_RNG, NRF_RNG_SHORT_VALRDY_STOP_MASK);
|
||||
nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_START);
|
||||
while (!nrf_rng_event_check(NRF_RNG, NRF_RNG_EVENT_VALRDY));
|
||||
uint8_t rb_a = nrf_rng_random_value_get(NRF_RNG);
|
||||
nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
|
||||
while (!nrf_rng_event_check(NRF_RNG, NRF_RNG_EVENT_VALRDY));
|
||||
uint8_t rb_b = nrf_rng_random_value_get(NRF_RNG);
|
||||
nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
|
||||
while (!nrf_rng_event_check(NRF_RNG, NRF_RNG_EVENT_VALRDY));
|
||||
uint8_t rb_c = nrf_rng_random_value_get(NRF_RNG);
|
||||
nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
|
||||
while (!nrf_rng_event_check(NRF_RNG, NRF_RNG_EVENT_VALRDY));
|
||||
uint8_t rb_d = nrf_rng_random_value_get(NRF_RNG);
|
||||
nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
|
||||
nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP);
|
||||
return rb_a << 24 | rb_b << 16 | rb_c << 8 | rb_d;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_NP == true
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#define NUMPIXELS 1
|
||||
#define NP_M 0.15
|
||||
Adafruit_NeoPixel pixels(NUMPIXELS, pin_np, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
uint8_t npr = 0;
|
||||
@ -109,10 +129,23 @@ uint8_t boot_vector = 0x00;
|
||||
}
|
||||
|
||||
void led_init() {
|
||||
#if BOARD_MODEL == BOARD_HELTEC_T114
|
||||
// Enable vext power supply to neopixel
|
||||
pinMode(PIN_VEXT_EN, OUTPUT);
|
||||
digitalWrite(PIN_VEXT_EN, HIGH);
|
||||
#endif
|
||||
|
||||
#if MCU_VARIANT == MCU_NRF52
|
||||
if (eeprom_read(eeprom_addr(ADDR_CONF_PSET)) == CONF_OK_BYTE) {
|
||||
uint8_t int_val = eeprom_read(eeprom_addr(ADDR_CONF_PINT));
|
||||
led_set_intensity(int_val);
|
||||
}
|
||||
#else
|
||||
if (EEPROM.read(eeprom_addr(ADDR_CONF_PSET)) == CONF_OK_BYTE) {
|
||||
uint8_t int_val = EEPROM.read(eeprom_addr(ADDR_CONF_PINT));
|
||||
led_set_intensity(int_val);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void npset(uint8_t r, uint8_t g, uint8_t b) {
|
||||
@ -149,52 +182,72 @@ uint8_t boot_vector = 0x00;
|
||||
void led_rx_off() { npset(0, 0, 0); }
|
||||
void led_tx_on() { npset(0xFF, 0x50, 0x00); }
|
||||
void led_tx_off() { npset(0, 0, 0); }
|
||||
void led_id_on() { npset(0x90, 0, 0x70); }
|
||||
void led_id_off() { npset(0, 0, 0); }
|
||||
#elif BOARD_MODEL == BOARD_RNODE_NG_20
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_RNODE_NG_21
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_T3S3
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_E22_ESP32
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_TBEAM
|
||||
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, LOW); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_TDECK
|
||||
void led_rx_on() { }
|
||||
void led_rx_off() { }
|
||||
void led_tx_on() { }
|
||||
void led_tx_off() { }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
void led_rx_on() { }
|
||||
void led_rx_off() { }
|
||||
void led_tx_on() { }
|
||||
void led_tx_off() { }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_LORA32_V1_0
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#else
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#endif
|
||||
#elif BOARD_MODEL == BOARD_LORA32_V2_0
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
@ -202,11 +255,15 @@ uint8_t boot_vector = 0x00;
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#else
|
||||
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); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#endif
|
||||
#elif BOARD_MODEL == BOARD_HELTEC32_V2
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
@ -214,49 +271,96 @@ uint8_t boot_vector = 0x00;
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#else
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#endif
|
||||
#elif BOARD_MODEL == BOARD_HELTEC32_V3
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_H_W_PAPER
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_LORA32_V2_1
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_XIAO_S3
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, LED_ON); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LED_OFF); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, LED_ON); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LED_OFF); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_HUZZAH32
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_XIAO_S3
|
||||
void led_rx_on() {}
|
||||
void led_rx_off() {}
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, LED_ON); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LED_OFF); }
|
||||
void led_id_on() {}
|
||||
void led_id_off() {}
|
||||
#elif BOARD_MODEL == BOARD_GENERIC_ESP32
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#endif
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
#if BOARD_MODEL == BOARD_OPENCOM_XL
|
||||
void led_rx_on() { analogWrite(pin_led_rx, 1); }
|
||||
void led_rx_off() { analogWrite(pin_led_rx, 0); }
|
||||
void led_tx_on() { analogWrite(pin_led_tx, 1); }
|
||||
void led_tx_off() { analogWrite(pin_led_tx, 0); }
|
||||
#elif BOARD_MODEL == BOARD_RAK4631
|
||||
#if HAS_NP == true
|
||||
void led_rx_on() { npset(0, 0, 0xFF); }
|
||||
void led_rx_off() { npset(0, 0, 0); }
|
||||
void led_tx_on() { npset(0xFF, 0x50, 0x00); }
|
||||
void led_tx_off() { npset(0, 0, 0); }
|
||||
void led_id_on() { npset(0x90, 0, 0x70); }
|
||||
void led_id_off() { npset(0, 0, 0); }
|
||||
#elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
// Heltec T114 pulls pins LOW to turn on
|
||||
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); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_TECHO
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, LED_ON); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LED_OFF); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, LED_ON); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LED_OFF); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -439,6 +543,8 @@ unsigned long led_standby_ticks = 0;
|
||||
#endif
|
||||
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
int led_standby_lng = 200;
|
||||
int led_standby_cut = 100;
|
||||
uint8_t led_standby_min = 200;
|
||||
uint8_t led_standby_max = 255;
|
||||
uint8_t led_notready_min = 0;
|
||||
@ -453,8 +559,7 @@ unsigned long led_standby_ticks = 0;
|
||||
unsigned long led_standby_value = led_standby_min;
|
||||
int8_t led_standby_direction = 0;
|
||||
|
||||
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
|
||||
#if HAS_NP == true
|
||||
#if HAS_NP == true
|
||||
void led_indicate_standby() {
|
||||
led_standby_ticks++;
|
||||
|
||||
@ -506,11 +611,11 @@ int8_t led_standby_direction = 0;
|
||||
// } else {
|
||||
// led_standby_intensity = led_standby_ti;
|
||||
// }
|
||||
// npset(led_standby_intensity, 0x00, led_standby_intensity);
|
||||
// npset(led_standby_intensity, 0x00, led_standby_intensity);
|
||||
// }
|
||||
}
|
||||
|
||||
#else
|
||||
#else
|
||||
void led_indicate_standby() {
|
||||
led_standby_ticks++;
|
||||
if (led_standby_ticks > led_standby_wait) {
|
||||
@ -522,9 +627,17 @@ int8_t led_standby_direction = 0;
|
||||
}
|
||||
led_standby_value += led_standby_direction;
|
||||
if (led_standby_value > 253) {
|
||||
#if BOARD_MODEL == BOARD_TECHO
|
||||
led_rx_on();
|
||||
#else
|
||||
led_tx_on();
|
||||
#endif
|
||||
} else {
|
||||
#if BOARD_MODEL == BOARD_TECHO
|
||||
led_rx_off();
|
||||
#else
|
||||
led_tx_off();
|
||||
#endif
|
||||
}
|
||||
#if BOARD_MODEL == BOARD_LORA32_V2_1
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
@ -543,12 +656,10 @@ int8_t led_standby_direction = 0;
|
||||
void led_indicate_console() {
|
||||
led_indicate_standby();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
|
||||
#if HAS_NP == true
|
||||
void led_indicate_not_ready() {
|
||||
#if HAS_NP == true
|
||||
void led_indicate_not_ready() {
|
||||
led_standby_ticks++;
|
||||
|
||||
if (led_standby_ticks > led_notready_wait) {
|
||||
@ -575,7 +686,7 @@ int8_t led_standby_direction = 0;
|
||||
npset(led_standby_intensity, 0x00, 0x00);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#else
|
||||
void led_indicate_not_ready() {
|
||||
led_notready_ticks++;
|
||||
if (led_notready_ticks > led_notready_wait) {
|
||||
@ -604,7 +715,6 @@ int8_t led_standby_direction = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -628,13 +738,8 @@ void serial_write(uint8_t byte) {
|
||||
#if MCU_VARIANT == MCU_NRF52 && HAS_BLE
|
||||
// This ensures that the TX buffer is flushed after a frame is queued in serial.
|
||||
// serial_in_frame is used to ensure that the flush only happens at the end of the frame
|
||||
if (serial_in_frame && byte == FEND) {
|
||||
SerialBT.flushTXD();
|
||||
serial_in_frame = false;
|
||||
}
|
||||
else if (!serial_in_frame && byte == FEND) {
|
||||
serial_in_frame = true;
|
||||
}
|
||||
if (serial_in_frame && byte == FEND) { SerialBT.flushTXD(); serial_in_frame = false; }
|
||||
else if (!serial_in_frame && byte == FEND) { serial_in_frame = true; }
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
@ -664,6 +769,10 @@ void kiss_indicate_error(uint8_t error_code) {
|
||||
|
||||
void kiss_indicate_radiostate(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_RADIO_STATE);
|
||||
serial_write(radio->getRadioOnline());
|
||||
serial_write(FEND);
|
||||
@ -691,7 +800,11 @@ void kiss_indicate_stat_tx() {
|
||||
//serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_stat_rssi() {
|
||||
void kiss_indicate_stat_rssi(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
uint8_t packet_rssi_val = (uint8_t)(last_rssi+rssi_offset);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_STAT_RSSI);
|
||||
@ -699,7 +812,11 @@ void kiss_indicate_stat_rssi() {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_stat_snr() {
|
||||
void kiss_indicate_stat_snr(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_STAT_SNR);
|
||||
escaped_serial_write(last_snr_raw);
|
||||
@ -708,6 +825,10 @@ void kiss_indicate_stat_snr() {
|
||||
|
||||
void kiss_indicate_radio_lock(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_RADIO_LOCK);
|
||||
serial_write(radio->getRadioLock());
|
||||
serial_write(FEND);
|
||||
@ -715,6 +836,10 @@ void kiss_indicate_radio_lock(RadioInterface* radio) {
|
||||
|
||||
void kiss_indicate_spreadingfactor(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SF);
|
||||
serial_write(radio->getSpreadingFactor());
|
||||
serial_write(FEND);
|
||||
@ -722,6 +847,10 @@ void kiss_indicate_spreadingfactor(RadioInterface* radio) {
|
||||
|
||||
void kiss_indicate_codingrate(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_CR);
|
||||
serial_write(radio->getCodingRate4());
|
||||
serial_write(FEND);
|
||||
@ -737,6 +866,10 @@ void kiss_indicate_implicit_length() {
|
||||
void kiss_indicate_txpower(RadioInterface* radio) {
|
||||
int8_t txp = radio->getTxPower();
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_TXPOWER);
|
||||
serial_write(txp);
|
||||
serial_write(FEND);
|
||||
@ -745,6 +878,10 @@ void kiss_indicate_txpower(RadioInterface* radio) {
|
||||
void kiss_indicate_bandwidth(RadioInterface* radio) {
|
||||
uint32_t bw = radio->getSignalBandwidth();
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_BANDWIDTH);
|
||||
escaped_serial_write(bw>>24);
|
||||
escaped_serial_write(bw>>16);
|
||||
@ -756,6 +893,10 @@ void kiss_indicate_bandwidth(RadioInterface* radio) {
|
||||
void kiss_indicate_frequency(RadioInterface* radio) {
|
||||
uint32_t freq = radio->getFrequency();
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_FREQUENCY);
|
||||
escaped_serial_write(freq>>24);
|
||||
escaped_serial_write(freq>>16);
|
||||
@ -776,6 +917,10 @@ void kiss_indicate_interface(int index) {
|
||||
void kiss_indicate_st_alock(RadioInterface* radio) {
|
||||
uint16_t at = (uint16_t)(radio->getSTALock()*100*100);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_ST_ALOCK);
|
||||
escaped_serial_write(at>>8);
|
||||
escaped_serial_write(at);
|
||||
@ -785,17 +930,30 @@ void kiss_indicate_st_alock(RadioInterface* radio) {
|
||||
void kiss_indicate_lt_alock(RadioInterface* radio) {
|
||||
uint16_t at = (uint16_t)(radio->getLTALock()*100*100);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_LT_ALOCK);
|
||||
escaped_serial_write(at>>8);
|
||||
escaped_serial_write(at);
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_channel_stats(RadioInterface* radio) {
|
||||
void kiss_indicate_channel_stats(uint8_t index) {
|
||||
RadioInterface* radio = interface_obj[index];
|
||||
int current_rssi = radio->currentRssi();
|
||||
uint16_t ats = (uint16_t)(radio->getAirtime()*100*100);
|
||||
uint16_t atl = (uint16_t)(radio->getLongtermAirtime()*100*100);
|
||||
uint16_t cls = (uint16_t)(radio->getTotalChannelUtil()*100*100);
|
||||
uint16_t cll = (uint16_t)(radio->getLongtermChannelUtil()*100*100);
|
||||
uint8_t crs = (uint8_t)(current_rssi+rssi_offset);
|
||||
//uint8_t nfl = (uint8_t)(radio->getNoiseFloor()+rssi_offset);
|
||||
//uint8_t ntf = 0xFF; if (radio->getInterference()) { ntf = (uint8_t)(current_rssi+rssi_offset); }
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_STAT_CHTM);
|
||||
escaped_serial_write(ats>>8);
|
||||
@ -815,29 +973,42 @@ void kiss_indicate_phy_stats(RadioInterface* radio) {
|
||||
uint16_t prs = (uint16_t)(radio->getPreambleLength()+4);
|
||||
uint16_t prt = (uint16_t)((radio->getPreambleLength()+4)*radio->getSymbolTime());
|
||||
uint16_t cst = (uint16_t)(radio->getCSMASlotMS());
|
||||
//uint16_t dft = (uint16_t)(radio->getDifsMS());
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(radio->getIndex());
|
||||
serial_write(FEND);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_STAT_PHYPRM);
|
||||
escaped_serial_write(lst>>8);
|
||||
escaped_serial_write(lst);
|
||||
escaped_serial_write(lsr>>8);
|
||||
escaped_serial_write(lsr);
|
||||
escaped_serial_write(prs>>8);
|
||||
escaped_serial_write(prs);
|
||||
escaped_serial_write(prt>>8);
|
||||
escaped_serial_write(prt);
|
||||
escaped_serial_write(cst>>8);
|
||||
escaped_serial_write(cst);
|
||||
escaped_serial_write(lst>>8); escaped_serial_write(lst);
|
||||
escaped_serial_write(lsr>>8); escaped_serial_write(lsr);
|
||||
escaped_serial_write(prs>>8); escaped_serial_write(prs);
|
||||
escaped_serial_write(prt>>8); escaped_serial_write(prt);
|
||||
escaped_serial_write(cst>>8); escaped_serial_write(cst);
|
||||
//escaped_serial_write(dft>>8); escaped_serial_write(dft);
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_csma_stats(uint8_t index) {
|
||||
// selected_radio = interface_obj[index];
|
||||
// serial_write(FEND);
|
||||
// serial_write(CMD_SEL_INT);
|
||||
// serial_write(index);
|
||||
// serial_write(FEND);
|
||||
// serial_write(FEND);
|
||||
// serial_write(CMD_STAT_CSMA);
|
||||
// escaped_serial_write(selected_radio->getCWBand());
|
||||
// escaped_serial_write(selected_radio->getCWMin());
|
||||
// escaped_serial_write(selected_radio->getCWMax());
|
||||
// serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_battery() {
|
||||
#if MCU_VARIANT == MCU_ESP32
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_STAT_BAT);
|
||||
escaped_serial_write(battery_state);
|
||||
escaped_serial_write((uint8_t)int(battery_percent));
|
||||
serial_write(FEND);
|
||||
#endif
|
||||
}
|
||||
|
||||
void kiss_indicate_btpin() {
|
||||
@ -874,7 +1045,6 @@ void kiss_indicate_fbstate() {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
|
||||
void kiss_indicate_device_hash() {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_DEV_HASH);
|
||||
@ -928,7 +1098,6 @@ void kiss_indicate_fbstate() {
|
||||
}
|
||||
serial_write(FEND);
|
||||
}
|
||||
#endif
|
||||
|
||||
void kiss_indicate_fb() {
|
||||
serial_write(FEND);
|
||||
@ -944,6 +1113,20 @@ void kiss_indicate_fb() {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_disp() {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_DISP_READ);
|
||||
#if HAS_DISPLAY
|
||||
uint8_t *da = disp_area.getBuffer();
|
||||
uint8_t *sa = stat_area.getBuffer();
|
||||
for (int i = 0; i < 512; i++) { escaped_serial_write(da[i]); }
|
||||
for (int i = 0; i < 512; i++) { escaped_serial_write(sa[i]); }
|
||||
#else
|
||||
serial_write(0xFF);
|
||||
#endif
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_ready() {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_READY);
|
||||
@ -1026,15 +1209,15 @@ void setTXPower(RadioInterface* radio, int txp) {
|
||||
// Todo, revamp this function. The current parameters for setTxPower are
|
||||
// suboptimal, as some chips have power amplifiers which means that the max
|
||||
// dBm is not always the same.
|
||||
if (model == MODEL_11) {
|
||||
if (interfaces[radio->getIndex()] == SX128X) {
|
||||
if (model == MODEL_12) {
|
||||
if (interfaces[radio->getIndex()] == SX1280) {
|
||||
radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
} else {
|
||||
radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
}
|
||||
}
|
||||
if (model == MODEL_12) {
|
||||
if (interfaces[radio->getIndex()] == SX128X) {
|
||||
if (model == MODEL_13) {
|
||||
if (interfaces[radio->getIndex()] == SX1280) {
|
||||
radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
} else {
|
||||
radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
@ -1042,7 +1225,7 @@ void setTXPower(RadioInterface* radio, int txp) {
|
||||
}
|
||||
|
||||
if (model == MODEL_21) {
|
||||
if (interfaces[radio->getIndex()] == SX128X) {
|
||||
if (interfaces[radio->getIndex()] == SX1280) {
|
||||
radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
} else {
|
||||
radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
@ -1059,17 +1242,19 @@ void setTXPower(RadioInterface* radio, int txp) {
|
||||
if (model == MODEL_A8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_A9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_AA) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_AC) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
|
||||
if (model == MODEL_B3) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_B4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_B8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_B9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_BA) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_BB) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
|
||||
if (model == MODEL_C4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_C9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
|
||||
if (model == MODEL_C5) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_C6) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
if (model == MODEL_C7) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
if (model == MODEL_CA) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
|
||||
if (model == MODEL_D4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
@ -1095,80 +1280,6 @@ uint8_t getRandom(RadioInterface* radio) {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getInterfaceIndex(uint8_t byte) {
|
||||
switch (byte) {
|
||||
case CMD_INT0_DATA:
|
||||
case CMD_SEL_INT0:
|
||||
return 0;
|
||||
case CMD_INT1_DATA:
|
||||
case CMD_SEL_INT1:
|
||||
return 1;
|
||||
case CMD_INT2_DATA:
|
||||
case CMD_SEL_INT2:
|
||||
return 2;
|
||||
case CMD_INT3_DATA:
|
||||
case CMD_SEL_INT3:
|
||||
return 3;
|
||||
case CMD_INT4_DATA:
|
||||
case CMD_SEL_INT4:
|
||||
return 4;
|
||||
case CMD_INT5_DATA:
|
||||
case CMD_SEL_INT5:
|
||||
return 5;
|
||||
case CMD_INT6_DATA:
|
||||
case CMD_SEL_INT6:
|
||||
return 6;
|
||||
case CMD_INT7_DATA:
|
||||
case CMD_SEL_INT7:
|
||||
return 7;
|
||||
case CMD_INT8_DATA:
|
||||
case CMD_SEL_INT8:
|
||||
return 8;
|
||||
case CMD_INT9_DATA:
|
||||
case CMD_SEL_INT9:
|
||||
return 9;
|
||||
case CMD_INT10_DATA:
|
||||
case CMD_SEL_INT10:
|
||||
return 10;
|
||||
case CMD_INT11_DATA:
|
||||
case CMD_SEL_INT11:
|
||||
return 11;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getInterfaceCommandByte(uint8_t index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return CMD_INT0_DATA;
|
||||
case 1:
|
||||
return CMD_INT1_DATA;
|
||||
case 2:
|
||||
return CMD_INT2_DATA;
|
||||
case 3:
|
||||
return CMD_INT3_DATA;
|
||||
case 4:
|
||||
return CMD_INT4_DATA;
|
||||
case 5:
|
||||
return CMD_INT5_DATA;
|
||||
case 6:
|
||||
return CMD_INT6_DATA;
|
||||
case 7:
|
||||
return CMD_INT7_DATA;
|
||||
case 8:
|
||||
return CMD_INT8_DATA;
|
||||
case 9:
|
||||
return CMD_INT9_DATA;
|
||||
case 10:
|
||||
return CMD_INT10_DATA;
|
||||
case 11:
|
||||
return CMD_INT11_DATA;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t getQueueSize(uint8_t index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
@ -1234,21 +1345,18 @@ void promisc_disable() {
|
||||
bool eeprom_begin() {
|
||||
InternalFS.begin();
|
||||
|
||||
eeprom_file.open(EEPROM_FILE, FILE_O_READ);
|
||||
|
||||
// if file doesn't exist
|
||||
if (!eeprom_file) {
|
||||
if (eeprom_file.open(EEPROM_FILE, FILE_O_WRITE)) {
|
||||
// initialise the file with empty content
|
||||
uint8_t empty_content[EEPROM_SIZE] = {0};
|
||||
eeprom_file.write(empty_content, EEPROM_SIZE);
|
||||
file.open(EEPROM_FILE, FILE_O_READ);
|
||||
if (!file) {
|
||||
if (file.open(EEPROM_FILE, FILE_O_WRITE)) {
|
||||
for (uint32_t mapped_addr = 0; mapped_addr < EEPROM_SIZE; mapped_addr++) { file.seek(mapped_addr); file.write(0xFF); }
|
||||
eeprom_flush();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
eeprom_file.close();
|
||||
eeprom_file.open(EEPROM_FILE, FILE_O_WRITE);
|
||||
file.close();
|
||||
file.open(EEPROM_FILE, FILE_O_WRITE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1256,8 +1364,8 @@ void promisc_disable() {
|
||||
uint8_t eeprom_read(uint32_t mapped_addr) {
|
||||
uint8_t byte;
|
||||
void* byte_ptr = &byte;
|
||||
eeprom_file.seek(mapped_addr);
|
||||
eeprom_file.read(byte_ptr, 1);
|
||||
file.seek(mapped_addr);
|
||||
file.read(byte_ptr, 1);
|
||||
return byte;
|
||||
}
|
||||
#endif
|
||||
@ -1317,9 +1425,8 @@ void kiss_dump_eeprom() {
|
||||
|
||||
#if !HAS_EEPROM && MCU_VARIANT == MCU_NRF52
|
||||
void eeprom_flush() {
|
||||
// sync file contents to flash
|
||||
eeprom_file.close();
|
||||
eeprom_file.open(EEPROM_FILE, FILE_O_WRITE);
|
||||
file.close();
|
||||
file.open(EEPROM_FILE, FILE_O_WRITE);
|
||||
written_bytes = 0;
|
||||
}
|
||||
#endif
|
||||
@ -1332,27 +1439,17 @@ void eeprom_update(int mapped_addr, uint8_t byte) {
|
||||
}
|
||||
#elif !HAS_EEPROM && MCU_VARIANT == MCU_NRF52
|
||||
// todo: clean up this implementation, writing one byte and syncing
|
||||
// each time is really slow, but this is also suboptimal
|
||||
// each time is really slow
|
||||
uint8_t read_byte;
|
||||
void* read_byte_ptr = &read_byte;
|
||||
eeprom_file.seek(mapped_addr);
|
||||
eeprom_file.read(read_byte_ptr, 1);
|
||||
eeprom_file.seek(mapped_addr);
|
||||
file.seek(mapped_addr);
|
||||
file.read(read_byte_ptr, 1);
|
||||
file.seek(mapped_addr);
|
||||
if (read_byte != byte) {
|
||||
eeprom_file.write(byte);
|
||||
file.write(byte);
|
||||
}
|
||||
written_bytes++;
|
||||
|
||||
if (((mapped_addr - eeprom_addr(0)) == ADDR_INFO_LOCK) || (mapped_addr - eeprom_addr(0)) == ADDR_CONF_OK) {
|
||||
// have to do a flush because we're only writing 1 byte and it syncs after 4
|
||||
eeprom_flush();
|
||||
}
|
||||
|
||||
if (written_bytes >= 4) {
|
||||
eeprom_file.close();
|
||||
eeprom_file.open(EEPROM_FILE, FILE_O_WRITE);
|
||||
written_bytes = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1365,9 +1462,13 @@ void eeprom_write(uint8_t addr, uint8_t byte) {
|
||||
}
|
||||
|
||||
void eeprom_erase() {
|
||||
#if !HAS_EEPROM && MCU_VARIANT == MCU_NRF52
|
||||
InternalFS.format();
|
||||
#else
|
||||
for (int addr = 0; addr < EEPROM_RESERVED; addr++) {
|
||||
eeprom_update(eeprom_addr(addr), 0xFF);
|
||||
}
|
||||
#endif
|
||||
hard_reset();
|
||||
}
|
||||
|
||||
@ -1529,13 +1630,28 @@ void db_conf_save(uint8_t val) {
|
||||
display_blanking_enabled = false;
|
||||
} else {
|
||||
display_blanking_enabled = true;
|
||||
//display_blanking_timeout = val*1000;
|
||||
display_blanking_timeout = val*1000;
|
||||
}
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_BSET), CONF_OK_BYTE);
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_DBLK), val);
|
||||
#endif
|
||||
}
|
||||
|
||||
void drot_conf_save(uint8_t val) {
|
||||
#if HAS_DISPLAY
|
||||
if (val >= 0x00 and val <= 0x03) {
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_DROT), val);
|
||||
hard_reset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dia_conf_save(uint8_t val) {
|
||||
if (val > 0x00) { eeprom_update(eeprom_addr(ADDR_CONF_DIA), 0x01); }
|
||||
else { eeprom_update(eeprom_addr(ADDR_CONF_DIA), 0x00); }
|
||||
hard_reset();
|
||||
}
|
||||
|
||||
void np_int_conf_save(uint8_t p_int) {
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_PSET), CONF_OK_BYTE);
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_PINT), p_int);
|
||||
@ -1616,4 +1732,24 @@ void unlock_rom() {
|
||||
eeprom_erase();
|
||||
}
|
||||
|
||||
void log_debug(const char* msg) {
|
||||
serial_write(FEND);
|
||||
serial_write(LOG_MSG);
|
||||
serial_write(MSG_DBG);
|
||||
for (int i = 0; i < strlen(msg); i++) {
|
||||
escaped_serial_write(msg[i]);
|
||||
}
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void log_debug(char* msg) {
|
||||
serial_write(FEND);
|
||||
serial_write(LOG_MSG);
|
||||
serial_write(MSG_DBG);
|
||||
for (int i = 0; i < strlen(msg); i++) {
|
||||
escaped_serial_write(msg[i]);
|
||||
}
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
#include "src/misc/FIFOBuffer.h"
|
||||
|
@ -191,7 +191,6 @@ void setup() {
|
||||
// Create and configure interface objects
|
||||
for (uint8_t i = 0; i < INTERFACE_COUNT; i++) {
|
||||
switch (interfaces[i]) {
|
||||
case SX126X:
|
||||
case SX1262:
|
||||
{
|
||||
sx126x* obj;
|
||||
@ -213,7 +212,6 @@ void setup() {
|
||||
break;
|
||||
}
|
||||
|
||||
case SX127X:
|
||||
case SX1276:
|
||||
case SX1278:
|
||||
{
|
||||
@ -234,7 +232,6 @@ void setup() {
|
||||
break;
|
||||
}
|
||||
|
||||
case SX128X:
|
||||
case SX1280:
|
||||
{
|
||||
sx128x* obj;
|
||||
@ -265,12 +262,9 @@ void setup() {
|
||||
// the configured modems cannot be initialised, do not boot
|
||||
for (int i = 0; i < INTERFACE_COUNT; i++) {
|
||||
switch (interfaces[i]) {
|
||||
case SX126X:
|
||||
case SX1262:
|
||||
case SX127X:
|
||||
case SX1276:
|
||||
case SX1278:
|
||||
case SX128X:
|
||||
case SX1280:
|
||||
selected_radio = interface_obj[i];
|
||||
break;
|
||||
@ -353,12 +347,14 @@ void lora_receive(RadioInterface* radio) {
|
||||
}
|
||||
|
||||
inline void kiss_write_packet(int index) {
|
||||
// We need to convert the interface index to the command byte representation
|
||||
uint8_t cmd_byte = getInterfaceCommandByte(index);
|
||||
// Print index of interface the packet came from
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SEL_INT);
|
||||
serial_write(index);
|
||||
serial_write(FEND);
|
||||
|
||||
serial_write(FEND);
|
||||
// Add index of interface the packet came from
|
||||
serial_write(cmd_byte);
|
||||
serial_write(CMD_DATA);
|
||||
|
||||
for (uint16_t i = 0; i < read_len[index]; i++) {
|
||||
#if MCU_VARIANT == MCU_NRF52
|
||||
@ -619,7 +615,7 @@ void flushQueue(RadioInterface* radio) {
|
||||
selected_radio->updateAirtime();
|
||||
queue_flushing = false;
|
||||
#if HAS_DISPLAY
|
||||
display_tx = true;
|
||||
display_tx[index] = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -696,39 +692,27 @@ void transmit(RadioInterface* radio, uint16_t size) {
|
||||
|
||||
void serialCallback(uint8_t sbyte) {
|
||||
if (IN_FRAME && sbyte == FEND &&
|
||||
(command == CMD_INT0_DATA
|
||||
|| command == CMD_INT1_DATA
|
||||
|| command == CMD_INT2_DATA
|
||||
|| command == CMD_INT3_DATA
|
||||
|| command == CMD_INT4_DATA
|
||||
|| command == CMD_INT5_DATA
|
||||
|| command == CMD_INT6_DATA
|
||||
|| command == CMD_INT7_DATA
|
||||
|| command == CMD_INT8_DATA
|
||||
|| command == CMD_INT9_DATA
|
||||
|| command == CMD_INT10_DATA
|
||||
|| command == CMD_INT11_DATA)) {
|
||||
command == CMD_DATA) {
|
||||
IN_FRAME = false;
|
||||
|
||||
if (getInterfaceIndex(command) < INTERFACE_COUNT) {
|
||||
uint8_t index = getInterfaceIndex(command);
|
||||
if (!fifo16_isfull(&packet_starts[index]) && (queued_bytes[index] < (getQueueSize(index)))) {
|
||||
uint16_t s = current_packet_start[index];
|
||||
int32_t e = queue_cursor[index]-1; if (e == -1) e = (getQueueSize(index))-1;
|
||||
if (interface < INTERFACE_COUNT) {
|
||||
if (!fifo16_isfull(&packet_starts[interface]) && (queued_bytes[interface] < (getQueueSize(interface)))) {
|
||||
uint16_t s = current_packet_start[interface];
|
||||
int32_t e = queue_cursor[interface]-1; if (e == -1) e = (getQueueSize(interface))-1;
|
||||
uint16_t l;
|
||||
|
||||
if (s != e) {
|
||||
l = (s < e) ? e - s + 1: (getQueueSize(index)) - s + e + 1;
|
||||
l = (s < e) ? e - s + 1: (getQueueSize(interface)) - s + e + 1;
|
||||
} else {
|
||||
l = 1;
|
||||
}
|
||||
|
||||
if (l >= MIN_L) {
|
||||
queue_height[index]++;
|
||||
queue_height[interface]++;
|
||||
|
||||
fifo16_push(&packet_starts[index], s);
|
||||
fifo16_push(&packet_lengths[index], l);
|
||||
current_packet_start[index] = queue_cursor[index];
|
||||
fifo16_push(&packet_starts[interface], s);
|
||||
fifo16_push(&packet_lengths[interface], l);
|
||||
current_packet_start[interface] = queue_cursor[interface];
|
||||
}
|
||||
|
||||
}
|
||||
@ -742,33 +726,9 @@ void serialCallback(uint8_t sbyte) {
|
||||
// Have a look at the command byte first
|
||||
if (frame_len == 0 && command == CMD_UNKNOWN) {
|
||||
command = sbyte;
|
||||
if (command == CMD_SEL_INT0
|
||||
|| command == CMD_SEL_INT1
|
||||
|| command == CMD_SEL_INT2
|
||||
|| command == CMD_SEL_INT3
|
||||
|| command == CMD_SEL_INT4
|
||||
|| command == CMD_SEL_INT5
|
||||
|| command == CMD_SEL_INT6
|
||||
|| command == CMD_SEL_INT7
|
||||
|| command == CMD_SEL_INT8
|
||||
|| command == CMD_SEL_INT9
|
||||
|| command == CMD_SEL_INT10
|
||||
|| command == CMD_SEL_INT11) {
|
||||
interface = getInterfaceIndex(command);
|
||||
}
|
||||
|
||||
} else if (command == CMD_INT0_DATA
|
||||
|| command == CMD_INT1_DATA
|
||||
|| command == CMD_INT2_DATA
|
||||
|| command == CMD_INT3_DATA
|
||||
|| command == CMD_INT4_DATA
|
||||
|| command == CMD_INT5_DATA
|
||||
|| command == CMD_INT6_DATA
|
||||
|| command == CMD_INT7_DATA
|
||||
|| command == CMD_INT8_DATA
|
||||
|| command == CMD_INT9_DATA
|
||||
|| command == CMD_INT10_DATA
|
||||
|| command == CMD_INT11_DATA) {
|
||||
} else if (command == CMD_SEL_INT) {
|
||||
interface = sbyte;
|
||||
} else if (command == CMD_DATA) {
|
||||
if (bt_state != BT_STATE_CONNECTED) cable_state = CABLE_STATE_CONNECTED;
|
||||
if (sbyte == FESC) {
|
||||
ESCAPE = true;
|
||||
@ -779,13 +739,10 @@ void serialCallback(uint8_t sbyte) {
|
||||
ESCAPE = false;
|
||||
}
|
||||
|
||||
if (getInterfaceIndex(command) < INTERFACE_COUNT) {
|
||||
uint8_t index = getInterfaceIndex(command);
|
||||
if (queue_height[index] < CONFIG_QUEUE_MAX_LENGTH && queued_bytes[index] < (getQueueSize(index))) {
|
||||
queued_bytes[index]++;
|
||||
packet_queue[index][queue_cursor[index]++] = sbyte;
|
||||
if (queue_cursor[index] == (getQueueSize(index))) queue_cursor[index] = 0;
|
||||
}
|
||||
if (queue_height[interface] < CONFIG_QUEUE_MAX_LENGTH && queued_bytes[interface] < (getQueueSize(interface))) {
|
||||
queued_bytes[interface]++;
|
||||
packet_queue[interface][queue_cursor[interface]++] = sbyte;
|
||||
if (queue_cursor[interface] == (getQueueSize(interface))) queue_cursor[interface] = 0;
|
||||
}
|
||||
}
|
||||
} else if (command == CMD_INTERFACES) {
|
||||
@ -969,7 +926,7 @@ void serialCallback(uint8_t sbyte) {
|
||||
} else if (command == CMD_STAT_TX) {
|
||||
kiss_indicate_stat_tx();
|
||||
} else if (command == CMD_STAT_RSSI) {
|
||||
kiss_indicate_stat_rssi();
|
||||
kiss_indicate_stat_rssi(interface_obj[interface]);
|
||||
} else if (command == CMD_RADIO_LOCK) {
|
||||
selected_radio = interface_obj[interface];
|
||||
update_radio_lock(selected_radio);
|
||||
@ -1157,7 +1114,7 @@ void serialCallback(uint8_t sbyte) {
|
||||
}
|
||||
display_intensity = sbyte;
|
||||
di_conf_save(display_intensity);
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1176,21 +1133,6 @@ void serialCallback(uint8_t sbyte) {
|
||||
}
|
||||
|
||||
#endif
|
||||
} else if (command == CMD_FW_LENGTH) {
|
||||
if (sbyte == FESC) {
|
||||
ESCAPE = true;
|
||||
} else {
|
||||
if (ESCAPE) {
|
||||
if (sbyte == TFEND) sbyte = FEND;
|
||||
if (sbyte == TFESC) sbyte = FESC;
|
||||
ESCAPE = false;
|
||||
}
|
||||
if (frame_len < CMD_L) cmdbuf[frame_len++] = sbyte;
|
||||
}
|
||||
|
||||
if (frame_len == FW_LENGTH_LEN) {
|
||||
set_fw_length(cmdbuf);
|
||||
}
|
||||
} else if (command == CMD_DISP_BLNK) {
|
||||
#if HAS_DISPLAY
|
||||
if (sbyte == FESC) {
|
||||
@ -1202,7 +1144,7 @@ void serialCallback(uint8_t sbyte) {
|
||||
ESCAPE = false;
|
||||
}
|
||||
db_conf_save(sbyte);
|
||||
//display_unblank();
|
||||
display_unblank();
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1216,7 +1158,6 @@ void serialCallback(uint8_t sbyte) {
|
||||
if (sbyte == TFESC) sbyte = FESC;
|
||||
ESCAPE = false;
|
||||
}
|
||||
sbyte;
|
||||
led_set_intensity(sbyte);
|
||||
np_int_conf_save(sbyte);
|
||||
}
|
||||
@ -1343,7 +1284,7 @@ void loop() {
|
||||
#if MCU_VARIANT == MCU_ESP32
|
||||
modem_packet_t *modem_packet = NULL;
|
||||
if(modem_packet_queue && xQueueReceive(modem_packet_queue, &modem_packet, 0) == pdTRUE && modem_packet) {
|
||||
packet_interface = modem_packet->interface;
|
||||
uint8_t packet_interface = modem_packet->interface;
|
||||
read_len[packet_interface] = modem_packet->len;
|
||||
last_rssi = modem_packet->rssi;
|
||||
last_snr_raw = modem_packet->snr_raw;
|
||||
@ -1359,7 +1300,7 @@ void loop() {
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
modem_packet_t *modem_packet = NULL;
|
||||
if(modem_packet_queue && xQueueReceive(modem_packet_queue, &modem_packet, 0) == pdTRUE && modem_packet) {
|
||||
packet_interface = modem_packet->interface;
|
||||
uint8_t packet_interface = modem_packet->interface;
|
||||
read_len[packet_interface] = modem_packet->len;
|
||||
last_rssi = modem_packet->rssi;
|
||||
last_snr_raw = modem_packet->snr_raw;
|
||||
@ -1367,8 +1308,8 @@ void loop() {
|
||||
free(modem_packet);
|
||||
modem_packet = NULL;
|
||||
|
||||
kiss_indicate_stat_rssi();
|
||||
kiss_indicate_stat_snr();
|
||||
kiss_indicate_stat_rssi(interface_obj[packet_interface]);
|
||||
kiss_indicate_stat_snr(interface_obj[packet_interface]);
|
||||
kiss_write_packet(packet_interface);
|
||||
}
|
||||
#endif
|
||||
@ -1492,7 +1433,7 @@ void process_serial() {
|
||||
void button_event(uint8_t event, unsigned long duration) {
|
||||
if (duration > BUTTON_MIN_DURATION) {
|
||||
if (duration > BUTTON_9S_DURATION) {
|
||||
bt_bond_wipe();
|
||||
bt_debond_all();
|
||||
} else if (duration > BUTTON_6S_DURATION) {
|
||||
bt_stop();
|
||||
bt_conf_save(false);
|
||||
|
@ -20,6 +20,7 @@ import sys
|
||||
import RNS
|
||||
import json
|
||||
import hashlib
|
||||
import subprocess
|
||||
|
||||
major_version = None
|
||||
minor_version = None
|
||||
@ -27,9 +28,23 @@ target_version = None
|
||||
|
||||
target_file = os.path.join(sys.argv[1])
|
||||
|
||||
firmware_data = open(target_file, "rb").read()
|
||||
calc_hash = hashlib.sha256(firmware_data[0:-32]).digest()
|
||||
part_hash = firmware_data[-32:]
|
||||
if sys.argv[1] == "from_device":
|
||||
from_device = True
|
||||
else:
|
||||
from_device = False
|
||||
|
||||
if calc_hash == part_hash:
|
||||
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))
|
||||
|
@ -13,8 +13,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// This class is for BLE serial functionality on ESP32 boards ONLY
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "../../Boards.h"
|
||||
|
||||
@ -99,6 +97,17 @@ void BLESerial::flush() {
|
||||
}
|
||||
}
|
||||
|
||||
void BLESerial::disconnect() {
|
||||
if (ble_server->getConnectedCount() > 0) {
|
||||
uint16_t conn_id = ble_server->getConnId();
|
||||
// Serial.printf("Have connected: %d\n", conn_id);
|
||||
ble_server->disconnect(conn_id);
|
||||
// Serial.println("Disconnected");
|
||||
} else {
|
||||
// Serial.println("No connected");
|
||||
}
|
||||
}
|
||||
|
||||
void BLESerial::begin(const char *name) {
|
||||
ConnectedDeviceCount = 0;
|
||||
BLEDevice::init(name);
|
||||
@ -113,7 +122,10 @@ void BLESerial::begin(const char *name) {
|
||||
BLEDevice::setSecurityCallbacks(this);
|
||||
|
||||
SetupSerialService();
|
||||
this->startAdvertising();
|
||||
}
|
||||
|
||||
void BLESerial::startAdvertising() {
|
||||
ble_adv = BLEDevice::getAdvertising();
|
||||
ble_adv->addServiceUUID(BLE_SERIAL_SERVICE_UUID);
|
||||
ble_adv->setMinPreferred(0x20);
|
||||
@ -122,6 +134,11 @@ void BLESerial::begin(const char *name) {
|
||||
ble_adv->start();
|
||||
}
|
||||
|
||||
void BLESerial::stopAdvertising() {
|
||||
ble_adv = BLEDevice::getAdvertising();
|
||||
ble_adv->stop();
|
||||
}
|
||||
|
||||
void BLESerial::end() { BLEDevice::deinit(); }
|
||||
|
||||
void BLESerial::onWrite(BLECharacteristic *characteristic) {
|
||||
|
@ -13,8 +13,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// This class is for BLE serial functionality on ESP32 boards ONLY
|
||||
|
||||
#include "../../Boards.h"
|
||||
|
||||
#if PLATFORM != PLATFORM_NRF52
|
||||
@ -80,6 +78,9 @@ public:
|
||||
|
||||
void begin(const char *name);
|
||||
void end();
|
||||
void disconnect();
|
||||
void startAdvertising();
|
||||
void stopAdvertising();
|
||||
void onWrite(BLECharacteristic *characteristic);
|
||||
int available();
|
||||
int peek();
|
||||
|
45
src/misc/ModemISR.h
Normal file
45
src/misc/ModemISR.h
Normal file
@ -0,0 +1,45 @@
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user