Browse Source

feat: add M5Stack Unit C6L variant support

Add variant configuration for M5Stack Unit C6L (ESP32-C6, SX1262 LoRa,
SSD1306 64x48 SPI display). Includes:
- Board class with PI4IO I/O expander for LoRa RF control
- DIO flash mode fix for ESP32-C6 bootloader compatibility
- SSD1306 SPI display with custom minimal UITask for 64x48
- CustomSerialBLEInterface fix for correct BLE Connected status
- All 4 firmware environments: companion (USB/BLE), repeater, room server
pull/2632/head
vistalba 3 weeks ago
parent
commit
bf6d2b9442
  1. 2
      src/helpers/esp32/SerialBLEInterface.cpp
  2. 32
      src/helpers/ui/DisplayDriver.h
  3. 120
      src/helpers/ui/SSD1306SPIDisplay.cpp
  4. 38
      src/helpers/ui/SSD1306SPIDisplay.h
  5. 11
      variants/m5stack_unit_c6l/UnitC6LBoard.cpp
  6. 117
      variants/m5stack_unit_c6l/UnitC6LBoard.h
  7. 111
      variants/m5stack_unit_c6l/companion/UITask.cpp
  8. 29
      variants/m5stack_unit_c6l/companion/UITask.h
  9. 138
      variants/m5stack_unit_c6l/platformio.ini
  10. 15
      variants/m5stack_unit_c6l/target.h

2
src/helpers/esp32/SerialBLEInterface.cpp

@ -1,5 +1,5 @@
#include "SerialBLEInterface.h" #include "SerialBLEInterface.h"
#include "esp_mac.h" #include <esp_mac.h>
// See the following for generating UUIDs: // See the following for generating UUIDs:
// https://www.uuidgenerator.net/ // https://www.uuidgenerator.net/

32
src/helpers/ui/DisplayDriver.h

