mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-03-30 10:39:59 +00:00
Merge pull request #889 from fdlamotte/sensecap_indicator
Sensecap indicator
This commit is contained in:
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);
|
||||
}
|
||||
39
src/helpers/ui/LGFXDisplay.h
Normal file
39
src/helpers/ui/LGFXDisplay.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#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 = false;
|
||||
int _color = TFT_WHITE;
|
||||
|
||||
public:
|
||||
LGFXDisplay(int w, int h, LGFX_Device &disp)
|
||||
: DisplayDriver(w/UI_ZOOM, h/UI_ZOOM), display(&disp) {}
|
||||
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);
|
||||
};
|
||||
128
variants/sensecap_indicator-espnow/SCIndicatorDisplay.h
Normal file
128
variants/sensecap_indicator-espnow/SCIndicatorDisplay.h
Normal file
@@ -0,0 +1,128 @@
|
||||
#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, 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();
|
||||
Reference in New Issue
Block a user