Skip to content

Commit 7b3a0bb

Browse files
committed
Merge remote-tracking branch 'upstream/dev' into dev
2 parents 2536fa6 + 695473f commit 7b3a0bb

40 files changed

+1182
-452
lines changed

boards/ebyte_eora-s3.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"build": {
3+
"arduino": {
4+
"ldscript": "esp32s3_out.ld",
5+
"partitions": "default.csv",
6+
"memory_type": "qio_qspi"
7+
},
8+
"core": "esp32",
9+
"extra_flags": [
10+
"-DARDUINO_LILYGO_T3_S3_V1_X",
11+
"-DBOARD_HAS_PSRAM",
12+
"-DARDUINO_USB_CDC_ON_BOOT=1",
13+
"-DARDUINO_RUNNING_CORE=1",
14+
"-DARDUINO_EVENT_RUNNING_CORE=1",
15+
"-DARDUINO_USB_MODE=1"
16+
],
17+
"f_cpu": "240000000L",
18+
"f_flash": "80000000L",
19+
"flash_mode": "qio",
20+
"mcu": "esp32s3",
21+
"variant": "esp32s3"
22+
},
23+
"connectivity": [
24+
"wifi"
25+
],
26+
"debug": {
27+
"openocd_target": "esp32s3.cfg"
28+
},
29+
"frameworks": [
30+
"arduino",
31+
"espidf"
32+
],
33+
"name": "Ebyte EoRa-S3-XXXTB Radio",
34+
"upload": {
35+
"flash_size": "4MB",
36+
"maximum_ram_size": 327680,
37+
"maximum_size": 4194304,
38+
"use_1200bps_touch": true,
39+
"wait_for_upload_port": true,
40+
"require_upload_port": true,
41+
"speed": 460800
42+
},
43+
"url": "https://www.cdebyte.com/products/EoRa-S3-900TB",
44+
"vendor": "Chengdu Ebyte Electronic Technology Co., Ltd"
45+
}

boards/tiny_relay.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"build": {
3+
"arduino": {
4+
"variant_h": "variant_RAK3172_MODULE.h"
5+
},
6+
"core": "stm32",
7+
"cpu": "cortex-m4",
8+
"extra_flags": "-DSTM32WL -DSTM32WLxx -DSTM32WLE5xx",
9+
"framework_extra_flags": {
10+
"arduino": "-DUSE_CM4_STARTUP_FILE -DARDUINO_RAK3172_MODULE"
11+
},
12+
"f_cpu": "48000000L",
13+
"mcu": "stm32wle5ccu",
14+
"product_line": "STM32WLE5xx",
15+
"variant": "STM32WLxx/WL54CCU_WL55CCU_WLE4C(8-B-C)U_WLE5C(8-B-C)U"
16+
},
17+
"debug": {
18+
"default_tools": ["stlink"],
19+
"jlink_device": "STM32WLE5CC",
20+
"openocd_target": "stm32wlx",
21+
"svd_path": "STM32WLE5_CM4.svd"
22+
},
23+
"frameworks": ["arduino"],
24+
"name": "BB-STM32WL",
25+
"upload": {
26+
"maximum_ram_size": 65536,
27+
"maximum_size": 262144,
28+
"protocol": "stlink",
29+
"protocols": ["stlink", "jlink"]
30+
},
31+
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wle5cc.html",
32+
"vendor": "YAOYAO"
33+
}

examples/companion_radio/AbstractUITask.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ class AbstractUITask {
4141
void disableSerial() { _serial->disable(); }
4242
virtual void msgRead(int msgcount) = 0;
4343
virtual void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) = 0;
44-
virtual void soundBuzzer(UIEventType bet = UIEventType::none) = 0;
44+
virtual void notify(UIEventType t = UIEventType::none) = 0;
4545
virtual void loop() = 0;
4646
};

examples/companion_radio/DataStore.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,17 @@ static File openWrite(FILESYSTEM* fs, const char* filename) {
4242
#endif
4343
}
4444

