Browse Source

Add heltec rc32 board

pull/2966/head
Quency-D 2 weeks ago
parent
commit
17d68e328f
  1. 43
      boards/heltec-rc32.json
  2. 553
      src/helpers/ui/NV3001BDisplay.cpp
  3. 68
      src/helpers/ui/NV3001BDisplay.h
  4. 66
      variants/heltec_rc32/HeltecRC32Board.cpp
  5. 32
      variants/heltec_rc32/HeltecRC32Board.h
  6. 60
      variants/heltec_rc32/pins_arduino.h
  7. 346
      variants/heltec_rc32/platformio.ini
  8. 45
      variants/heltec_rc32/target.cpp
  9. 31
      variants/heltec_rc32/target.h
  10. 51
      variants/heltec_rc32/variant.h

43
boards/heltec-rc32.json

@ -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"
}

553
src/helpers/ui/NV3001BDisplay.cpp

@ -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() {
}

68
src/helpers/ui/NV3001BDisplay.h

@ -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;
};

66
variants/heltec_rc32/HeltecRC32Board.cpp

@ -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";
}

32
variants/heltec_rc32/HeltecRC32Board.h

@ -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;
};

60
variants/heltec_rc32/pins_arduino.h

@ -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

346
variants/heltec_rc32/platformio.ini

@ -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/>

45
variants/heltec_rc32/target.cpp

@ -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);
}

31
variants/heltec_rc32/target.h

@ -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();

51
variants/heltec_rc32/variant.h

@ -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…
Cancel
Save