mirror of https://github.com/meshcore-dev/MeshCore
10 changed files with 1295 additions and 0 deletions
@ -0,0 +1,43 @@ |
|||||
|
{ |
||||
|
"build": { |
||||
|
"arduino": { |
||||
|
"ldscript": "esp32s3_out.ld", |
||||
|
"partitions": "default_16MB.csv", |
||||
|
"memory_type": "qio_opi" |
||||
|
}, |
||||
|
"core": "esp32", |
||||
|
"extra_flags": [ |
||||
|
"-DBOARD_HAS_PSRAM", |
||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1", |
||||
|
"-DARDUINO_USB_MODE=1", |
||||
|
"-DARDUINO_RUNNING_CORE=1", |
||||
|
"-DARDUINO_EVENT_RUNNING_CORE=1" |
||||
|
], |
||||
|
"f_cpu": "240000000L", |
||||
|
"f_flash": "80000000L", |
||||
|
"flash_mode": "qio", |
||||
|
"psram_type": "opi", |
||||
|
"hwids": [["0x303A", "0x1001"]], |
||||
|
"mcu": "esp32s3", |
||||
|
"variant": "heltec_rc32" |
||||
|
}, |
||||
|
"connectivity": ["wifi", "bluetooth", "lora"], |
||||
|
"debug": { |
||||
|
"default_tool": "esp-builtin", |
||||
|
"onboard_tools": ["esp-builtin"], |
||||
|
"openocd_target": "esp32s3.cfg" |
||||
|
}, |
||||
|
"frameworks": ["arduino", "espidf"], |
||||
|
"name": "Heltec RC32 (16 MB FLASH, 8 MB PSRAM)", |
||||
|
"upload": { |
||||
|
"flash_size": "16MB", |
||||
|
"maximum_ram_size": 327680, |
||||
|
"maximum_size": 16777216, |
||||
|
"use_1200bps_touch": true, |
||||
|
"wait_for_upload_port": true, |
||||
|
"require_upload_port": true, |
||||
|
"speed": 921600 |
||||
|
}, |
||||
|
"url": "https://heltec.org/", |
||||
|
"vendor": "Heltec" |
||||
|
} |
||||
@ -0,0 +1,553 @@ |
|||||
|
#include "NV3001BDisplay.h" |
||||
|
#include <Arduino.h> |
||||
|
#include <string.h> |
||||
|
|
||||
|
#ifndef SPI_FREQUENCY |
||||
|
#define SPI_FREQUENCY 8000000 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_SCL |
||||
|
#error "PIN_TFT_SCL must be defined" |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_SDA |
||||
|
#error "PIN_TFT_SDA must be defined" |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_CS |
||||
|
#error "PIN_TFT_CS must be defined" |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_DC |
||||
|
#error "PIN_TFT_DC must be defined" |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_MISO |
||||
|
#define PIN_TFT_MISO -1 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_RST |
||||
|
#define PIN_TFT_RST -1 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_EN |
||||
|
#define PIN_TFT_EN -1 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_BL |
||||
|
#define PIN_TFT_BL -1 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_EN_ACTIVE |
||||
|
#define PIN_TFT_EN_ACTIVE LOW |
||||
|
#endif |
||||
|
|
||||
|
#ifndef PIN_TFT_BL_ACTIVE |
||||
|
#define PIN_TFT_BL_ACTIVE HIGH |
||||
|
#endif |
||||
|
|
||||
|
#ifndef DISPLAY_ROTATION |
||||
|
#define DISPLAY_ROTATION 0 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_SCREEN_WIDTH |
||||
|
#define NV3001B_SCREEN_WIDTH 220 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_SCREEN_HEIGHT |
||||
|
#define NV3001B_SCREEN_HEIGHT 128 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef DISPLAY_SCALE_X |
||||
|
#define DISPLAY_SCALE_X ((float)NV3001B_SCREEN_WIDTH / NV3001B_LOGICAL_WIDTH) |
||||
|
#endif |
||||
|
|
||||
|
#ifndef DISPLAY_SCALE_Y |
||||
|
#define DISPLAY_SCALE_Y ((float)NV3001B_SCREEN_HEIGHT / NV3001B_LOGICAL_HEIGHT) |
||||
|
#endif |
||||
|
|
||||
|
#define NV3001B_SWRESET 0x01 |
||||
|
#define NV3001B_SLPOUT 0x11 |
||||
|
#define NV3001B_DISPON 0x29 |
||||
|
#define NV3001B_CASET 0x2A |
||||
|
#define NV3001B_RASET 0x2B |
||||
|
#define NV3001B_RAMWR 0x2C |
||||
|
#define NV3001B_MADCTL 0x36 |
||||
|
#define NV3001B_COLMOD 0x3A |
||||
|
|
||||
|
#define NV3001B_MADCTL_MY 0x80 |
||||
|
#define NV3001B_MADCTL_MX 0x40 |
||||
|
#define NV3001B_MADCTL_MV 0x20 |
||||
|
#define NV3001B_MADCTL_RGB 0x00 |
||||
|
|
||||
|
#ifndef NV3001B_TEXT_SIZE1_SCALE_X |
||||
|
#define NV3001B_TEXT_SIZE1_SCALE_X 1 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_TEXT_SIZE1_SCALE_Y |
||||
|
#define NV3001B_TEXT_SIZE1_SCALE_Y 2 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_TEXT_SIZE2_SCALE_X |
||||
|
#define NV3001B_TEXT_SIZE2_SCALE_X 2 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_TEXT_SIZE2_SCALE_Y |
||||
|
#define NV3001B_TEXT_SIZE2_SCALE_Y 3 |
||||
|
#endif |
||||
|
|
||||
|
static uint16_t mapColor(DisplayDriver::Color c) { |
||||
|
switch (c) { |
||||
|
case DisplayDriver::DARK: return 0x0000; |
||||
|
case DisplayDriver::LIGHT: return 0xffff; |
||||
|
case DisplayDriver::RED: return 0xf800; |
||||
|
case DisplayDriver::GREEN: return 0x07e0; |
||||
|
case DisplayDriver::BLUE: return 0x001f; |
||||
|
case DisplayDriver::YELLOW: return 0xffe0; |
||||
|
case DisplayDriver::ORANGE: return 0xfd20; |
||||
|
default: return 0xffff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static int scaleX(int x) { |
||||
|
return (int)(x * DISPLAY_SCALE_X); |
||||
|
} |
||||
|
|
||||
|
static int scaleY(int y) { |
||||
|
return (int)(y * DISPLAY_SCALE_Y); |
||||
|
} |
||||
|
|
||||
|
static int scaleWidth(int x, int w) { |
||||
|
if (w <= 0) return 0; |
||||
|
int scaled = scaleX(x + w) - scaleX(x); |
||||
|
return scaled > 0 ? scaled : 1; |
||||
|
} |
||||
|
|
||||
|
static int scaleHeight(int y, int h) { |
||||
|
if (h <= 0) return 0; |
||||
|
int scaled = scaleY(y + h) - scaleY(y); |
||||
|
return scaled > 0 ? scaled : 1; |
||||
|
} |
||||
|
|
||||
|
static uint8_t nv3001bMADCTL(uint8_t rotation) { |
||||
|
uint8_t madctl; |
||||
|
switch (rotation & 3) { |
||||
|
case 0: |
||||
|
madctl = NV3001B_MADCTL_MY | NV3001B_MADCTL_MV | NV3001B_MADCTL_RGB; |
||||
|
break; |
||||
|
case 1: |
||||
|
madctl = NV3001B_MADCTL_MY | NV3001B_MADCTL_MX | NV3001B_MADCTL_RGB; |
||||
|
break; |
||||
|
case 2: |
||||
|
madctl = NV3001B_MADCTL_RGB; |
||||
|
break; |
||||
|
default: |
||||
|
madctl = NV3001B_MADCTL_MX | NV3001B_MADCTL_MV | NV3001B_MADCTL_RGB; |
||||
|
break; |
||||
|
} |
||||
|
return madctl; |
||||
|
} |
||||
|
|
||||
|
static const uint8_t font5x7[] PROGMEM = { |
||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, |
||||
|
0x7f, 0x14, 0x7f, 0x14, 0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49, |
||||
|
0x55, 0x22, 0x50, 0x00, 0x05, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, 0x00, 0x41, 0x22, |
||||
|
0x1c, 0x00, 0x14, 0x08, 0x3e, 0x08, 0x14, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x50, 0x30, 0x00, |
||||
|
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x60, 0x60, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, |
||||
|
0x3e, 0x51, 0x49, 0x45, 0x3e, 0x00, 0x42, 0x7f, 0x40, 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, 0x21, |
||||
|
0x41, 0x45, 0x4b, 0x31, 0x18, 0x14, 0x12, 0x7f, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3c, 0x4a, |
||||
|
0x49, 0x49, 0x30, 0x01, 0x71, 0x09, 0x05, 0x03, 0x36, 0x49, 0x49, 0x49, 0x36, 0x06, 0x49, 0x49, |
||||
|
0x29, 0x1e, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x56, 0x36, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, |
||||
|
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41, 0x22, 0x14, 0x08, 0x02, 0x01, 0x51, 0x09, 0x06, |
||||
|
0x32, 0x49, 0x79, 0x41, 0x3e, 0x7e, 0x11, 0x11, 0x11, 0x7e, 0x7f, 0x49, 0x49, 0x49, 0x36, 0x3e, |
||||
|
0x41, 0x41, 0x41, 0x22, 0x7f, 0x41, 0x41, 0x22, 0x1c, 0x7f, 0x49, 0x49, 0x49, 0x41, 0x7f, 0x09, |
||||
|
0x09, 0x09, 0x01, 0x3e, 0x41, 0x49, 0x49, 0x7a, 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00, 0x41, 0x7f, |
||||
|
0x41, 0x00, 0x20, 0x40, 0x41, 0x3f, 0x01, 0x7f, 0x08, 0x14, 0x22, 0x41, 0x7f, 0x40, 0x40, 0x40, |
||||
|
0x40, 0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x7f, 0x04, 0x08, 0x10, 0x7f, 0x3e, 0x41, 0x41, 0x41, 0x3e, |
||||
|
0x7f, 0x09, 0x09, 0x09, 0x06, 0x3e, 0x41, 0x51, 0x21, 0x5e, 0x7f, 0x09, 0x19, 0x29, 0x46, 0x46, |
||||
|
0x49, 0x49, 0x49, 0x31, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x3f, 0x40, 0x40, 0x40, 0x3f, 0x1f, 0x20, |
||||
|
0x40, 0x20, 0x1f, 0x3f, 0x40, 0x38, 0x40, 0x3f, 0x63, 0x14, 0x08, 0x14, 0x63, 0x07, 0x08, 0x70, |
||||
|
0x08, 0x07, 0x61, 0x51, 0x49, 0x45, 0x43, 0x00, 0x7f, 0x41, 0x41, 0x00, 0x02, 0x04, 0x08, 0x10, |
||||
|
0x20, 0x00, 0x41, 0x41, 0x7f, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, |
||||
|
0x00, 0x01, 0x02, 0x04, 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, 0x7f, 0x48, 0x44, 0x44, 0x38, 0x38, |
||||
|
0x44, 0x44, 0x44, 0x20, 0x38, 0x44, 0x44, 0x48, 0x7f, 0x38, 0x54, 0x54, 0x54, 0x18, 0x08, 0x7e, |
||||
|
0x09, 0x01, 0x02, 0x0c, 0x52, 0x52, 0x52, 0x3e, 0x7f, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7d, |
||||
|
0x40, 0x00, 0x20, 0x40, 0x44, 0x3d, 0x00, 0x7f, 0x10, 0x28, 0x44, 0x00, 0x00, 0x41, 0x7f, 0x40, |
||||
|
0x00, 0x7c, 0x04, 0x18, 0x04, 0x78, 0x7c, 0x08, 0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, |
||||
|
0x7c, 0x14, 0x14, 0x14, 0x08, 0x08, 0x14, 0x14, 0x18, 0x7c, 0x7c, 0x08, 0x04, 0x04, 0x08, 0x48, |
||||
|
0x54, 0x54, 0x54, 0x20, 0x04, 0x3f, 0x44, 0x40, 0x20, 0x3c, 0x40, 0x40, 0x20, 0x7c, 0x1c, 0x20, |
||||
|
0x40, 0x20, 0x1c, 0x3c, 0x40, 0x30, 0x40, 0x3c, 0x44, 0x28, 0x10, 0x28, 0x44, 0x0c, 0x50, 0x50, |
||||
|
0x50, 0x3c, 0x44, 0x64, 0x54, 0x4c, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x7f, 0x00, |
||||
|
0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x08, 0x08, 0x2a, 0x1c, 0x08, 0x00, 0x06, 0x09, 0x09, 0x06 |
||||
|
}; |
||||
|
|
||||
|
static int textPixelScaleX(uint8_t size) { |
||||
|
return size <= 1 ? NV3001B_TEXT_SIZE1_SCALE_X : NV3001B_TEXT_SIZE2_SCALE_X; |
||||
|
} |
||||
|
|
||||
|
static int textPixelScaleY(uint8_t size) { |
||||
|
return size <= 1 ? NV3001B_TEXT_SIZE1_SCALE_Y : NV3001B_TEXT_SIZE2_SCALE_Y; |
||||
|
} |
||||
|
|
||||
|
static void setupOptionalOutput(int pin, int level) { |
||||
|
if (pin < 0) return; |
||||
|
|
||||
|
pinMode(pin, OUTPUT); |
||||
|
digitalWrite(pin, level); |
||||
|
} |
||||
|
|
||||
|
static void writeOptionalPin(int pin, int level) { |
||||
|
if (pin < 0) return; |
||||
|
|
||||
|
digitalWrite(pin, level); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::writeCommand(uint8_t cmd) { |
||||
|
spi.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0)); |
||||
|
digitalWrite(PIN_TFT_DC, LOW); |
||||
|
digitalWrite(PIN_TFT_CS, LOW); |
||||
|
spi.transfer(cmd); |
||||
|
digitalWrite(PIN_TFT_CS, HIGH); |
||||
|
spi.endTransaction(); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::writeBytes(const uint8_t* data, size_t len) { |
||||
|
if (!data || len == 0) return; |
||||
|
|
||||
|
spi.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0)); |
||||
|
digitalWrite(PIN_TFT_DC, HIGH); |
||||
|
digitalWrite(PIN_TFT_CS, LOW); |
||||
|
for (size_t i = 0; i < len; i++) { |
||||
|
spi.transfer(data[i]); |
||||
|
} |
||||
|
digitalWrite(PIN_TFT_CS, HIGH); |
||||
|
spi.endTransaction(); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::writeCommandData(uint8_t cmd, const uint8_t* data, size_t len) { |
||||
|
writeCommand(cmd); |
||||
|
writeBytes(data, len); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { |
||||
|
uint16_t x2 = x + w - 1; |
||||
|
uint16_t y2 = y + h - 1; |
||||
|
uint8_t data[4]; |
||||
|
|
||||
|
data[0] = x >> 8; |
||||
|
data[1] = x & 0xff; |
||||
|
data[2] = x2 >> 8; |
||||
|
data[3] = x2 & 0xff; |
||||
|
writeCommandData(NV3001B_CASET, data, sizeof(data)); |
||||
|
|
||||
|
data[0] = y >> 8; |
||||
|
data[1] = y & 0xff; |
||||
|
data[2] = y2 >> 8; |
||||
|
data[3] = y2 & 0xff; |
||||
|
writeCommandData(NV3001B_RASET, data, sizeof(data)); |
||||
|
|
||||
|
writeCommand(NV3001B_RAMWR); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::writeColor(uint16_t rgb, uint32_t count) { |
||||
|
uint8_t hi = rgb >> 8; |
||||
|
uint8_t lo = rgb & 0xff; |
||||
|
|
||||
|
spi.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0)); |
||||
|
digitalWrite(PIN_TFT_DC, HIGH); |
||||
|
digitalWrite(PIN_TFT_CS, LOW); |
||||
|
while (count--) { |
||||
|
spi.transfer(hi); |
||||
|
spi.transfer(lo); |
||||
|
} |
||||
|
digitalWrite(PIN_TFT_CS, HIGH); |
||||
|
spi.endTransaction(); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::initPanel() { |
||||
|
#define CMD0(C) do { writeCommand(C); } while (0) |
||||
|
#define CMD1(C, A) do { const uint8_t d[] = { A }; writeCommandData(C, d, sizeof(d)); } while (0) |
||||
|
#define CMD2(C, A, B) do { const uint8_t d[] = { A, B }; writeCommandData(C, d, sizeof(d)); } while (0) |
||||
|
|
||||
|
CMD0(NV3001B_SWRESET); |
||||
|
delay(120); |
||||
|
CMD1(0xFF, 0xA5); |
||||
|
CMD1(0x41, 0x00); |
||||
|
CMD1(0x50, 0x02); |
||||
|
CMD1(0x52, 0x6E); |
||||
|
CMD1(0x57, 0x02); |
||||
|
CMD1(0x46, 0x11); |
||||
|
CMD2(0x47, 0x00, 0x01); |
||||
|
CMD2(0x8F, 0x22, 0x03); |
||||
|
CMD1(0x9A, 0x78); |
||||
|
CMD1(0x9B, 0x78); |
||||
|
CMD1(0x9C, 0xA0); |
||||
|
CMD1(0x9D, 0x17); |
||||
|
CMD1(0x9E, 0xC1); |
||||
|
CMD1(0x83, 0x5A); |
||||
|
CMD1(0x84, 0xB6); |
||||
|
CMD1(0xFF, 0xA5); |
||||
|
CMD1(0x85, 0x5F); |
||||
|
CMD1(0x6E, 0x0F); |
||||
|
CMD1(0x7E, 0x0F); |
||||
|
CMD1(0x60, 0x00); |
||||
|
CMD1(0x70, 0x00); |
||||
|
CMD1(0x6D, 0x33); |
||||
|
CMD1(0x7D, 0x37); |
||||
|
CMD1(0x61, 0x09); |
||||
|
CMD1(0x71, 0x0A); |
||||
|
CMD1(0x6C, 0x2A); |
||||
|
CMD1(0x7C, 0x36); |
||||
|
CMD1(0x62, 0x11); |
||||
|
CMD1(0x72, 0x10); |
||||
|
CMD1(0x68, 0x4E); |
||||
|
CMD1(0x78, 0x4E); |
||||
|
CMD1(0x66, 0x36); |
||||
|
CMD1(0x76, 0x3C); |
||||
|
CMD1(0x1A, 0x1C); |
||||
|
CMD1(0x7B, 0x14); |
||||
|
CMD1(0x63, 0x0D); |
||||
|
CMD1(0x73, 0x0A); |
||||
|
CMD1(0x6A, 0x16); |
||||
|
CMD1(0x7A, 0x12); |
||||
|
CMD1(0x64, 0x0B); |
||||
|
CMD1(0x74, 0x0A); |
||||
|
CMD1(0x69, 0x08); |
||||
|
CMD1(0x79, 0x0A); |
||||
|
CMD1(0x65, 0x06); |
||||
|
CMD1(0x75, 0x07); |
||||
|
CMD1(0x67, 0x23); |
||||
|
CMD1(0x77, 0x44); |
||||
|
CMD1(0xE0, 0x00); |
||||
|
CMD1(0xE9, 0x30); |
||||
|
CMD1(0xEB, 0xB7); |
||||
|
CMD1(0xEC, 0x00); |
||||
|
CMD1(0xED, 0x11); |
||||
|
CMD1(0xF0, 0xB7); |
||||
|
CMD1(0x53, 0x04); |
||||
|
CMD1(0x54, 0x04); |
||||
|
CMD1(0x55, 0x40); |
||||
|
CMD1(0x56, 0x40); |
||||
|
CMD2(0xA0, 0x60, 0x01); |
||||
|
CMD1(0xA1, 0x84); |
||||
|
CMD1(0xA2, 0x85); |
||||
|
CMD2(0xAB, 0x00, 0x02); |
||||
|
CMD2(0xAC, 0x00, 0x06); |
||||
|
CMD2(0xAD, 0x00, 0x03); |
||||
|
CMD2(0xAE, 0x00, 0x07); |
||||
|
CMD1(0xC7, 0x01); |
||||
|
CMD1(0xB9, 0x82); |
||||
|
CMD1(0xBA, 0x83); |
||||
|
CMD1(0xBB, 0x00); |
||||
|
CMD1(0xBC, 0x81); |
||||
|
CMD1(0xBD, 0x02); |
||||
|
CMD1(0xBE, 0x01); |
||||
|
CMD1(0xBF, 0x04); |
||||
|
CMD1(0xC0, 0x03); |
||||
|
CMD1(0xC8, 0x55); |
||||
|
CMD1(0xC9, 0xC9); |
||||
|
CMD1(0xCA, 0xC8); |
||||
|
CMD1(0xCB, 0xCB); |
||||
|
CMD1(0xCC, 0xCA); |
||||
|
CMD1(0xCD, 0x55); |
||||
|
CMD1(0xCE, 0xCE); |
||||
|
CMD1(0xCF, 0xCD); |
||||
|
CMD1(0xD0, 0xD0); |
||||
|
CMD1(0xD1, 0xCF); |
||||
|
CMD1(0xF2, 0x46); |
||||
|
CMD1(0xA8, 0x04); |
||||
|
CMD1(0xA9, 0xB0); |
||||
|
CMD1(0xAA, 0xA3); |
||||
|
CMD1(0xB6, 0x00); |
||||
|
CMD1(0xB7, 0xB0); |
||||
|
CMD1(0xB8, 0xA3); |
||||
|
CMD1(0xC4, 0x03); |
||||
|
CMD1(0xC5, 0xB0); |
||||
|
CMD1(0xC6, 0xA3); |
||||
|
CMD1(0x80, 0x10); |
||||
|
CMD1(0xFF, 0x00); |
||||
|
CMD1(0x35, 0x00); |
||||
|
CMD0(NV3001B_SLPOUT); |
||||
|
delay(120); |
||||
|
CMD1(NV3001B_COLMOD, 0x05); |
||||
|
CMD1(NV3001B_MADCTL, nv3001bMADCTL(DISPLAY_ROTATION)); |
||||
|
CMD0(NV3001B_DISPON); |
||||
|
delay(10); |
||||
|
|
||||
|
#undef CMD0 |
||||
|
#undef CMD1 |
||||
|
#undef CMD2 |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::fillPhysicalRect(int x, int y, int w, int h) { |
||||
|
if (!is_on || w <= 0 || h <= 0) return; |
||||
|
|
||||
|
if (x < 0) { |
||||
|
w += x; |
||||
|
x = 0; |
||||
|
} |
||||
|
if (y < 0) { |
||||
|
h += y; |
||||
|
y = 0; |
||||
|
} |
||||
|
if (x + w > NV3001B_SCREEN_WIDTH) w = NV3001B_SCREEN_WIDTH - x; |
||||
|
if (y + h > NV3001B_SCREEN_HEIGHT) h = NV3001B_SCREEN_HEIGHT - y; |
||||
|
if (w <= 0 || h <= 0) return; |
||||
|
|
||||
|
setAddrWindow(x, y, w, h); |
||||
|
writeColor(color, (uint32_t)w * h); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::drawChar(int x, int y, char ch) { |
||||
|
if (ch < 32 || ch > 127) ch = '?'; |
||||
|
|
||||
|
uint16_t index = (uint16_t)(ch - 32) * 5; |
||||
|
int scale_x = textPixelScaleX(text_size); |
||||
|
int scale_y = textPixelScaleY(text_size); |
||||
|
for (int col = 0; col < 5; col++) { |
||||
|
uint8_t line = pgm_read_byte(font5x7 + index + col); |
||||
|
for (int row = 0; row < 7; row++) { |
||||
|
if (line & (1 << row)) { |
||||
|
fillPhysicalRect(x + col * scale_x, y + row * scale_y, scale_x, scale_y); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bool NV3001BDisplay::begin() { |
||||
|
if (is_on) return true; |
||||
|
|
||||
|
if (periph_power) periph_power->claim(); |
||||
|
|
||||
|
setupOptionalOutput(PIN_TFT_EN, PIN_TFT_EN_ACTIVE); |
||||
|
setupOptionalOutput(PIN_TFT_BL, !PIN_TFT_BL_ACTIVE); |
||||
|
pinMode(PIN_TFT_CS, OUTPUT); |
||||
|
pinMode(PIN_TFT_DC, OUTPUT); |
||||
|
digitalWrite(PIN_TFT_CS, HIGH); |
||||
|
digitalWrite(PIN_TFT_DC, HIGH); |
||||
|
delay(20); |
||||
|
|
||||
|
spi.begin(PIN_TFT_SCL, PIN_TFT_MISO, PIN_TFT_SDA, PIN_TFT_CS); |
||||
|
if (PIN_TFT_RST >= 0) { |
||||
|
pinMode(PIN_TFT_RST, OUTPUT); |
||||
|
digitalWrite(PIN_TFT_RST, HIGH); |
||||
|
delay(10); |
||||
|
digitalWrite(PIN_TFT_RST, LOW); |
||||
|
delay(20); |
||||
|
digitalWrite(PIN_TFT_RST, HIGH); |
||||
|
delay(120); |
||||
|
} |
||||
|
|
||||
|
initPanel(); |
||||
|
is_on = true; |
||||
|
color = 0x0000; |
||||
|
fillPhysicalRect(0, 0, NV3001B_SCREEN_WIDTH, NV3001B_SCREEN_HEIGHT); |
||||
|
color = 0xffff; |
||||
|
text_size = 1; |
||||
|
cursor_x = 0; |
||||
|
cursor_y = 0; |
||||
|
writeOptionalPin(PIN_TFT_BL, PIN_TFT_BL_ACTIVE); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::turnOn() { |
||||
|
begin(); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::turnOff() { |
||||
|
if (!is_on) return; |
||||
|
|
||||
|
writeOptionalPin(PIN_TFT_BL, !PIN_TFT_BL_ACTIVE); |
||||
|
writeOptionalPin(PIN_TFT_EN, !PIN_TFT_EN_ACTIVE); |
||||
|
is_on = false; |
||||
|
if (periph_power) periph_power->release(); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::clear() { |
||||
|
uint16_t saved = color; |
||||
|
color = 0x0000; |
||||
|
fillPhysicalRect(0, 0, NV3001B_SCREEN_WIDTH, NV3001B_SCREEN_HEIGHT); |
||||
|
color = saved; |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::startFrame(Color bkg) { |
||||
|
color = mapColor(bkg); |
||||
|
fillPhysicalRect(0, 0, NV3001B_SCREEN_WIDTH, NV3001B_SCREEN_HEIGHT); |
||||
|
color = 0xffff; |
||||
|
text_size = 1; |
||||
|
cursor_x = 0; |
||||
|
cursor_y = 0; |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::setTextSize(int sz) { |
||||
|
text_size = sz < 1 ? 1 : sz; |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::setColor(Color c) { |
||||
|
color = mapColor(c); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::setCursor(int x, int y) { |
||||
|
cursor_x = scaleX(x); |
||||
|
cursor_y = scaleY(y); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::print(const char* str) { |
||||
|
if (!str || !is_on) return; |
||||
|
|
||||
|
int scale_x = textPixelScaleX(text_size); |
||||
|
int scale_y = textPixelScaleY(text_size); |
||||
|
while (*str) { |
||||
|
if (*str == '\n') { |
||||
|
cursor_x = 0; |
||||
|
cursor_y += 8 * scale_y; |
||||
|
} else if (*str == '\r') { |
||||
|
cursor_x = 0; |
||||
|
} else { |
||||
|
drawChar(cursor_x, cursor_y, *str); |
||||
|
cursor_x += 6 * scale_x; |
||||
|
} |
||||
|
str++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::fillRect(int x, int y, int w, int h) { |
||||
|
fillPhysicalRect(scaleX(x), scaleY(y), scaleWidth(x, w), scaleHeight(y, h)); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::drawRect(int x, int y, int w, int h) { |
||||
|
int x1 = scaleX(x); |
||||
|
int y1 = scaleY(y); |
||||
|
int sw = scaleWidth(x, w); |
||||
|
int sh = scaleHeight(y, h); |
||||
|
|
||||
|
fillPhysicalRect(x1, y1, sw, 1); |
||||
|
fillPhysicalRect(x1, y1 + sh - 1, sw, 1); |
||||
|
fillPhysicalRect(x1, y1, 1, sh); |
||||
|
fillPhysicalRect(x1 + sw - 1, y1, 1, sh); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::drawXbm(int x, int y, const uint8_t* bits, int w, int h) { |
||||
|
if (!bits || !is_on) return; |
||||
|
|
||||
|
int byte_width = (w + 7) / 8; |
||||
|
for (int j = 0; j < h; j++) { |
||||
|
for (int i = 0; i < w; i++) { |
||||
|
uint8_t byte = pgm_read_byte(bits + j * byte_width + i / 8); |
||||
|
if (byte & (0x80 >> (i & 7))) { |
||||
|
fillPhysicalRect(scaleX(x + i), scaleY(y + j), scaleWidth(x + i, 1), scaleHeight(y + j, 1)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
uint16_t NV3001BDisplay::getTextWidth(const char* str) { |
||||
|
if (!str) return 0; |
||||
|
|
||||
|
uint16_t len = 0; |
||||
|
while (str[len] && str[len] != '\n' && str[len] != '\r') len++; |
||||
|
return (uint16_t)((len * 6 * textPixelScaleX(text_size)) / DISPLAY_SCALE_X); |
||||
|
} |
||||
|
|
||||
|
void NV3001BDisplay::endFrame() { |
||||
|
} |
||||
@ -0,0 +1,68 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include "DisplayDriver.h" |
||||
|
#include <SPI.h> |
||||
|
#include <helpers/RefCountedDigitalPin.h> |
||||
|
|
||||
|
#ifndef NV3001B_LOGICAL_WIDTH |
||||
|
#define NV3001B_LOGICAL_WIDTH 128 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_LOGICAL_HEIGHT |
||||
|
#define NV3001B_LOGICAL_HEIGHT 64 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_PANEL_WIDTH |
||||
|
#define NV3001B_PANEL_WIDTH 128 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_PANEL_HEIGHT |
||||
|
#define NV3001B_PANEL_HEIGHT 220 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NV3001B_SPI_HOST |
||||
|
#define NV3001B_SPI_HOST HSPI |
||||
|
#endif |
||||
|
|
||||
|
class NV3001BDisplay : public DisplayDriver { |
||||
|
SPIClass spi; |
||||
|
RefCountedDigitalPin* periph_power; |
||||
|
bool is_on = false; |
||||
|
uint16_t color = 0xffff; |
||||
|
uint8_t text_size = 1; |
||||
|
int cursor_x = 0; |
||||
|
int cursor_y = 0; |
||||
|
|
||||
|
void writeCommand(uint8_t cmd); |
||||
|
void writeBytes(const uint8_t* data, size_t len); |
||||
|
void writeCommandData(uint8_t cmd, const uint8_t* data, size_t len); |
||||
|
void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h); |
||||
|
void writeColor(uint16_t rgb, uint32_t count); |
||||
|
void fillPhysicalRect(int x, int y, int w, int h); |
||||
|
void initPanel(); |
||||
|
void drawChar(int x, int y, char ch); |
||||
|
|
||||
|
public: |
||||
|
NV3001BDisplay(RefCountedDigitalPin* power = nullptr) : |
||||
|
DisplayDriver(NV3001B_LOGICAL_WIDTH, NV3001B_LOGICAL_HEIGHT), spi(NV3001B_SPI_HOST), periph_power(power) { } |
||||
|
|
||||
|
bool begin(); |
||||
|
static const char* driverName() { return "NV3001B"; } |
||||
|
static uint16_t physicalWidth() { return NV3001B_PANEL_WIDTH; } |
||||
|
static uint16_t physicalHeight() { return NV3001B_PANEL_HEIGHT; } |
||||
|
|
||||
|
bool isOn() override { return is_on; } |
||||
|
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; |
||||
|
}; |
||||
@ -0,0 +1,66 @@ |
|||||
|
#include "HeltecRC32Board.h" |
||||
|
|
||||
|
void HeltecRC32Board::begin() { |
||||
|
ESP32Board::begin(); |
||||
|
|
||||
|
pinMode(PIN_ADC_CTRL, OUTPUT); |
||||
|
digitalWrite(PIN_ADC_CTRL, !ADC_CTRL_ENABLED); |
||||
|
|
||||
|
#ifdef SENSOR_RST_PIN |
||||
|
pinMode(SENSOR_RST_PIN, OUTPUT); |
||||
|
digitalWrite(SENSOR_RST_PIN, HIGH); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef LED_POWER |
||||
|
pinMode(LED_POWER, OUTPUT); |
||||
|
digitalWrite(LED_POWER, LOW); |
||||
|
#endif |
||||
|
|
||||
|
periph_power.begin(); |
||||
|
vext_power.begin(); |
||||
|
|
||||
|
esp_reset_reason_t reason = esp_reset_reason(); |
||||
|
if (reason == ESP_RST_DEEPSLEEP) { |
||||
|
long wakeup_source = esp_sleep_get_ext1_wakeup_status(); |
||||
|
if (wakeup_source & (1L << P_LORA_DIO_1)) { |
||||
|
startup_reason = BD_STARTUP_RX_PACKET; |
||||
|
} |
||||
|
|
||||
|
rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); |
||||
|
rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void HeltecRC32Board::powerOff() { |
||||
|
enterDeepSleep(0); |
||||
|
} |
||||
|
|
||||
|
void HeltecRC32Board::onBeforeTransmit() { |
||||
|
digitalWrite(P_LORA_TX_LED, HIGH); |
||||
|
} |
||||
|
|
||||
|
void HeltecRC32Board::onAfterTransmit() { |
||||
|
digitalWrite(P_LORA_TX_LED, LOW); |
||||
|
} |
||||
|
|
||||
|
uint16_t HeltecRC32Board::getBattMilliVolts() { |
||||
|
analogReadResolution(12); |
||||
|
digitalWrite(PIN_ADC_CTRL, ADC_CTRL_ENABLED); |
||||
|
delay(10); |
||||
|
uint32_t raw = 0; |
||||
|
for (int i = 0; i < 8; i++) { |
||||
|
raw += analogReadMilliVolts(PIN_VBAT_READ); |
||||
|
} |
||||
|
raw = raw / 8; |
||||
|
|
||||
|
return (adc_mult * raw); |
||||
|
} |
||||
|
|
||||
|
bool HeltecRC32Board::setAdcMultiplier(float multiplier) { |
||||
|
adc_mult = multiplier == 0.0f ? ADC_MULTIPLIER : multiplier; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
const char* HeltecRC32Board::getManufacturerName() const { |
||||
|
return "Heltec RC32"; |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <Arduino.h> |
||||
|
#include <driver/rtc_io.h> |
||||
|
#include <helpers/ESP32Board.h> |
||||
|
#include <helpers/RefCountedDigitalPin.h> |
||||
|
|
||||
|
#ifndef ADC_MULTIPLIER |
||||
|
#define ADC_MULTIPLIER 4.9f |
||||
|
#endif |
||||
|
|
||||
|
class HeltecRC32Board : public ESP32Board { |
||||
|
protected: |
||||
|
float adc_mult = ADC_MULTIPLIER; |
||||
|
|
||||
|
public: |
||||
|
RefCountedDigitalPin periph_power; |
||||
|
RefCountedDigitalPin vext_power; |
||||
|
|
||||
|
HeltecRC32Board() : |
||||
|
periph_power(SENSOR_POWER_CTRL_PIN, SENSOR_POWER_ON), |
||||
|
vext_power(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE) { } |
||||
|
|
||||
|
void begin(); |
||||
|
void onBeforeTransmit() override; |
||||
|
void onAfterTransmit() override; |
||||
|
void powerOff() override; |
||||
|
uint16_t getBattMilliVolts() override; |
||||
|
bool setAdcMultiplier(float multiplier) override; |
||||
|
float getAdcMultiplier() const override { return adc_mult; } |
||||
|
const char* getManufacturerName() const override; |
||||
|
}; |
||||
@ -0,0 +1,60 @@ |
|||||
|
#ifndef Pins_Arduino_h |
||||
|
#define Pins_Arduino_h |
||||
|
|
||||
|
#include <stdint.h> |
||||
|
|
||||
|
#define USB_VID 0x303a |
||||
|
#define USB_PID 0x1001 |
||||
|
|
||||
|
static const uint8_t TX = 43; |
||||
|
static const uint8_t RX = 44; |
||||
|
|
||||
|
static const uint8_t SDA = 21; |
||||
|
static const uint8_t SCL = 18; |
||||
|
|
||||
|
static const uint8_t SS = 10; |
||||
|
static const uint8_t MOSI = 12; |
||||
|
static const uint8_t MISO = 13; |
||||
|
static const uint8_t SCK = 11; |
||||
|
|
||||
|
static const uint8_t A0 = 1; |
||||
|
static const uint8_t A1 = 2; |
||||
|
static const uint8_t A2 = 3; |
||||
|
static const uint8_t A3 = 4; |
||||
|
static const uint8_t A4 = 5; |
||||
|
static const uint8_t A5 = 6; |
||||
|
static const uint8_t A6 = 7; |
||||
|
static const uint8_t A7 = 8; |
||||
|
static const uint8_t A8 = 9; |
||||
|
static const uint8_t A9 = 10; |
||||
|
static const uint8_t A10 = 11; |
||||
|
static const uint8_t A11 = 12; |
||||
|
static const uint8_t A12 = 13; |
||||
|
static const uint8_t A13 = 14; |
||||
|
static const uint8_t A14 = 15; |
||||
|
static const uint8_t A15 = 16; |
||||
|
static const uint8_t A16 = 17; |
||||
|
static const uint8_t A17 = 18; |
||||
|
static const uint8_t A18 = 19; |
||||
|
static const uint8_t A19 = 20; |
||||
|
|
||||
|
static const uint8_t T1 = 1; |
||||
|
static const uint8_t T2 = 2; |
||||
|
static const uint8_t T3 = 3; |
||||
|
static const uint8_t T4 = 4; |
||||
|
static const uint8_t T5 = 5; |
||||
|
static const uint8_t T6 = 6; |
||||
|
static const uint8_t T7 = 7; |
||||
|
static const uint8_t T8 = 8; |
||||
|
static const uint8_t T9 = 9; |
||||
|
static const uint8_t T10 = 10; |
||||
|
static const uint8_t T11 = 11; |
||||
|
static const uint8_t T12 = 12; |
||||
|
static const uint8_t T13 = 13; |
||||
|
static const uint8_t T14 = 14; |
||||
|
|
||||
|
static const uint8_t RST_LoRa = 9; |
||||
|
static const uint8_t BUSY_LoRa = 1; |
||||
|
static const uint8_t DIO1_LoRa = 14; |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,346 @@ |
|||||
|
[Heltec_RC32] |
||||
|
extends = esp32_base |
||||
|
board = heltec-rc32 |
||||
|
board_build.partitions = default_16MB.csv |
||||
|
build_flags = |
||||
|
${esp32_base.build_flags} |
||||
|
${sensor_base.build_flags} |
||||
|
-I variants/heltec_rc32 |
||||
|
-I src/helpers/ui |
||||
|
-D HELTEC_RC32 |
||||
|
-D USE_SX1262 |
||||
|
-D ESP32_CPU_FREQ=160 |
||||
|
-D RADIO_CLASS=CustomSX1262 |
||||
|
-D WRAPPER_CLASS=CustomSX1262Wrapper |
||||
|
-D P_LORA_DIO_1=14 |
||||
|
-D P_LORA_NSS=10 |
||||
|
-D P_LORA_RESET=9 |
||||
|
-D P_LORA_BUSY=1 |
||||
|
-D P_LORA_SCLK=11 |
||||
|
-D P_LORA_MISO=13 |
||||
|
-D P_LORA_MOSI=12 |
||||
|
-D LORA_TX_POWER=22 |
||||
|
-D PIN_USER_BTN=0 |
||||
|
-D PIN_BOARD_SDA=21 |
||||
|
-D PIN_BOARD_SCL=18 |
||||
|
-D PIN_VEXT_EN=3 |
||||
|
-D PIN_VEXT_EN_ACTIVE=HIGH |
||||
|
-D SENSOR_POWER_CTRL_PIN=46 |
||||
|
-D SENSOR_POWER_ON=HIGH |
||||
|
-D SENSOR_RST_PIN=2 |
||||
|
-D P_LORA_TX_LED=47 |
||||
|
-D PIN_BUZZER=48 |
||||
|
-D PIN_TFT_SCL=17 |
||||
|
-D PIN_TFT_SDA=38 |
||||
|
-D PIN_TFT_CS=39 |
||||
|
-D PIN_TFT_DC=16 |
||||
|
-D PIN_TFT_RST=4 |
||||
|
-D PIN_TFT_EN=6 |
||||
|
-D PIN_TFT_EN_ACTIVE=LOW |
||||
|
-D PIN_TFT_BL=5 |
||||
|
-D PIN_TFT_BL_ACTIVE=HIGH |
||||
|
-D SPI_FREQUENCY=8000000 |
||||
|
-D PIN_GPS_TX=44 |
||||
|
-D PIN_GPS_RX=43 |
||||
|
-D PIN_GPS_EN=45 |
||||
|
-D PIN_GPS_EN_ACTIVE=HIGH |
||||
|
-D PIN_GPS_RESET=40 |
||||
|
-D PIN_GPS_RESET_ACTIVE=LOW |
||||
|
-D PIN_GPS_PPS=41 |
||||
|
-D GPS_BAUD_RATE=9600 |
||||
|
-D ENV_INCLUDE_GPS=1 |
||||
|
-D PIN_ADC_CTRL=15 |
||||
|
-D PIN_VBAT_READ=7 |
||||
|
-D ADC_CTRL_ENABLED=HIGH |
||||
|
-D ADC_MULTIPLIER=4.9 |
||||
|
-D SX126X_DIO2_AS_RF_SWITCH=true |
||||
|
-D SX126X_DIO3_TCXO_VOLTAGE=1.8 |
||||
|
-D SX126X_CURRENT_LIMIT=140 |
||||
|
-D SX126X_RX_BOOSTED_GAIN=1 |
||||
|
build_src_filter = ${esp32_base.build_src_filter} |
||||
|
+<../variants/heltec_rc32> |
||||
|
+<helpers/sensors> |
||||
|
lib_deps = |
||||
|
${esp32_base.lib_deps} |
||||
|
${sensor_base.lib_deps} |
||||
|
|
||||
|
[Heltec_RC32_with_display] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-D HELTEC_RC32_WITH_DISPLAY |
||||
|
-D DISPLAY_CLASS=NV3001BDisplay |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<helpers/ui/NV3001BDisplay.cpp> |
||||
|
+<helpers/ui/MomentaryButton.cpp> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
|
||||
|
[env:heltec_rc32_without_display_repeater] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-D ADVERT_NAME='"Heltec RC32 Repeater"' |
||||
|
-D ADVERT_LAT=0.0 |
||||
|
-D ADVERT_LON=0.0 |
||||
|
-D ADMIN_PASSWORD='"password"' |
||||
|
-D MAX_NEIGHBOURS=50 |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<../examples/simple_repeater> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
${esp32_ota.lib_deps} |
||||
|
bakercp/CRC32 @ ^2.0.0 |
||||
|
|
||||
|
[env:heltec_rc32_without_display_repeater_bridge_espnow] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-D ADVERT_NAME='"ESPNow Bridge"' |
||||
|
-D ADVERT_LAT=0.0 |
||||
|
-D ADVERT_LON=0.0 |
||||
|
-D ADMIN_PASSWORD='"password"' |
||||
|
-D MAX_NEIGHBOURS=50 |
||||
|
-D WITH_ESPNOW_BRIDGE=1 |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<helpers/bridges/ESPNowBridge.cpp> |
||||
|
+<../examples/simple_repeater> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
${esp32_ota.lib_deps} |
||||
|
|
||||
|
[env:heltec_rc32_without_display_room_server] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-D ADVERT_NAME='"Heltec RC32 Room"' |
||||
|
-D ADVERT_LAT=0.0 |
||||
|
-D ADVERT_LON=0.0 |
||||
|
-D ADMIN_PASSWORD='"password"' |
||||
|
-D ROOM_PASSWORD='"hello"' |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<../examples/simple_room_server> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
${esp32_ota.lib_deps} |
||||
|
|
||||
|
[env:heltec_rc32_without_display_companion_radio_usb] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-I examples/companion_radio/ui-new |
||||
|
-D DISPLAY_CLASS=NullDisplayDriver |
||||
|
-D MAX_CONTACTS=350 |
||||
|
-D MAX_GROUP_CHANNELS=40 |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<helpers/ui/MomentaryButton.cpp> |
||||
|
+<helpers/ui/buzzer.cpp> |
||||
|
+<helpers/esp32/*.cpp> |
||||
|
+<../examples/companion_radio/*.cpp> |
||||
|
+<../examples/companion_radio/ui-new/*.cpp> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
densaugeo/base64 @ ~1.4.0 |
||||
|
end2endzone/NonBlockingRTTTL@^1.3.0 |
||||
|
|
||||
|
[env:heltec_rc32_without_display_companion_radio_ble] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-I examples/companion_radio/ui-new |
||||
|
-D DISPLAY_CLASS=NullDisplayDriver |
||||
|
-D MAX_CONTACTS=350 |
||||
|
-D MAX_GROUP_CHANNELS=40 |
||||
|
-D BLE_PIN_CODE=123456 |
||||
|
-D AUTO_SHUTDOWN_MILLIVOLTS=3400 |
||||
|
-D BLE_DEBUG_LOGGING=1 |
||||
|
-D OFFLINE_QUEUE_SIZE=256 |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<helpers/ui/MomentaryButton.cpp> |
||||
|
+<helpers/ui/buzzer.cpp> |
||||
|
+<helpers/esp32/*.cpp> |
||||
|
+<../examples/companion_radio/*.cpp> |
||||
|
+<../examples/companion_radio/ui-new/*.cpp> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
densaugeo/base64 @ ~1.4.0 |
||||
|
end2endzone/NonBlockingRTTTL@^1.3.0 |
||||
|
|
||||
|
[env:heltec_rc32_without_display_companion_radio_wifi] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-I examples/companion_radio/ui-new |
||||
|
-D DISPLAY_CLASS=NullDisplayDriver |
||||
|
-D MAX_CONTACTS=350 |
||||
|
-D MAX_GROUP_CHANNELS=40 |
||||
|
-D WIFI_DEBUG_LOGGING=1 |
||||
|
-D WIFI_SSID='"myssid"' |
||||
|
-D WIFI_PWD='"mypwd"' |
||||
|
-D OFFLINE_QUEUE_SIZE=256 |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<helpers/ui/MomentaryButton.cpp> |
||||
|
+<helpers/ui/buzzer.cpp> |
||||
|
+<helpers/esp32/*.cpp> |
||||
|
+<../examples/companion_radio/*.cpp> |
||||
|
+<../examples/companion_radio/ui-new/*.cpp> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
densaugeo/base64 @ ~1.4.0 |
||||
|
end2endzone/NonBlockingRTTTL@^1.3.0 |
||||
|
|
||||
|
[env:heltec_rc32_without_display_sensor] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-D ADVERT_NAME='"Heltec RC32 Sensor"' |
||||
|
-D ADVERT_LAT=0.0 |
||||
|
-D ADVERT_LON=0.0 |
||||
|
-D ADMIN_PASSWORD='"password"' |
||||
|
-D ENV_PIN_SDA=21 |
||||
|
-D ENV_PIN_SCL=18 |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<../examples/simple_sensor> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
${esp32_ota.lib_deps} |
||||
|
|
||||
|
[env:heltec_rc32_repeater] |
||||
|
extends = Heltec_RC32_with_display |
||||
|
build_flags = |
||||
|
${Heltec_RC32_with_display.build_flags} |
||||
|
-D ADVERT_NAME='"Heltec RC32 Repeater"' |
||||
|
-D ADVERT_LAT=0.0 |
||||
|
-D ADVERT_LON=0.0 |
||||
|
-D ADMIN_PASSWORD='"password"' |
||||
|
-D MAX_NEIGHBOURS=50 |
||||
|
build_src_filter = ${Heltec_RC32_with_display.build_src_filter} |
||||
|
+<../examples/simple_repeater> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32_with_display.lib_deps} |
||||
|
${esp32_ota.lib_deps} |
||||
|
bakercp/CRC32 @ ^2.0.0 |
||||
|
|
||||
|
[env:heltec_rc32_repeater_bridge_espnow] |
||||
|
extends = Heltec_RC32_with_display |
||||
|
build_flags = |
||||
|
${Heltec_RC32_with_display.build_flags} |
||||
|
-D ADVERT_NAME='"ESPNow Bridge"' |
||||
|
-D ADVERT_LAT=0.0 |
||||
|
-D ADVERT_LON=0.0 |
||||
|
-D ADMIN_PASSWORD='"password"' |
||||
|
-D MAX_NEIGHBOURS=50 |
||||
|
-D WITH_ESPNOW_BRIDGE=1 |
||||
|
build_src_filter = ${Heltec_RC32_with_display.build_src_filter} |
||||
|
+<helpers/bridges/ESPNowBridge.cpp> |
||||
|
+<../examples/simple_repeater> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32_with_display.lib_deps} |
||||
|
${esp32_ota.lib_deps} |
||||
|
|
||||
|
[env:heltec_rc32_room_server] |
||||
|
extends = Heltec_RC32_with_display |
||||
|
build_flags = |
||||
|
${Heltec_RC32_with_display.build_flags} |
||||
|
-D ADVERT_NAME='"Heltec RC32 Room"' |
||||
|
-D ADVERT_LAT=0.0 |
||||
|
-D ADVERT_LON=0.0 |
||||
|
-D ADMIN_PASSWORD='"password"' |
||||
|
-D ROOM_PASSWORD='"hello"' |
||||
|
build_src_filter = ${Heltec_RC32_with_display.build_src_filter} |
||||
|
+<../examples/simple_room_server> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32_with_display.lib_deps} |
||||
|
${esp32_ota.lib_deps} |
||||
|
|
||||
|
[env:heltec_rc32_terminal_chat] |
||||
|
extends = Heltec_RC32 |
||||
|
build_flags = |
||||
|
${Heltec_RC32.build_flags} |
||||
|
-D MAX_CONTACTS=350 |
||||
|
-D MAX_GROUP_CHANNELS=1 |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<../examples/simple_secure_chat/main.cpp> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32.lib_deps} |
||||
|
densaugeo/base64 @ ~1.4.0 |
||||
|
|
||||
|
[env:heltec_rc32_companion_radio_usb] |
||||
|
extends = Heltec_RC32_with_display |
||||
|
build_flags = |
||||
|
${Heltec_RC32_with_display.build_flags} |
||||
|
-I examples/companion_radio/ui-new |
||||
|
-D MAX_CONTACTS=350 |
||||
|
-D MAX_GROUP_CHANNELS=40 |
||||
|
build_src_filter = ${Heltec_RC32_with_display.build_src_filter} |
||||
|
+<helpers/ui/buzzer.cpp> |
||||
|
+<helpers/esp32/*.cpp> |
||||
|
+<../examples/companion_radio/*.cpp> |
||||
|
+<../examples/companion_radio/ui-new/*.cpp> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32_with_display.lib_deps} |
||||
|
densaugeo/base64 @ ~1.4.0 |
||||
|
end2endzone/NonBlockingRTTTL@^1.3.0 |
||||
|
|
||||
|
[env:heltec_rc32_companion_radio_ble] |
||||
|
extends = Heltec_RC32_with_display |
||||
|
build_flags = |
||||
|
${Heltec_RC32_with_display.build_flags} |
||||
|
-I examples/companion_radio/ui-new |
||||
|
-D MAX_CONTACTS=350 |
||||
|
-D MAX_GROUP_CHANNELS=40 |
||||
|
-D BLE_PIN_CODE=123456 |
||||
|
-D AUTO_SHUTDOWN_MILLIVOLTS=3400 |
||||
|
-D BLE_DEBUG_LOGGING=1 |
||||
|
-D OFFLINE_QUEUE_SIZE=256 |
||||
|
build_src_filter = ${Heltec_RC32_with_display.build_src_filter} |
||||
|
+<helpers/ui/buzzer.cpp> |
||||
|
+<helpers/esp32/*.cpp> |
||||
|
+<../examples/companion_radio/*.cpp> |
||||
|
+<../examples/companion_radio/ui-new/*.cpp> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32_with_display.lib_deps} |
||||
|
densaugeo/base64 @ ~1.4.0 |
||||
|
end2endzone/NonBlockingRTTTL@^1.3.0 |
||||
|
|
||||
|
[env:heltec_rc32_companion_radio_wifi] |
||||
|
extends = Heltec_RC32_with_display |
||||
|
build_flags = |
||||
|
${Heltec_RC32_with_display.build_flags} |
||||
|
-I examples/companion_radio/ui-new |
||||
|
-D MAX_CONTACTS=350 |
||||
|
-D MAX_GROUP_CHANNELS=40 |
||||
|
-D WIFI_DEBUG_LOGGING=1 |
||||
|
-D WIFI_SSID='"myssid"' |
||||
|
-D WIFI_PWD='"mypwd"' |
||||
|
-D OFFLINE_QUEUE_SIZE=256 |
||||
|
build_src_filter = ${Heltec_RC32_with_display.build_src_filter} |
||||
|
+<helpers/ui/buzzer.cpp> |
||||
|
+<helpers/esp32/*.cpp> |
||||
|
+<../examples/companion_radio/*.cpp> |
||||
|
+<../examples/companion_radio/ui-new/*.cpp> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32_with_display.lib_deps} |
||||
|
densaugeo/base64 @ ~1.4.0 |
||||
|
end2endzone/NonBlockingRTTTL@^1.3.0 |
||||
|
|
||||
|
[env:heltec_rc32_sensor] |
||||
|
extends = Heltec_RC32_with_display |
||||
|
build_flags = |
||||
|
${Heltec_RC32_with_display.build_flags} |
||||
|
-D ADVERT_NAME='"Heltec RC32 Sensor"' |
||||
|
-D ADVERT_LAT=0.0 |
||||
|
-D ADVERT_LON=0.0 |
||||
|
-D ADMIN_PASSWORD='"password"' |
||||
|
-D ENV_PIN_SDA=21 |
||||
|
-D ENV_PIN_SCL=18 |
||||
|
build_src_filter = ${Heltec_RC32_with_display.build_src_filter} |
||||
|
+<../examples/simple_sensor> |
||||
|
lib_deps = |
||||
|
${Heltec_RC32_with_display.lib_deps} |
||||
|
${esp32_ota.lib_deps} |
||||
|
|
||||
|
[env:heltec_rc32_kiss_modem] |
||||
|
extends = Heltec_RC32 |
||||
|
build_src_filter = ${Heltec_RC32.build_src_filter} |
||||
|
+<../examples/kiss_modem/> |
||||
@ -0,0 +1,45 @@ |
|||||
|
#include <Arduino.h> |
||||
|
#include "target.h" |
||||
|
|
||||
|
HeltecRC32Board board; |
||||
|
|
||||
|
#if defined(P_LORA_SCLK) |
||||
|
static SPIClass spi(FSPI); |
||||
|
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi); |
||||
|
#else |
||||
|
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); |
||||
|
#endif |
||||
|
|
||||
|
WRAPPER_CLASS radio_driver(radio, board); |
||||
|
|
||||
|
ESP32RTCClock fallback_clock; |
||||
|
AutoDiscoverRTCClock rtc_clock(fallback_clock); |
||||
|
|
||||
|
#if ENV_INCLUDE_GPS |
||||
|
#include <helpers/sensors/MicroNMEALocationProvider.h> |
||||
|
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock, PIN_GPS_RESET, PIN_GPS_EN, &board.periph_power); |
||||
|
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); |
||||
|
#else |
||||
|
EnvironmentSensorManager sensors; |
||||
|
#endif |
||||
|
|
||||
|
#ifdef DISPLAY_CLASS |
||||
|
DISPLAY_CLASS display; |
||||
|
MomentaryButton user_btn(PIN_USER_BTN, 1000, true); |
||||
|
#endif |
||||
|
|
||||
|
bool radio_init() { |
||||
|
fallback_clock.begin(); |
||||
|
rtc_clock.begin(Wire); |
||||
|
|
||||
|
#if defined(P_LORA_SCLK) |
||||
|
return radio.std_init(&spi); |
||||
|
#else |
||||
|
return radio.std_init(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
mesh::LocalIdentity radio_new_identity() { |
||||
|
RadioNoiseListener rng(radio); |
||||
|
return mesh::LocalIdentity(&rng); |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#define RADIOLIB_STATIC_ONLY 1 |
||||
|
#include <RadioLib.h> |
||||
|
#include <HeltecRC32Board.h> |
||||
|
#include <helpers/AutoDiscoverRTCClock.h> |
||||
|
#include <helpers/radiolib/CustomSX1262Wrapper.h> |
||||
|
#include <helpers/radiolib/RadioLibWrappers.h> |
||||
|
#include <helpers/sensors/EnvironmentSensorManager.h> |
||||
|
|
||||
|
#ifdef DISPLAY_CLASS |
||||
|
#include <helpers/ui/MomentaryButton.h> |
||||
|
#ifdef HELTEC_RC32_WITH_DISPLAY |
||||
|
#include <helpers/ui/NV3001BDisplay.h> |
||||
|
#else |
||||
|
#include <helpers/ui/NullDisplayDriver.h> |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
extern HeltecRC32Board board; |
||||
|
extern WRAPPER_CLASS radio_driver; |
||||
|
extern AutoDiscoverRTCClock rtc_clock; |
||||
|
extern EnvironmentSensorManager sensors; |
||||
|
|
||||
|
#ifdef DISPLAY_CLASS |
||||
|
extern DISPLAY_CLASS display; |
||||
|
extern MomentaryButton user_btn; |
||||
|
#endif |
||||
|
|
||||
|
bool radio_init(); |
||||
|
mesh::LocalIdentity radio_new_identity(); |
||||
@ -0,0 +1,51 @@ |
|||||
|
#ifndef _VARIANT_HELTEC_RC32_ |
||||
|
#define _VARIANT_HELTEC_RC32_ |
||||
|
|
||||
|
#define BUTTON_PIN 0 |
||||
|
|
||||
|
#define HAS_GPS 1 |
||||
|
#undef GPS_RX_PIN |
||||
|
#undef GPS_TX_PIN |
||||
|
#define GPS_RX_PIN 44 |
||||
|
#define GPS_TX_PIN 43 |
||||
|
#define PIN_GPS_EN 45 |
||||
|
#define GPS_EN_ACTIVE HIGH |
||||
|
#define PIN_GPS_RESET 40 |
||||
|
#define GPS_RESET_MODE LOW |
||||
|
#define PIN_GPS_PPS 41 |
||||
|
|
||||
|
#define I2C_SCL 18 |
||||
|
#define I2C_SDA 21 |
||||
|
#define SENSOR_INT_PIN 42 |
||||
|
#define SENSOR_RST_PIN 2 |
||||
|
#define SENSOR_POWER_CTRL_PIN 46 |
||||
|
#define SENSOR_POWER_ON HIGH |
||||
|
#define PERIPHERAL_WARMUP_MS 100 |
||||
|
|
||||
|
#define VEXT_ENABLE 3 |
||||
|
#define VEXT_ON_VALUE HIGH |
||||
|
|
||||
|
#define USE_SX1262 |
||||
|
#define LORA_SCK 11 |
||||
|
#define LORA_MISO 13 |
||||
|
#define LORA_MOSI 12 |
||||
|
#define LORA_CS 10 |
||||
|
#define LORA_DIO0 RADIOLIB_NC |
||||
|
#define LORA_DIO1 14 |
||||
|
#define LORA_RESET 9 |
||||
|
|
||||
|
#define SX126X_CS LORA_CS |
||||
|
#define SX126X_DIO1 LORA_DIO1 |
||||
|
#define SX126X_BUSY 1 |
||||
|
#define SX126X_RESET LORA_RESET |
||||
|
#define SX126X_DIO2_AS_RF_SWITCH |
||||
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 |
||||
|
|
||||
|
#define BATTERY_PIN 7 |
||||
|
#define ADC_CHANNEL ADC_CHANNEL_6 |
||||
|
#define ADC_CTRL 15 |
||||
|
#define ADC_CTRL_ENABLED HIGH |
||||
|
#define ADC_MULTIPLIER 4.9 |
||||
|
#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 |
||||
|
|
||||
|
#endif |
||||
Loading…
Reference in new issue