45+
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
46+
static uint32_t _ContactsChannelsTotalBlocks = 0;
47+
#endif
48+
4549
void DataStore::begin() {
4650
#if defined(RP2040_PLATFORM)
4751
identity_store.begin();
4852
#endif
4953

5054
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
55+
_ContactsChannelsTotalBlocks = _getContactsChannelsFS()->_getFS()->cfg->block_count;
5156
checkAdvBlobFile();
5257
#if defined(EXTRAFS) || defined(QSPIFLASH)
5358
migrateToSecondaryFS();
@@ -74,14 +79,22 @@ void DataStore::begin() {
7479

7580
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
7681
int _countLfsBlock(void *p, lfs_block_t block){
82+
if (block > _ContactsChannelsTotalBlocks) {
83+
MESH_DEBUG_PRINTLN("ERROR: Block %d exceeds filesystem bounds - CORRUPTION DETECTED!", block);
84+
return LFS_ERR_CORRUPT; // return error to abort lfs_traverse() gracefully
85+
}
7786
lfs_size_t *size = (lfs_size_t*) p;
7887
*size += 1;
79-
return 0;
88+
return 0;
8089
}
8190

8291
lfs_ssize_t _getLfsUsedBlockCount(FILESYSTEM* fs) {
8392
lfs_size_t size = 0;
84-
lfs_traverse(fs->_getFS(), _countLfsBlock, &size);
93+
int err = lfs_traverse(fs->_getFS(), _countLfsBlock, &size);
94+
if (err) {
95+
MESH_DEBUG_PRINTLN("ERROR: lfs_traverse() error: %d", err);
96+
return 0;
97+
}
8598
return size;
8699
}
87100
#endif

examples/companion_radio/MyMesh.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path
243243
}
244244
} else {
245245
#ifdef DISPLAY_CLASS
246-
if (_ui) _ui->soundBuzzer(UIEventType::newContactMessage);
246+
if (_ui) _ui->notify(UIEventType::newContactMessage);
247247
#endif
248248
}
249249

@@ -294,7 +294,7 @@ void MyMesh::onContactPathUpdated(const ContactInfo &contact) {
294294
dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
295295
}
296296