@ -3,6 +3,38 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
struct MarqueeScroller {
int offset = 0;
unsigned long next_time = 0;
bool paused = true;
void reset() {
offset = 0;
next_time = 0;
paused = true;
}
// Call once per loop iteration to advance the scroll.
// textW/displayW in pixels, now = millis().
void update(int textW, int displayW, unsigned long now,
unsigned long speed_ms = 150, unsigned long pause_ms = 2000) {
int maxScroll = textW - displayW;
if (maxScroll <= 0) { offset = 0; return; }
if (now < next_time) return;
if (paused) {
paused = false;
next_time = now + pause_ms;
} else {
offset++;
if (offset >= maxScroll) {
offset = 0;
paused = true;
}
next_time = now + speed_ms;
}
}
};
class DisplayDriver { class DisplayDriver {
int _w, _h; int _w, _h;
protected: protected:

120
src/helpers/ui/SSD1306SPIDisplay.cpp

@ -0,0 +1,120 @@
#include "SSD1306SPIDisplay.h"
// Check if SPI is ready (set by radio_init in target.cpp)
#if defined(P_LORA_SCLK)
extern bool spi_initialized;
#else
static bool spi_initialized = true; // Assume ready if no custom SPI
#endif
bool SSD1306SPIDisplay::begin() {
// Defer actual initialization - SPI may not be ready yet
// Real init happens in lazyInit() on first use (after radio_init)
return true;
}
bool SSD1306SPIDisplay::lazyInit() {
if (_initialized) return true;
if (!spi_initialized) {
Serial.println("SSD1306: SPI not initialized yet");
return false;
}
Serial.println("SSD1306: Attempting display init...");
#ifdef DISPLAY_ROTATION
display.setRotation(DISPLAY_ROTATION);
#endif
// SPI is now initialized by radio_init()
// Pass periphBegin=false to skip spi.begin() since radio already did it
if (!display.begin(SSD1306_SWITCHCAPVCC, 0, true, false)) {
Serial.println("SSD1306: display.begin() FAILED");
return false;
}
Serial.println("SSD1306: display.begin() OK");
// Fix for 64x48 displays: Adafruit library lacks this case and defaults
// to comPins=0x02 (sequential). Displays taller than 32px need 0x12
// (alternative COM pin config) or the output is garbled.
#if defined(DISPLAY_WIDTH) && defined(DISPLAY_HEIGHT)
#if (DISPLAY_WIDTH == 64) && (DISPLAY_HEIGHT == 48)
display.ssd1306_command(SSD1306_SETCOMPINS);
display.ssd1306_command(0x12);
#endif
#endif
// Clear any garbage in the display buffer
display.clearDisplay();
display.display();
_initialized = true;
return true;
}
void SSD1306SPIDisplay::turnOn() {
if (!lazyInit()) return;
display.ssd1306_command(SSD1306_DISPLAYON);
_isOn = true;
}
void SSD1306SPIDisplay::turnOff() {
if (!lazyInit()) return;
display.ssd1306_command(SSD1306_DISPLAYOFF);
_isOn = false;
}
void SSD1306SPIDisplay::clear() {
if (!lazyInit()) return;
display.clearDisplay();
display.display();
}
void SSD1306SPIDisplay::startFrame(Color bkg) {
if (!lazyInit()) return;
display.clearDisplay(); // TODO: apply 'bkg'
_color = SSD1306_WHITE;
display.setTextColor(_color);
display.setFont(NULL); // Default 6x8 font
display.setTextSize(1);
display.setTextWrap(false);
display.cp437(true);
}
void SSD1306SPIDisplay::setTextSize(int sz) {
display.setTextSize(sz);
}
void SSD1306SPIDisplay::setColor(Color c) {
_color = (c != 0) ? SSD1306_WHITE : SSD1306_BLACK;
display.setTextColor(_color);
}
void SSD1306SPIDisplay::setCursor(int x, int y) {
display.setCursor(x, y);
}
void SSD1306SPIDisplay::print(const char* str) {
display.print(str);
}
void SSD1306SPIDisplay::fillRect(int x, int y, int w, int h) {
display.fillRect(x, y, w, h, _color);
}
void SSD1306SPIDisplay::drawRect(int x, int y, int w, int h) {
display.drawRect(x, y, w, h, _color);
}
void SSD1306SPIDisplay::drawXbm(int x, int y, const uint8_t* bits, int w, int h) {
display.drawBitmap(x, y, bits, w, h, SSD1306_WHITE);
}
uint16_t SSD1306SPIDisplay::getTextWidth(const char* str) {
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(str, 0, 0, &x1, &y1, &w, &h);
return w;
}
void SSD1306SPIDisplay::endFrame() {
if (!_initialized) return;
display.display();
}

38
src/helpers/ui/SSD1306SPIDisplay.h

@ -0,0 +1,38 @@
#pragma once
#include "DisplayDriver.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#define SSD1306_NO_SPLASH
#include <Adafruit_SSD1306.h>
class SSD1306SPIDisplay : public DisplayDriver {
Adafruit_SSD1306 display;
bool _isOn;
bool _initialized;
uint8_t _color;
bool lazyInit(); // Deferred init for SPI bus sharing
public:
// Accept pre-initialized SPI - do NOT call spi.begin()
SSD1306SPIDisplay(SPIClass* spi, int16_t w, int16_t h, int8_t dc, int8_t rst, int8_t cs)
: DisplayDriver(w, h), display(w, h, spi, dc, rst, cs) { _isOn = false; _initialized = false; }
bool begin();
bool isOn() override { return _isOn; }
void turnOn() override;
void turnOff() override;
void clear() override;
void startFrame(Color bkg = DARK) override;
void setTextSize(int sz) override;
void setColor(Color c) override;
void setCursor(int x, int y) override;
void print(const char* str) override;
void fillRect(int x, int y, int w, int h) override;
void drawRect(int x, int y, int w, int h) override;
void drawXbm(int x, int y, const uint8_t* bits, int w, int h) override;
uint16_t getTextWidth(const char* str) override;
void endFrame() override;
};

11
variants/m5stack_unit_c6l/UnitC6LBoard.cpp

@ -4,7 +4,8 @@
UnitC6LBoard board; UnitC6LBoard board;
#if defined(P_LORA_SCLK) #if defined(P_LORA_SCLK)
static SPIClass spi(0); SPIClass spi(0);
bool spi_initialized = false;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
#else #else
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
@ -16,12 +17,17 @@ ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock); AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors; SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display(&spi, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DC, DISPLAY_RST, DISPLAY_CS);
#endif
bool radio_init() { bool radio_init() {
fallback_clock.begin(); fallback_clock.begin();
rtc_clock.begin(Wire); rtc_clock.begin(Wire);
#if defined(P_LORA_SCLK) #if defined(P_LORA_SCLK)
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
spi_initialized = true;
return radio.std_init(&spi); return radio.std_init(&spi);
#else #else
return radio.std_init(); return radio.std_init();
@ -30,6 +36,5 @@ bool radio_init() {
mesh::LocalIdentity radio_new_identity() { mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio); RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity return mesh::LocalIdentity(&rng);
} }

117
variants/m5stack_unit_c6l/UnitC6LBoard.h

@ -1,15 +1,130 @@
#pragma once #pragma once
#include <Arduino.h> #include <Arduino.h>
#include <Wire.h>
#include <helpers/ESP32Board.h> #include <helpers/ESP32Board.h>
// PI4IO I/O Expander (I2C address 0x43)
// Pin mapping:
// P0 = Button (active low)
// P1 = (unused input)
// P5 = LNA_EN (LNA Enable)
// P6 = ANT_SW (RF Switch)
// P7 = NRST (LoRa Reset)
#define PI4IO_ADDR 0x43
// PI4IO registers
#define PI4IO_REG_CHIP_RESET 0x01
#define PI4IO_REG_IO_DIR 0x03
#define PI4IO_REG_OUT_SET 0x05
#define PI4IO_REG_OUT_H_IM 0x07
#define PI4IO_REG_IN_DEF_STA 0x09
#define PI4IO_REG_PULL_EN 0x0B
#define PI4IO_REG_PULL_SEL 0x0D
#define PI4IO_REG_IN_STA 0x0F
#define PI4IO_REG_INT_MASK 0x11
#define PI4IO_REG_IRQ_STA 0x13
class UnitC6LBoard : public ESP32Board { class UnitC6LBoard : public ESP32Board {
private:
bool i2c_write_byte(uint8_t addr, uint8_t reg, uint8_t value) {
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.write(value);
return Wire.endTransmission() == 0;
}
bool i2c_read_byte(uint8_t addr, uint8_t reg, uint8_t *value) {
Wire.beginTransmission(addr);
Wire.write(reg);
if (Wire.endTransmission() != 0) return false;
if (Wire.requestFrom(addr, (uint8_t)1) != 1) return false;
if (!Wire.available()) return false;
*value = Wire.read();
return true;
}
void initIOExpander() {
uint8_t in_data;
// Reset the I/O expander
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_CHIP_RESET, 0xFF);
delay(10);
i2c_read_byte(PI4IO_ADDR, PI4IO_REG_CHIP_RESET, &in_data);
delay(10);
// Set P5, P6, P7 as outputs (0: input, 1: output)
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_IO_DIR, 0b11100000);
delay(10);
// Disable High-Impedance for used pins
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_OUT_H_IM, 0b00011100);
delay(10);
// Pull up/down select (0: down, 1: up)
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_PULL_SEL, 0b11100011);
delay(10);
// Pull up/down enable (0: disable, 1: enable)
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_PULL_EN, 0b11100011);
delay(10);
// Default input state for P0, P1 (buttons)
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_IN_DEF_STA, 0b00000011);
delay(10);
// Enable interrupts for P0, P1 (0: enable, 1: disable)
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_INT_MASK, 0b11111100);
delay(10);
// Set P7 (Reset) high, P5 and P6 will be set after
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_OUT_SET, 0b10000000);
delay(10);
// Clear IRQ status
i2c_read_byte(PI4IO_ADDR, PI4IO_REG_IRQ_STA, &in_data);
// Enable RF switch (P6 high) and LNA (P5 high)
i2c_read_byte(PI4IO_ADDR, PI4IO_REG_OUT_SET, &in_data);
in_data |= (1 << 6); // P6 = RF Switch = HIGH
in_data |= (1 << 5); // P5 = LNA Enable = HIGH
i2c_write_byte(PI4IO_ADDR, PI4IO_REG_OUT_SET, in_data);
}
public: public:
void begin() { void begin() {
ESP32Board::begin(); ESP32Board::begin();
// Initialize I/O expander for LoRa RF control
initIOExpander();
#ifdef PIN_BUZZER
pinMode(PIN_BUZZER, OUTPUT);
digitalWrite(PIN_BUZZER, LOW);
#endif
} }
const char* getManufacturerName() const override { const char* getManufacturerName() const override {
return "Unit C6L"; return "M5Stack Unit C6L";
}
// Read button state from I/O expander P0 (active low)
bool isButtonPressed() {
uint8_t in_data = 0xFF;
if (!i2c_read_byte(PI4IO_ADDR, PI4IO_REG_IN_STA, &in_data)) {
return false;
}
return !(in_data & 0x01);
}
#ifdef PIN_BUZZER
void playTone(uint16_t frequency, uint16_t duration_ms) {
tone(PIN_BUZZER, frequency, duration_ms);
}
void stopTone() {
noTone(PIN_BUZZER);
} }
#endif
}; };

