mirror of
https://github.com/liberatedsystems/RNode_Firmware_CE.git
synced 2024-07-02 14:34:13 +02:00
Compare commits
5 Commits
dcb8388ca9
...
055083ffba
Author | SHA1 | Date | |
---|---|---|---|
|
055083ffba | ||
|
f3558b66fc | ||
|
266fd6f8bd | ||
|
66fc47124c | ||
|
35d9ec2bab |
11
.github/ISSUE_TEMPLATE/config.yml
vendored
11
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,11 +0,0 @@
|
|||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: ✨ Feature Request or Idea
|
|
||||||
url: https://github.com/markqvist/Reticulum/discussions/new?category=ideas
|
|
||||||
about: Propose and discuss features and ideas
|
|
||||||
- name: 💬 Questions, Help & Discussion
|
|
||||||
about: Ask anything, or get help
|
|
||||||
url: https://github.com/markqvist/Reticulum/discussions/new/choose
|
|
||||||
- name: 📖 Read the Reticulum Manual
|
|
||||||
url: https://markqvist.github.io/Reticulum/manual/
|
|
||||||
about: The complete documentation for Reticulum
|
|
35
.github/ISSUE_TEMPLATE/🐛-bug-report.md
vendored
35
.github/ISSUE_TEMPLATE/🐛-bug-report.md
vendored
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
name: "\U0001F41B Bug Report"
|
|
||||||
about: Report a reproducible bug
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Read the Contribution Guidelines**
|
|
||||||
Before creating a bug report on this issue tracker, you **must** read the [Contribution Guidelines](https://github.com/markqvist/Reticulum/blob/master/Contributing.md). Issues that do not follow the contribution guidelines **will be deleted without comment**.
|
|
||||||
|
|
||||||
- The issue tracker is used by developers of this project. **Do not use it to ask general questions, or for support requests**.
|
|
||||||
- Ideas and feature requests can be made on the [Discussions](https://github.com/markqvist/Reticulum/discussions). **Only** feature requests accepted by maintainers and developers are tracked and included on the issue tracker. **Do not post feature requests here**.
|
|
||||||
- After reading the [Contribution Guidelines](https://github.com/markqvist/Reticulum/blob/master/Contributing.md), delete this section from your bug report.
|
|
||||||
|
|
||||||
**Describe the Bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Describe in detail how to reproduce the bug.
|
|
||||||
|
|
||||||
**Expected Behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Logs & Screenshots**
|
|
||||||
Please include any relevant log output. If applicable, also add screenshots to help explain your problem.
|
|
||||||
|
|
||||||
**System Information**
|
|
||||||
- OS and version
|
|
||||||
- Python version
|
|
||||||
- Program version
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
17
Bluetooth.h
17
Bluetooth.h
@ -13,12 +13,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#if MCU_VARIANT == MCU_ESP32
|
|
||||||
|
|
||||||
|
|
||||||
#elif MCU_VARIANT == MCU_NRF52
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MCU_VARIANT == MCU_ESP32
|
#if MCU_VARIANT == MCU_ESP32
|
||||||
#if HAS_BLUETOOTH == true
|
#if HAS_BLUETOOTH == true
|
||||||
#include "BluetoothSerial.h"
|
#include "BluetoothSerial.h"
|
||||||
@ -265,6 +259,8 @@ void bt_disable_pairing() {
|
|||||||
|
|
||||||
void bt_pairing_complete(uint16_t conn_handle, uint8_t auth_status) {
|
void bt_pairing_complete(uint16_t conn_handle, uint8_t auth_status) {
|
||||||
if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
|
if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
|
||||||
|
bt_state = BT_STATE_CONNECTED;
|
||||||
|
cable_state = CABLE_STATE_DISCONNECTED;
|
||||||
bt_disable_pairing();
|
bt_disable_pairing();
|
||||||
} else {
|
} else {
|
||||||
bt_ssp_pin = 0;
|
bt_ssp_pin = 0;
|
||||||
@ -285,11 +281,6 @@ bool bt_passkey_callback(uint16_t conn_handle, uint8_t const passkey[6], bool ma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_connect_callback(uint16_t conn_handle) {
|
|
||||||
bt_state = BT_STATE_CONNECTED;
|
|
||||||
cable_state = CABLE_STATE_DISCONNECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||||
bt_state = BT_STATE_ON;
|
bt_state = BT_STATE_ON;
|
||||||
}
|
}
|
||||||
@ -308,10 +299,9 @@ bool bt_setup_hw() {
|
|||||||
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
|
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
|
||||||
Bluefruit.autoConnLed(false);
|
Bluefruit.autoConnLed(false);
|
||||||
if (Bluefruit.begin()) {
|
if (Bluefruit.begin()) {
|
||||||
Bluefruit.setTxPower(4); // Check bluefruit.h for supported values
|
Bluefruit.setTxPower(8); // Check bluefruit.h for supported values
|
||||||
Bluefruit.Security.setIOCaps(true, true, false);
|
Bluefruit.Security.setIOCaps(true, true, false);
|
||||||
Bluefruit.Security.setPairPasskeyCallback(bt_passkey_callback);
|
Bluefruit.Security.setPairPasskeyCallback(bt_passkey_callback);
|
||||||
Bluefruit.Periph.setConnectCallback(bt_connect_callback);
|
|
||||||
Bluefruit.Periph.setDisconnectCallback(bt_disconnect_callback);
|
Bluefruit.Periph.setDisconnectCallback(bt_disconnect_callback);
|
||||||
Bluefruit.Security.setPairCompleteCallback(bt_pairing_complete);
|
Bluefruit.Security.setPairCompleteCallback(bt_pairing_complete);
|
||||||
const ble_gap_addr_t gap_addr = Bluefruit.getAddr();
|
const ble_gap_addr_t gap_addr = Bluefruit.getAddr();
|
||||||
@ -348,7 +338,6 @@ void bt_start() {
|
|||||||
|
|
||||||
blebas.begin();
|
blebas.begin();
|
||||||
|
|
||||||
// non-connectable advertising
|
|
||||||
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
|
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
|
||||||
Bluefruit.Advertising.addTxPower();
|
Bluefruit.Advertising.addTxPower();
|
||||||
|
|
||||||
|
24
Boards.h
24
Boards.h
@ -43,6 +43,10 @@
|
|||||||
#define BOARD_GENERIC_NRF52 0x50
|
#define BOARD_GENERIC_NRF52 0x50
|
||||||
#define BOARD_RAK4631 0x51
|
#define BOARD_RAK4631 0x51
|
||||||
|
|
||||||
|
#define OLED 0x01
|
||||||
|
#define EINK_BW 0x02
|
||||||
|
#define EINK_3C 0x03
|
||||||
|
|
||||||
#if defined(__AVR_ATmega1284P__)
|
#if defined(__AVR_ATmega1284P__)
|
||||||
#define PLATFORM PLATFORM_AVR
|
#define PLATFORM PLATFORM_AVR
|
||||||
#define MCU_VARIANT MCU_1284P
|
#define MCU_VARIANT MCU_1284P
|
||||||
@ -147,6 +151,7 @@
|
|||||||
|
|
||||||
#elif BOARD_MODEL == BOARD_TBEAM
|
#elif BOARD_MODEL == BOARD_TBEAM
|
||||||
#define HAS_DISPLAY true
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY OLED
|
||||||
#define HAS_PMU true
|
#define HAS_PMU true
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_BLE true
|
#define HAS_BLE true
|
||||||
@ -184,6 +189,7 @@
|
|||||||
|
|
||||||
#elif BOARD_MODEL == BOARD_LORA32_V1_0
|
#elif BOARD_MODEL == BOARD_LORA32_V1_0
|
||||||
#define HAS_DISPLAY true
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY OLED
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_BLE true
|
#define HAS_BLE true
|
||||||
#define HAS_CONSOLE true
|
#define HAS_CONSOLE true
|
||||||
@ -201,6 +207,7 @@
|
|||||||
|
|
||||||
#elif BOARD_MODEL == BOARD_LORA32_V2_0
|
#elif BOARD_MODEL == BOARD_LORA32_V2_0
|
||||||
#define HAS_DISPLAY true
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY OLED
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_BLE true
|
#define HAS_BLE true
|
||||||
#define HAS_CONSOLE true
|
#define HAS_CONSOLE true
|
||||||
@ -218,6 +225,7 @@
|
|||||||
|
|
||||||
#elif BOARD_MODEL == BOARD_LORA32_V2_1
|
#elif BOARD_MODEL == BOARD_LORA32_V2_1
|
||||||
#define HAS_DISPLAY true
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY OLED
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_BLE true
|
#define HAS_BLE true
|
||||||
#define HAS_PMU true
|
#define HAS_PMU true
|
||||||
@ -239,6 +247,7 @@
|
|||||||
|
|
||||||
#elif BOARD_MODEL == BOARD_HELTEC32_V2
|
#elif BOARD_MODEL == BOARD_HELTEC32_V2
|
||||||
#define HAS_DISPLAY true
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY OLED
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_CONSOLE true
|
#define HAS_CONSOLE true
|
||||||
#define HAS_EEPROM true
|
#define HAS_EEPROM true
|
||||||
@ -292,6 +301,7 @@
|
|||||||
|
|
||||||
#elif BOARD_MODEL == BOARD_RNODE_NG_20
|
#elif BOARD_MODEL == BOARD_RNODE_NG_20
|
||||||
#define HAS_DISPLAY true
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY OLED
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_NP true
|
#define HAS_NP true
|
||||||
#define HAS_CONSOLE true
|
#define HAS_CONSOLE true
|
||||||
@ -312,6 +322,7 @@
|
|||||||
|
|
||||||
#elif BOARD_MODEL == BOARD_RNODE_NG_21
|
#elif BOARD_MODEL == BOARD_RNODE_NG_21
|
||||||
#define HAS_DISPLAY true
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY OLED
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_CONSOLE true
|
#define HAS_CONSOLE true
|
||||||
#define HAS_PMU true
|
#define HAS_PMU true
|
||||||
@ -346,6 +357,7 @@
|
|||||||
#define HAS_TCXO true
|
#define HAS_TCXO true
|
||||||
|
|
||||||
#define HAS_DISPLAY true
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY OLED
|
||||||
#define HAS_CONSOLE false
|
#define HAS_CONSOLE false
|
||||||
#define HAS_BLUETOOTH false
|
#define HAS_BLUETOOTH false
|
||||||
#define HAS_BLE true
|
#define HAS_BLE true
|
||||||
@ -397,11 +409,12 @@
|
|||||||
#elif MCU_VARIANT == MCU_NRF52
|
#elif MCU_VARIANT == MCU_NRF52
|
||||||
#if BOARD_MODEL == BOARD_RAK4631
|
#if BOARD_MODEL == BOARD_RAK4631
|
||||||
#define HAS_EEPROM false
|
#define HAS_EEPROM false
|
||||||
#define HAS_DISPLAY false
|
#define HAS_DISPLAY true
|
||||||
|
#define DISPLAY EINK_3C
|
||||||
#define HAS_BLUETOOTH false
|
#define HAS_BLUETOOTH false
|
||||||
#define HAS_BLE true
|
#define HAS_BLE true
|
||||||
#define HAS_CONSOLE false
|
#define HAS_CONSOLE false
|
||||||
#define HAS_PMU false
|
#define HAS_PMU true
|
||||||
#define HAS_NP false
|
#define HAS_NP false
|
||||||
#define HAS_SD false
|
#define HAS_SD false
|
||||||
#define HAS_TCXO true
|
#define HAS_TCXO true
|
||||||
@ -425,6 +438,13 @@
|
|||||||
const int pin_miso = 45;
|
const int pin_miso = 45;
|
||||||
const int pin_busy = 46;
|
const int pin_busy = 46;
|
||||||
const int pin_dio = 47;
|
const int pin_dio = 47;
|
||||||
|
|
||||||
|
const int pin_disp_cs = SS;
|
||||||
|
const int pin_disp_dc = WB_IO1;
|
||||||
|
const int pin_disp_reset = -1;
|
||||||
|
const int pin_disp_busy = WB_IO4;
|
||||||
|
const int pin_disp_en = WB_IO2;
|
||||||
|
|
||||||
const int pin_led_rx = LED_BLUE;
|
const int pin_led_rx = LED_BLUE;
|
||||||
const int pin_led_tx = LED_GREEN;
|
const int pin_led_tx = LED_GREEN;
|
||||||
const int pin_tcxo_enable = -1;
|
const int pin_tcxo_enable = -1;
|
||||||
|
509
Display.h
509
Display.h
@ -13,47 +13,112 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "Graphics.h"
|
|
||||||
#include <Wire.h>
|
|
||||||
#include <Adafruit_GFX.h>
|
#include <Adafruit_GFX.h>
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
|
#include <Wire.h>
|
||||||
#include <Adafruit_SSD1306.h>
|
#include <Adafruit_SSD1306.h>
|
||||||
#include "Fonts/Org_01.h"
|
|
||||||
#define DISP_W 128
|
#define DISP_W 128
|
||||||
#define DISP_H 64
|
#define DISP_H 64
|
||||||
|
#elif DISPLAY == EINK_BW || DISPLAY == EINK_3C
|
||||||
|
void (*display_callback)();
|
||||||
|
void display_add_callback(void (*callback)()) {
|
||||||
|
display_callback = callback;
|
||||||
|
}
|
||||||
|
void busyCallback(const void* p) {
|
||||||
|
display_callback();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if DISPLAY == EINK_BW
|
||||||
|
// use GxEPD2 because adafruit EPD support for partial refresh is bad
|
||||||
|
#include <GxEPD2_BW.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#elif DISPLAY == EINK_3C
|
||||||
|
#include <GxEPD2_3C.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Fonts/Org_01.h"
|
||||||
#if BOARD_MODEL == BOARD_RNODE_NG_20 || BOARD_MODEL == BOARD_LORA32_V2_0
|
#if BOARD_MODEL == BOARD_RNODE_NG_20 || BOARD_MODEL == BOARD_LORA32_V2_0
|
||||||
|
#if BOARD_TYPE == OLED
|
||||||
#define DISP_RST -1
|
#define DISP_RST -1
|
||||||
#define DISP_ADDR 0x3C
|
#define DISP_ADDR 0x3C
|
||||||
|
#endif
|
||||||
#elif BOARD_MODEL == BOARD_TBEAM
|
#elif BOARD_MODEL == BOARD_TBEAM
|
||||||
|
#if BOARD_TYPE == OLED
|
||||||
#define DISP_RST 13
|
#define DISP_RST 13
|
||||||
#define DISP_ADDR 0x3C
|
#define DISP_ADDR 0x3C
|
||||||
#define DISP_CUSTOM_ADDR true
|
#define DISP_CUSTOM_ADDR true
|
||||||
|
#endif
|
||||||
#elif BOARD_MODEL == BOARD_HELTEC32_V2 || BOARD_MODEL == BOARD_LORA32_V1_0
|
#elif BOARD_MODEL == BOARD_HELTEC32_V2 || BOARD_MODEL == BOARD_LORA32_V1_0
|
||||||
|
#if BOARD_TYPE == OLED
|
||||||
#define DISP_RST 16
|
#define DISP_RST 16
|
||||||
#define DISP_ADDR 0x3C
|
#define DISP_ADDR 0x3C
|
||||||
#define SCL_OLED 15
|
#define SCL_OLED 15
|
||||||
#define SDA_OLED 4
|
#define SDA_OLED 4
|
||||||
|
#endif
|
||||||
#elif BOARD_MODEL == BOARD_HELTEC32_V3
|
#elif BOARD_MODEL == BOARD_HELTEC32_V3
|
||||||
#define DISP_RST 21
|
#define DISP_RST 21
|
||||||
#define DISP_ADDR 0x3C
|
#define DISP_ADDR 0x3C
|
||||||
#define SCL_OLED 18
|
#define SCL_OLED 18
|
||||||
#define SDA_OLED 17
|
#define SDA_OLED 17
|
||||||
#elif BOARD_MODEL == BOARD_RNODE_NG_21
|
#elif BOARD_MODEL == BOARD_RNODE_NG_21
|
||||||
|
#if BOARD_TYPE == OLED
|
||||||
#define DISP_RST -1
|
#define DISP_RST -1
|
||||||
#define DISP_ADDR 0x3C
|
#define DISP_ADDR 0x3C
|
||||||
|
#endif
|
||||||
#elif BOARD_MODEL == BOARD_RNODE_NG_22
|
#elif BOARD_MODEL == BOARD_RNODE_NG_22
|
||||||
|
#if BOARD_TYPE == OLED
|
||||||
#define DISP_RST 21
|
#define DISP_RST 21
|
||||||
#define DISP_ADDR 0x3C
|
#define DISP_ADDR 0x3C
|
||||||
#define SCL_OLED 17
|
#define SCL_OLED 17
|
||||||
#define SDA_OLED 18
|
#define SDA_OLED 18
|
||||||
|
#endif
|
||||||
|
#elif BOARD_MODEL == BOARD_RAK4631
|
||||||
|
#if DISPLAY == OLED
|
||||||
|
// todo: add support for OLED board
|
||||||
|
#elif DISPLAY == EINK_BW
|
||||||
|
#define DISP_W 250
|
||||||
|
#define DISP_H 122
|
||||||
|
#define DISP_ADDR -1
|
||||||
|
#define DISPLAY_MODEL GxEPD2_213_BN
|
||||||
|
#elif DISPLAY == EINK_3C
|
||||||
|
#define DISP_W 250
|
||||||
|
#define DISP_H 122
|
||||||
|
#define DISP_ADDR -1
|
||||||
|
#define DISPLAY_MODEL GxEPD2_213_Z98c
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define DISP_RST -1
|
#define DISP_RST -1
|
||||||
#define DISP_ADDR 0x3C
|
#define DISP_ADDR 0x3C
|
||||||
#define DISP_CUSTOM_ADDR true
|
#define DISP_CUSTOM_ADDR true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define UNSCALED_MAX 64
|
||||||
|
|
||||||
#define SMALL_FONT &Org_01
|
#define SMALL_FONT &Org_01
|
||||||
|
|
||||||
|
#include "Graphics.h"
|
||||||
|
|
||||||
|
#if BOARD_MODEL != BOARD_RAK4631
|
||||||
|
// support for BOARD_RAK4631 OLED not implemented yet
|
||||||
|
#if DISPLAY == OLED
|
||||||
Adafruit_SSD1306 display(DISP_W, DISP_H, &Wire, DISP_RST);
|
Adafruit_SSD1306 display(DISP_W, DISP_H, &Wire, DISP_RST);
|
||||||
|
float disp_target_fps = 7;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if BOARD_MODEL == BOARD_RAK4631
|
||||||
|
#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;
|
||||||
|
#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 4x the refresh period
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// add more eink compatible boards here
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DISP_MODE_UNKNOWN 0x00
|
#define DISP_MODE_UNKNOWN 0x00
|
||||||
#define DISP_MODE_LANDSCAPE 0x01
|
#define DISP_MODE_LANDSCAPE 0x01
|
||||||
@ -63,14 +128,20 @@ uint8_t disp_mode = DISP_MODE_UNKNOWN;
|
|||||||
uint8_t disp_ext_fb = false;
|
uint8_t disp_ext_fb = false;
|
||||||
unsigned char fb[512];
|
unsigned char fb[512];
|
||||||
uint32_t last_disp_update = 0;
|
uint32_t last_disp_update = 0;
|
||||||
uint8_t disp_target_fps = 7;
|
|
||||||
int disp_update_interval = 1000/disp_target_fps;
|
int disp_update_interval = 1000/disp_target_fps;
|
||||||
uint32_t last_page_flip = 0;
|
uint32_t last_page_flip = 0;
|
||||||
int page_interval = 4000;
|
int page_interval = 4000;
|
||||||
bool device_signatures_ok();
|
bool device_signatures_ok();
|
||||||
bool device_firmware_ok();
|
bool device_firmware_ok();
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
#define WATERFALL_SIZE 46
|
#define WATERFALL_SIZE 46
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
#define WATERFALL_SIZE 92
|
||||||
|
#else
|
||||||
|
// add more eink compatible boards here
|
||||||
|
#endif
|
||||||
|
|
||||||
int waterfall[WATERFALL_SIZE];
|
int waterfall[WATERFALL_SIZE];
|
||||||
int waterfall_head = 0;
|
int waterfall_head = 0;
|
||||||
|
|
||||||
@ -79,28 +150,35 @@ int p_ad_y = 0;
|
|||||||
int p_as_x = 0;
|
int p_as_x = 0;
|
||||||
int p_as_y = 0;
|
int p_as_y = 0;
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
GFXcanvas1 stat_area(64, 64);
|
GFXcanvas1 stat_area(64, 64);
|
||||||
GFXcanvas1 disp_area(64, 64);
|
GFXcanvas1 disp_area(64, 64);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
GFXcanvas1 stat_area(DISP_H, DISP_W/2);
|
||||||
|
GFXcanvas1 disp_area(DISP_H, DISP_W/2);
|
||||||
|
#endif
|
||||||
|
|
||||||
void update_area_positions() {
|
void update_area_positions() {
|
||||||
if (disp_mode == DISP_MODE_PORTRAIT) {
|
if (disp_mode == DISP_MODE_PORTRAIT) {
|
||||||
p_ad_x = 0;
|
p_ad_x = 0;
|
||||||
p_ad_y = 0;
|
p_ad_y = 0;
|
||||||
p_as_x = 0;
|
p_as_x = 0;
|
||||||
p_as_y = 64;
|
p_as_y = DISP_H;
|
||||||
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
|
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
|
||||||
p_ad_x = 0;
|
p_ad_x = 0;
|
||||||
p_ad_y = 0;
|
p_ad_y = 0;
|
||||||
p_as_x = 64;
|
p_as_x = DISP_H;
|
||||||
p_as_y = 0;
|
p_as_y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t display_contrast = 0x00;
|
uint8_t display_contrast = 0x00;
|
||||||
|
#if DISPLAY == OLED
|
||||||
void set_contrast(Adafruit_SSD1306 *display, uint8_t contrast) {
|
void set_contrast(Adafruit_SSD1306 *display, uint8_t contrast) {
|
||||||
display->ssd1306_command(SSD1306_SETCONTRAST);
|
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||||
display->ssd1306_command(contrast);
|
display.ssd1306_command(contrast);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool display_init() {
|
bool display_init() {
|
||||||
#if HAS_DISPLAY
|
#if HAS_DISPLAY
|
||||||
@ -131,6 +209,20 @@ bool display_init() {
|
|||||||
delay(50);
|
delay(50);
|
||||||
digitalWrite(pin_display_en, HIGH);
|
digitalWrite(pin_display_en, HIGH);
|
||||||
Wire.begin(SDA_OLED, SCL_OLED);
|
Wire.begin(SDA_OLED, SCL_OLED);
|
||||||
|
#elif BOARD_MODEL == BOARD_RAK4631
|
||||||
|
#if DISPLAY == OLED
|
||||||
|
#elif DISPLAY == EINK_BW || DISPLAY == EINK_3C
|
||||||
|
pinMode(pin_disp_en, INPUT_PULLUP);
|
||||||
|
digitalWrite(pin_disp_en, HIGH);
|
||||||
|
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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DISP_CUSTOM_ADDR == true
|
#if DISP_CUSTOM_ADDR == true
|
||||||
@ -145,10 +237,17 @@ bool display_init() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
if(!display.begin(SSD1306_SWITCHCAPVCC, display_address)) {
|
if(!display.begin(SSD1306_SWITCHCAPVCC, display_address)) {
|
||||||
|
#elif DISPLAY == EINK_BW || DISPLAY == EINK_3C
|
||||||
|
// don't check if display is actually connected
|
||||||
|
if(false) {
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
set_contrast(&display, display_contrast);
|
set_contrast(&display, display_contrast);
|
||||||
|
#endif
|
||||||
#if BOARD_MODEL == BOARD_RNODE_NG_20
|
#if BOARD_MODEL == BOARD_RNODE_NG_20
|
||||||
disp_mode = DISP_MODE_PORTRAIT;
|
disp_mode = DISP_MODE_PORTRAIT;
|
||||||
display.setRotation(3);
|
display.setRotation(3);
|
||||||
@ -170,6 +269,11 @@ bool display_init() {
|
|||||||
#elif BOARD_MODEL == BOARD_HELTEC32_V2
|
#elif BOARD_MODEL == BOARD_HELTEC32_V2
|
||||||
disp_mode = DISP_MODE_PORTRAIT;
|
disp_mode = DISP_MODE_PORTRAIT;
|
||||||
display.setRotation(1);
|
display.setRotation(1);
|
||||||
|
#elif BOARD_MODEL == BOARD_RAK4631
|
||||||
|
#if DISPLAY == OLED
|
||||||
|
#elif DISPLAY == EINK_BW || DISPLAY == EINK_3C
|
||||||
|
disp_mode = DISP_MODE_PORTRAIT;
|
||||||
|
#endif
|
||||||
#elif BOARD_MODEL == BOARD_HELTEC32_V3
|
#elif BOARD_MODEL == BOARD_HELTEC32_V3
|
||||||
disp_mode = DISP_MODE_PORTRAIT;
|
disp_mode = DISP_MODE_PORTRAIT;
|
||||||
// Antenna conx up
|
// Antenna conx up
|
||||||
@ -193,9 +297,9 @@ bool display_init() {
|
|||||||
display.cp437(true);
|
display.cp437(true);
|
||||||
|
|
||||||
#if HAS_EEPROM
|
#if HAS_EEPROM
|
||||||
uint8_t display_intensity = EEPROM.read(eeprom_addr(ADDR_CONF_DINT));
|
display_intensity = EEPROM.read(eeprom_addr(ADDR_CONF_DINT));
|
||||||
#elif MCU_VARIANT == MCU_NRF52
|
#elif MCU_VARIANT == MCU_NRF52
|
||||||
uint8_t display_intensity = eeprom_read(eeprom_addr(ADDR_CONF_DINT));
|
display_intensity = eeprom_read(eeprom_addr(ADDR_CONF_DINT));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -207,39 +311,83 @@ bool display_init() {
|
|||||||
|
|
||||||
void draw_cable_icon(int px, int py) {
|
void draw_cable_icon(int px, int py) {
|
||||||
if (cable_state == CABLE_STATE_DISCONNECTED) {
|
if (cable_state == CABLE_STATE_DISCONNECTED) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_cable+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_cable+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_cable+0*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else if (cable_state == CABLE_STATE_CONNECTED) {
|
} else if (cable_state == CABLE_STATE_CONNECTED) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_cable+1*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_cable+1*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_cable+1*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_bt_icon(int px, int py) {
|
void draw_bt_icon(int px, int py) {
|
||||||
if (bt_state == BT_STATE_OFF) {
|
if (bt_state == BT_STATE_OFF) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_bt+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_bt+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_bt+0*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else if (bt_state == BT_STATE_ON) {
|
} else if (bt_state == BT_STATE_ON) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_bt+1*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_bt+1*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_bt+1*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else if (bt_state == BT_STATE_PAIRING) {
|
} else if (bt_state == BT_STATE_PAIRING) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_bt+2*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_bt+2*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_bt+2*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else if (bt_state == BT_STATE_CONNECTED) {
|
} else if (bt_state == BT_STATE_CONNECTED) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_bt+3*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_bt+3*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_bt+3*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_bt+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_bt+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_bt+0*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_lora_icon(int px, int py) {
|
void draw_lora_icon(int px, int py) {
|
||||||
if (radio_online) {
|
if (radio_online) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_rf+1*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_rf+1*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_rf+1*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_rf+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_rf+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_rf+0*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_mw_icon(int px, int py) {
|
void draw_mw_icon(int px, int py) {
|
||||||
if (mw_radio_online) {
|
if (mw_radio_online) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_rf+3*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_rf+3*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_rf+3*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(px, py, bm_rf+2*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px, py, bm_rf+2*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(px, py, bm_rf+2*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,14 +405,25 @@ void draw_battery_bars(int px, int py) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (battery_indeterminate && battery_state == BATTERY_STATE_CHARGING) {
|
if (battery_indeterminate && battery_state == BATTERY_STATE_CHARGING) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||||
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.fillRect(px-2, py-2, 24, 9, GxEPD_BLACK);
|
||||||
|
stat_area.drawBitmap(px-2, py-5, bm_plug, 34, 13, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (battery_state == BATTERY_STATE_CHARGED) {
|
if (battery_state == BATTERY_STATE_CHARGED) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||||
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.fillRect(px-2, py-2, 24, 9, GxEPD_BLACK);
|
||||||
|
stat_area.drawBitmap(px-2, py-5, bm_plug, 34, 13, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// stat_area.fillRect(px, py, 14, 3, SSD1306_BLACK);
|
#if DISPLAY == OLED
|
||||||
|
stat_area.fillRect(px, py, 14, 3, SSD1306_BLACK);
|
||||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||||
stat_area.drawRect(px-2, py-2, 17, 7, SSD1306_WHITE);
|
stat_area.drawRect(px-2, py-2, 17, 7, SSD1306_WHITE);
|
||||||
stat_area.drawLine(px+15, py, px+15, py+3, SSD1306_WHITE);
|
stat_area.drawLine(px+15, py, px+15, py+3, SSD1306_WHITE);
|
||||||
@ -275,16 +434,42 @@ void draw_battery_bars(int px, int py) {
|
|||||||
if (battery_value > 59) stat_area.drawLine(px+4*2, py, px+4*2, py+2, SSD1306_WHITE);
|
if (battery_value > 59) stat_area.drawLine(px+4*2, py, px+4*2, py+2, SSD1306_WHITE);
|
||||||
if (battery_value > 72) stat_area.drawLine(px+5*2, py, px+5*2, py+2, SSD1306_WHITE);
|
if (battery_value > 72) stat_area.drawLine(px+5*2, py, px+5*2, py+2, SSD1306_WHITE);
|
||||||
if (battery_value > 85) stat_area.drawLine(px+6*2, py, px+6*2, py+2, SSD1306_WHITE);
|
if (battery_value > 85) stat_area.drawLine(px+6*2, py, px+6*2, py+2, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.fillRect(px, py, 20, 5, GxEPD_BLACK);
|
||||||
|
stat_area.fillRect(px-2, py-4, 34, 19, GxEPD_BLACK);
|
||||||
|
stat_area.drawRect(px-2, py-2, 23, 9, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+21, py, px+21, py+5, GxEPD_WHITE);
|
||||||
|
if (battery_value > 0) stat_area.drawLine(px, py, px, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 10) stat_area.drawLine(px+1*2, py, px+1*2, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 20) stat_area.drawLine(px+2*2, py, px+2*2, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 30) stat_area.drawLine(px+3*2, py, px+3*2, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 40) stat_area.drawLine(px+4*2, py, px+4*2, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 50) stat_area.drawLine(px+5*2, py, px+5*2, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 60) stat_area.drawLine(px+6*2, py, px+6*2, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 70) stat_area.drawLine(px+7*2, py, px+7*2, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 80) stat_area.drawLine(px+8*2, py, px+8*2, py+4, GxEPD_WHITE);
|
||||||
|
if (battery_value >= 90) stat_area.drawLine(px+9*2, py, px+9*2, py+4, GxEPD_WHITE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||||
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.fillRect(px-2, py-2, 24, 9, GxEPD_BLACK);
|
||||||
|
stat_area.drawBitmap(px-2, py-5, bm_plug, 34, 13, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||||
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.fillRect(px-2, py-2, 24, 9, GxEPD_BLACK);
|
||||||
|
stat_area.drawBitmap(px-2, py-5, bm_plug, 34, 13, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,8 +486,8 @@ void draw_quality_bars(int px, int py) {
|
|||||||
if (quality > 100.0) quality = 100.0;
|
if (quality > 100.0) quality = 100.0;
|
||||||
if (quality < 0.0) quality = 0.0;
|
if (quality < 0.0) quality = 0.0;
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.fillRect(px, py, 13, 7, SSD1306_BLACK);
|
stat_area.fillRect(px, py, 13, 7, SSD1306_BLACK);
|
||||||
// Serial.printf("Last SNR: %.2f\n, quality: %.2f\n", snr, quality);
|
|
||||||
if (quality > 0) stat_area.drawLine(px+0*2, py+7, px+0*2, py+6, SSD1306_WHITE);
|
if (quality > 0) stat_area.drawLine(px+0*2, py+7, px+0*2, py+6, SSD1306_WHITE);
|
||||||
if (quality > 15) stat_area.drawLine(px+1*2, py+7, px+1*2, py+5, SSD1306_WHITE);
|
if (quality > 15) stat_area.drawLine(px+1*2, py+7, px+1*2, py+5, SSD1306_WHITE);
|
||||||
if (quality > 30) stat_area.drawLine(px+2*2, py+7, px+2*2, py+4, SSD1306_WHITE);
|
if (quality > 30) stat_area.drawLine(px+2*2, py+7, px+2*2, py+4, SSD1306_WHITE);
|
||||||
@ -310,6 +495,38 @@ void draw_quality_bars(int px, int py) {
|
|||||||
if (quality > 60) stat_area.drawLine(px+4*2, py+7, px+4*2, py+2, SSD1306_WHITE);
|
if (quality > 60) stat_area.drawLine(px+4*2, py+7, px+4*2, py+2, SSD1306_WHITE);
|
||||||
if (quality > 75) stat_area.drawLine(px+5*2, py+7, px+5*2, py+1, SSD1306_WHITE);
|
if (quality > 75) stat_area.drawLine(px+5*2, py+7, px+5*2, py+1, SSD1306_WHITE);
|
||||||
if (quality > 90) stat_area.drawLine(px+6*2, py+7, px+6*2, py+0, SSD1306_WHITE);
|
if (quality > 90) stat_area.drawLine(px+6*2, py+7, px+6*2, py+0, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.fillRect(px, py, 26, 14, GxEPD_BLACK);
|
||||||
|
if (quality > 0) {
|
||||||
|
stat_area.drawLine(px+0*4, py+14, px+0*4, py+6, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+0*4+1, py+14, px+0*4+1, py+6, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (quality > 15) {
|
||||||
|
stat_area.drawLine(px+1*4, py+14, px+1*4, py+5, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+1*4+1, py+14, px+1*4+1, py+5, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (quality > 30) {
|
||||||
|
stat_area.drawLine(px+2*4, py+14, px+2*4, py+4, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+2*4+1, py+14, px+2*4+1, py+4, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (quality > 45) {
|
||||||
|
stat_area.drawLine(px+3*4, py+14, px+3*4, py+3, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+3*4+1, py+14, px+3*4+1, py+3, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (quality > 60) {
|
||||||
|
stat_area.drawLine(px+4*4, py+14, px+4*4, py+2, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+4*4+1, py+14, px+4*4+1, py+2, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (quality > 75) {
|
||||||
|
stat_area.drawLine(px+5*4, py+14, px+5*4, py+1, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+5*4+1, py+14, px+5*4+1, py+1, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (quality > 90) {
|
||||||
|
stat_area.drawLine(px+6*4, py+14, px+6*4, py+0, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+6*4+1, py+14, px+6*4+1, py+0, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Serial.printf("Last SNR: %.2f\n, quality: %.2f\n", snr, quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define S_RSSI_MIN -135.0
|
#define S_RSSI_MIN -135.0
|
||||||
@ -324,8 +541,8 @@ void draw_signal_bars(int px, int py) {
|
|||||||
if (signal > 100.0) signal = 100.0;
|
if (signal > 100.0) signal = 100.0;
|
||||||
if (signal < 0.0) signal = 0.0;
|
if (signal < 0.0) signal = 0.0;
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.fillRect(px, py, 13, 7, SSD1306_BLACK);
|
stat_area.fillRect(px, py, 13, 7, SSD1306_BLACK);
|
||||||
// Serial.printf("Last SNR: %.2f\n, quality: %.2f\n", snr, quality);
|
|
||||||
if (signal > 85) stat_area.drawLine(px+0*2, py+7, px+0*2, py+0, SSD1306_WHITE);
|
if (signal > 85) stat_area.drawLine(px+0*2, py+7, px+0*2, py+0, SSD1306_WHITE);
|
||||||
if (signal > 72) stat_area.drawLine(px+1*2, py+7, px+1*2, py+1, SSD1306_WHITE);
|
if (signal > 72) stat_area.drawLine(px+1*2, py+7, px+1*2, py+1, SSD1306_WHITE);
|
||||||
if (signal > 59) stat_area.drawLine(px+2*2, py+7, px+2*2, py+2, SSD1306_WHITE);
|
if (signal > 59) stat_area.drawLine(px+2*2, py+7, px+2*2, py+2, SSD1306_WHITE);
|
||||||
@ -333,12 +550,48 @@ void draw_signal_bars(int px, int py) {
|
|||||||
if (signal > 33) stat_area.drawLine(px+4*2, py+7, px+4*2, py+4, SSD1306_WHITE);
|
if (signal > 33) stat_area.drawLine(px+4*2, py+7, px+4*2, py+4, SSD1306_WHITE);
|
||||||
if (signal > 20) stat_area.drawLine(px+5*2, py+7, px+5*2, py+5, SSD1306_WHITE);
|
if (signal > 20) stat_area.drawLine(px+5*2, py+7, px+5*2, py+5, SSD1306_WHITE);
|
||||||
if (signal > 7) stat_area.drawLine(px+6*2, py+7, px+6*2, py+6, SSD1306_WHITE);
|
if (signal > 7) stat_area.drawLine(px+6*2, py+7, px+6*2, py+6, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.fillRect(px, py, 26, 14, GxEPD_BLACK);
|
||||||
|
if (signal > 85) {
|
||||||
|
stat_area.drawLine(px+0*4, py+14, px+0*4, py+0, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+0*4+1, py+14, px+0*4+1, py+0, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (signal > 72) {
|
||||||
|
stat_area.drawLine(px+1*4, py+14, px+1*4, py+1, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+1*4+1, py+14, px+1*4+1, py+1, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (signal > 59) {
|
||||||
|
stat_area.drawLine(px+2*4, py+14, px+2*4, py+2, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+2*4+1, py+14, px+2*4+1, py+2, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (signal > 46) {
|
||||||
|
stat_area.drawLine(px+3*4, py+14, px+3*4, py+3, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+3*4+1, py+14, px+3*4+1, py+3, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (signal > 33) {
|
||||||
|
stat_area.drawLine(px+4*4, py+14, px+4*4, py+4, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+4*4+1, py+14, px+4*4+1, py+4, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (signal > 20) {
|
||||||
|
stat_area.drawLine(px+5*4, py+14, px+5*4, py+5, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+5*4+1, py+14, px+5*4+1, py+5, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
if (signal > 7) {
|
||||||
|
stat_area.drawLine(px+6*4, py+14, px+6*4, py+6, GxEPD_WHITE);
|
||||||
|
stat_area.drawLine(px+6*4+1, py+14, px+6*4+1, py+6, GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Serial.printf("Last SNR: %.2f\n, quality: %.2f\n", snr, quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WF_RSSI_MAX -60
|
#define WF_RSSI_MAX -60
|
||||||
#define WF_RSSI_MIN -135
|
#define WF_RSSI_MIN -135
|
||||||
#define WF_RSSI_SPAN (WF_RSSI_MAX-WF_RSSI_MIN)
|
#define WF_RSSI_SPAN (WF_RSSI_MAX-WF_RSSI_MIN)
|
||||||
|
#if DISPLAY == OLED
|
||||||
#define WF_PIXEL_WIDTH 10
|
#define WF_PIXEL_WIDTH 10
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
#define WF_PIXEL_WIDTH 22
|
||||||
|
#endif
|
||||||
void draw_waterfall(int px, int py) {
|
void draw_waterfall(int px, int py) {
|
||||||
int rssi_val = current_rssi;
|
int rssi_val = current_rssi;
|
||||||
if (rssi_val < WF_RSSI_MIN) rssi_val = WF_RSSI_MIN;
|
if (rssi_val < WF_RSSI_MIN) rssi_val = WF_RSSI_MIN;
|
||||||
@ -348,55 +601,101 @@ void draw_waterfall(int px, int py) {
|
|||||||
waterfall[waterfall_head++] = rssi_normalised;
|
waterfall[waterfall_head++] = rssi_normalised;
|
||||||
if (waterfall_head >= WATERFALL_SIZE) waterfall_head = 0;
|
if (waterfall_head >= WATERFALL_SIZE) waterfall_head = 0;
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.fillRect(px,py,WF_PIXEL_WIDTH, WATERFALL_SIZE, SSD1306_BLACK);
|
stat_area.fillRect(px,py,WF_PIXEL_WIDTH, WATERFALL_SIZE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.fillRect(px,py,WF_PIXEL_WIDTH, WATERFALL_SIZE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
for (int i = 0; i < WATERFALL_SIZE; i++){
|
for (int i = 0; i < WATERFALL_SIZE; i++){
|
||||||
int wi = (waterfall_head+i)%WATERFALL_SIZE;
|
int wi = (waterfall_head+i)%WATERFALL_SIZE;
|
||||||
int ws = waterfall[wi];
|
int ws = waterfall[wi];
|
||||||
if (ws > 0) {
|
if (ws > 0) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawLine(px, py+i, px+ws-1, py+i, SSD1306_WHITE);
|
stat_area.drawLine(px, py+i, px+ws-1, py+i, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawLine(px, py+i, px+ws-1, py+i, GxEPD_WHITE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stat_area_intialised = false;
|
bool stat_area_initialised = false;
|
||||||
void draw_stat_area() {
|
void draw_stat_area() {
|
||||||
if (device_init_done) {
|
if (device_init_done) {
|
||||||
if (!stat_area_intialised) {
|
if (!stat_area_initialised) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
stat_area.drawBitmap(0, 0, bm_frame, 64, 64, SSD1306_WHITE, SSD1306_BLACK);
|
stat_area.drawBitmap(0, 0, bm_frame, 64, 64, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
stat_area_intialised = true;
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
stat_area.drawBitmap(0, 0, bm_frame, stat_area.width(), stat_area.height(), GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
|
stat_area_initialised = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
draw_cable_icon(3, 8);
|
draw_cable_icon(3, 8);
|
||||||
draw_bt_icon(3, 30);
|
draw_bt_icon(3, 30);
|
||||||
draw_lora_icon(45, 8);
|
draw_lora_icon(45, 8);
|
||||||
draw_mw_icon(45, 30);
|
draw_mw_icon(45, 30);
|
||||||
draw_battery_bars(4, 58);
|
draw_battery_bars(4, 58);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
draw_cable_icon(6, 18);
|
||||||
|
draw_bt_icon(6, 60);
|
||||||
|
draw_lora_icon(86, 18);
|
||||||
|
draw_mw_icon(86, 60);
|
||||||
|
draw_battery_bars(8, 113);
|
||||||
|
#endif
|
||||||
if (radio_online) {
|
if (radio_online) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
draw_quality_bars(28, 56);
|
draw_quality_bars(28, 56);
|
||||||
draw_signal_bars(44, 56);
|
draw_signal_bars(44, 56);
|
||||||
draw_waterfall(27, 4);
|
draw_waterfall(27, 4);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
draw_quality_bars(53, 109);
|
||||||
|
draw_signal_bars(83, 109);
|
||||||
|
draw_waterfall(50, 8);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_stat_area() {
|
void update_stat_area() {
|
||||||
if (eeprom_ok && !firmware_update_mode && !console_active) {
|
if (eeprom_ok && !firmware_update_mode && !console_active) {
|
||||||
|
|
||||||
draw_stat_area();
|
draw_stat_area();
|
||||||
if (disp_mode == DISP_MODE_PORTRAIT) {
|
if (disp_mode == DISP_MODE_PORTRAIT) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
display.drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
display.drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
display.drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
|
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
display.drawBitmap(p_as_x+2, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
display.drawBitmap(p_as_x+2, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
||||||
if (device_init_done && !disp_ext_fb) display.drawLine(p_as_x, 0, p_as_x, 64, SSD1306_WHITE);
|
if (device_init_done && !disp_ext_fb) display.drawLine(p_as_x, 0, p_as_x, 64, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
display.drawBitmap(p_as_x+2, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
if (device_init_done && !disp_ext_fb) display.drawLine(p_as_x, 0, p_as_x, DISP_W/2, GxEPD_WHITE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (firmware_update_mode) {
|
if (firmware_update_mode) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
display.drawBitmap(p_as_x, p_as_y, bm_updating, stat_area.width(), stat_area.height(), SSD1306_BLACK, SSD1306_WHITE);
|
display.drawBitmap(p_as_x, p_as_y, bm_updating, stat_area.width(), stat_area.height(), SSD1306_BLACK, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
display.drawBitmap(p_as_x, p_as_y, bm_updating, stat_area.width(), stat_area.height(), GxEPD_BLACK, GxEPD_WHITE);
|
||||||
|
#endif
|
||||||
} else if (console_active && device_init_done) {
|
} else if (console_active && device_init_done) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
display.drawBitmap(p_as_x, p_as_y, bm_console, stat_area.width(), stat_area.height(), SSD1306_BLACK, SSD1306_WHITE);
|
display.drawBitmap(p_as_x, p_as_y, bm_console, stat_area.width(), stat_area.height(), SSD1306_BLACK, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
display.drawBitmap(p_as_x, p_as_y, bm_console, stat_area.width(), stat_area.height(), GxEPD_BLACK, GxEPD_WHITE);
|
||||||
|
#endif
|
||||||
if (disp_mode == DISP_MODE_LANDSCAPE) {
|
if (disp_mode == DISP_MODE_LANDSCAPE) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
display.drawLine(p_as_x, 0, p_as_x, 64, SSD1306_WHITE);
|
display.drawLine(p_as_x, 0, p_as_x, 64, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
display.drawLine(p_as_x, 0, p_as_x, DISP_W/2, GxEPD_WHITE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,13 +709,23 @@ void draw_disp_area() {
|
|||||||
uint8_t p_by = 37;
|
uint8_t p_by = 37;
|
||||||
if (disp_mode == DISP_MODE_LANDSCAPE || firmware_update_mode) {
|
if (disp_mode == DISP_MODE_LANDSCAPE || firmware_update_mode) {
|
||||||
p_by = 18;
|
p_by = 18;
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.fillRect(0, 0, disp_area.width(), disp_area.height(), SSD1306_BLACK);
|
disp_area.fillRect(0, 0, disp_area.width(), disp_area.height(), SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.fillRect(0, 0, disp_area.width(), disp_area.height(), GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if DISPLAY == OLED
|
||||||
if (!device_init_done) disp_area.drawBitmap(0, p_by, bm_boot, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
if (!device_init_done) disp_area.drawBitmap(0, p_by, bm_boot, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
if (firmware_update_mode) disp_area.drawBitmap(0, p_by, bm_fw_update, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
if (firmware_update_mode) disp_area.drawBitmap(0, p_by, bm_fw_update, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
if (!device_init_done) disp_area.drawBitmap(0, p_by, bm_boot, disp_area.width(), 54, GxEPD_WHITE);
|
||||||
|
if (firmware_update_mode) disp_area.drawBitmap(0, p_by, bm_fw_update, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (!disp_ext_fb or bt_ssp_pin != 0) {
|
if (!disp_ext_fb or bt_ssp_pin != 0) {
|
||||||
if (radio_online && display_diagnostics) {
|
if (radio_online && display_diagnostics) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.fillRect(0,8,disp_area.width(),37, SSD1306_BLACK); disp_area.fillRect(0,37,disp_area.width(),27, SSD1306_WHITE);
|
disp_area.fillRect(0,8,disp_area.width(),37, SSD1306_BLACK); disp_area.fillRect(0,37,disp_area.width(),27, SSD1306_WHITE);
|
||||||
disp_area.setFont(SMALL_FONT); disp_area.setTextWrap(false); disp_area.setTextColor(SSD1306_WHITE);
|
disp_area.setFont(SMALL_FONT); disp_area.setTextWrap(false); disp_area.setTextColor(SSD1306_WHITE);
|
||||||
|
|
||||||
@ -427,32 +736,29 @@ void draw_disp_area() {
|
|||||||
disp_area.setCursor(21, 13);
|
disp_area.setCursor(21, 13);
|
||||||
disp_area.printf("%.1fKbps", (float)lora_bitrate/1000.0);
|
disp_area.printf("%.1fKbps", (float)lora_bitrate/1000.0);
|
||||||
|
|
||||||
//disp_area.setCursor(31, 23-1);
|
|
||||||
disp_area.setCursor(2, 23-1);
|
disp_area.setCursor(2, 23-1);
|
||||||
disp_area.print("Airtime:");
|
disp_area.print("Airtime:");
|
||||||
|
|
||||||
disp_area.setCursor(11, 33-1);
|
disp_area.setCursor(11, 33-1);
|
||||||
if (total_channel_util < 0.099) {
|
if (total_channel_util < 0.099) {
|
||||||
//disp_area.printf("%.1f%%", total_channel_util*100.0);
|
|
||||||
disp_area.printf("%.1f%%", airtime*100.0);
|
disp_area.printf("%.1f%%", airtime*100.0);
|
||||||
} else {
|
} else {
|
||||||
//disp_area.printf("%.0f%%", total_channel_util*100.0);
|
|
||||||
disp_area.printf("%.0f%%", airtime*100.0);
|
disp_area.printf("%.0f%%", airtime*100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
disp_area.drawBitmap(2, 26-1, bm_hg_low, 5, 9, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(2, 26-1, bm_hg_low, 5, 9, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
|
||||||
disp_area.setCursor(32+11, 33-1);
|
disp_area.setCursor(32+11, 33-1);
|
||||||
|
|
||||||
if (longterm_channel_util < 0.099) {
|
if (longterm_channel_util < 0.099) {
|
||||||
//disp_area.printf("%.1f%%", longterm_channel_util*100.0);
|
|
||||||
disp_area.printf("%.1f%%", longterm_airtime*100.0);
|
disp_area.printf("%.1f%%", longterm_airtime*100.0);
|
||||||
} else {
|
} else {
|
||||||
//disp_area.printf("%.0f%%", longterm_channel_util*100.0);
|
|
||||||
disp_area.printf("%.0f%%", longterm_airtime*100.0);
|
disp_area.printf("%.0f%%", longterm_airtime*100.0);
|
||||||
}
|
}
|
||||||
disp_area.drawBitmap(32+2, 26-1, bm_hg_high, 5, 9, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(32+2, 26-1, bm_hg_high, 5, 9, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
|
||||||
|
|
||||||
disp_area.setTextColor(SSD1306_BLACK);
|
disp_area.setTextColor(SSD1306_BLACK);
|
||||||
|
|
||||||
disp_area.setCursor(2, 46);
|
disp_area.setCursor(2, 46);
|
||||||
disp_area.print("Channel");
|
disp_area.print("Channel");
|
||||||
disp_area.setCursor(38, 46);
|
disp_area.setCursor(38, 46);
|
||||||
@ -460,51 +766,132 @@ void draw_disp_area() {
|
|||||||
|
|
||||||
disp_area.setCursor(11, 57);
|
disp_area.setCursor(11, 57);
|
||||||
if (total_channel_util < 0.099) {
|
if (total_channel_util < 0.099) {
|
||||||
//disp_area.printf("%.1f%%", airtime*100.0);
|
|
||||||
disp_area.printf("%.1f%%", total_channel_util*100.0);
|
disp_area.printf("%.1f%%", total_channel_util*100.0);
|
||||||
} else {
|
} else {
|
||||||
//disp_area.printf("%.0f%%", airtime*100.0);
|
|
||||||
disp_area.printf("%.0f%%", total_channel_util*100.0);
|
disp_area.printf("%.0f%%", total_channel_util*100.0);
|
||||||
}
|
}
|
||||||
disp_area.drawBitmap(2, 50, bm_hg_low, 5, 9, SSD1306_BLACK, SSD1306_WHITE);
|
disp_area.drawBitmap(2, 50, bm_hg_low, 5, 9, SSD1306_BLACK, SSD1306_WHITE);
|
||||||
|
|
||||||
disp_area.setCursor(32+11, 57);
|
disp_area.setCursor(32+11, 57);
|
||||||
if (longterm_channel_util < 0.099) {
|
if (longterm_channel_util < 0.099) {
|
||||||
//disp_area.printf("%.1f%%", longterm_airtime*100.0);
|
|
||||||
disp_area.printf("%.1f%%", longterm_channel_util*100.0);
|
disp_area.printf("%.1f%%", longterm_channel_util*100.0);
|
||||||
} else {
|
} else {
|
||||||
//disp_area.printf("%.0f%%", longterm_airtime*100.0);
|
|
||||||
disp_area.printf("%.0f%%", longterm_channel_util*100.0);
|
disp_area.printf("%.0f%%", longterm_channel_util*100.0);
|
||||||
}
|
}
|
||||||
disp_area.drawBitmap(32+2, 50, bm_hg_high, 5, 9, SSD1306_BLACK, SSD1306_WHITE);
|
disp_area.drawBitmap(32+2, 50, bm_hg_high, 5, 9, SSD1306_BLACK, SSD1306_WHITE);
|
||||||
|
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.fillRect(0,12,disp_area.width(),57, GxEPD_BLACK); disp_area.fillRect(0,69,disp_area.width(),56, GxEPD_WHITE);
|
||||||
|
disp_area.setFont(SMALL_FONT); disp_area.setTextWrap(false); disp_area.setTextColor(GxEPD_WHITE);
|
||||||
|
disp_area.setTextSize(2); // scale text 2x
|
||||||
|
|
||||||
|
disp_area.setCursor(2, 22);
|
||||||
|
disp_area.print("On");
|
||||||
|
disp_area.setCursor(14*2, 22);
|
||||||
|
disp_area.print("@");
|
||||||
|
disp_area.setCursor(21*2, 22);
|
||||||
|
disp_area.printf("%.1fKbps", (float)lora_bitrate/1000.0);
|
||||||
|
|
||||||
|
disp_area.setCursor(2, 36);
|
||||||
|
disp_area.print("Airtime:");
|
||||||
|
|
||||||
|
disp_area.setCursor(7+12, 53);
|
||||||
|
if (total_channel_util < 0.099) {
|
||||||
|
disp_area.printf("%.1f%%", airtime*100.0);
|
||||||
|
} else {
|
||||||
|
disp_area.printf("%.0f%%", airtime*100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
disp_area.drawBitmap(2, 41, bm_hg_low, 10, 18, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
|
||||||
|
disp_area.setCursor(64+17, 53);
|
||||||
|
if (longterm_channel_util < 0.099) {
|
||||||
|
disp_area.printf("%.1f%%", longterm_airtime*100.0);
|
||||||
|
} else {
|
||||||
|
disp_area.printf("%.0f%%", longterm_airtime*100.0);
|
||||||
|
}
|
||||||
|
disp_area.drawBitmap(64, 41, bm_hg_high, 10, 18, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
|
||||||
|
disp_area.setTextColor(GxEPD_BLACK);
|
||||||
|
|
||||||
|
disp_area.setCursor(2, 88);
|
||||||
|
disp_area.print("Channel");
|
||||||
|
disp_area.setCursor(38*2, 88);
|
||||||
|
disp_area.print("Load:");
|
||||||
|
|
||||||
|
disp_area.setCursor(7+12, 110);
|
||||||
|
if (total_channel_util < 0.099) {
|
||||||
|
disp_area.printf("%.1f%%", total_channel_util*100.0);
|
||||||
|
} else {
|
||||||
|
disp_area.printf("%.0f%%", total_channel_util*100.0);
|
||||||
|
}
|
||||||
|
disp_area.drawBitmap(2, 98, bm_hg_low, 10, 18, GxEPD_BLACK, GxEPD_WHITE);
|
||||||
|
|
||||||
|
disp_area.setCursor(64+17, 110);
|
||||||
|
if (longterm_channel_util < 0.099) {
|
||||||
|
disp_area.printf("%.1f%%", longterm_channel_util*100.0);
|
||||||
|
} else {
|
||||||
|
disp_area.printf("%.0f%%", longterm_channel_util*100.0);
|
||||||
|
}
|
||||||
|
disp_area.drawBitmap(64, 98, bm_hg_high, 10, 18, GxEPD_BLACK, GxEPD_WHITE);
|
||||||
|
#endif
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (device_signatures_ok()) {
|
if (device_signatures_ok()) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 0, bm_def_lc, disp_area.width(), 37, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 0, bm_def_lc, disp_area.width(), 37, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 0, bm_def_lc, disp_area.width(), 71, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 0, bm_def, disp_area.width(), 37, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 0, bm_def, disp_area.width(), 37, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 0, bm_def, disp_area.width(), 71, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hw_ready || radio_error || !device_firmware_ok()) {
|
if (!hw_ready || radio_error || !device_firmware_ok()) {
|
||||||
if (!device_firmware_ok()) {
|
if (!device_firmware_ok()) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_fw_corrupt, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_fw_corrupt, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_fw_corrupt, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (!modem_installed) {
|
if (!modem_installed) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_no_radio, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_no_radio, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_no_radio, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_hwfail, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_hwfail, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_hwfail, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (bt_state == BT_STATE_PAIRING and bt_ssp_pin != 0) {
|
} else if (bt_state == BT_STATE_PAIRING and bt_ssp_pin != 0) {
|
||||||
char *pin_str = (char*)malloc(DISP_PIN_SIZE+1);
|
char *pin_str = (char*)malloc(DISP_PIN_SIZE+1);
|
||||||
sprintf(pin_str, "%06d", bt_ssp_pin);
|
sprintf(pin_str, "%06d", bt_ssp_pin);
|
||||||
|
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_pairing, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_pairing, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_pairing, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
for (int i = 0; i < DISP_PIN_SIZE; i++) {
|
for (int i = 0; i < DISP_PIN_SIZE; i++) {
|
||||||
uint8_t numeric = pin_str[i]-48;
|
uint8_t numeric = pin_str[i]-48;
|
||||||
|
#if DISPLAY == OLED
|
||||||
uint8_t offset = numeric*5;
|
uint8_t offset = numeric*5;
|
||||||
disp_area.drawBitmap(7+9*i, 37+16, bm_n_uh+offset, 8, 5, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(7+9*i, 37+16, bm_n_uh+offset, 8, 5, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
uint8_t offset = numeric*20;
|
||||||
|
disp_area.drawBitmap(14+17*i, 71+32, bm_n_uh+offset, 10, 10, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
free(pin_str);
|
free(pin_str);
|
||||||
} else {
|
} else {
|
||||||
@ -516,64 +903,119 @@ void draw_disp_area() {
|
|||||||
|
|
||||||
if (radio_online) {
|
if (radio_online) {
|
||||||
if (!display_diagnostics) {
|
if (!display_diagnostics) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_online, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_online, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_online, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (disp_page == 0) {
|
if (disp_page == 0) {
|
||||||
if (true || device_signatures_ok()) {
|
if (true || device_signatures_ok()) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_checks, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_checks, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_checks, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_nfr, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_nfr, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_nfr, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else if (disp_page == 1) {
|
} else if (disp_page == 1) {
|
||||||
if (!console_active) {
|
if (!console_active) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_hwok, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_hwok, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_hwok, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_console_active, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_console_active, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_console_active, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else if (disp_page == 2) {
|
} else if (disp_page == 2) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 37, bm_version, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 37, bm_version, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 71, bm_version, disp_area.width(), 54, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
char *v_str = (char*)malloc(3+1);
|
char *v_str = (char*)malloc(3+1);
|
||||||
sprintf(v_str, "%01d%02d", MAJ_VERS, MIN_VERS);
|
sprintf(v_str, "%01d%02d", MAJ_VERS, MIN_VERS);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
uint8_t numeric = v_str[i]-48; uint8_t bm_offset = numeric*5;
|
#if DISPLAY == OLED
|
||||||
uint8_t dxp = 20;
|
uint8_t dxp = 20;
|
||||||
if (i == 1) dxp += 9*1+4;
|
uint8_t numeric = v_str[i]-48; uint8_t bm_offset = numeric*5;
|
||||||
if (i == 2) dxp += 9*2+4;
|
if (i == 2) dxp += 9*2+4;
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
uint8_t dxp = 43;
|
||||||
|
uint8_t numeric = v_str[i]-48; uint8_t bm_offset = numeric*20;
|
||||||
|
if (i == 2) dxp += 9*2+6;
|
||||||
|
#endif
|
||||||
|
if (i == 1) dxp += 9*1+4;
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(dxp, 37+16, bm_n_uh+bm_offset, 8, 5, SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(dxp, 37+16, bm_n_uh+bm_offset, 8, 5, SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
// add gap manually rather than oversizing bitmap, as the gfx lib fills in the extra space with black
|
||||||
|
disp_area.drawBitmap(dxp, 71+32, bm_n_uh+bm_offset, 10, 10, GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
free(v_str);
|
free(v_str);
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawLine(27, 37+19, 28, 37+19, SSD1306_BLACK);
|
disp_area.drawLine(27, 37+19, 28, 37+19, SSD1306_BLACK);
|
||||||
disp_area.drawLine(27, 37+20, 28, 37+20, SSD1306_BLACK);
|
disp_area.drawLine(27, 37+19, 28, 37+19, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawLine(27, 37+20, 28, 37+20, GxEPD_BLACK);
|
||||||
|
disp_area.drawLine(27, 37+20, 28, 37+20, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#if DISPLAY == OLED
|
||||||
disp_area.drawBitmap(0, 0, fb, disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
disp_area.drawBitmap(0, 0, fb, disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
disp_area.drawBitmap(0, 0, fb, disp_area.width(), disp_area.height(), GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_disp_area() {
|
void update_disp_area() {
|
||||||
draw_disp_area();
|
draw_disp_area();
|
||||||
|
#if DISPLAY == OLED
|
||||||
display.drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
display.drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
display.drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), GxEPD_WHITE, GxEPD_BLACK);
|
||||||
|
#endif
|
||||||
if (disp_mode == DISP_MODE_LANDSCAPE) {
|
if (disp_mode == DISP_MODE_LANDSCAPE) {
|
||||||
if (device_init_done && !firmware_update_mode && !disp_ext_fb) {
|
if (device_init_done && !firmware_update_mode && !disp_ext_fb) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
display.drawLine(0, 0, 0, 63, SSD1306_WHITE);
|
display.drawLine(0, 0, 0, 63, SSD1306_WHITE);
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
display.drawLine(0, 0, 0, 63, GxEPD_WHITE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_display(bool blank = false) {
|
void update_display(bool blank = false) {
|
||||||
if (blank) {
|
if (blank) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
if (display_contrast != display_intensity) {
|
if (display_contrast != display_intensity) {
|
||||||
display_contrast = display_intensity;
|
display_contrast = display_intensity;
|
||||||
set_contrast(&display, display_contrast);
|
set_contrast(&display, display_contrast);
|
||||||
}
|
}
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
|
#endif
|
||||||
display.display();
|
display.display();
|
||||||
} else {
|
} else {
|
||||||
if (millis()-last_disp_update >= disp_update_interval) {
|
if (millis()-last_disp_update >= disp_update_interval) {
|
||||||
|
#if DISPLAY == OLED
|
||||||
if (display_contrast != display_intensity) {
|
if (display_contrast != display_intensity) {
|
||||||
display_contrast = display_intensity;
|
display_contrast = display_intensity;
|
||||||
set_contrast(&display, display_contrast);
|
set_contrast(&display, display_contrast);
|
||||||
@ -582,6 +1024,13 @@ void update_display(bool blank = false) {
|
|||||||
update_stat_area();
|
update_stat_area();
|
||||||
update_disp_area();
|
update_disp_area();
|
||||||
display.display();
|
display.display();
|
||||||
|
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||||
|
display.setFullWindow();
|
||||||
|
display.fillScreen(GxEPD_WHITE);
|
||||||
|
update_stat_area();
|
||||||
|
update_disp_area();
|
||||||
|
display.display(true);
|
||||||
|
#endif
|
||||||
last_disp_update = millis();
|
last_disp_update = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ This entry should include, at a minimum, the following:
|
|||||||
* RX and TX leds (preferably LEDs of different colours)
|
* RX and TX leds (preferably LEDs of different colours)
|
||||||
|
|
||||||
An example of a minimal entry can be seen below:
|
An example of a minimal entry can be seen below:
|
||||||
`
|
```
|
||||||
#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD
|
#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_PMU true
|
#define HAS_PMU true
|
||||||
@ -28,7 +28,7 @@ An example of a minimal entry can be seen below:
|
|||||||
// const int pin_busy = 0; not present
|
// const int pin_busy = 0; not present
|
||||||
const int pin_led_rx = 5;
|
const int pin_led_rx = 5;
|
||||||
const int pin_led_tx = 6;
|
const int pin_led_tx = 6;
|
||||||
`
|
```
|
||||||
|
|
||||||
In some cases the SPI pins will not be required, as they will be the default pins for the SPI library supporting the board anyway, and therefore do not need overriding in the config.
|
In some cases the SPI pins will not be required, as they will be the default pins for the SPI library supporting the board anyway, and therefore do not need overriding in the config.
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ If the SX1262 is being used the following should also be considered:
|
|||||||
* the enable pin for the TCXO (if present)
|
* the enable pin for the TCXO (if present)
|
||||||
|
|
||||||
An example of an entry using the SX1262 modem can be seen below:
|
An example of an entry using the SX1262 modem can be seen below:
|
||||||
`
|
```
|
||||||
#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD
|
#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_PMU true
|
#define HAS_PMU true
|
||||||
@ -62,13 +62,13 @@ An example of an entry using the SX1262 modem can be seen below:
|
|||||||
const int pin_tcxo_enable = -1;
|
const int pin_tcxo_enable = -1;
|
||||||
const int pin_led_rx = 5;
|
const int pin_led_rx = 5;
|
||||||
const int pin_led_tx = 6;
|
const int pin_led_tx = 6;
|
||||||
`
|
```
|
||||||
|
|
||||||
If the SX1280 is being used, the following should also be added:
|
If the SX1280 is being used, the following should also be added:
|
||||||
* the TXEN and RXEN pins
|
* the TXEN and RXEN pins
|
||||||
|
|
||||||
An example of an entry using the SX1280 modem can be seen below:
|
An example of an entry using the SX1280 modem can be seen below:
|
||||||
`
|
```
|
||||||
#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD
|
#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD
|
||||||
#define HAS_BLUETOOTH true
|
#define HAS_BLUETOOTH true
|
||||||
#define HAS_PMU true
|
#define HAS_PMU true
|
||||||
@ -91,12 +91,12 @@ An example of an entry using the SX1280 modem can be seen below:
|
|||||||
const int pin_tcxo_enable = -1;
|
const int pin_tcxo_enable = -1;
|
||||||
const int pin_led_rx = 5;
|
const int pin_led_rx = 5;
|
||||||
const int pin_led_tx = 6;
|
const int pin_led_tx = 6;
|
||||||
`
|
```
|
||||||
|
|
||||||
Please submit this, and any other support in different areas of the project your board may require, as a PR for my consideration.
|
Please submit this, and any other support in different areas of the project your board may require, as a PR for my consideration.
|
||||||
|
|
||||||
# Feature request
|
# Feature request
|
||||||
Feature requests are welcomed, given that those requesting it are happy to write it themselves, or a contributor considers it to be important enough to them to write it themselves. They must be written and **properly** tested before being proposed as a pull request for the project on [GitHub](https://github.com/liberatedsystems/RNode_Firmware_CE). **Manufacturers are encouraged to contribute support for their products back to this repository**, and such support will be receieved gladly, given it does not effect support for other products or boards.
|
Feature requests are welcomed, given that those requesting it are happy to write it themselves, or a contributor considers it to be important enough to them to write it themselves. They must be written and **properly** tested before being proposed as a pull request for the project on [GitHub](https://github.com/liberatedsystems/RNode_Firmware_CE). **Manufacturers are encouraged to contribute support for their products back to this repository**, and such support will be received gladly, given it does not effect support for other products or boards.
|
||||||
|
|
||||||
# Caveat
|
# Caveat
|
||||||
All contributions must not be written using **any** LLM (ChatGPT, etc.), please handwrite them **only**. Any PRs with proposed contributions which have been discovered to be written using an LLM will **NOT** be merged. The contributor concerned may rewrite their entire pull request **by hand** and it may be reconsidered for merging in the future.
|
All contributions must not be written using **any** LLM (ChatGPT, etc.), please handwrite them **only**. Any PRs with proposed contributions which have been discovered to be written using an LLM will **NOT** be merged. The contributor concerned may rewrite their entire pull request **by hand** and it may be reconsidered for merging in the future.
|
1676
Graphics.h
1676
Graphics.h
File diff suppressed because it is too large
Load Diff
95
Power.h
95
Power.h
@ -44,6 +44,26 @@
|
|||||||
int bat_charged_samples = 0;
|
int bat_charged_samples = 0;
|
||||||
bool bat_voltage_dropping = false;
|
bool bat_voltage_dropping = false;
|
||||||
float bat_delay_v = 0;
|
float bat_delay_v = 0;
|
||||||
|
#elif BOARD_MODEL == BOARD_RAK4631
|
||||||
|
#include "nrfx_power.h"
|
||||||
|
#define BAT_C_SAMPLES 7
|
||||||
|
#define BAT_D_SAMPLES 2
|
||||||
|
#define BAT_V_MIN 2.75
|
||||||
|
#define BAT_V_MAX 4.2
|
||||||
|
#define BAT_V_FLOAT 4.22
|
||||||
|
#define BAT_SAMPLES 5
|
||||||
|
#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12 - bit ADC resolution = 3000mV / 4096
|
||||||
|
#define VBAT_DIVIDER_COMP (1.73) // Compensation factor for the VBAT divider
|
||||||
|
#define VBAT_MV_PER_LSB_FIN (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
|
||||||
|
#define PIN_VBAT WB_A0
|
||||||
|
float bat_p_samples[BAT_SAMPLES];
|
||||||
|
float bat_v_samples[BAT_SAMPLES];
|
||||||
|
uint8_t bat_samples_count = 0;
|
||||||
|
int bat_discharging_samples = 0;
|
||||||
|
int bat_charging_samples = 0;
|
||||||
|
int bat_charged_samples = 0;
|
||||||
|
bool bat_voltage_dropping = false;
|
||||||
|
float bat_delay_v = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t last_pmu_update = 0;
|
uint32_t last_pmu_update = 0;
|
||||||
@ -193,6 +213,66 @@ void measure_battery() {
|
|||||||
else {
|
else {
|
||||||
battery_ready = false;
|
battery_ready = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif BOARD_MODEL == BOARD_RAK4631
|
||||||
|
battery_installed = true;
|
||||||
|
battery_indeterminate = false;
|
||||||
|
|
||||||
|
bat_v_samples[bat_samples_count%BAT_SAMPLES] = (float)(analogRead(PIN_VBAT)) * VBAT_MV_PER_LSB_FIN;
|
||||||
|
|
||||||
|
if (bat_v_samples[bat_samples_count%BAT_SAMPLES] < 3300) {
|
||||||
|
bat_p_samples[bat_samples_count%BAT_SAMPLES] = 0;
|
||||||
|
}
|
||||||
|
else if (bat_v_samples[bat_samples_count%BAT_SAMPLES] < 3600)
|
||||||
|
{
|
||||||
|
bat_v_samples[bat_samples_count%BAT_SAMPLES] -= 3300;
|
||||||
|
bat_p_samples[bat_samples_count%BAT_SAMPLES] = bat_v_samples[bat_samples_count%BAT_SAMPLES] / 30;
|
||||||
|
} else {
|
||||||
|
bat_v_samples[bat_samples_count%BAT_SAMPLES] -= 3600;
|
||||||
|
}
|
||||||
|
bat_p_samples[bat_samples_count%BAT_SAMPLES] = 10 + (bat_v_samples[bat_samples_count%BAT_SAMPLES] * 0.15F);
|
||||||
|
|
||||||
|
bat_samples_count++;
|
||||||
|
if (!battery_ready && bat_samples_count >= BAT_SAMPLES) {
|
||||||
|
battery_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
battery_percent = 0;
|
||||||
|
for (uint8_t bi = 0; bi < BAT_SAMPLES; bi++) {
|
||||||
|
battery_percent += bat_p_samples[bi];
|
||||||
|
}
|
||||||
|
battery_percent = battery_percent/BAT_SAMPLES;
|
||||||
|
|
||||||
|
battery_voltage = 0;
|
||||||
|
for (uint8_t bi = 0; bi < BAT_SAMPLES; bi++) {
|
||||||
|
battery_voltage += bat_v_samples[bi];
|
||||||
|
}
|
||||||
|
battery_voltage = battery_voltage/BAT_SAMPLES;
|
||||||
|
|
||||||
|
if (bat_delay_v == 0) bat_delay_v = battery_voltage;
|
||||||
|
if (battery_percent > 100.0) battery_percent = 100.0;
|
||||||
|
if (battery_percent < 0.0) battery_percent = 0.0;
|
||||||
|
|
||||||
|
if (bat_samples_count%BAT_SAMPLES == 0) {
|
||||||
|
if (battery_voltage < bat_delay_v && battery_voltage < BAT_V_FLOAT) {
|
||||||
|
bat_voltage_dropping = true;
|
||||||
|
} else {
|
||||||
|
bat_voltage_dropping = false;
|
||||||
|
}
|
||||||
|
bat_samples_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrfx_power_usb_state_t usbstate = nrfx_power_usbstatus_get();
|
||||||
|
if (usbstate == NRFX_POWER_USB_STATE_CONNECTED || usbstate == NRFX_POWER_USB_STATE_READY) {
|
||||||
|
// charging
|
||||||
|
battery_state = BATTERY_STATE_CHARGING;
|
||||||
|
} else {
|
||||||
|
battery_state = BATTERY_STATE_DISCHARGING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battery_percent >= 98) {
|
||||||
|
battery_state = BATTERY_STATE_CHARGED;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (battery_ready) {
|
if (battery_ready) {
|
||||||
@ -340,6 +420,21 @@ bool init_pmu() {
|
|||||||
// Set the time of pressing the button to turn off
|
// Set the time of pressing the button to turn off
|
||||||
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#elif BOARD_MODEL == BOARD_RAK4631
|
||||||
|
// board doesn't have PMU but we can measure batt voltage
|
||||||
|
|
||||||
|
// prep ADC for reading battery level
|
||||||
|
analogReference(AR_INTERNAL_3_0);
|
||||||
|
|
||||||
|
// Set the resolution to 12-bit (0..4095)
|
||||||
|
analogReadResolution(12);
|
||||||
|
|
||||||
|
// Let the ADC settle
|
||||||
|
delay(1);
|
||||||
|
|
||||||
|
// Get a single ADC sample and throw it away
|
||||||
|
float raw = analogRead(PIN_VBAT);
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
|
@ -43,7 +43,7 @@ You must have at least version `2.1.3` of `rnodeconf` installed to update the RN
|
|||||||
| Heltec LoRa32 v3 | [Buy here](https://heltec.org/project/wifi-lora-32-v3/) | SX1276/8 | ESP32 |
|
| Heltec LoRa32 v3 | [Buy here](https://heltec.org/project/wifi-lora-32-v3/) | SX1276/8 | ESP32 |
|
||||||
| Homebrew ESP32 boards | | Any supported | ESP32 | This can be any board with an Adafruit Feather (or generic) ESP32 chip |
|
| Homebrew ESP32 boards | | Any supported | ESP32 | This can be any board with an Adafruit Feather (or generic) ESP32 chip |
|
||||||
|
|
||||||
It's easy to create your own RNodes from one of the supported development boards and devices. If a device or board you want to use is not yet supported, you are welcome to [join the effort](/CONTRIBUTING.md) and help create a board definition and pin mapping for it!
|
It's easy to create your own RNodes from one of the supported development boards and devices. If a device or board you want to use is not yet supported, you are welcome to [join the effort](Documentation/CONTRIBUTING.md) and help create a board definition and pin mapping for it!
|
||||||
|
|
||||||
<!--<img src="Documentation/images/devboards_1.webp" width="100%"/>-->
|
<!--<img src="Documentation/images/devboards_1.webp" width="100%"/>-->
|
||||||
|
|
||||||
@ -113,6 +113,9 @@ For more detailed instruction and in-depth guides, you can have a look at some o
|
|||||||
- Once you've got the hang of it, start building RNodes for your community, or [even for selling them](https://unsigned.io/sell_rnodes.html)
|
- Once you've got the hang of it, start building RNodes for your community, or [even for selling them](https://unsigned.io/sell_rnodes.html)
|
||||||
|
|
||||||
## Support development
|
## Support development
|
||||||
|
### Contributing
|
||||||
|
You can contribute features and board support to the project if you wish. Please see [here](Documentation/CONTRIBUTING.md).
|
||||||
|
|
||||||
### Hardware donations
|
### Hardware donations
|
||||||
If you would like to see support added for a board which you possess, you may donate it to myself, Jacob Eva, so that I can implement support for it into this project. There will be no official timescale given for implementation however, but I will try my best when I have time :) Please [contact me (scroll to the bottom)](https://liberatedsystems.co.uk/about) if you wish to donate hardware to the project.
|
If you would like to see support added for a board which you possess, you may donate it to myself, Jacob Eva, so that I can implement support for it into this project. There will be no official timescale given for implementation however, but I will try my best when I have time :) Please [contact me (scroll to the bottom)](https://liberatedsystems.co.uk/about) if you wish to donate hardware to the project.
|
||||||
|
|
||||||
@ -139,6 +142,9 @@ You can help support the continued development of open, free and private communi
|
|||||||
```
|
```
|
||||||
- Ko-Fi: https://ko-fi.com/markqvist
|
- Ko-Fi: https://ko-fi.com/markqvist
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
Please see [here](Documentation/FAQ.md).
|
||||||
|
|
||||||
## License & Use
|
## License & Use
|
||||||
The upstream RNode Firmware is Copyright © 2024 Mark Qvist / [unsigned.io](https://unsigned.io).
|
The upstream RNode Firmware is Copyright © 2024 Mark Qvist / [unsigned.io](https://unsigned.io).
|
||||||
The modified RNode Firmware CE (community edition) is Copyright © Jacob Eva / [Liberated Embedded Systems](https://liberatedsystems.co.uk) and is made available under the **GNU General Public License v3.0**.
|
The modified RNode Firmware CE (community edition) is Copyright © Jacob Eva / [Liberated Embedded Systems](https://liberatedsystems.co.uk) and is made available under the **GNU General Public License v3.0**.
|
||||||
|
@ -166,6 +166,11 @@ void setup() {
|
|||||||
eeprom_update(eeprom_addr(ADDR_CONF_DSET), CONF_OK_BYTE);
|
eeprom_update(eeprom_addr(ADDR_CONF_DSET), CONF_OK_BYTE);
|
||||||
eeprom_update(eeprom_addr(ADDR_CONF_DINT), 0xFF);
|
eeprom_update(eeprom_addr(ADDR_CONF_DINT), 0xFF);
|
||||||
}
|
}
|
||||||
|
#if DISPLAY == EINK_BW || DISPLAY == EINK_3C
|
||||||
|
// Poll and process incoming serial commands whilst e-ink display is
|
||||||
|
// refreshing to make device still seem responsive
|
||||||
|
display_add_callback(process_serial);
|
||||||
|
#endif
|
||||||
disp_ready = display_init();
|
disp_ready = display_init();
|
||||||
update_display();
|
update_display();
|
||||||
#endif
|
#endif
|
||||||
@ -1310,6 +1315,11 @@ void loop() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void process_serial() {
|
||||||
|
buffer_serial();
|
||||||
|
if (!fifo_isempty(&serialFIFO)) serial_poll();
|
||||||
|
}
|
||||||
|
|
||||||
void sleep_now() {
|
void sleep_now() {
|
||||||
#if HAS_SLEEP == true
|
#if HAS_SLEEP == true
|
||||||
#if BOARD_MODEL == BOARD_RNODE_NG_22
|
#if BOARD_MODEL == BOARD_RNODE_NG_22
|
||||||
|
Loading…
Reference in New Issue
Block a user