297-
bool MyMesh::processAck(const uint8_t *data) {
297+
ContactInfo* MyMesh::processAck(const uint8_t *data) {
298298
// see if matches any in a table
299299
for (int i = 0; i < EXPECTED_ACK_TABLE_SIZE; i++) {
300300
if (memcmp(data, &expected_ack_table[i].ack, 4) == 0) { // got an ACK from recipient
@@ -306,7 +306,7 @@ bool MyMesh::processAck(const uint8_t *data) {
306306

307307
// NOTE: the same ACK can be received multiple times!
308308
expected_ack_table[i].ack = 0; // clear expected hash, now that we have received ACK
309-
return true;
309+
return expected_ack_table[i].contact;
310310
}
311311
}
312312
return checkConnectionsAck(data);
@@ -353,7 +353,7 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe
353353
if (should_display && _ui) {
354354
_ui->newMsg(path_len, from.name, text, offline_queue_len);
355355
if (!_serial->isConnected()) {
356-
_ui->soundBuzzer(UIEventType::contactMessage);
356+
_ui->notify(UIEventType::contactMessage);
357357
}
358358
}
359359
#endif
@@ -412,7 +412,7 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe
412412
_serial->writeFrame(frame, 1);
413413
} else {
414414
#ifdef DISPLAY_CLASS
415-
if (_ui) _ui->soundBuzzer(UIEventType::channelMessage);
415+
if (_ui) _ui->notify(UIEventType::channelMessage);
416416
#endif
417417
}
418418
#ifdef DISPLAY_CLASS
@@ -825,6 +825,7 @@ void MyMesh::handleCmdFrame(size_t len) {
825825
if (expected_ack) {
826826
expected_ack_table[next_ack_idx].msg_sent = _ms->getMillis(); // add to circular table
827827
expected_ack_table[next_ack_idx].ack = expected_ack;
828+
expected_ack_table[next_ack_idx].contact = recipient;
828829
next_ack_idx = (next_ack_idx + 1) % EXPECTED_ACK_TABLE_SIZE;
829830
}
830831

examples/companion_radio/MyMesh.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class MyMesh : public BaseChatMesh, public DataStoreHost {
112112
bool onContactPathRecv(ContactInfo& from, uint8_t* in_path, uint8_t in_path_len, uint8_t* out_path, uint8_t out_path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override;
113113
void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) override;
114114
void onContactPathUpdated(const ContactInfo &contact) override;
115-
bool processAck(const uint8_t *data) override;
115+
ContactInfo* processAck(const uint8_t *data) override;
116116
void queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packet *pkt, uint32_t sender_timestamp,
117117
const uint8_t *extra, int extra_len, const char *text);
118118

@@ -205,6 +205,7 @@ class MyMesh : public BaseChatMesh, public DataStoreHost {
205205
struct AckTableEntry {
206206
unsigned long msg_sent;
207207
uint32_t ack;
208+
ContactInfo* contact;
208209
};
209210
#define EXPECTED_ACK_TABLE_SIZE 8
210211
AckTableEntry expected_ack_table[EXPECTED_ACK_TABLE_SIZE]; // circular table

examples/companion_radio/ui-new/UITask.cpp

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class HomeScreen : public UIScreen {
9090
bool _shutdown_init;
9191
AdvertPath recent[UI_RECENT_LIST_SIZE];
9292

93+
9394
void renderBatteryIndicator(DisplayDriver& display, uint16_t batteryMilliVolts) {
9495
// Convert millivolts to percentage
9596
const int minMilliVolts = 3000; // Minimum voltage (e.g., 3.0V)
@@ -157,10 +158,12 @@ class HomeScreen : public UIScreen {
157158
int render(DisplayDriver& display) override {
158159
char tmp[80];
159160
// node name
160-
display.setCursor(0, 0);
161161
display.setTextSize(1);
162162
display.setColor(DisplayDriver::GREEN);
163-
display.print(_node_prefs->node_name);
163+
char filtered_name[sizeof(_node_prefs->node_name)];
164+
display.translateUTF8ToBlocks(filtered_name, _node_prefs->node_name, sizeof(filtered_name));
165+
display.setCursor(0, 0);
166+
display.print(filtered_name);
164167

165168
// battery voltage
166169
renderBatteryIndicator(display, _task->getBattMilliVolts());
@@ -199,8 +202,6 @@ class HomeScreen : public UIScreen {
199202
for (int i = 0; i < UI_RECENT_LIST_SIZE; i++, y += 11) {
200203
auto a = &recent[i];
201204
if (a->name[0] == 0) continue; // empty slot
202-
display.setCursor(0, y);
203-
display.print(a->name);
204205
int secs = _rtc->getCurrentTime() - a->recv_timestamp;
205206
if (secs < 60) {
206207
sprintf(tmp, "%ds", secs);
@@ -209,7 +210,14 @@ class HomeScreen : public UIScreen {
209210
} else {
210211
sprintf(tmp, "%dh", secs / (60*60));
211212
}
212-
display.setCursor(display.width() - display.getTextWidth(tmp) - 1, y);
213+
214+
int timestamp_width = display.getTextWidth(tmp);
215+
int max_name_width = display.width() - timestamp_width - 1;
216+
217+
char filtered_recent_name[sizeof(a->name)];
218+
display.translateUTF8ToBlocks(filtered_recent_name, a->name, sizeof(filtered_recent_name));
219+
display.drawTextEllipsized(0, y, max_name_width, filtered_recent_name);
220+
display.setCursor(display.width() - timestamp_width - 1, y);
213221
display.print(tmp);
214222
}
215223
} else if (_page == HomePage::RADIO) {
@@ -348,9 +356,7 @@ class HomeScreen : public UIScreen {
348356
return true;
349357
}
350358
if (c == KEY_ENTER && _page == HomePage::ADVERT) {
351-
#ifdef PIN_BUZZER
352-
_task->soundBuzzer(UIEventType::ack);
353-
#endif
359+
_task->notify(UIEventType::ack);
354360
if (the_mesh.advert()) {
355361
_task->showAlert("Advert sent!", 1000);
356362
} else {
@@ -427,11 +433,15 @@ class MsgPreviewScreen : public UIScreen {
427433

428434
display.setCursor(0, 14);
429435
display.setColor(DisplayDriver::YELLOW);
430-
display.print(p->origin);
436+
char filtered_origin[sizeof(p->origin)];
437+
display.translateUTF8ToBlocks(filtered_origin, p->origin, sizeof(filtered_origin));
438+
display.print(filtered_origin);
431439

432440
display.setCursor(0, 25);
433441
display.setColor(DisplayDriver::LIGHT);
434-
display.printWordWrap(p->msg, display.width());
442+
char filtered_msg[sizeof(p->msg)];
443+
display.translateUTF8ToBlocks(filtered_msg, p->msg, sizeof(filtered_msg));
444+
display.printWordWrap(filtered_msg, display.width());
435445

436446
#if AUTO_OFF_MILLIS==0 // probably e-ink
437447
return 10000; // 10 s
@@ -483,6 +493,10 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
483493
buzzer.begin();
484494
#endif
485495

496+
#ifdef PIN_VIBRATION
497+
vibration.begin();
498+
#endif
499+
486500
ui_started_at = millis();
487501
_alert_expiry = 0;
488502

@@ -497,9 +511,9 @@ void UITask::showAlert(const char* text, int duration_millis) {
497511
_alert_expiry = millis() + duration_millis;
498512
}
499513

500-
void UITask::soundBuzzer(UIEventType bet) {
514+
void UITask::notify(UIEventType t) {
501515
#if defined(PIN_BUZZER)
502-
switch(bet){
516+
switch(t){
503517
case UIEventType::contactMessage:
504518
// gemini's pick
505519
buzzer.play("MsgRcv3:d=4,o=6,b=200:32e,32g,32b,16c7");
@@ -517,8 +531,16 @@ switch(bet){
517531
break;
518532
}
519533
#endif
534+
535+
#ifdef PIN_VIBRATION
536+
// Trigger vibration for all UI events except none
537+
if (t != UIEventType::none) {
538+
vibration.trigger();
539+
}
540+
#endif
520541
}
521542

543+
522544
void UITask::msgRead(int msgcount) {
523545
_msgcount = msgcount;
524546
if (msgcount == 0) {
@@ -687,6 +709,10 @@ void UITask::loop() {
687709
#endif
688710
}
689711

712+
#ifdef PIN_VIBRATION
713+
vibration.loop();
714+
#endif
715+
690716
#ifdef AUTO_SHUTDOWN_MILLIVOLTS
691717
if (millis() > next_batt_chck) {
692718
uint16_t milliVolts = getBattMilliVolts();
@@ -755,11 +781,11 @@ void UITask::toggleGPS() {
755781
if (strcmp(_sensors->getSettingName(i), "gps") == 0) {
756782
if (strcmp(_sensors->getSettingValue(i), "1") == 0) {
757783
_sensors->setSettingValue("gps", "0");
758-
soundBuzzer(UIEventType::ack);
784+
notify(UIEventType::ack);
759785
showAlert("GPS: Disabled", 800);
760786
} else {
761787
_sensors->setSettingValue("gps", "1");
762-
soundBuzzer(UIEventType::ack);
788+
notify(UIEventType::ack);
763789
showAlert("GPS: Enabled", 800);
764790
}
765791
_next_refresh = 0;
@@ -774,7 +800,7 @@ void UITask::toggleBuzzer() {
774800
#ifdef PIN_BUZZER
775801
if (buzzer.isQuiet()) {
776802
buzzer.quiet(false);
777-
soundBuzzer(UIEventType::ack);
803+
notify(UIEventType::ack);
778804
showAlert("Buzzer: ON", 800);
779805
} else {
780806
buzzer.quiet(true);

examples/companion_radio/ui-new/UITask.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#ifdef PIN_BUZZER
1212
#include <helpers/ui/buzzer.h>
1313
#endif
14+
#ifdef PIN_VIBRATION
15+
#include <helpers/ui/GenericVibration.h>
16+
#endif
1417

1518
#include "../AbstractUITask.h"
1619
#include "../NodePrefs.h"
@@ -20,6 +23,9 @@ class UITask : public AbstractUITask {
2023
SensorManager* _sensors;
2124
#ifdef PIN_BUZZER
2225
genericBuzzer buzzer;
26+
#endif
27+
#ifdef PIN_VIBRATION
28+
GenericVibration vibration;
2329
#endif
2430
unsigned long _next_refresh, _auto_off;
2531
NodePrefs* _node_prefs;
@@ -71,7 +77,7 @@ class UITask : public AbstractUITask {
7177
// from AbstractUITask
7278
void msgRead(int msgcount) override;
7379
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
74-
void soundBuzzer(UIEventType bet = UIEventType::none) override;
80+
void notify(UIEventType t = UIEventType::none) override;
7581
void loop() override;
7682

7783
void shutdown(bool restart = false);

0 commit comments

Comments
 (0)