mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
sensecap_indicator: initial espnow support
This commit is contained in:
parent
5ae574b426
commit
45ab0e8cf7
6 changed files with 433 additions and 0 deletions
125
src/helpers/ui/LGFXDisplay.cpp
Normal file
125
src/helpers/ui/LGFXDisplay.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
#include "LGFXDisplay.h"
|
||||||
|
|
||||||
|
bool LGFXDisplay::begin() {
|
||||||
|
turnOn();
|
||||||
|
display->init();
|
||||||
|
display->setRotation(1);
|
||||||
|
display->setBrightness(64);
|
||||||
|
display->setColorDepth(8);
|
||||||
|
display->setTextColor(TFT_WHITE);
|
||||||
|
|
||||||
|
buffer.setColorDepth(8);
|
||||||
|
buffer.setPsram(true);
|
||||||
|
buffer.createSprite(width(), height());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::turnOn() {
|
||||||
|
// display->wakeup();
|
||||||
|
if (!_isOn) {
|
||||||
|
display->wakeup();
|
||||||
|
}
|
||||||
|
_isOn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::turnOff() {
|
||||||
|
if (_isOn) {
|
||||||
|
display->sleep();
|
||||||
|
}
|
||||||
|
_isOn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::clear() {
|
||||||
|
// display->clearDisplay();
|
||||||
|
buffer.clearDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::startFrame(Color bkg) {
|
||||||
|
// display->startWrite();
|
||||||
|
// display->getScanLine();
|
||||||
|
buffer.clearDisplay();
|
||||||
|
buffer.setTextColor(TFT_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::setTextSize(int sz) {
|
||||||
|
buffer.setTextSize(sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::setColor(Color c) {
|
||||||
|
// _color = (c != 0) ? ILI9342_WHITE : ILI9342_BLACK;
|
||||||
|
switch (c) {
|
||||||
|
case DARK:
|
||||||
|
_color = TFT_BLACK;
|
||||||
|
break;
|
||||||
|
case LIGHT:
|
||||||
|
_color = TFT_WHITE;
|
||||||
|
break;
|
||||||
|
case RED:
|
||||||
|
_color = TFT_RED;
|
||||||
|
break;
|
||||||
|
case GREEN:
|
||||||
|
_color = TFT_GREEN;
|
||||||
|
break;
|
||||||
|
case BLUE:
|
||||||
|
_color = TFT_BLUE;
|
||||||
|
break;
|
||||||
|
case YELLOW:
|
||||||
|
_color = TFT_YELLOW;
|
||||||
|
break;
|
||||||
|
case ORANGE:
|
||||||
|
_color = TFT_ORANGE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_color = TFT_WHITE;
|
||||||
|
}
|
||||||
|
buffer.setTextColor(_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::setCursor(int x, int y) {
|
||||||
|
buffer.setCursor(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::print(const char* str) {
|
||||||
|
buffer.println(str);
|
||||||
|
// Serial.println(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::fillRect(int x, int y, int w, int h) {
|
||||||
|
buffer.fillRect(x, y, w, h, _color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::drawRect(int x, int y, int w, int h) {
|
||||||
|
buffer.drawRect(x, y, w, h, _color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::drawXbm(int x, int y, const uint8_t* bits, int w, int h) {
|
||||||
|
buffer.drawBitmap(x, y, bits, w, h, _color);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t LGFXDisplay::getTextWidth(const char* str) {
|
||||||
|
return buffer.textWidth(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGFXDisplay::endFrame() {
|
||||||
|
display->startWrite();
|
||||||
|
if (UI_ZOOM != 1) {
|
||||||
|
buffer.pushRotateZoom(display, display->width()/2, display->height()/2 , 0, UI_ZOOM, UI_ZOOM);
|
||||||
|
} else {
|
||||||
|
buffer.pushSprite(display, 0, 0);
|
||||||
|
}
|
||||||
|
display->endWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LGFXDisplay::getTouch(int *x, int *y) {
|
||||||
|
lgfx::v1::touch_point_t point;
|
||||||
|
display->getTouch(&point);
|
||||||
|
if (UI_ZOOM != 1) {
|
||||||
|
*x = point.x / UI_ZOOM;
|
||||||
|
*y = point.y / UI_ZOOM;
|
||||||
|
} else {
|
||||||
|
*x = point.x;
|
||||||
|
*y = point.y;
|
||||||
|
}
|
||||||
|
return (*x >= 0) && (*y >= 0);
|
||||||
|
}
|
||||||
44
src/helpers/ui/LGFXDisplay.h
Normal file
44
src/helpers/ui/LGFXDisplay.h
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Base class for LovyanGFX supported display (works on ESP32 mainly)
|
||||||
|
* You can extend this class to support your display, providing your own LGFX
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <helpers/ui/DisplayDriver.h>
|
||||||
|
|
||||||
|
#define LGFX_USE_V1
|
||||||
|
#include <LovyanGFX.hpp>
|
||||||
|
|
||||||
|
#ifndef UI_ZOOM
|
||||||
|
#define UI_ZOOM 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class LGFXDisplay : public DisplayDriver {
|
||||||
|
protected:
|
||||||
|
LGFX_Device* display;
|
||||||
|
LGFX_Sprite buffer;
|
||||||
|
|
||||||
|
bool _isOn;
|
||||||
|
int _color = TFT_WHITE;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LGFXDisplay(int w, int h):DisplayDriver(w/UI_ZOOM, h/UI_ZOOM) {_isOn = 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;
|
||||||
|
virtual bool getTouch(int *x, int *y);
|
||||||
|
};
|
||||||
129
variants/sensecap_indicator-espnow/SCIndicatorDisplay.h
Normal file
129
variants/sensecap_indicator-espnow/SCIndicatorDisplay.h
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <helpers/ui/LGFXDisplay.h>
|
||||||
|
|
||||||
|
#define LGFX_USE_V1
|
||||||
|
#include <LovyanGFX.hpp>
|
||||||
|
|
||||||
|
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
|
||||||
|
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
|
||||||
|
|
||||||
|
class LGFX : public lgfx::LGFX_Device
|
||||||
|
{
|
||||||
|
lgfx::Panel_ST7701 _panel_instance;
|
||||||
|
lgfx::Bus_RGB _bus_instance;
|
||||||
|
lgfx::Light_PWM _light_instance;
|
||||||
|
lgfx::Touch_FT5x06 _touch_instance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const uint16_t screenWidth = 480;
|
||||||
|
const uint16_t screenHeight = 480;
|
||||||
|
|
||||||
|
bool hasButton(void) { return true; }
|
||||||
|
|
||||||
|
LGFX(void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto cfg = _panel_instance.config();
|
||||||
|
cfg.memory_width = 480;
|
||||||
|
cfg.memory_height = 480;
|
||||||
|
cfg.panel_width = screenWidth;
|
||||||
|
cfg.panel_height = screenHeight;
|
||||||
|
cfg.offset_x = 0;
|
||||||
|
cfg.offset_y = 0;
|
||||||
|
cfg.offset_rotation = 1;
|
||||||
|
_panel_instance.config(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto cfg = _panel_instance.config_detail();
|
||||||
|
cfg.pin_cs = 4 | IO_EXPANDER;
|
||||||
|
cfg.pin_sclk = 41;
|
||||||
|
cfg.pin_mosi = 48;
|
||||||
|
cfg.use_psram = 1;
|
||||||
|
_panel_instance.config_detail(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto cfg = _bus_instance.config();
|
||||||
|
cfg.panel = &_panel_instance;
|
||||||
|
|
||||||
|
cfg.freq_write = 8000000;
|
||||||
|
cfg.pin_henable = 18;
|
||||||
|
|
||||||
|
cfg.pin_pclk = 21;
|
||||||
|
cfg.pclk_active_neg = 0;
|
||||||
|
cfg.pclk_idle_high = 0;
|
||||||
|
cfg.de_idle_high = 1;
|
||||||
|
|
||||||
|
cfg.pin_hsync = 16;
|
||||||
|
cfg.hsync_polarity = 0;
|
||||||
|
cfg.hsync_front_porch = 10;
|
||||||
|
cfg.hsync_pulse_width = 8;
|
||||||
|
cfg.hsync_back_porch = 50;
|
||||||
|
|
||||||
|
cfg.pin_vsync = 17;
|
||||||
|
cfg.vsync_polarity = 0;
|
||||||
|
cfg.vsync_front_porch = 10;
|
||||||
|
cfg.vsync_pulse_width = 8;
|
||||||
|
cfg.vsync_back_porch = 20;
|
||||||
|
|
||||||
|
cfg.pin_d0 = 15;
|
||||||
|
cfg.pin_d1 = 14;
|
||||||
|
cfg.pin_d2 = 13;
|
||||||
|
cfg.pin_d3 = 12;
|
||||||
|
cfg.pin_d4 = 11;
|
||||||
|
cfg.pin_d5 = 10;
|
||||||
|
cfg.pin_d6 = 9;
|
||||||
|
cfg.pin_d7 = 8;
|
||||||
|
cfg.pin_d8 = 7;
|
||||||
|
cfg.pin_d9 = 6;
|
||||||
|
cfg.pin_d10 = 5;
|
||||||
|
cfg.pin_d11 = 4;
|
||||||
|
cfg.pin_d12 = 3;
|
||||||
|
cfg.pin_d13 = 2;
|
||||||
|
cfg.pin_d14 = 1;
|
||||||
|
cfg.pin_d15 = 0;
|
||||||
|
|
||||||
|
_bus_instance.config(cfg);
|
||||||
|
}
|
||||||
|
_panel_instance.setBus(&_bus_instance);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto cfg = _light_instance.config();
|
||||||
|
cfg.pin_bl = 45;
|
||||||
|
_light_instance.config(cfg);
|
||||||
|
}
|
||||||
|
_panel_instance.light(&_light_instance);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto cfg = _touch_instance.config();
|
||||||
|
cfg.pin_cs = GPIO_NUM_NC;
|
||||||
|
cfg.x_min = 0;
|
||||||
|
cfg.x_max = 479;
|
||||||
|
cfg.y_min = 0;
|
||||||
|
cfg.y_max = 479;
|
||||||
|
cfg.pin_int = GPIO_NUM_NC;
|
||||||
|
cfg.pin_rst = GPIO_NUM_NC;
|
||||||
|
cfg.bus_shared = true;
|
||||||
|
cfg.offset_rotation = 0;
|
||||||
|
|
||||||
|
cfg.i2c_port = 0;
|
||||||
|
cfg.i2c_addr = 0x48;
|
||||||
|
cfg.pin_sda = 39;
|
||||||
|
cfg.pin_scl = 40;
|
||||||
|
cfg.freq = 400000;
|
||||||
|
_touch_instance.config(cfg);
|
||||||
|
_panel_instance.setTouch(&_touch_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPanel(&_panel_instance);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SCIndicatorDisplay : public LGFXDisplay {
|
||||||
|
LGFX disp;
|
||||||
|
public:
|
||||||
|
SCIndicatorDisplay() : LGFXDisplay(480, 480)
|
||||||
|
{ display=&disp; }
|
||||||
|
};
|
||||||
50
variants/sensecap_indicator-espnow/platformio.ini
Normal file
50
variants/sensecap_indicator-espnow/platformio.ini
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
[SenseCapIndicator-ESPNow]
|
||||||
|
extends = esp32_base
|
||||||
|
board = esp32-s3-devkitc-1
|
||||||
|
board_build.arduino.memory_type = qio_opi
|
||||||
|
board_build.flash_mode = qio
|
||||||
|
board_build.psram_type = opi
|
||||||
|
board_upload.flash_size = 8MB
|
||||||
|
board_upload.maximum_size = 8388608
|
||||||
|
board_build.partitions = default.csv
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags}
|
||||||
|
-D PIN_BOARD_SDA=39
|
||||||
|
-D PIN_BOARD_SCL=40
|
||||||
|
-D DISPLAY_CLASS=SCIndicatorDisplay
|
||||||
|
-D DISPLAY_LINES=21
|
||||||
|
-D LINE_LENGTH=53
|
||||||
|
-D DISABLE_WIFI_OTA=1
|
||||||
|
-D IO_EXPANDER=0x40
|
||||||
|
-D IO_EXPANDER_IRQ=42
|
||||||
|
-D UI_ZOOM=3.5
|
||||||
|
-D UI_RECENT_LIST_SIZE=9
|
||||||
|
-D UI_SENSORS_PAGE=1
|
||||||
|
-D PIN_USER_BTN=38
|
||||||
|
-D HAS_TOUCH
|
||||||
|
-I variants/sensecap_indicator-espnow
|
||||||
|
build_src_filter = ${esp32_base.build_src_filter}
|
||||||
|
+<../variants/sensecap_indicator-espnow/*.cpp>
|
||||||
|
+<helpers/esp32/ESPNOWRadio.cpp>
|
||||||
|
+<helpers/ui/LGFXDisplay.cpp>
|
||||||
|
+<helpers/sensors/*>
|
||||||
|
lib_deps=${esp32_base.lib_deps}
|
||||||
|
adafruit/Adafruit BusIO @ ^1.17.2
|
||||||
|
lovyan03/LovyanGFX @ ^1.2.7
|
||||||
|
|
||||||
|
[env:SenseCapIndicator-ESPNow_comp_radio_usb]
|
||||||
|
extends =SenseCapIndicator-ESPNow
|
||||||
|
build_flags =
|
||||||
|
${SenseCapIndicator-ESPNow.build_flags}
|
||||||
|
-I examples/companion_radio/ui-new
|
||||||
|
-D MAX_CONTACTS=300
|
||||||
|
-D MAX_GROUP_CHANNELS=8
|
||||||
|
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
|
||||||
|
; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1
|
||||||
|
; NOTE: DO NOT ENABLE --> -D ESPNOW_DEBUG_LOGGING=1
|
||||||
|
build_src_filter = ${SenseCapIndicator-ESPNow.build_src_filter}
|
||||||
|
+<../examples/companion_radio/ui-new/*.cpp>
|
||||||
|
+<../examples/companion_radio/*.cpp>
|
||||||
|
lib_deps =
|
||||||
|
${SenseCapIndicator-ESPNow.lib_deps}
|
||||||
|
densaugeo/base64 @ ~1.4.0
|
||||||
56
variants/sensecap_indicator-espnow/target.cpp
Normal file
56
variants/sensecap_indicator-espnow/target.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "target.h"
|
||||||
|
#include <helpers/ArduinoHelpers.h>
|
||||||
|
|
||||||
|
ESP32Board board;
|
||||||
|
|
||||||
|
ESPNOWRadio radio_driver;
|
||||||
|
|
||||||
|
ESP32RTCClock rtc_clock;
|
||||||
|
#if defined(ENV_INCLUDE_GPS)
|
||||||
|
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, (mesh::RTCClock*)&rtc_clock);
|
||||||
|
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
|
||||||
|
#else
|
||||||
|
EnvironmentSensorManager sensors = EnvironmentSensorManager();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DISPLAY_CLASS
|
||||||
|
DISPLAY_CLASS display;
|
||||||
|
#ifdef PIN_USER_BTN
|
||||||
|
MomentaryButton user_btn(PIN_USER_BTN, 1000, true, true);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool radio_init() {
|
||||||
|
rtc_clock.begin();
|
||||||
|
|
||||||
|
radio_driver.init();
|
||||||
|
|
||||||
|
return true; // success
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t radio_get_rng_seed() {
|
||||||
|
return millis() + radio_driver.intID(); // TODO: where to get some entropy?
|
||||||
|
}
|
||||||
|
|
||||||
|
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
void radio_set_tx_power(uint8_t dbm) {
|
||||||
|
radio_driver.setTxPower(dbm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: as we are using the WiFi radio, the ESP_IDF will have enabled hardware RNG:
|
||||||
|
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html
|
||||||
|
class ESP_RNG : public mesh::RNG {
|
||||||
|
public:
|
||||||
|
void random(uint8_t* dest, size_t sz) override {
|
||||||
|
esp_fill_random(dest, sz);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mesh::LocalIdentity radio_new_identity() {
|
||||||
|
ESP_RNG rng;
|
||||||
|
return mesh::LocalIdentity(&rng); // create new random identity
|
||||||
|
}
|
||||||
29
variants/sensecap_indicator-espnow/target.h
Normal file
29
variants/sensecap_indicator-espnow/target.h
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <helpers/ESP32Board.h>
|
||||||
|
#include <helpers/esp32/ESPNOWRadio.h>
|
||||||
|
#include <helpers/SensorManager.h>
|
||||||
|
#include <helpers/sensors/EnvironmentSensorManager.h>
|
||||||
|
#ifdef ENV_INCLUDE_GPS
|
||||||
|
#include <helpers/sensors/MicroNMEALocationProvider.h>
|
||||||
|
#endif
|
||||||
|
#ifdef DISPLAY_CLASS
|
||||||
|
#include "SCIndicatorDisplay.h"
|
||||||
|
#include <helpers/ui/MomentaryButton.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern ESP32Board board;
|
||||||
|
extern ESPNOWRadio radio_driver;
|
||||||
|
extern ESP32RTCClock rtc_clock;
|
||||||
|
extern EnvironmentSensorManager sensors;
|
||||||
|
|
||||||
|
#ifdef DISPLAY_CLASS
|
||||||
|
extern DISPLAY_CLASS display;
|
||||||
|
extern MomentaryButton user_btn;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool radio_init();
|
||||||
|
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…
Add table
Add a link
Reference in a new issue