mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-02 08:00:38 +00:00
Compare commits
83 Commits
v1.3.42.9b
...
v1.3.44.4f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fa8d02b08 | ||
|
|
43fb0d80f1 | ||
|
|
b25ace14e5 | ||
|
|
8734751bc4 | ||
|
|
5559a1edb0 | ||
|
|
bf503354f3 | ||
|
|
7b10441a28 | ||
|
|
994e396c00 | ||
|
|
6e22ee9061 | ||
|
|
b5fb0f60b0 | ||
|
|
a7fe69ed6b | ||
|
|
7f05298172 | ||
|
|
92a2505056 | ||
|
|
aae9d2fcf6 | ||
|
|
b59e928589 | ||
|
|
1db08b3b0e | ||
|
|
2cf3c105a1 | ||
|
|
505e4e8176 | ||
|
|
49a9973548 | ||
|
|
18af9d734d | ||
|
|
3e22aafea8 | ||
|
|
434db4347b | ||
|
|
b2c3b405b1 | ||
|
|
4bc8f6a6b9 | ||
|
|
4534d17d79 | ||
|
|
f88dde2f60 | ||
|
|
f8982ddaf8 | ||
|
|
784cd8c6f1 | ||
|
|
c3ab8f12cf | ||
|
|
b5adb7babc | ||
|
|
62c809a596 | ||
|
|
d2fe4426c1 | ||
|
|
984f0ca12c | ||
|
|
9d3eba9ea4 | ||
|
|
323f81eaba | ||
|
|
8d0e25fd82 | ||
|
|
20eaddee58 | ||
|
|
30b1bd85d9 | ||
|
|
09cce094d1 | ||
|
|
33a208e3c4 | ||
|
|
dd4c4fba80 | ||
|
|
a17c40ad09 | ||
|
|
9d73e606ac | ||
|
|
da12360105 | ||
|
|
ee1ae627a3 | ||
|
|
137a8dcfdf | ||
|
|
b2d753ed86 | ||
|
|
6e40102f26 | ||
|
|
511fe23b8a | ||
|
|
e433895873 | ||
|
|
5572195af9 | ||
|
|
cb956cd35b | ||
|
|
b551c7738e | ||
|
|
3d45c4dbd8 | ||
|
|
8681489cb7 | ||
|
|
ed328766b2 | ||
|
|
fb852ee6eb | ||
|
|
a6ee708b90 | ||
|
|
c9398e7b8a | ||
|
|
b591e35442 | ||
|
|
e50e15dc04 | ||
|
|
d4e65d8607 | ||
|
|
63ced7da7c | ||
|
|
03868d05db | ||
|
|
186374525a | ||
|
|
f116585c2a | ||
|
|
f4945729bc | ||
|
|
a3c76232c8 | ||
|
|
5bc41118e2 | ||
|
|
9445a96b3a | ||
|
|
a5761069ca | ||
|
|
2d4bfe183c | ||
|
|
bf4115a80f | ||
|
|
b2e84dfd29 | ||
|
|
004f6fa4d6 | ||
|
|
cefd4cd647 | ||
|
|
fd2ae61e3e | ||
|
|
7cda61ca01 | ||
|
|
98e1d52eaa | ||
|
|
1d09beb8a7 | ||
|
|
d44cce2928 | ||
|
|
51b3d4d06e | ||
|
|
a17ddaa951 |
4
.github/workflows/main_matrix.yml
vendored
4
.github/workflows/main_matrix.yml
vendored
@@ -224,6 +224,7 @@ jobs:
|
||||
path: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
release/*.zip
|
||||
retention-days: 90
|
||||
|
||||
build-rpi2040:
|
||||
@@ -368,7 +369,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Move files up
|
||||
run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
|
||||
run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -377,6 +378,7 @@ jobs:
|
||||
path: |
|
||||
./*.bin
|
||||
./*.uf2
|
||||
./firmware-*-ota.zip
|
||||
./meshtasticd_linux_amd64
|
||||
./device-*.sh
|
||||
./device-*.bat
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||
[esp32_base]
|
||||
extends = arduino_base
|
||||
platform = espressif32@^5.2.0
|
||||
platform = platformio/espressif32@^5.2.0
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
|
||||
upload_speed = 921600
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[esp32s3_base]
|
||||
extends = arduino_base
|
||||
platform = espressif32@^5.2.0
|
||||
platform = platformio/espressif32@^5.2.0
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
|
||||
upload_speed = 961200
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
[nrf52_base]
|
||||
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
||||
; platform = nordicnrf52 ;pending https://github.com/platformio/builder-framework-arduino-nrf5/pull/7
|
||||
platform = https://github.com/meshtastic/platform-nordicnrf52.git#merge
|
||||
platform = platformio/nordicnrf52@^9.4.0
|
||||
|
||||
extends = arduino_base
|
||||
build_type = debug ; I'm debugging with ICE a lot now
|
||||
; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME)
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable
|
||||
-Isrc/platform/nrf52
|
||||
|
||||
@@ -4,7 +4,7 @@ build_flags = ${nrf52_base.build_flags}
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/Kongduino/Adafruit_nRFCrypto.git#20fc7fdaf086bd70e901c007dd23c6e8856aec25
|
||||
https://github.com/Kongduino/Adafruit_nRFCrypto.git#e31a8825ea3300b163a0a3c1ddd5de34e10e1371
|
||||
|
||||
; Note: By default no lora device is created for this build - it uses a simulated interface
|
||||
[env:nrf52840dk]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
; Common settings for rp2040 Processor based targets
|
||||
[rp2040_base]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#5ce1a228e7cae453f366deb8962252b9b7356bbc
|
||||
extends = arduino_base
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[stm32wl5e_base]
|
||||
platform = ststm32
|
||||
platform = platformio/ststm32@^15.4.1
|
||||
board = generic_wl5e
|
||||
framework = arduino
|
||||
build_type = debug
|
||||
|
||||
@@ -26,7 +26,9 @@ basename=firmware-$1-$VERSION
|
||||
|
||||
pio run --environment $1 # -v
|
||||
SRCELF=.pio/build/$1/firmware.elf
|
||||
DFUPKG=.pio/build/$1/firmware.zip
|
||||
cp $SRCELF $OUTDIR/$basename.elf
|
||||
cp $DFUPKG $OUTDIR/$basename-ota.zip
|
||||
|
||||
echo "Generating NRF52 uf2 file"
|
||||
SRCHEX=.pio/build/$1/firmware.hex
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
default_envs = tbeam
|
||||
;default_envs = tbeam
|
||||
;default_envs = pico
|
||||
;default_envs = tbeam-s3-core
|
||||
;default_envs = tbeam0.7
|
||||
;default_envs = heltec-v1
|
||||
@@ -64,6 +65,7 @@ lib_deps =
|
||||
${env.lib_deps}
|
||||
; Portduino is using meshtastic fork for now
|
||||
jgromes/RadioLib@5.4.1
|
||||
https://github.com/caveman99/SparkFun_ATECCX08a_Arduino_Library.git#008e7f9d40bad66b2f7a0074aaac05b7c424339d
|
||||
|
||||
build_flags = ${env.build_flags} -Os
|
||||
-DRADIOLIB_SPI_PARANOID=0
|
||||
|
||||
Submodule protobufs updated: d3375fe599...d3dfaa63a5
@@ -7,7 +7,7 @@ const uint8_t MESH_SERVICE_UUID_16[16u] = {0xfd, 0xea, 0x73, 0xe2, 0xca, 0x5d, 0
|
||||
0x1f, 0x46, 0xa8, 0x15, 0x18, 0xb2, 0xa1, 0x6b};
|
||||
const uint8_t TORADIO_UUID_16[16u] = {0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, 0xa1,
|
||||
0xad, 0x4d, 0x9e, 0x12, 0xd2, 0x76, 0x5c, 0xf7};
|
||||
const uint8_t FROMRADIO_UUID_16[16u] = {0xd5, 0x54, 0xe4, 0xc5, 0x25, 0xc5, 0x31, 0xa5,
|
||||
0x55, 0x4a, 0x02, 0xee, 0xc2, 0xbc, 0xa2, 0x8b};
|
||||
const uint8_t FROMRADIO_UUID_16[16u] = {0x02, 0x00, 0x12, 0xac, 0x42, 0x02, 0x78, 0xb8,
|
||||
0xed, 0x11, 0x93, 0x49, 0x9e, 0xe6, 0x55, 0x2c};
|
||||
const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6,
|
||||
0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed};
|
||||
@@ -9,7 +9,7 @@
|
||||
#define MESH_SERVICE_UUID "6ba1b218-15a8-461f-9fa8-5dcae273eafd"
|
||||
|
||||
#define TORADIO_UUID "f75c76d2-129e-4dad-a1dd-7866124401e7"
|
||||
#define FROMRADIO_UUID "8ba2bcc2-ee02-4a55-a531-c525c5e454d5"
|
||||
#define FROMRADIO_UUID "2c55e69e-4993-11ed-b878-0242ac120002"
|
||||
#define FROMNUM_UUID "ed9da18c-a800-4f66-a670-aa7547e34453"
|
||||
|
||||
// NRF52 wants these constants as byte arrays
|
||||
|
||||
@@ -368,8 +368,21 @@ bool Power::axpChipInit()
|
||||
|
||||
#ifdef HAS_PMU
|
||||
|
||||
TwoWire * w = NULL;
|
||||
|
||||
// Use macro to distinguish which wire is used by PMU
|
||||
#ifdef PMU_USE_WIRE1
|
||||
w = &Wire1;
|
||||
#else
|
||||
w = &Wire;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* It is not necessary to specify the wire pin,
|
||||
* just input the wire, because the wire has been initialized in main.cpp
|
||||
*/
|
||||
if (!PMU) {
|
||||
PMU = new XPowersAXP2101(Wire, I2C_SDA, I2C_SCL);
|
||||
PMU = new XPowersAXP2101(*w);
|
||||
if (!PMU->init()) {
|
||||
DEBUG_MSG("Warning: Failed to find AXP2101 power management\n");
|
||||
delete PMU;
|
||||
@@ -380,7 +393,7 @@ bool Power::axpChipInit()
|
||||
}
|
||||
|
||||
if (!PMU) {
|
||||
PMU = new XPowersAXP192(Wire, I2C_SDA, I2C_SCL);
|
||||
PMU = new XPowersAXP192(*w);
|
||||
if (!PMU->init()) {
|
||||
DEBUG_MSG("Warning: Failed to find AXP192 power management\n");
|
||||
delete PMU;
|
||||
@@ -396,7 +409,9 @@ bool Power::axpChipInit()
|
||||
* In order not to affect other devices, if the initialization of the PMU fails, Wire needs to be re-initialized once,
|
||||
* if there are multiple devices sharing the bus.
|
||||
* * */
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
#ifndef PMU_USE_WIRE1
|
||||
w->begin(I2C_SDA, I2C_SCL);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -456,6 +471,23 @@ bool Power::axpChipInit()
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC3);
|
||||
|
||||
/**
|
||||
* ALDO2 cannot be turned off.
|
||||
* It is a necessary condition for sensor communication.
|
||||
* It must be turned on to properly access the sensor and screen
|
||||
* It is also responsible for the power supply of PCF8563
|
||||
*/
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||
|
||||
// 6-axis , magnetometer ,bme280 , oled screen power channel
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO1);
|
||||
|
||||
// sdcard power channle
|
||||
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_BLDO1);
|
||||
|
||||
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
|
||||
// PMU->enablePowerOutput(XPOWERS_DCDC4);
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ struct ToneDuration {
|
||||
#define NOTE_A3 220
|
||||
#define NOTE_AS3 233
|
||||
#define NOTE_B3 247
|
||||
#define NOTE_CS4 277
|
||||
|
||||
const int DURATION_1_8 = 125; // 1/8 note
|
||||
const int DURATION_1_4 = 250; // 1/4 note
|
||||
@@ -65,16 +66,17 @@ void playBeep() { tone(PIN_BUZZER, NOTE_B3, DURATION_1_4); }
|
||||
#endif
|
||||
|
||||
void playStartMelody() {
|
||||
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
|
||||
{NOTE_B3, DURATION_1_8},
|
||||
{NOTE_B3, DURATION_1_8}};
|
||||
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8},
|
||||
{NOTE_AS3, DURATION_1_8},
|
||||
{NOTE_CS4, DURATION_1_4}};
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
|
||||
|
||||
void playShutdownMelody() {
|
||||
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
|
||||
{NOTE_G3, DURATION_1_8},
|
||||
{NOTE_D3, DURATION_1_8}};
|
||||
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8},
|
||||
{NOTE_AS3, DURATION_1_8},
|
||||
{NOTE_FS3, DURATION_1_4}};
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
#endif
|
||||
@@ -108,6 +108,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define MCP9808_ADDR 0x18
|
||||
#define INA_ADDR 0x40
|
||||
#define INA_ADDR_ALTERNATE 0x41
|
||||
#define QMC6310_ADDR 0x1C
|
||||
#define QMI8658_ADDR 0x6B
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Security
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define ATECC608B_ADDR 0x35
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GPS
|
||||
|
||||
@@ -9,6 +9,41 @@
|
||||
#endif
|
||||
|
||||
#if HAS_WIRE
|
||||
|
||||
void printATECCInfo()
|
||||
{
|
||||
#ifndef ARCH_PORTDUINO
|
||||
atecc.readConfigZone(false);
|
||||
|
||||
DEBUG_MSG("ATECC608B Serial Number: ");
|
||||
for (int i = 0 ; i < 9 ; i++) {
|
||||
DEBUG_MSG("%02x",atecc.serialNumber[i]);
|
||||
}
|
||||
|
||||
DEBUG_MSG(", Rev Number: ");
|
||||
for (int i = 0 ; i < 4 ; i++) {
|
||||
DEBUG_MSG("%02x",atecc.revisionNumber[i]);
|
||||
}
|
||||
DEBUG_MSG("\n");
|
||||
|
||||
DEBUG_MSG("ATECC608B Config %s",atecc.configLockStatus ? "Locked" : "Unlocked");
|
||||
DEBUG_MSG(", Data %s",atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
|
||||
DEBUG_MSG(", Slot 0 %s\n",atecc.slot0LockStatus ? "Locked" : "Unlocked");
|
||||
|
||||
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
|
||||
if (atecc.generatePublicKey() == false) {
|
||||
DEBUG_MSG("ATECC608B Error generating public key\n");
|
||||
} else {
|
||||
DEBUG_MSG("ATECC608B Public Key: ");
|
||||
for (int i = 0 ; i < 64 ; i++) {
|
||||
DEBUG_MSG("%02x",atecc.publicKey64Bytes[i]);
|
||||
}
|
||||
DEBUG_MSG("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
|
||||
uint16_t value = 0x00;
|
||||
Wire.beginTransmission(address);
|
||||
@@ -79,6 +114,17 @@ void scanI2Cdevice(void)
|
||||
DEBUG_MSG("unknown display found\n");
|
||||
}
|
||||
}
|
||||
#ifndef ARCH_PORTDUINO
|
||||
if (addr == ATECC608B_ADDR){
|
||||
keystore_found = addr;
|
||||
if (atecc.begin(keystore_found) == true) {
|
||||
DEBUG_MSG("ATECC608B initialized\n");
|
||||
} else {
|
||||
DEBUG_MSG("ATECC608B initialization failed\n");
|
||||
}
|
||||
printATECCInfo();
|
||||
}
|
||||
#endif
|
||||
#ifdef RV3028_RTC
|
||||
if (addr == RV3028_RTC){
|
||||
rtc_found = addr;
|
||||
@@ -145,6 +191,14 @@ void scanI2Cdevice(void)
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
|
||||
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
}
|
||||
if(addr == QMC6310_ADDR){
|
||||
DEBUG_MSG("QMC6310 3-Axis magnetic sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
|
||||
}
|
||||
if(addr == QMI8658_ADDR){
|
||||
DEBUG_MSG("QMI8658 6-Axis inertial measurement sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
|
||||
}
|
||||
} else if (err == 4) {
|
||||
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,6 @@ namespace graphics
|
||||
|
||||
// This means the *visible* area (sh1106 can address 132, but shows 128 for example)
|
||||
#define IDLE_FRAMERATE 1 // in fps
|
||||
#define COMPASS_DIAM 44
|
||||
|
||||
// DEBUG
|
||||
#define NUM_EXTRA_FRAMES 3 // text message and debug frame
|
||||
@@ -98,7 +97,7 @@ static uint16_t displayWidth, displayHeight;
|
||||
#define SCREEN_WIDTH displayWidth
|
||||
#define SCREEN_HEIGHT displayHeight
|
||||
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER)
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
@@ -669,6 +668,26 @@ static bool hasPosition(NodeInfo *n)
|
||||
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
|
||||
}
|
||||
|
||||
static uint16_t getCompassDiam(OLEDDisplay *display)
|
||||
{
|
||||
uint16_t diam = 0;
|
||||
// get the smaller of the 2 dimensions and subtract 20
|
||||
if(display->getWidth() > display->getHeight()) {
|
||||
diam = display->getHeight();
|
||||
// if 2/3 of the other size would be smaller, use that
|
||||
if (diam > (display->getWidth() * 2 / 3)) {
|
||||
diam = display->getWidth() * 2 / 3;
|
||||
}
|
||||
} else {
|
||||
diam = display->getWidth();
|
||||
if (diam > (display->getHeight() * 2 / 3)) {
|
||||
diam = display->getHeight() * 2 / 3;
|
||||
}
|
||||
}
|
||||
|
||||
return diam - 20;
|
||||
};
|
||||
|
||||
/// We will skip one node - the one for us, so we just blindly loop over all
|
||||
/// nodes
|
||||
static size_t nodeIndex;
|
||||
@@ -685,7 +704,7 @@ static void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t comp
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
arrowPoints[i]->rotate(headingRadian);
|
||||
arrowPoints[i]->scale(COMPASS_DIAM * 0.6);
|
||||
arrowPoints[i]->scale(getCompassDiam(display) * 0.6);
|
||||
arrowPoints[i]->translate(compassX, compassY);
|
||||
}
|
||||
drawLine(display, tip, tail);
|
||||
@@ -707,7 +726,7 @@ static void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t com
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// North on compass will be negative of heading
|
||||
rosePoints[i]->rotate(-myHeading);
|
||||
rosePoints[i]->scale(COMPASS_DIAM);
|
||||
rosePoints[i]->scale(getCompassDiam(display));
|
||||
rosePoints[i]->translate(compassX, compassY);
|
||||
}
|
||||
drawLine(display, N1, N3);
|
||||
@@ -772,7 +791,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
||||
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
|
||||
|
||||
// coordinates for the center of the compass/circle
|
||||
int16_t compassX = x + SCREEN_WIDTH - COMPASS_DIAM / 2 - 5, compassY = y + SCREEN_HEIGHT / 2;
|
||||
int16_t compassX = x + SCREEN_WIDTH - getCompassDiam(display) / 2 - 5, compassY = y + SCREEN_HEIGHT / 2;
|
||||
bool hasNodeHeading = false;
|
||||
|
||||
if (ourNode && hasPosition(ourNode)) {
|
||||
@@ -813,7 +832,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
||||
// Debug info for gps lock errors
|
||||
// DEBUG_MSG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasPosition(ourNode), hasPosition(node));
|
||||
display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
|
||||
display->drawCircle(compassX, compassY, COMPASS_DIAM / 2);
|
||||
display->drawCircle(compassX, compassY, getCompassDiam(display) / 2);
|
||||
|
||||
// Must be after distStr is populated
|
||||
drawColumns(display, x, y, fields);
|
||||
|
||||
@@ -17,7 +17,7 @@ uint8_t read_from_14004(uint8_t reg, uint8_t *data, uint8_t length)
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission(); // stop transmitting
|
||||
delay(20);
|
||||
Wire.requestFrom(CARDKB_ADDR, length);
|
||||
Wire.requestFrom(CARDKB_ADDR, (int)length);
|
||||
int i = 0;
|
||||
while ( Wire.available() ) // slave may send less than requested
|
||||
{
|
||||
|
||||
21
src/main.cpp
21
src/main.cpp
@@ -80,6 +80,12 @@ uint8_t kb_model;
|
||||
// The I2C address of the RTC Module (if found)
|
||||
uint8_t rtc_found;
|
||||
|
||||
// Keystore Chips
|
||||
uint8_t keystore_found;
|
||||
#ifndef ARCH_PORTDUINO
|
||||
ATECCX08A atecc;
|
||||
#endif
|
||||
|
||||
bool eink_found = true;
|
||||
|
||||
uint32_t serialSinceMsec;
|
||||
@@ -87,7 +93,7 @@ uint32_t serialSinceMsec;
|
||||
bool pmu_found;
|
||||
|
||||
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
|
||||
uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_LPS22+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
||||
|
||||
@@ -214,6 +220,10 @@ void setup()
|
||||
// router = new DSRRouter();
|
||||
router = new ReliableRouter();
|
||||
|
||||
#ifdef I2C_SDA1
|
||||
Wire1.begin(I2C_SDA1, I2C_SCL1);
|
||||
#endif
|
||||
|
||||
#ifdef I2C_SDA
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
#elif HAS_WIRE
|
||||
@@ -229,6 +239,7 @@ void setup()
|
||||
delay(1);
|
||||
#endif
|
||||
|
||||
// We need to scan here to decide if we have a screen for nodeDB.init()
|
||||
scanI2Cdevice();
|
||||
#ifdef RAK4630
|
||||
// scanEInkDevice();
|
||||
@@ -269,6 +280,14 @@ void setup()
|
||||
powerStatus->observe(&power->newStatus);
|
||||
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
|
||||
|
||||
/*
|
||||
* Repeat the scanning for I2C devices after power initialization.
|
||||
* Boards with an PMU need to be powered on to correctly scan to the device address, such as t-beam-s3-core
|
||||
*/
|
||||
if ((HW_VENDOR == HardwareModel_LILYGO_TBEAM_S3_CORE) || (HW_VENDOR == HardwareModel_TBEAM)) {
|
||||
scanI2Cdevice();
|
||||
}
|
||||
|
||||
// Init our SPI controller (must be before screen and lora)
|
||||
initSPI();
|
||||
#ifndef ARCH_ESP32
|
||||
|
||||
10
src/main.h
10
src/main.h
@@ -6,19 +6,27 @@
|
||||
#include "PowerStatus.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "mesh/generated/telemetry.pb.h"
|
||||
#ifndef ARCH_PORTDUINO
|
||||
#include <SparkFun_ATECCX08a_Arduino_Library.h>
|
||||
#endif
|
||||
|
||||
extern uint8_t screen_found;
|
||||
extern uint8_t screen_model;
|
||||
extern uint8_t cardkb_found;
|
||||
extern uint8_t kb_model;
|
||||
extern uint8_t rtc_found;
|
||||
extern uint8_t keystore_found;
|
||||
|
||||
extern bool eink_found;
|
||||
extern bool pmu_found;
|
||||
extern bool isCharging;
|
||||
extern bool isUSBPowered;
|
||||
|
||||
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_LPS22+1];
|
||||
#ifndef ARCH_PORTDUINO
|
||||
extern ATECCX08A atecc;
|
||||
#endif
|
||||
|
||||
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1];
|
||||
|
||||
extern int TCPPort; // set by Portduino
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
||||
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
|
||||
!ch ||
|
||||
strlen(ch->settings.name) > 0 ||
|
||||
(strcmp(ch->settings.name, pi.boundChannel) == 0);
|
||||
(strcasecmp(ch->settings.name, pi.boundChannel) == 0);
|
||||
|
||||
if (!rxChannelOk) {
|
||||
// no one should have already replied!
|
||||
|
||||
@@ -699,11 +699,23 @@ NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
|
||||
|
||||
if (!info) {
|
||||
if (*numNodes >= MAX_NUM_NODES) {
|
||||
screen->print("error: node_db full!\n");
|
||||
DEBUG_MSG("ERROR! could not create new node, node_db is full! (%d nodes)", *numNodes);
|
||||
return NULL;
|
||||
screen->print("warning: node_db full! erasing oldest entry\n");
|
||||
// look for oldest node and erase it
|
||||
uint32_t oldest = UINT32_MAX;
|
||||
int oldestIndex = -1;
|
||||
for (int i = 0; i < *numNodes; i++) {
|
||||
if (nodes[i].last_heard < oldest) {
|
||||
oldest = nodes[i].last_heard;
|
||||
oldestIndex = i;
|
||||
}
|
||||
}
|
||||
// Shove the remaining nodes down the chain
|
||||
for (int i = oldestIndex; i < *numNodes - 1; i++) {
|
||||
nodes[i] = nodes[i + 1];
|
||||
}
|
||||
(*numNodes)--;
|
||||
}
|
||||
// add the node
|
||||
// add the node at the end
|
||||
info = &nodes[(*numNodes)++];
|
||||
|
||||
// everything is missing except the nodenum
|
||||
|
||||
@@ -79,17 +79,17 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
|
||||
memset(&toRadioScratch, 0, sizeof(toRadioScratch));
|
||||
if (pb_decode_from_bytes(buf, bufLength, ToRadio_fields, &toRadioScratch)) {
|
||||
switch (toRadioScratch.which_payload_variant) {
|
||||
case ToRadio_packet_tag:
|
||||
return handleToRadioPacket(toRadioScratch.packet);
|
||||
case ToRadio_want_config_id_tag:
|
||||
config_nonce = toRadioScratch.want_config_id;
|
||||
DEBUG_MSG("Client wants config, nonce=%u\n", config_nonce);
|
||||
handleStartConfig();
|
||||
break;
|
||||
case ToRadio_disconnect_tag:
|
||||
DEBUG_MSG("Disconnecting from phone\n");
|
||||
close();
|
||||
break;
|
||||
case ToRadio_packet_tag:
|
||||
return handleToRadioPacket(toRadioScratch.packet);
|
||||
case ToRadio_want_config_id_tag:
|
||||
config_nonce = toRadioScratch.want_config_id;
|
||||
DEBUG_MSG("Client wants config, nonce=%u\n", config_nonce);
|
||||
handleStartConfig();
|
||||
break;
|
||||
case ToRadio_disconnect_tag:
|
||||
DEBUG_MSG("Disconnecting from phone\n");
|
||||
close();
|
||||
break;
|
||||
default:
|
||||
// Ignore nop messages
|
||||
// DEBUG_MSG("Error: unexpected ToRadio variant\n");
|
||||
@@ -109,8 +109,10 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
|
||||
*
|
||||
* Our sending states progress in the following sequence (the client app ASSUMES THIS SEQUENCE, DO NOT CHANGE IT):
|
||||
* STATE_SEND_MY_INFO, // send our my info record
|
||||
* STATE_SEND_CHANNELS
|
||||
* STATE_SEND_NODEINFO, // states progress in this order as the device sends to the client
|
||||
STATE_SEND_CONFIG,
|
||||
STATE_SEND_MODULE_CONFIG,
|
||||
STATE_SEND_COMPLETE_ID,
|
||||
STATE_SEND_PACKETS // send packets or debug strings
|
||||
*/
|
||||
@@ -128,7 +130,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
case STATE_SEND_NOTHING:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_NOTHING\n");
|
||||
break;
|
||||
|
||||
|
||||
case STATE_SEND_MY_INFO:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_MY_INFO\n");
|
||||
// If the user has specified they don't want our node to share its location, make sure to tell the phone
|
||||
@@ -154,51 +156,63 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
// Stay in current state until done sending nodeinfos
|
||||
} else {
|
||||
DEBUG_MSG("Done sending nodeinfos\n");
|
||||
state = STATE_SEND_CONFIG;
|
||||
state = STATE_SEND_CHANNELS;
|
||||
// Go ahead and send that ID right now
|
||||
return getFromRadio(buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STATE_SEND_CHANNELS:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_CHANNELS\n");
|
||||
fromRadioScratch.which_payload_variant = FromRadio_channel_tag;
|
||||
fromRadioScratch.channel = channels.getByIndex(config_state);
|
||||
config_state++;
|
||||
// Advance when we have sent all of our Channels
|
||||
if (config_state >= MAX_NUM_CHANNELS) {
|
||||
state = STATE_SEND_CONFIG;
|
||||
config_state = Config_device_tag;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_SEND_CONFIG:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_CONFIG\n");
|
||||
fromRadioScratch.which_payload_variant = FromRadio_config_tag;
|
||||
switch (config_state) {
|
||||
case Config_device_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_device_tag;
|
||||
fromRadioScratch.config.payload_variant.device = config.device;
|
||||
break;
|
||||
case Config_position_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_position_tag;
|
||||
fromRadioScratch.config.payload_variant.position = config.position;
|
||||
break;
|
||||
case Config_power_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_power_tag;
|
||||
fromRadioScratch.config.payload_variant.power = config.power;
|
||||
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
|
||||
break;
|
||||
case Config_network_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_network_tag;
|
||||
fromRadioScratch.config.payload_variant.network = config.network;
|
||||
break;
|
||||
case Config_display_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_display_tag;
|
||||
fromRadioScratch.config.payload_variant.display = config.display;
|
||||
break;
|
||||
case Config_lora_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_lora_tag;
|
||||
fromRadioScratch.config.payload_variant.lora = config.lora;
|
||||
break;
|
||||
case Config_bluetooth_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_bluetooth_tag;
|
||||
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
|
||||
break;
|
||||
case Config_device_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_device_tag;
|
||||
fromRadioScratch.config.payload_variant.device = config.device;
|
||||
break;
|
||||
case Config_position_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_position_tag;
|
||||
fromRadioScratch.config.payload_variant.position = config.position;
|
||||
break;
|
||||
case Config_power_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_power_tag;
|
||||
fromRadioScratch.config.payload_variant.power = config.power;
|
||||
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
|
||||
break;
|
||||
case Config_network_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_network_tag;
|
||||
fromRadioScratch.config.payload_variant.network = config.network;
|
||||
break;
|
||||
case Config_display_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_display_tag;
|
||||
fromRadioScratch.config.payload_variant.display = config.display;
|
||||
break;
|
||||
case Config_lora_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_lora_tag;
|
||||
fromRadioScratch.config.payload_variant.lora = config.lora;
|
||||
break;
|
||||
case Config_bluetooth_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_bluetooth_tag;
|
||||
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
|
||||
break;
|
||||
}
|
||||
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
|
||||
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
|
||||
// using to the app (so that even old phone apps work with new device loads).
|
||||
|
||||
|
||||
config_state++;
|
||||
// Advance when we have sent all of our config objects
|
||||
if (config_state > Config_bluetooth_tag) {
|
||||
@@ -211,37 +225,37 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_MODULECONFIG\n");
|
||||
fromRadioScratch.which_payload_variant = FromRadio_moduleConfig_tag;
|
||||
switch (config_state) {
|
||||
case ModuleConfig_mqtt_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_mqtt_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
|
||||
break;
|
||||
case ModuleConfig_serial_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_serial_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
|
||||
break;
|
||||
case ModuleConfig_external_notification_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_external_notification_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
|
||||
break;
|
||||
case ModuleConfig_range_test_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_range_test_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
|
||||
break;
|
||||
case ModuleConfig_telemetry_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_telemetry_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
|
||||
break;
|
||||
case ModuleConfig_canned_message_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
|
||||
break;
|
||||
case ModuleConfig_mqtt_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_mqtt_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
|
||||
break;
|
||||
case ModuleConfig_serial_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_serial_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
|
||||
break;
|
||||
case ModuleConfig_external_notification_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_external_notification_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
|
||||
break;
|
||||
case ModuleConfig_range_test_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_range_test_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
|
||||
break;
|
||||
case ModuleConfig_telemetry_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_telemetry_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
|
||||
break;
|
||||
case ModuleConfig_canned_message_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
|
||||
break;
|
||||
}
|
||||
|
||||
config_state++;
|
||||
// Advance when we have sent all of our ModuleConfig objects
|
||||
if (config_state > ModuleConfig_canned_message_tag) {
|
||||
state = STATE_SEND_COMPLETE_ID;
|
||||
config_state = Config_device_tag;
|
||||
config_state = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -274,7 +288,8 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
if (fromRadioScratch.which_payload_variant != 0) {
|
||||
// Encapsulate as a FromRadio packet
|
||||
size_t numbytes = pb_encode_to_bytes(buf, FromRadio_size, FromRadio_fields, &fromRadioScratch);
|
||||
// DEBUG_MSG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payloadVariant, numbytes);
|
||||
|
||||
DEBUG_MSG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payload_variant, numbytes);
|
||||
return numbytes;
|
||||
}
|
||||
|
||||
@@ -282,7 +297,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PhoneAPI::handleDisconnect()
|
||||
void PhoneAPI::handleDisconnect()
|
||||
{
|
||||
DEBUG_MSG("PhoneAPI disconnect\n");
|
||||
}
|
||||
@@ -301,26 +316,25 @@ void PhoneAPI::releasePhonePacket()
|
||||
bool PhoneAPI::available()
|
||||
{
|
||||
switch (state) {
|
||||
case STATE_SEND_NOTHING:
|
||||
return false;
|
||||
case STATE_SEND_MY_INFO:
|
||||
return true;
|
||||
case STATE_SEND_CONFIG:
|
||||
return true;
|
||||
case STATE_SEND_MODULECONFIG:
|
||||
return true;
|
||||
case STATE_SEND_NODEINFO:
|
||||
if (!nodeInfoForPhone)
|
||||
nodeInfoForPhone = nodeDB.readNextInfo();
|
||||
return true; // Always say we have something, because we might need to advance our state machine
|
||||
case STATE_SEND_COMPLETE_ID:
|
||||
return true;
|
||||
case STATE_SEND_PACKETS: {
|
||||
if (!packetForPhone)
|
||||
packetForPhone = service.getForPhone();
|
||||
bool hasPacket = !!packetForPhone;
|
||||
// DEBUG_MSG("available hasPacket=%d\n", hasPacket);
|
||||
return hasPacket;
|
||||
case STATE_SEND_NOTHING:
|
||||
return false;
|
||||
case STATE_SEND_MY_INFO:
|
||||
case STATE_SEND_CHANNELS:
|
||||
case STATE_SEND_CONFIG:
|
||||
case STATE_SEND_MODULECONFIG:
|
||||
case STATE_SEND_COMPLETE_ID:
|
||||
return true;
|
||||
case STATE_SEND_NODEINFO:
|
||||
if (!nodeInfoForPhone)
|
||||
nodeInfoForPhone = nodeDB.readNextInfo();
|
||||
return true; // Always say we have something, because we might need to advance our state machine
|
||||
|
||||
case STATE_SEND_PACKETS: {
|
||||
if (!packetForPhone)
|
||||
packetForPhone = service.getForPhone();
|
||||
bool hasPacket = !!packetForPhone;
|
||||
// DEBUG_MSG("available hasPacket=%d\n", hasPacket);
|
||||
return hasPacket;
|
||||
}
|
||||
default:
|
||||
assert(0); // unexpected state - FIXME, make an error code and reboot
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
* Eventually there should be once instance of this class for each live connection (because it has a bit of state
|
||||
* for that connection)
|
||||
*/
|
||||
class PhoneAPI
|
||||
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
||||
class PhoneAPI : public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
||||
{
|
||||
enum State {
|
||||
STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config
|
||||
STATE_SEND_MY_INFO, // send our my info record
|
||||
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
|
||||
STATE_SEND_CHANNELS, // Send all channels
|
||||
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
|
||||
STATE_SEND_MODULECONFIG, // Send Module specific config
|
||||
STATE_SEND_COMPLETE_ID,
|
||||
@@ -31,7 +31,7 @@ class PhoneAPI
|
||||
|
||||
State state = STATE_SEND_NOTHING;
|
||||
|
||||
int8_t config_state = Config_device_tag;
|
||||
uint8_t config_state = 0;
|
||||
|
||||
/**
|
||||
* Each packet sent to the phone has an incrementing count
|
||||
|
||||
@@ -422,7 +422,7 @@ void RadioInterface::applyModemConfig()
|
||||
|
||||
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
|
||||
const char *channelName = channels.getName(channels.getPrimaryIndex());
|
||||
int channel_num = loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName) % numChannels;
|
||||
int channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
|
||||
|
||||
// Old frequency selection formula
|
||||
// float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num);
|
||||
|
||||
@@ -58,12 +58,12 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
|
||||
* this way if an ACK is dropped and a packet is resent we'll ACK the resent packet
|
||||
* make sure wasSeenRecently _doesn't_ update
|
||||
* finding the channel requires decoding the packet. */
|
||||
if (p->want_ack && (p->to == getNodeNum()) && wasSeenRecently(p, false)) {
|
||||
if (p->want_ack && (p->to == getNodeNum()) && wasSeenRecently(p, false) && !MeshModule::currentReply) {
|
||||
if (perhapsDecode(p)) {
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
DEBUG_MSG("acking a repeated want_ack packet\n");
|
||||
}
|
||||
} else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE) {
|
||||
} else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply) {
|
||||
// retransmission on broadcast has hop_limit still equal to HOP_RELIABLE
|
||||
DEBUG_MSG("Resending implicit ack for a repeated floodmsg\n");
|
||||
MeshPacket *tosend = packetPool.allocCopy(*p);
|
||||
@@ -94,7 +94,7 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
// - not DSR routing)
|
||||
if (p->want_ack) {
|
||||
if (MeshModule::currentReply)
|
||||
DEBUG_MSG("Someone else has replied to this message, no need for a 2nd ack\n");
|
||||
DEBUG_MSG("Some other module has replied to this message, no need for a 2nd ack\n");
|
||||
else
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ class SinglePortModule : public MeshModule
|
||||
SinglePortModule(const char *_name, PortNum _ourPortNum) : MeshModule(_name), ourPortNum(_ourPortNum) {}
|
||||
|
||||
protected:
|
||||
uint32_t max_channel_util_percent = 40;
|
||||
uint32_t polite_channel_util_percent = 25;
|
||||
|
||||
/**
|
||||
* @return true if you want to receive the specified portnum
|
||||
*/
|
||||
|
||||
@@ -59,14 +59,12 @@ typedef struct _AdminMessage {
|
||||
AdminMessage_ModuleConfigType get_module_config_request;
|
||||
/* Send the current Config in the response to this message. */
|
||||
ModuleConfig get_module_config_response;
|
||||
/* Send all channels in the response to this message */
|
||||
bool get_all_channel_request;
|
||||
/* Get the Canned Message Module messages in the response to this message. */
|
||||
bool get_canned_message_module_messages_request;
|
||||
/* Get the Canned Message Module messages in the response to this message. */
|
||||
char get_canned_message_module_messages_response[201];
|
||||
/* Request the node to send device metadata (firmware, protobuf version, etc) */
|
||||
uint32_t get_device_metadata_request;
|
||||
bool get_device_metadata_request;
|
||||
/* Device metadata response */
|
||||
DeviceMetadata get_device_metadata_response;
|
||||
/* Set the owner for this node */
|
||||
@@ -94,6 +92,9 @@ typedef struct _AdminMessage {
|
||||
bool confirm_set_channel;
|
||||
/* TODO: REPLACE */
|
||||
bool confirm_set_radio;
|
||||
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
||||
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. */
|
||||
int32_t reboot_ota_seconds;
|
||||
/* This message is only supported for the simulator porduino build.
|
||||
If received the simulator will exit successfully. */
|
||||
bool exit_simulator;
|
||||
@@ -136,7 +137,6 @@ extern "C" {
|
||||
#define AdminMessage_get_config_response_tag 6
|
||||
#define AdminMessage_get_module_config_request_tag 7
|
||||
#define AdminMessage_get_module_config_response_tag 8
|
||||
#define AdminMessage_get_all_channel_request_tag 9
|
||||
#define AdminMessage_get_canned_message_module_messages_request_tag 10
|
||||
#define AdminMessage_get_canned_message_module_messages_response_tag 11
|
||||
#define AdminMessage_get_device_metadata_request_tag 12
|
||||
@@ -150,6 +150,7 @@ extern "C" {
|
||||
#define AdminMessage_confirm_set_module_config_tag 65
|
||||
#define AdminMessage_confirm_set_channel_tag 66
|
||||
#define AdminMessage_confirm_set_radio_tag 67
|
||||
#define AdminMessage_reboot_ota_seconds_tag 95
|
||||
#define AdminMessage_exit_simulator_tag 96
|
||||
#define AdminMessage_reboot_seconds_tag 97
|
||||
#define AdminMessage_shutdown_seconds_tag 98
|
||||
@@ -166,10 +167,9 @@ X(a, STATIC, ONEOF, UENUM, (payload_variant,get_config_request,get_confi
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_config_response,get_config_response), 6) \
|
||||
X(a, STATIC, ONEOF, UENUM, (payload_variant,get_module_config_request,get_module_config_request), 7) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_module_config_response,get_module_config_response), 8) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_all_channel_request,get_all_channel_request), 9) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_canned_message_module_messages_request,get_canned_message_module_messages_request), 10) \
|
||||
X(a, STATIC, ONEOF, STRING, (payload_variant,get_canned_message_module_messages_response,get_canned_message_module_messages_response), 11) \
|
||||
X(a, STATIC, ONEOF, UINT32, (payload_variant,get_device_metadata_request,get_device_metadata_request), 12) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_device_metadata_request,get_device_metadata_request), 12) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_device_metadata_response,get_device_metadata_response), 13) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_owner,set_owner), 32) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 33) \
|
||||
@@ -180,6 +180,7 @@ X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_config,confirm_s
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_module_config,confirm_set_module_config), 65) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_channel,confirm_set_channel), 66) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_radio,confirm_set_radio), 67) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_seconds), 97) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#ifndef PB_MESH_PB_H_INCLUDED
|
||||
#define PB_MESH_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "channel.pb.h"
|
||||
#include "config.pb.h"
|
||||
#include "module_config.pb.h"
|
||||
#include "portnums.pb.h"
|
||||
@@ -652,6 +653,8 @@ typedef struct _FromRadio {
|
||||
bool rebooted;
|
||||
/* Include module config */
|
||||
ModuleConfig moduleConfig;
|
||||
/* One packet is sent for each channel */
|
||||
Channel channel;
|
||||
};
|
||||
} FromRadio;
|
||||
|
||||
@@ -854,6 +857,7 @@ extern "C" {
|
||||
#define FromRadio_config_complete_id_tag 7
|
||||
#define FromRadio_rebooted_tag 8
|
||||
#define FromRadio_moduleConfig_tag 9
|
||||
#define FromRadio_channel_tag 10
|
||||
#define ToRadio_packet_tag 1
|
||||
#define ToRadio_peer_info_tag 2
|
||||
#define ToRadio_want_config_id_tag 3
|
||||
@@ -1001,7 +1005,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,config,config), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,log_record,log_record), 6) \
|
||||
X(a, STATIC, ONEOF, UINT32, (payload_variant,config_complete_id,config_complete_id), 7) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,rebooted,rebooted), 8) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig), 9)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig), 9) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10)
|
||||
#define FromRadio_CALLBACK NULL
|
||||
#define FromRadio_DEFAULT NULL
|
||||
#define FromRadio_payload_variant_packet_MSGTYPE MeshPacket
|
||||
@@ -1010,6 +1015,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig),
|
||||
#define FromRadio_payload_variant_config_MSGTYPE Config
|
||||
#define FromRadio_payload_variant_log_record_MSGTYPE LogRecord
|
||||
#define FromRadio_payload_variant_moduleConfig_MSGTYPE ModuleConfig
|
||||
#define FromRadio_payload_variant_channel_MSGTYPE Channel
|
||||
|
||||
#define ToRadio_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \
|
||||
|
||||
@@ -29,7 +29,11 @@ typedef enum _TelemetrySensorType {
|
||||
/* High accuracy temperature and humidity */
|
||||
TelemetrySensorType_SHTC3 = 7,
|
||||
/* High accuracy pressure */
|
||||
TelemetrySensorType_LPS22 = 8
|
||||
TelemetrySensorType_LPS22 = 8,
|
||||
/* 3-Axis magnetic sensor */
|
||||
TelemetrySensorType_QMC6310 = 9,
|
||||
/* 6-Axis inertial measurement sensor */
|
||||
TelemetrySensorType_QMI8658 = 10
|
||||
} TelemetrySensorType;
|
||||
|
||||
/* Struct definitions */
|
||||
@@ -81,8 +85,8 @@ typedef struct _Telemetry {
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _TelemetrySensorType_MIN TelemetrySensorType_SENSOR_UNSET
|
||||
#define _TelemetrySensorType_MAX TelemetrySensorType_LPS22
|
||||
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_LPS22+1))
|
||||
#define _TelemetrySensorType_MAX TelemetrySensorType_QMI8658
|
||||
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_QMI8658+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "Channels.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#ifdef ARCH_ESP32
|
||||
#include "BleOta.h"
|
||||
#endif
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
@@ -103,6 +106,21 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
|
||||
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_reboot_ota_seconds_tag: {
|
||||
int32_t s = r->reboot_ota_seconds;
|
||||
#ifdef ARCH_ESP32
|
||||
if (BleOta::getOtaAppVersion().isEmpty()) {
|
||||
DEBUG_MSG("No OTA firmware available, scheduling regular reboot in %d seconds\n", s);
|
||||
}else{
|
||||
BleOta::switchToOtaApp();
|
||||
DEBUG_MSG("Rebooting to OTA in %d seconds\n", s);
|
||||
}
|
||||
#else
|
||||
DEBUG_MSG("Not on ESP32, scheduling regular reboot in %d seconds\n", s);
|
||||
#endif
|
||||
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_shutdown_seconds_tag: {
|
||||
int32_t s = r->shutdown_seconds;
|
||||
DEBUG_MSG("Shutdown in %d seconds\n", s);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#if HAS_SCREEN
|
||||
#include "CannedMessageModule.h"
|
||||
#include "FSCommon.h"
|
||||
#include "NodeDB.h"
|
||||
#include "MeshService.h"
|
||||
#include "PowerFSM.h" // neede for button bypass
|
||||
#include "mesh/generated/cannedmessages.pb.h"
|
||||
@@ -10,7 +11,7 @@
|
||||
#include "graphics/fonts/OLEDDisplayFontsRU.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER)
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
@@ -202,7 +203,7 @@ void CannedMessageModule::sendText(NodeNum dest, const char *message, bool wantR
|
||||
p->decoded.payload.size++;
|
||||
}
|
||||
|
||||
DEBUG_MSG("Sending message id=%d, msg=%.*s\n", p->id, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||
DEBUG_MSG("Sending message id=%d, dest=%x, msg=%.*s\n", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||
|
||||
service.sendToMesh(p);
|
||||
}
|
||||
@@ -222,25 +223,26 @@ int32_t CannedMessageModule::runOnce()
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->notifyObservers(&e);
|
||||
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) {
|
||||
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
|
||||
// Reset module
|
||||
DEBUG_MSG("Reset due to lack of activity.\n");
|
||||
e.frameChanged = true;
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
this->notifyObservers(&e);
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
||||
if (this->payload == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
if (this->freetext.length() > 0) {
|
||||
sendText(NODENUM_BROADCAST, this->freetext.c_str(), true);
|
||||
sendText(this->dest, this->freetext.c_str(), true);
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||
} else {
|
||||
DEBUG_MSG("Reset message is empty.\n");
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
e.frameChanged = true;
|
||||
}
|
||||
} else {
|
||||
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
|
||||
@@ -249,12 +251,13 @@ int32_t CannedMessageModule::runOnce()
|
||||
} else {
|
||||
DEBUG_MSG("Reset message is empty.\n");
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
e.frameChanged = true;
|
||||
}
|
||||
}
|
||||
e.frameChanged = true;
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->notifyObservers(&e);
|
||||
return 2000;
|
||||
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
||||
@@ -263,31 +266,69 @@ int32_t CannedMessageModule::runOnce()
|
||||
e.frameChanged = true;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) {
|
||||
this->currentMessageIndex = getPrevIndex();
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
if (this->messagesCount > 0) {
|
||||
this->currentMessageIndex = getPrevIndex();
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
}
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN) {
|
||||
this->currentMessageIndex = this->getNextIndex();
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
if (this->messagesCount > 0) {
|
||||
this->currentMessageIndex = this->getNextIndex();
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
}
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
e.frameChanged = true;
|
||||
switch (this->payload) {
|
||||
case 0xb4: // left
|
||||
if (this->cursor > 0) {
|
||||
this->cursor--;
|
||||
if (this->destSelect){
|
||||
size_t numNodes = nodeDB.getNumNodes();
|
||||
if(this->dest == NODENUM_BROADCAST) {
|
||||
this->dest = nodeDB.getNodeNum();
|
||||
}
|
||||
for (unsigned int i = 0; i < numNodes; i++) {
|
||||
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
|
||||
this->dest = (i > 0) ? nodeDB.getNodeByIndex(i-1)->num : nodeDB.getNodeByIndex(numNodes-1)->num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(this->dest == nodeDB.getNodeNum()) {
|
||||
this->dest = NODENUM_BROADCAST;
|
||||
}
|
||||
}else{
|
||||
if (this->cursor > 0) {
|
||||
this->cursor--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xb7: // right
|
||||
if (this->cursor < this->freetext.length()) {
|
||||
this->cursor++;
|
||||
if (this->destSelect){
|
||||
size_t numNodes = nodeDB.getNumNodes();
|
||||
if(this->dest == NODENUM_BROADCAST) {
|
||||
this->dest = nodeDB.getNodeNum();
|
||||
}
|
||||
for (unsigned int i = 0; i < numNodes; i++) {
|
||||
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
|
||||
this->dest = (i < numNodes-1) ? nodeDB.getNodeByIndex(i+1)->num : nodeDB.getNodeByIndex(0)->num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(this->dest == nodeDB.getNodeNum()) {
|
||||
this->dest = NODENUM_BROADCAST;
|
||||
}
|
||||
}else{
|
||||
if (this->cursor < this->freetext.length()) {
|
||||
this->cursor++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8: // backspace
|
||||
case 0x08: // backspace
|
||||
if (this->freetext.length() > 0) {
|
||||
if(this->cursor == this->freetext.length()) {
|
||||
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
|
||||
@@ -297,6 +338,13 @@ int32_t CannedMessageModule::runOnce()
|
||||
this->cursor--;
|
||||
}
|
||||
break;
|
||||
case 0x09: // tab
|
||||
if(this->destSelect) {
|
||||
this->destSelect = false;
|
||||
} else {
|
||||
this->destSelect = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(this->cursor == this->freetext.length()) {
|
||||
this->freetext += this->payload;
|
||||
@@ -339,6 +387,19 @@ const char *CannedMessageModule::getNextMessage()
|
||||
{
|
||||
return this->messages[this->getNextIndex()];
|
||||
}
|
||||
const char* CannedMessageModule::getNodeName(NodeNum node) {
|
||||
if (node == NODENUM_BROADCAST){
|
||||
return "Broadcast";
|
||||
}else{
|
||||
NodeInfo *info = nodeDB.getNode(node);
|
||||
if(info != NULL) {
|
||||
return info->user.long_name;
|
||||
}else{
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CannedMessageModule::shouldDraw()
|
||||
{
|
||||
if (!moduleConfig.canned_message.enabled) {
|
||||
@@ -369,6 +430,8 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
{
|
||||
displayedNodeNum = 0; // Not currently showing a node pane
|
||||
|
||||
char buffer[50];
|
||||
|
||||
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
@@ -379,21 +442,29 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
|
||||
}else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
display->drawString(0 + x, 0 + y, "To: Broadcast");
|
||||
display->setFont(FONT_SMALL);
|
||||
if (this->destSelect) {
|
||||
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||
display->setColor(BLACK);
|
||||
}
|
||||
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
|
||||
// used chars right aligned
|
||||
char buffer[9];
|
||||
sprintf(buffer, "%d left", Constants_DATA_PAYLOAD_LEN - this->freetext.length());
|
||||
display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_MEDIUM, cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
||||
display->setColor(WHITE);
|
||||
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
||||
} else {
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(0 + x, 0 + y, cannedMessageModule->getPrevMessage());
|
||||
display->setFont(FONT_MEDIUM);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getCurrentMessage());
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_MEDIUM, cannedMessageModule->getNextMessage());
|
||||
if (this->messagesCount > 0) {
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getPrevMessage());
|
||||
display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||
display->setColor(BLACK);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, cannedMessageModule->getCurrentMessage());
|
||||
display->setColor(WHITE);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 3, cannedMessageModule->getNextMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ enum cannedMessageModuleRunState
|
||||
CANNED_MESSAGE_RUN_STATE_INACTIVE,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTIVE,
|
||||
CANNED_MESSAGE_RUN_STATE_FREETEXT,
|
||||
CANNED_MESSAGE_RUN_STATE_MATRIX,
|
||||
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
|
||||
@@ -36,6 +35,7 @@ class CannedMessageModule :
|
||||
const char* getCurrentMessage();
|
||||
const char* getPrevMessage();
|
||||
const char* getNextMessage();
|
||||
const char* getNodeName(NodeNum node);
|
||||
bool shouldDraw();
|
||||
void eventUp();
|
||||
void eventDown();
|
||||
@@ -74,9 +74,11 @@ class CannedMessageModule :
|
||||
|
||||
int currentMessageIndex = -1;
|
||||
cannedMessageModuleRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
char payload;
|
||||
char payload = 0x00;
|
||||
unsigned int cursor = 0;
|
||||
String freetext = ""; // Text Buffer for Freetext Editor
|
||||
bool destSelect = false; // Freetext Editor Mode
|
||||
NodeNum dest = NODENUM_BROADCAST;
|
||||
|
||||
char messageStore[CANNED_MESSAGE_MODULE_MESSAGES_SIZE+1];
|
||||
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
|
||||
@@ -85,4 +87,4 @@ class CannedMessageModule :
|
||||
};
|
||||
|
||||
extern CannedMessageModule *cannedMessageModule;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -144,7 +144,7 @@ int32_t PositionModule::runOnce()
|
||||
if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) {
|
||||
|
||||
// Only send packets if the channel is less than 40% utilized.
|
||||
if (airTime->channelUtilizationPercent() < 40) {
|
||||
if (airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
||||
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
|
||||
lastGpsSend = now;
|
||||
|
||||
@@ -165,7 +165,7 @@ int32_t PositionModule::runOnce()
|
||||
} else if (config.position.position_broadcast_smart_enabled) {
|
||||
|
||||
// Only send packets if the channel is less than 25% utilized.
|
||||
if (airTime->channelUtilizationPercent() < 25) {
|
||||
if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
|
||||
|
||||
NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
|
||||
|
||||
|
||||
@@ -13,15 +13,16 @@
|
||||
int32_t DeviceTelemetryModule::runOnce()
|
||||
{
|
||||
#ifndef ARCH_PORTDUINO
|
||||
if (firstTime) {
|
||||
// This is the first time the OSThread library has called this function, so do some setup
|
||||
firstTime = 0;
|
||||
DEBUG_MSG("Device Telemetry: Initializing\n");
|
||||
uint32_t now = millis();
|
||||
if ((lastSentToMesh == 0 || (now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval))
|
||||
&& airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
||||
sendTelemetry();
|
||||
lastSentToMesh = now;
|
||||
} else {
|
||||
// Just send to phone when it's not our time to send to mesh yet
|
||||
sendTelemetry(NODENUM_BROADCAST, true);
|
||||
}
|
||||
sendOurTelemetry();
|
||||
// OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds
|
||||
|
||||
return getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval);
|
||||
return sendToPhoneIntervalMs;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -45,7 +46,7 @@ bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemet
|
||||
return false; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
bool DeviceTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies)
|
||||
bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
{
|
||||
Telemetry t;
|
||||
|
||||
@@ -68,11 +69,16 @@ bool DeviceTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies)
|
||||
|
||||
MeshPacket *p = allocDataProtobuf(t);
|
||||
p->to = dest;
|
||||
p->decoded.want_response = wantReplies;
|
||||
p->decoded.want_response = false;
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(*p);
|
||||
DEBUG_MSG("Device Telemetry: Sending packet to mesh\n");
|
||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
nodeDB.updateTelemetry(nodeDB.getNodeNum(), t, RX_SRC_LOCAL);
|
||||
if (phoneOnly) {
|
||||
DEBUG_MSG("Device Telemetry: Sending packet to phone\n");
|
||||
service.sendToPhone(p);
|
||||
} else {
|
||||
DEBUG_MSG("Device Telemetry: Sending packet to mesh\n");
|
||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,9 +24,10 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
|
||||
/**
|
||||
* Send our Telemetry into the mesh
|
||||
*/
|
||||
bool sendOurTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
|
||||
bool sendTelemetry(NodeNum dest = NODENUM_BROADCAST, bool phoneOnly = false);
|
||||
|
||||
private:
|
||||
bool firstTime = 1;
|
||||
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
|
||||
uint32_t lastSentToMesh = 0;
|
||||
const MeshPacket *lastMeasurementPacket;
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ int32_t StoreForwardModule::runOnce()
|
||||
if (this->busy) {
|
||||
|
||||
// Only send packets if the channel is less than 25% utilized.
|
||||
if (airTime->channelUtilizationPercent() < 25) {
|
||||
if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
|
||||
|
||||
// DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index);
|
||||
storeForwardModule->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
MQTT *mqtt;
|
||||
|
||||
String statusTopic = "msh/1/stat/";
|
||||
String cryptTopic = "msh/1/c/"; // msh/1/c/CHANNELID/NODEID
|
||||
String jsonTopic = "msh/1/json/"; // msh/1/json/CHANNELID/NODEID
|
||||
String statusTopic = "msh/2/stat/";
|
||||
String cryptTopic = "msh/2/c/"; // msh/2/c/CHANNELID/NODEID
|
||||
String jsonTopic = "msh/2/json/"; // msh/2/json/CHANNELID/NODEID
|
||||
|
||||
void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
{
|
||||
|
||||
43
src/platform/esp32/BleOta.cpp
Normal file
43
src/platform/esp32/BleOta.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "Arduino.h"
|
||||
#include "BleOta.h"
|
||||
#include <esp_ota_ops.h>
|
||||
|
||||
static const String MESHTASTIC_OTA_APP_PROJECT_NAME("Meshtastic-OTA");
|
||||
|
||||
const esp_partition_t* BleOta::findEspOtaAppPartition() {
|
||||
const esp_partition_t *part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, nullptr);
|
||||
|
||||
esp_app_desc_t app_desc;
|
||||
esp_err_t ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
|
||||
|
||||
if (ret != ESP_OK || MESHTASTIC_OTA_APP_PROJECT_NAME != app_desc.project_name) {
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, nullptr);
|
||||
ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
|
||||
}
|
||||
|
||||
if (ret == ESP_OK && MESHTASTIC_OTA_APP_PROJECT_NAME == app_desc.project_name) {
|
||||
return part;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
String BleOta::getOtaAppVersion() {
|
||||
const esp_partition_t *part = findEspOtaAppPartition();
|
||||
esp_app_desc_t app_desc;
|
||||
esp_err_t ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
|
||||
String version;
|
||||
if (ret == ESP_OK) {
|
||||
version = app_desc.version;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
bool BleOta::switchToOtaApp() {
|
||||
bool success = false;
|
||||
const esp_partition_t *part = findEspOtaAppPartition();
|
||||
if (part) {
|
||||
success = (ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_set_boot_partition(part)) == ESP_OK);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
18
src/platform/esp32/BleOta.h
Normal file
18
src/platform/esp32/BleOta.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef BLEOTA_H
|
||||
#define BLEOTA_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
class BleOta {
|
||||
public:
|
||||
explicit BleOta() {};
|
||||
|
||||
static String getOtaAppVersion();
|
||||
static bool switchToOtaApp();
|
||||
|
||||
private:
|
||||
String mUserAgent;
|
||||
static const esp_partition_t *findEspOtaAppPartition();
|
||||
};
|
||||
|
||||
#endif //BLEOTA_H
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "main.h"
|
||||
|
||||
#include "nimble/NimbleBluetooth.h"
|
||||
#include "BleOta.h"
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
|
||||
#include "sleep.h"
|
||||
@@ -63,6 +64,12 @@ void esp32Setup()
|
||||
preferences.putUInt("rebootCounter", rebootCounter);
|
||||
preferences.end();
|
||||
DEBUG_MSG("Number of Device Reboots: %d\n", rebootCounter);
|
||||
String BLEOTA=BleOta::getOtaAppVersion();
|
||||
if (BLEOTA.isEmpty()) {
|
||||
DEBUG_MSG("No OTA firmware available\n");
|
||||
}else{
|
||||
DEBUG_MSG("OTA firmware version %s\n", BLEOTA);
|
||||
}
|
||||
|
||||
// enableModemSleep();
|
||||
|
||||
|
||||
@@ -244,6 +244,9 @@ void NRF52Bluetooth::setup()
|
||||
Bluefruit.Periph.setConnectCallback(onConnect);
|
||||
Bluefruit.Periph.setDisconnectCallback(onDisconnect);
|
||||
|
||||
bledfu.setPermission(SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM);
|
||||
bledfu.begin(); // Install the DFU helper
|
||||
|
||||
// Configure and Start the Device Information Service
|
||||
DEBUG_MSG("Configuring the Device Information Service\n");
|
||||
bledis.setModel(optstr(HW_VERSION));
|
||||
@@ -254,7 +257,7 @@ void NRF52Bluetooth::setup()
|
||||
DEBUG_MSG("Configuring the Battery Service\n");
|
||||
blebas.begin();
|
||||
blebas.write(0); // Unknown battery level for now
|
||||
bledfu.begin(); // Install the DFU helper
|
||||
|
||||
|
||||
// Setup the Heart Rate Monitor service using
|
||||
// BLEService and BLECharacteristic classes
|
||||
|
||||
@@ -171,6 +171,8 @@ void SimRadio::onNotify(uint32_t notification)
|
||||
// Packet has been sent, count it toward our TX airtime utilization.
|
||||
uint32_t xmitMsec = getPacketTime(txp);
|
||||
airTime->logAirtime(TX_LOG, xmitMsec);
|
||||
|
||||
delay(xmitMsec); // Model the time it is busy sending
|
||||
completeSending();
|
||||
}
|
||||
}
|
||||
@@ -207,6 +209,9 @@ void SimRadio::startSend(MeshPacket * txp)
|
||||
|
||||
void SimRadio::startReceive(MeshPacket *p) {
|
||||
isReceiving = true;
|
||||
size_t length = getPacketLength(p);
|
||||
uint32_t xmitMsec = getPacketTime(length);
|
||||
delay(xmitMsec); // Model the time it is busy receiving
|
||||
handleReceiveInterrupt(p);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ build_flags =
|
||||
-DTFT_BL=32
|
||||
-DSPI_FREQUENCY=40000000
|
||||
-DSPI_READ_FREQUENCY=16000000
|
||||
-DDISABLE_ALL_LIBRARY_WARNINGS
|
||||
lib_ignore =
|
||||
m5stack-core
|
||||
lib_deps =
|
||||
|
||||
@@ -12,8 +12,7 @@ build_flags =
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.4.9
|
||||
# lewisxhe/PCF8563_Library@^1.0.1 // switch to this one when it is released!
|
||||
https://github.com/lewisxhe/PCF8563_Library.git#fe8cface109f63b5a4fb6abeaf87c6de0faa24c6
|
||||
lewisxhe/PCF8563_Library@^1.0.1
|
||||
board_build.f_cpu = 240000000L
|
||||
upload_protocol = esptool
|
||||
upload_port = /dev/ttyACM*
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[env:pico]
|
||||
extends = rp2040_base
|
||||
board = pico
|
||||
board = rpipico
|
||||
upload_protocol = picotool
|
||||
|
||||
# add our variants files to the include and src paths
|
||||
build_flags = ${rp2040_base.build_flags}
|
||||
-DPRIVATE_HW
|
||||
-Ivariants/pico
|
||||
-Ivariants/rpipico
|
||||
-DARDUINO_AVR_NANO_EVERY
|
||||
-DDEBUG_RP2040_WIRE
|
||||
-DDEBUG_RP2040_SPI
|
||||
17
variants/rpipicow/platformio.ini
Normal file
17
variants/rpipicow/platformio.ini
Normal file
@@ -0,0 +1,17 @@
|
||||
[env:picow]
|
||||
extends = rp2040_base
|
||||
board = rpipicow
|
||||
upload_protocol = picotool
|
||||
|
||||
# add our variants files to the include and src paths
|
||||
build_flags = ${rp2040_base.build_flags}
|
||||
-DPRIVATE_HW
|
||||
-Ivariants/rpipicow
|
||||
-DARDUINO_AVR_NANO_EVERY
|
||||
-DDEBUG_RP2040_WIRE
|
||||
-DDEBUG_RP2040_SPI
|
||||
-DDEBUG_RP2040_CORE
|
||||
-DDEBUG_RP2040_PORT=Serial
|
||||
-DUSE_TINYUSB
|
||||
lib_deps =
|
||||
${rp2040_base.lib_deps}
|
||||
52
variants/rpipicow/variant.h
Normal file
52
variants/rpipicow/variant.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// #define RADIOLIB_CUSTOM_ARDUINO 1
|
||||
// #define RADIOLIB_TONE_UNSUPPORTED 1
|
||||
// #define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED 1
|
||||
|
||||
#define ARDUINO_ARCH_AVR
|
||||
|
||||
#define CBC 0
|
||||
#define CTR 1
|
||||
#define ECB 0
|
||||
|
||||
#define NO_GPS 1
|
||||
#define USE_SH1106 1
|
||||
#undef GPS_SERIAL_NUM
|
||||
|
||||
// #define I2C_SDA 6
|
||||
// #define I2C_SCL 7
|
||||
|
||||
#define BUTTON_PIN 17
|
||||
#define EXT_NOTIFY_OUT 4
|
||||
|
||||
#define BATTERY_PIN 26
|
||||
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
||||
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
||||
|
||||
#define USE_RF95
|
||||
#define USE_SX1262
|
||||
|
||||
#undef RF95_SCK
|
||||
#undef RF95_MISO
|
||||
#undef RF95_MOSI
|
||||
#undef RF95_NSS
|
||||
|
||||
#define RF95_SCK 10
|
||||
#define RF95_MISO 12
|
||||
#define RF95_MOSI 11
|
||||
#define RF95_NSS 3
|
||||
|
||||
#define LORA_DIO0 RADIOLIB_NC
|
||||
#define LORA_RESET 15
|
||||
#define LORA_DIO1 20
|
||||
#define LORA_DIO2 2
|
||||
#define LORA_DIO3 RADIOLIB_NC
|
||||
|
||||
#ifdef USE_SX1262
|
||||
#define SX126X_CS RF95_NSS
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_DIO2
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_E22
|
||||
#endif
|
||||
|
||||
#include <Adafruit_TinyUSB.h>
|
||||
@@ -14,6 +14,5 @@ lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
https://github.com/meshtastic/GxEPD2#afce87a97dda1ac31d8a28dc8fa7c6f55dc96a61
|
||||
adafruit/Adafruit BusIO@^1.13.2
|
||||
# lewisxhe/PCF8563_Library@^1.0.1 // switch to this one when it is released!
|
||||
https://github.com/lewisxhe/PCF8563_Library.git#fe8cface109f63b5a4fb6abeaf87c6de0faa24c6
|
||||
lewisxhe/PCF8563_Library@^1.0.1
|
||||
;upload_protocol = fs
|
||||
|
||||
@@ -25,5 +25,12 @@ static const uint8_t MOSI = 11;
|
||||
static const uint8_t MISO = 13;
|
||||
static const uint8_t SCK = 12;
|
||||
|
||||
#define SDMMC_CMD (35)
|
||||
#define SDMMC_CLK (36)
|
||||
#define SDMMC_DATA (37)
|
||||
|
||||
#define ACCEL_INT1 (34)
|
||||
#define ACCEL_INT2 (33)
|
||||
#define RTC_INT (14)
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
|
||||
@@ -5,7 +5,9 @@ board = tbeam-s3-core
|
||||
|
||||
lib_deps =
|
||||
${esp32s3_base.lib_deps}
|
||||
lewisxhe/PCF8563_Library@1.0.1
|
||||
|
||||
build_flags =
|
||||
${esp32s3_base.build_flags}
|
||||
-Ivariants/tbeam-s3-core
|
||||
|
||||
-DPCF8563_RTC=0x51 ;Putting definitions in variant.h does not compile correctly
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
|
||||
|
||||
#define I2C_SDA 42
|
||||
#define I2C_SCL 41
|
||||
#define I2C_SDA1 42 //Used for PMU management
|
||||
#define I2C_SCL1 41 //Used for PMU management
|
||||
|
||||
#define I2C_SDA 17 //For sensors and screens
|
||||
#define I2C_SCL 18 //For sensors and screens
|
||||
|
||||
#define BUTTON_PIN 0 // The middle button GPIO on the T-Beam S3
|
||||
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented anywhere.
|
||||
// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
|
||||
|
||||
#define BUTTON1_PIN 47 //Additional keys
|
||||
|
||||
|
||||
#define LED_INVERTED 1
|
||||
// #define LED_PIN 4 // Newer tbeams (1.1) have an extra led on GPIO4
|
||||
|
||||
@@ -36,6 +42,9 @@
|
||||
// #define PMU_IRQ 40
|
||||
#define HAS_AXP2101
|
||||
|
||||
// Specify the PMU as Wire1. In the t-beam-s3-core, the PMU enjoys a separate bus
|
||||
#define PMU_USE_WIRE1
|
||||
|
||||
#define RF95_SCK 12
|
||||
#define RF95_MISO 13
|
||||
#define RF95_MOSI 11
|
||||
@@ -47,3 +56,10 @@
|
||||
#define GPS_1PPS_PIN 6
|
||||
|
||||
|
||||
#define HAS_SDCARD //Have 3-bit SDMMC interface SD card slot
|
||||
|
||||
// PCF8563 RTC Module
|
||||
// #define PCF8563_RTC 0x51 //Putting definitions in variant. h does not compile correctly
|
||||
|
||||
#define HAS_RTC 1
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
major = 1
|
||||
minor = 3
|
||||
build = 42
|
||||
build = 44
|
||||
|
||||
Reference in New Issue
Block a user