Skip to content

Commit 3bc8ec2

Browse files
authored
Merge pull request #830 from SoulOfNoob/feat/add_t-echo-lite_variant
Feat: add `T-Echo-Lite` Variant to MeshCore
2 parents ea13fa8 + 088b8fd commit 3bc8ec2

File tree

8 files changed

+523
-7
lines changed

8 files changed

+523
-7
lines changed

src/helpers/ui/GxEPDDisplay.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,10 @@
1212
#include <Fonts/FreeSans9pt7b.h>
1313
#include <Fonts/FreeSansBold12pt7b.h>
1414
#include <Fonts/FreeSans18pt7b.h>
15-
16-
#include <epd/GxEPD2_150_BN.h> // 1.54" b/w
17-
#include <epd/GxEPD2_213_B74.h> // 2.13" b/w
1815
#include <CRC32.h>
1916

2017
#include "DisplayDriver.h"
2118

22-
//GxEPD2_BW<GxEPD2_150_BN, 200> display(GxEPD2_150_BN(DISP_CS, DISP_DC, DISP_RST, DISP_BUSY)); // DEPG0150BN 200x200, SSD1681, TTGO T5 V2.4.1
23-
24-
2519
class GxEPDDisplay : public DisplayDriver {
2620

2721
#if defined(EINK_DISPLAY_MODEL)
@@ -44,7 +38,6 @@ class GxEPDDisplay : public DisplayDriver {
4438
int last_display_crc_value = 0;
4539

4640
public:
47-
// there is a margin in y...
4841
#if defined(EINK_DISPLAY_MODEL)
4942
GxEPDDisplay() : DisplayDriver(128, 128), display(EINK_DISPLAY_MODEL(PIN_DISPLAY_CS, PIN_DISPLAY_DC, PIN_DISPLAY_RST, PIN_DISPLAY_BUSY)) {}
5043
#else
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include <Arduino.h>
2+
#include "TechoBoard.h"
3+
4+
#ifdef LILYGO_TECHO
5+
6+
#include <bluefruit.h>
7+
#include <Wire.h>
8+
9+
static BLEDfu bledfu;
10+
11+
static void connect_callback(uint16_t conn_handle) {
12+
(void)conn_handle;
13+
MESH_DEBUG_PRINTLN("BLE client connected");
14+
}
15+
16+
static void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
17+
(void)conn_handle;
18+
(void)reason;
19+
20+
MESH_DEBUG_PRINTLN("BLE client disconnected");
21+
}
22+
23+
void TechoBoard::begin() {
24+
// for future use, sub-classes SHOULD call this from their begin()
25+
startup_reason = BD_STARTUP_NORMAL;
26+
27+
Wire.begin();
28+
29+
pinMode(SX126X_POWER_EN, OUTPUT);
30+
digitalWrite(SX126X_POWER_EN, HIGH);
31+
delay(10); // give sx1262 some time to power up
32+
}
33+
34+
uint16_t TechoBoard::getBattMilliVolts() {
35+
int adcvalue = 0;
36+
37+
analogReference(AR_INTERNAL_3_0);
38+
analogReadResolution(12);
39+
delay(10);
40+
41+
// ADC range is 0..3000mV and resolution is 12-bit (0..4095)
42+
adcvalue = analogRead(PIN_VBAT_READ);
43+
// Convert the raw value to compensated mv, taking the resistor-
44+
// divider into account (providing the actual LIPO voltage)
45+
return (uint16_t)((float)adcvalue * REAL_VBAT_MV_PER_LSB);
46+
}
47+
48+
bool TechoBoard::startOTAUpdate(const char* id, char reply[]) {
49+
// Config the peripheral connection with maximum bandwidth
50+
// more SRAM required by SoftDevice
51+
// Note: All config***() function must be called before begin()
52+
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
53+
Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16);
54+
55+
Bluefruit.begin(1, 0);
56+
// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
57+
Bluefruit.setTxPower(4);
58+
// Set the BLE device name
59+
Bluefruit.setName("TECHO_OTA");
60+
61+
Bluefruit.Periph.setConnectCallback(connect_callback);
62+
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
63+
64+
// To be consistent OTA DFU should be added first if it exists
65+
bledfu.begin();
66+
67+
// Set up and start advertising
68+
// Advertising packet
69+
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
70+
Bluefruit.Advertising.addTxPower();
71+
Bluefruit.Advertising.addName();
72+
73+
/* Start Advertising
74+
- Enable auto advertising if disconnected
75+
- Interval: fast mode = 20 ms, slow mode = 152.5 ms
76+
- Timeout for fast mode is 30 seconds
77+
- Start(timeout) with timeout = 0 will advertise forever (until connected)
78+
79+
For recommended advertising interval
80+
https://developer.apple.com/library/content/qa/qa1931/_index.html
81+
*/
82+
Bluefruit.Advertising.restartOnDisconnect(true);
83+
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
84+
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
85+
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
86+
87+
strcpy(reply, "OK - started");
88+
return true;
89+
}
90+
#endif
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
#include <MeshCore.h>
4+
#include <Arduino.h>
5+
6+
// built-ins
7+
#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
8+
9+
#define VBAT_DIVIDER (0.5F) // 150K + 150K voltage divider on VBAT
10+
#define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider
11+
12+
#define PIN_VBAT_READ (4)
13+
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
14+
15+
class TechoBoard : public mesh::MainBoard {
16+
protected:
17+
uint8_t startup_reason;
18+
19+
public:
20+
21+
void begin();
22+
uint16_t getBattMilliVolts() override;
23+
bool startOTAUpdate(const char* id, char reply[]) override;
24+
25+
uint8_t getStartupReason() const override {
26+
return startup_reason;
27+
}
28+
29+
const char* getManufacturerName() const override {
30+
return "LilyGo T-Echo";
31+
}
32+
33+
void powerOff() override {
34+
#ifdef LED_RED
35+
digitalWrite(LED_RED, LOW);
36+
#endif
37+
#ifdef LED_GREEN
38+
digitalWrite(LED_GREEN, LOW);
39+
#endif
40+
#ifdef LED_BLUE
41+
digitalWrite(LED_BLUE, LOW);
42+
#endif
43+
#ifdef DISP_BACKLIGHT
44+
digitalWrite(DISP_BACKLIGHT, LOW);
45+
#endif
46+
#ifdef PIN_PWR_EN
47+
digitalWrite(PIN_PWR_EN, LOW);
48+
#endif
49+
sd_power_system_off();
50+
}
51+
52+
void reboot() override {
53+
NVIC_SystemReset();
54+
}
55+
};
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
[LilyGo_T-Echo-Lite]
2+
extends = nrf52_base
3+
board = t-echo
4+
board_build.ldscript = boards/nrf52840_s140_v6.ld
5+
build_flags = ${nrf52_base.build_flags}
6+
-I variants/lilygo_techo_lite
7+
-I src/helpers/nrf52
8+
-I lib/nrf52/s140_nrf52_6.1.1_API/include
9+
-I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52
10+
-D LILYGO_TECHO
11+
-D RADIO_CLASS=CustomSX1262
12+
-D WRAPPER_CLASS=CustomSX1262Wrapper
13+
-D LORA_TX_POWER=22
14+
-D SX126X_POWER_EN=30
15+
-D SX126X_CURRENT_LIMIT=140
16+
-D SX126X_RX_BOOSTED_GAIN=1
17+
-D P_LORA_TX_LED=LED_GREEN
18+
-D DISABLE_DIAGNOSTIC_OUTPUT
19+
-D ENV_INCLUDE_GPS=1
20+
-D GPS_BAUD_RATE=9600
21+
-D PIN_GPS_EN=GPS_EN
22+
-D DISPLAY_CLASS=GxEPDDisplay
23+
-D EINK_DISPLAY_MODEL=GxEPD2_122_T61
24+
-D EINK_SCALE_X=1.5f
25+
-D EINK_SCALE_Y=2.0f
26+
-D EINK_X_OFFSET=0
27+
-D EINK_Y_OFFSET=10
28+
-D DISPLAY_ROTATION=4
29+
-D AUTO_OFF_MILLIS=0
30+
build_src_filter = ${nrf52_base.build_src_filter}
31+
+<helpers/*.cpp>
32+
+<TechoBoard.cpp>
33+
+<helpers/sensors/EnvironmentSensorManager.cpp>
34+
+<helpers/ui/GxEPDDisplay.cpp>
35+
+<helpers/ui/MomentaryButton.cpp>
36+
+<../variants/lilygo_techo_lite>
37+
lib_deps =
38+
${nrf52_base.lib_deps}
39+
stevemarple/MicroNMEA @ ^2.0.6
40+
adafruit/Adafruit BME280 Library @ ^2.3.0
41+
https://github.com/SoulOfNoob/GxEPD2.git
42+
bakercp/CRC32 @ ^2.0.0
43+
debug_tool = jlink
44+
upload_protocol = nrfutil
45+
46+
[env:LilyGo_T-Echo-Lite_repeater]
47+
extends = LilyGo_T-Echo-Lite
48+
build_src_filter = ${LilyGo_T-Echo-Lite.build_src_filter}
49+
+<../examples/simple_repeater>
50+
build_flags =
51+
${LilyGo_T-Echo-Lite.build_flags}
52+
-D ADVERT_NAME='"T-Echo-Lite Repeater"'
53+
-D ADVERT_LAT=0.0
54+
-D ADVERT_LON=0.0
55+
-D ADMIN_PASSWORD='"password"'
56+
-D MAX_NEIGHBOURS=8
57+
; -D MESH_PACKET_LOGGING=1
58+
; -D MESH_DEBUG=1
59+
60+
[env:LilyGo_T-Echo-Lite_room_server]
61+
extends = LilyGo_T-Echo-Lite
62+
build_src_filter = ${LilyGo_T-Echo-Lite.build_src_filter}
63+
+<../examples/simple_room_server>
64+
build_flags =
65+
${LilyGo_T-Echo-Lite.build_flags}
66+
-D ADVERT_NAME='"T-Echo-Lite Room"'
67+
-D ADVERT_LAT=0.0
68+
-D ADVERT_LON=0.0
69+
-D ADMIN_PASSWORD='"password"'
70+
; -D MESH_PACKET_LOGGING=1
71+
; -D MESH_DEBUG=1
72+
73+
[env:LilyGo_T-Echo-Lite_companion_radio_ble]
74+
extends = LilyGo_T-Echo-Lite
75+
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
76+
board_upload.maximum_size = 712704
77+
build_flags =
78+
${LilyGo_T-Echo-Lite.build_flags}
79+
-I src/helpers/ui
80+
-I examples/companion_radio/ui-new
81+
-D MAX_CONTACTS=350
82+
-D MAX_GROUP_CHANNELS=40
83+
; -D QSPIFLASH=1
84+
-D BLE_PIN_CODE=123456
85+
; -D BLE_DEBUG_LOGGING=1
86+
-D OFFLINE_QUEUE_SIZE=256
87+
-D UI_RECENT_LIST_SIZE=9
88+
-D UI_SENSORS_PAGE=1
89+
; -D MESH_PACKET_LOGGING=1
90+
; -D MESH_DEBUG=1
91+
-D AUTO_SHUTDOWN_MILLIVOLTS=3300
92+
build_src_filter = ${LilyGo_T-Echo-Lite.build_src_filter}
93+
+<helpers/nrf52/SerialBLEInterface.cpp>
94+
+<../examples/companion_radio/*.cpp>
95+
+<../examples/companion_radio/ui-new/*.cpp>
96+
lib_deps =
97+
${LilyGo_T-Echo-Lite.lib_deps}
98+
densaugeo/base64 @ ~1.4.0
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include <Arduino.h>
2+
#include "target.h"
3+
#include <helpers/ArduinoHelpers.h>
4+
#include <helpers/sensors/MicroNMEALocationProvider.h>
5+
6+
TechoBoard board;
7+
8+
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
9+
10+
WRAPPER_CLASS radio_driver(radio, board);
11+
12+
VolatileRTCClock fallback_clock;
13+
AutoDiscoverRTCClock rtc_clock(fallback_clock);
14+
15+
#ifdef ENV_INCLUDE_GPS
16+
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
17+
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
18+
#else
19+
EnvironmentSensorManager sensors = EnvironmentSensorManager();
20+
#endif
21+
22+
#ifdef DISPLAY_CLASS
23+
DISPLAY_CLASS display;
24+
MomentaryButton user_btn(PIN_USER_BTN, 1000, true);
25+
#endif
26+
27+
bool radio_init() {
28+
rtc_clock.begin(Wire);
29+
30+
return radio.std_init(&SPI);
31+
}
32+
33+
uint32_t radio_get_rng_seed() {
34+
return radio.random(0x7FFFFFFF);
35+
}
36+
37+
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
38+
radio.setFrequency(freq);
39+
radio.setSpreadingFactor(sf);
40+
radio.setBandwidth(bw);
41+
radio.setCodingRate(cr);
42+
}
43+
44+
void radio_set_tx_power(uint8_t dbm) {
45+
radio.setOutputPower(dbm);
46+
}
47+
48+
mesh::LocalIdentity radio_new_identity() {
49+
RadioNoiseListener rng(radio);
50+
return mesh::LocalIdentity(&rng); // create new random identity
51+
}
52+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#define RADIOLIB_STATIC_ONLY 1
4+
#include <RadioLib.h>
5+
#include <helpers/radiolib/RadioLibWrappers.h>
6+
#include <TechoBoard.h>
7+
#include <helpers/radiolib/CustomSX1262Wrapper.h>
8+
#include <helpers/AutoDiscoverRTCClock.h>
9+
#include <helpers/SensorManager.h>
10+
#include <helpers/sensors/EnvironmentSensorManager.h>
11+
#include <helpers/sensors/LocationProvider.h>
12+
#ifdef DISPLAY_CLASS
13+
#include <helpers/ui/GxEPDDisplay.h>
14+
#include <helpers/ui/MomentaryButton.h>
15+
#endif
16+
17+
extern TechoBoard board;
18+
extern WRAPPER_CLASS radio_driver;
19+
extern AutoDiscoverRTCClock rtc_clock;
20+
extern EnvironmentSensorManager sensors;
21+
22+
#ifdef DISPLAY_CLASS
23+
extern DISPLAY_CLASS display;
24+
extern MomentaryButton user_btn;
25+
#endif
26+
27+
bool radio_init();
28+
uint32_t radio_get_rng_seed();
29+
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
30+
void radio_set_tx_power(uint8_t dbm);
31+
mesh::LocalIdentity radio_new_identity();
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "variant.h"
2+
#include "wiring_constants.h"
3+
#include "wiring_digital.h"
4+
5+
const int MISO = PIN_SPI1_MISO;
6+
const int MOSI = PIN_SPI1_MOSI;
7+
const int SCK = PIN_SPI1_SCK;
8+
9+
const uint32_t g_ADigitalPinMap[] = {
10+
0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
11+
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
12+
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
13+
40, 41, 42, 43, 44, 45, 46, 47
14+
};
15+
16+
void initVariant() {
17+
pinMode(PIN_PWR_EN, OUTPUT);
18+
digitalWrite(PIN_PWR_EN, HIGH);
19+
20+
pinMode(PIN_BUTTON1, INPUT_PULLUP);
21+
pinMode(PIN_BUTTON2, INPUT_PULLUP);
22+
23+
pinMode(LED_RED, OUTPUT);
24+
pinMode(LED_GREEN, OUTPUT);
25+
pinMode(LED_BLUE, OUTPUT);
26+
digitalWrite(LED_BLUE, HIGH);
27+
digitalWrite(LED_GREEN, HIGH);
28+
digitalWrite(LED_RED, HIGH);
29+
30+
// pinMode(PIN_TXCO, OUTPUT);
31+
// digitalWrite(PIN_TXCO, HIGH);
32+
33+
pinMode(DISP_POWER, OUTPUT);
34+
digitalWrite(DISP_POWER, LOW);
35+
36+
// shutdown gps
37+
pinMode(GPS_EN, OUTPUT);
38+
digitalWrite(GPS_EN, LOW);
39+
}

0 commit comments

Comments
 (0)