111
variants/m5stack_unit_c6l/companion/UITask.cpp

@ -0,0 +1,111 @@
#include "UITask.h"
#include <target.h>
#include "../../examples/companion_radio/MyMesh.h"
#define AUTO_OFF_MILLIS 30000
#define BOOT_SCREEN_MILLIS 4000
#define SCROLL_SPEED_MS 150
#define SCROLL_PAUSE_MS 2000
void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* node_prefs) {
_display = display;
_node_prefs = node_prefs;
_need_refresh = true;
_msgcount = 0;
_next_refresh = 0;
_auto_off = millis() + AUTO_OFF_MILLIS;
_scroller.reset();
if (_display != NULL) {
_display->turnOn();
}
}
void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) {
_msgcount = msgcount;
_need_refresh = true;
if (_display != NULL && !_display->isOn()) {
_display->turnOn();
_auto_off = millis() + AUTO_OFF_MILLIS;
}
}
void UITask::renderScreen() {
if (_display == NULL) return;
int w = _display->width();
char tmp[32];
if (millis() < BOOT_SCREEN_MILLIS) {
_display->setTextSize(1);
_display->drawTextCentered(w / 2, 3, "MeshCore");
_display->drawTextCentered(w / 2, 20, FIRMWARE_VERSION);
_display->drawTextCentered(w / 2, 34, "Companion");
return;
}
_display->setTextSize(1);
#ifdef BLE_PIN_CODE
uint32_t pin = the_mesh.getBLEPin();
if (_connected) {
_display->drawTextCentered(w / 2, 0, "Connected");
} else if (pin != 0) {
sprintf(tmp, "PIN:%06d", pin);
_display->drawTextCentered(w / 2, 0, tmp);
} else {
_display->drawTextCentered(w / 2, 0, "Ready");
}
#else
_display->drawTextCentered(w / 2, 0, "USB Ready");
#endif
int nameW = _display->getTextWidth(_node_prefs->node_name);
if (nameW <= w) {
_display->setCursor(0, 10);
_display->print(_node_prefs->node_name);
} else {
_display->setCursor(-_scroller.offset, 10);
_display->print(_node_prefs->node_name);
}
sprintf(tmp, "%.3f", _node_prefs->freq);
_display->setCursor(0, 20);
_display->print(tmp);
if (_msgcount > 0) {
sprintf(tmp, "%d unread", _msgcount);
_display->setCursor(0, 30);
_display->print(tmp);
}
}
void UITask::loop() {
if (_display == NULL) return;
if (board.isButtonPressed()) {
if (!_display->isOn()) {
_display->turnOn();
_need_refresh = true;
}
_auto_off = millis() + AUTO_OFF_MILLIS;
}
if (_display->isOn()) {
if (_node_prefs != NULL) {
_scroller.update(_display->getTextWidth(_node_prefs->node_name),
_display->width(), millis(), SCROLL_SPEED_MS, SCROLL_PAUSE_MS);
}
if (millis() >= _next_refresh) {
_display->startFrame();
renderScreen();
_display->endFrame();
_next_refresh = millis() + 200;
}
if (millis() > _auto_off) {
_display->turnOff();
}
}
}

29
variants/m5stack_unit_c6l/companion/UITask.h

@ -0,0 +1,29 @@
#pragma once
#include <Arduino.h>
#include <helpers/ui/DisplayDriver.h>
#include <helpers/SensorManager.h>
#include "../../examples/companion_radio/NodePrefs.h"
#include "../../examples/companion_radio/AbstractUITask.h"
class UITask : public AbstractUITask {
public:
UITask(mesh::MainBoard* board, BaseSerialInterface* serial)
: AbstractUITask(board, serial), _display(NULL) {}
void begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* node_prefs);
void loop() override;
void notify(UIEventType t) override {}
void msgRead(int msgcount) override { _msgcount = msgcount; _need_refresh = true; }
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
private:
void renderScreen();
DisplayDriver* _display;
NodePrefs* _node_prefs;
int _msgcount;
bool _need_refresh;
uint32_t _next_refresh;
uint32_t _auto_off;
MarqueeScroller _scroller;
};

138
variants/m5stack_unit_c6l/platformio.ini

@ -1,12 +1,17 @@
[M5Stack_Unit_C6L] ; M5Stack Unit C6L - ESP32-C6 with SX1262 LoRa
; https://docs.m5stack.com/en/unit/Unit_C6L
[m5stack_unit_c6l]
extends = esp32c6_base extends = esp32c6_base
board = esp32-c6-devkitm-1 board = esp32-c6-devkitm-1
board_build.flash_mode = dio
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
build_flags = build_flags =
${esp32c6_base.build_flags} ${esp32c6_base.build_flags}
${sensor_base.build_flags} ${sensor_base.build_flags}
-I variants/m5stack_unit_c6l -I variants/m5stack_unit_c6l
-D P_LORA_TX_LED=15 -D ARDUINO_USB_CDC_ON_BOOT=1
-D ARDUINO_USB_MODE=1
; LoRa SX1262 SPI pins
-D P_LORA_SCLK=20 -D P_LORA_SCLK=20
-D P_LORA_MISO=22 -D P_LORA_MISO=22
-D P_LORA_MOSI=21 -D P_LORA_MOSI=21
@ -14,99 +19,102 @@ build_flags =
-D P_LORA_DIO_1=7 -D P_LORA_DIO_1=7
-D P_LORA_BUSY=19 -D P_LORA_BUSY=19
-D P_LORA_RESET=-1 -D P_LORA_RESET=-1
-D PIN_BUZZER=11 ; I2C pins (PI4IO expander + sensors)
-D PIN_BOARD_SDA=16 -D PIN_BOARD_SDA=10
-D PIN_BOARD_SCL=17 -D PIN_BOARD_SCL=8
-D SX126X_RXEN=5 ; SX1262 configuration
-D SX126X_DIO2_AS_RF_SWITCH=true -D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8 -D SX126X_DIO3_TCXO_VOLTAGE=3.0
-D SX126X_CURRENT_LIMIT=140 -D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1 -D SX126X_RX_BOOSTED_GAIN=1
-D USE_SX1262 ; Radio configuration
-D RADIO_CLASS=CustomSX1262 -D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper -D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D DISABLE_WIFI_OTA=1 -D DISABLE_WIFI_OTA=1
; NeoPixel LED for TX indication
-D P_LORA_TX_NEOPIXEL_LED=2
; Buzzer
-D PIN_BUZZER=11
; GPS on Grove port
-D GPS_RX=4 -D GPS_RX=4
-D GPS_TX=5 -D GPS_TX=5
build_src_filter = ${esp32c6_base.build_src_filter} ; Display configuration (64x48 SSD1306 OLED via SPI, shared with LoRa)
+<../variants/m5stack_unit_c6l> -D DISPLAY_CLASS=SSD1306SPIDisplay
+<UnitC6LBoard.cpp> -D DISPLAY_CS=6
-D DISPLAY_DC=18
-D DISPLAY_RST=15
-D DISPLAY_WIDTH=64
-D DISPLAY_HEIGHT=48
-D DISPLAY_ROTATION=2
lib_deps = lib_deps =
${esp32c6_base.lib_deps} ${esp32c6_base.lib_deps}
${sensor_base.lib_deps} adafruit/Adafruit SSD1306 @ ^2.5.13
build_src_filter = ${esp32c6_base.build_src_filter}
[env:M5Stack_Unit_C6L_repeater] +<../variants/m5stack_unit_c6l>
extends = M5Stack_Unit_C6L -<../variants/m5stack_unit_c6l/companion/*.cpp>
build_src_filter = ${M5Stack_Unit_C6L.build_src_filter} +<helpers/ui/SSD1306SPIDisplay.cpp>
+<../examples/simple_repeater/*.cpp>
build_flags =
${M5Stack_Unit_C6L.build_flags}
-D ADVERT_NAME='"Unit C6L Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
${M5Stack_Unit_C6L.lib_deps}
; ${esp32_ota.lib_deps}
[env:M5Stack_Unit_C6L_room_server] [env:m5stack_unit_c6l_companion_radio_usb]
extends = M5Stack_Unit_C6L extends = m5stack_unit_c6l
build_src_filter = ${M5Stack_Unit_C6L.build_src_filter}
+<../examples/simple_room_server>
build_flags = build_flags =
${M5Stack_Unit_C6L.build_flags} ${m5stack_unit_c6l.build_flags}
-D ADVERT_NAME='"Unit C6L Room"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
${M5Stack_Unit_C6L.lib_deps}
; ${esp32_ota.lib_deps}
[env:M5Stack_Unit_C6L_companion_radio_ble]
extends = M5Stack_Unit_C6L
build_flags = ${M5Stack_Unit_C6L.build_flags}
-D MAX_CONTACTS=350 -D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40 -D MAX_GROUP_CHANNELS=40
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256 -D OFFLINE_QUEUE_SIZE=256
; -D MESH_PACKET_LOGGING=1 -I variants/m5stack_unit_c6l/companion
; -D MESH_DEBUG=1 build_src_filter = ${m5stack_unit_c6l.build_src_filter}
build_src_filter = ${M5Stack_Unit_C6L.build_src_filter}
+<helpers/esp32/*.cpp> +<helpers/esp32/*.cpp>
-<helpers/esp32/ESPNOWRadio.cpp> -<helpers/esp32/ESPNOWRadio.cpp>
+<../examples/companion_radio/*.cpp> +<../examples/companion_radio/*.cpp>
+<../variants/m5stack_unit_c6l/companion/*.cpp>
lib_deps = lib_deps =
${M5Stack_Unit_C6L.lib_deps} ${m5stack_unit_c6l.lib_deps}
densaugeo/base64 @ ~1.4.0 densaugeo/base64 @ ~1.4.0
end2endzone/NonBlockingRTTTL@^1.3.0 end2endzone/NonBlockingRTTTL@^1.3.0
[env:M5Stack_Unit_C6L_companion_radio_usb] [env:m5stack_unit_c6l_companion_radio_ble]
extends = M5Stack_Unit_C6L extends = m5stack_unit_c6l
build_flags = ${M5Stack_Unit_C6L.build_flags} build_flags =
${m5stack_unit_c6l.build_flags}
-D MAX_CONTACTS=350 -D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40 -D MAX_GROUP_CHANNELS=40
-D BLE_PIN_CODE=123456
-D OFFLINE_QUEUE_SIZE=256 -D OFFLINE_QUEUE_SIZE=256
-D ARDUINO_USB_CDC_ON_BOOT=1 -I variants/m5stack_unit_c6l/companion
-D ARDUINO_USB_MODE=1 build_src_filter = ${m5stack_unit_c6l.build_src_filter}
build_src_filter = ${M5Stack_Unit_C6L.build_src_filter}
+<helpers/esp32/*.cpp> +<helpers/esp32/*.cpp>
-<helpers/esp32/ESPNOWRadio.cpp> -<helpers/esp32/ESPNOWRadio.cpp>
+<../examples/companion_radio/*.cpp> +<../examples/companion_radio/*.cpp>
+<../variants/m5stack_unit_c6l/companion/*.cpp>
lib_deps = lib_deps =
${M5Stack_Unit_C6L.lib_deps} ${m5stack_unit_c6l.lib_deps}
densaugeo/base64 @ ~1.4.0 densaugeo/base64 @ ~1.4.0
end2endzone/NonBlockingRTTTL@^1.3.0 end2endzone/NonBlockingRTTTL@^1.3.0
[env:M5Stack_Unit_C6L_kiss_modem] [env:m5stack_unit_c6l_repeater]
extends = M5Stack_Unit_C6L extends = m5stack_unit_c6l
build_src_filter = ${M5Stack_Unit_C6L.build_src_filter} build_flags =
+<../examples/kiss_modem/> ${m5stack_unit_c6l.build_flags}
-D ADVERT_NAME='"M5Stack C6L Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
build_src_filter = ${m5stack_unit_c6l.build_src_filter}
+<../examples/simple_repeater>
lib_deps =
${m5stack_unit_c6l.lib_deps}
[env:m5stack_unit_c6l_room_server]
extends = m5stack_unit_c6l
build_flags = ${m5stack_unit_c6l.build_flags}
-D ADVERT_NAME='"M5Stack C6L Room"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
build_src_filter = ${m5stack_unit_c6l.build_src_filter}
+<../examples/simple_room_server>
lib_deps =
${m5stack_unit_c6l.lib_deps}

15
variants/m5stack_unit_c6l/target.h

@ -9,10 +9,23 @@
#include <helpers/AutoDiscoverRTCClock.h> #include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h> #include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306SPIDisplay.h>
extern DISPLAY_CLASS display;
#endif
#if defined(P_LORA_SCLK)
extern SPIClass spi;
extern bool spi_initialized;
#endif
extern UnitC6LBoard board; extern UnitC6LBoard board;
extern WRAPPER_CLASS radio_driver; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock; extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors; extern SensorManager sensors;
bool radio_init(); bool radio_init();
mesh::LocalIdentity radio_new_identity(); uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

Loading…
Cancel
Save