Browse Source

Add heltec rcc6 board

pull/2981/head
Quency-D 2 weeks ago
parent
commit
f22bccd487
  1. 29
      boards/heltec_rcc6.json
  2. 2
      src/helpers/ESP32Board.h
  3. 75
      src/helpers/ui/NV3001BDisplay.cpp
  4. 33
      src/helpers/ui/NV3001BDisplay.h
  5. 37
      variants/heltec_rcc6/heltec_rcc6.cpp
  6. 25
      variants/heltec_rcc6/heltec_rcc6.h
  7. 20
      variants/heltec_rcc6/pins_arduino.h
  8. 243
      variants/heltec_rcc6/platformio.ini
  9. 45
      variants/heltec_rcc6/target.cpp
  10. 32
      variants/heltec_rcc6/target.h

29
boards/heltec_rcc6.json

@ -0,0 +1,29 @@
{
"build": {
"arduino": {
"partitions": "default_16MB.csv"
},
"core": "esp32",
"f_cpu": "160000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32c6",
"variant": "heltec_rcc6"
},
"connectivity": ["bluetooth", "wifi", "lora"],
"debug": {
"openocd_target": "esp32c6.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "heltec_rcc6",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"url": "https://heltec.org/",
"vendor": "heltec"
}

2
src/helpers/ESP32Board.h

@ -34,8 +34,10 @@ public:
#ifdef PIN_VBAT_READ
// battery read support
pinMode(PIN_VBAT_READ, INPUT);
#if ESP_ARDUINO_VERSION_MAJOR < 3
adcAttachPin(PIN_VBAT_READ);
#endif
#endif
#ifdef P_LORA_TX_LED
pinMode(P_LORA_TX_LED, OUTPUT);

75
src/helpers/ui/NV3001BDisplay.cpp

@ -2,6 +2,14 @@
#include <Arduino.h>
#include <string.h>
#if NV3001B_USE_FAST_GPIO
#if !defined(CONFIG_IDF_TARGET_ESP32C6)
#error "NV3001B_USE_FAST_GPIO is only supported on ESP32-C6"
#endif
#include <hal/gpio_ll.h>
#include <soc/gpio_struct.h>
#endif
#ifndef SPI_FREQUENCY
#define SPI_FREQUENCY 8000000
#endif
@ -202,26 +210,71 @@ static void writeOptionalPin(int pin, int level) {
digitalWrite(pin, level);
}
void NV3001BDisplay::writeCommand(uint8_t cmd) {
void NV3001BDisplay::beginTransport() {
#if NV3001B_USE_SOFTWARE_SPI
pinMode(PIN_TFT_SCL, OUTPUT);
pinMode(PIN_TFT_SDA, OUTPUT);
digitalWrite(PIN_TFT_SCL, LOW);
digitalWrite(PIN_TFT_SDA, LOW);
#else
spi.begin(PIN_TFT_SCL, PIN_TFT_MISO, PIN_TFT_SDA, PIN_TFT_CS);
#endif
}
void NV3001BDisplay::beginTransfer() {
#if NV3001B_USE_SOFTWARE_SPI
digitalWrite(PIN_TFT_SCL, LOW);
#else
spi.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
#endif
}
void NV3001BDisplay::transferByte(uint8_t value) {
#if NV3001B_USE_SOFTWARE_SPI
for (uint8_t mask = 0x80; mask != 0; mask >>= 1) {
#if NV3001B_USE_FAST_GPIO
gpio_ll_set_level(&GPIO, PIN_TFT_SDA, (value & mask) ? HIGH : LOW);
gpio_ll_set_level(&GPIO, PIN_TFT_SCL, HIGH);
gpio_ll_set_level(&GPIO, PIN_TFT_SCL, LOW);
#else
digitalWrite(PIN_TFT_SDA, (value & mask) ? HIGH : LOW);
digitalWrite(PIN_TFT_SCL, HIGH);
digitalWrite(PIN_TFT_SCL, LOW);
#endif
}
#else
spi.transfer(value);
#endif
}
void NV3001BDisplay::endTransfer() {
#if NV3001B_USE_SOFTWARE_SPI
digitalWrite(PIN_TFT_SCL, LOW);
#else
spi.endTransaction();
#endif
}
void NV3001BDisplay::writeCommand(uint8_t cmd) {
beginTransfer();
digitalWrite(PIN_TFT_DC, LOW);
digitalWrite(PIN_TFT_CS, LOW);
spi.transfer(cmd);
transferByte(cmd);
digitalWrite(PIN_TFT_CS, HIGH);
spi.endTransaction();
endTransfer();
}
void NV3001BDisplay::writeBytes(const uint8_t* data, size_t len) {
if (!data || len == 0) return;
spi.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
beginTransfer();
digitalWrite(PIN_TFT_DC, HIGH);
digitalWrite(PIN_TFT_CS, LOW);
for (size_t i = 0; i < len; i++) {
spi.transfer(data[i]);
transferByte(data[i]);
}
digitalWrite(PIN_TFT_CS, HIGH);
spi.endTransaction();
endTransfer();
}
void NV3001BDisplay::writeCommandData(uint8_t cmd, const uint8_t* data, size_t len) {
@ -253,15 +306,15 @@ 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));
beginTransfer();
digitalWrite(PIN_TFT_DC, HIGH);
digitalWrite(PIN_TFT_CS, LOW);
while (count--) {
spi.transfer(hi);
spi.transfer(lo);
transferByte(hi);
transferByte(lo);
}
digitalWrite(PIN_TFT_CS, HIGH);
spi.endTransaction();
endTransfer();
}
void NV3001BDisplay::initPanel() {
@ -427,7 +480,7 @@ bool NV3001BDisplay::begin() {
digitalWrite(PIN_TFT_DC, HIGH);
delay(20);
spi.begin(PIN_TFT_SCL, PIN_TFT_MISO, PIN_TFT_SDA, PIN_TFT_CS);
beginTransport();
if (PIN_TFT_RST >= 0) {
pinMode(PIN_TFT_RST, OUTPUT);
digitalWrite(PIN_TFT_RST, HIGH);

33
src/helpers/ui/NV3001BDisplay.h

@ -1,9 +1,24 @@
#pragma once
#include "DisplayDriver.h"
#include <SPI.h>
#include <helpers/RefCountedDigitalPin.h>
#ifndef NV3001B_USE_SOFTWARE_SPI
#define NV3001B_USE_SOFTWARE_SPI 0
#endif
#ifndef NV3001B_USE_FAST_GPIO
#define NV3001B_USE_FAST_GPIO 0
#endif
#if NV3001B_USE_FAST_GPIO && !NV3001B_USE_SOFTWARE_SPI
#error "NV3001B_USE_FAST_GPIO requires NV3001B_USE_SOFTWARE_SPI"
#endif
#if !NV3001B_USE_SOFTWARE_SPI
#include <SPI.h>
#endif
#ifndef NV3001B_LOGICAL_WIDTH
#define NV3001B_LOGICAL_WIDTH 128
#endif
@ -20,12 +35,14 @@
#define NV3001B_PANEL_HEIGHT 220
#endif
#ifndef NV3001B_SPI_HOST
#if !NV3001B_USE_SOFTWARE_SPI && !defined(NV3001B_SPI_HOST)
#define NV3001B_SPI_HOST HSPI
#endif
class NV3001BDisplay : public DisplayDriver {
#if !NV3001B_USE_SOFTWARE_SPI
SPIClass spi;
#endif
RefCountedDigitalPin* periph_power;
bool is_on = false;
uint16_t color = 0xffff;
@ -33,6 +50,10 @@ class NV3001BDisplay : public DisplayDriver {
int cursor_x = 0;
int cursor_y = 0;
void beginTransport();
void beginTransfer();
void transferByte(uint8_t value);
void endTransfer();
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);
@ -44,7 +65,13 @@ class NV3001BDisplay : public DisplayDriver {
public:
NV3001BDisplay(RefCountedDigitalPin* power = nullptr) :
DisplayDriver(NV3001B_LOGICAL_WIDTH, NV3001B_LOGICAL_HEIGHT), spi(NV3001B_SPI_HOST), periph_power(power) { }
DisplayDriver(NV3001B_LOGICAL_WIDTH, NV3001B_LOGICAL_HEIGHT)
#if !NV3001B_USE_SOFTWARE_SPI
,
spi(NV3001B_SPI_HOST)
#endif
,
periph_power(power) { }
bool begin();
static const char* driverName() { return "NV3001B"; }

37
variants/heltec_rcc6/heltec_rcc6.cpp

@ -0,0 +1,37 @@
#include "heltec_rcc6.h"
void HeltecRCC6Board::begin() {
ESP32Board::begin();
pinMode(PIN_USER_BTN, INPUT_PULLUP);
pinMode(PIN_ADC_CTRL, OUTPUT);
digitalWrite(PIN_ADC_CTRL, LOW);
if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
gpio_hold_dis((gpio_num_t)P_LORA_NSS);
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_GPIO &&
gpio_get_level((gpio_num_t)P_LORA_DIO_1) == HIGH) {
startup_reason = BD_STARTUP_RX_PACKET;
}
}
}
void HeltecRCC6Board::powerOff() {
enterDeepSleep(0);
}
uint16_t HeltecRCC6Board::getBattMilliVolts() {
analogReadResolution(12);
analogSetAttenuation(ADC_2_5db);
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;
digitalWrite(PIN_ADC_CTRL, !ADC_CTRL_ENABLED);
return (adcMultiplier * raw);
}

25
variants/heltec_rcc6/heltec_rcc6.h

@ -0,0 +1,25 @@
#pragma once
#include <Arduino.h>
#include <helpers/ESP32Board.h>
#ifndef ADC_MULTIPLIER
#define ADC_MULTIPLIER 4.95f
#endif
class HeltecRCC6Board : public ESP32Board {
float adcMultiplier = ADC_MULTIPLIER;
public:
void begin();
void powerOff() override;
uint16_t getBattMilliVolts() override;
bool setAdcMultiplier(float multiplier) override {
adcMultiplier = multiplier == 0.0f ? ADC_MULTIPLIER : multiplier;
return true;
}
float getAdcMultiplier() const override { return adcMultiplier; }
const char *getManufacturerName() const override { return "heltec_rcc6"; }
};

20
variants/heltec_rcc6/pins_arduino.h

@ -0,0 +1,20 @@
#ifndef PINS_ARDUINO_H
#define PINS_ARDUINO_H
#include <stdint.h>
#define USB_VID 0x303A
#define USB_PID 0x1001
static const uint8_t TX = 16;
static const uint8_t RX = 17;
static const int8_t SDA = -1;
static const int8_t SCL = -1;
static const uint8_t MISO = 20;
static const uint8_t SCK = 21;
static const uint8_t MOSI = 22;
static const uint8_t SS = 23;
#endif

243
variants/heltec_rcc6/platformio.ini

@ -0,0 +1,243 @@
[heltec_rcc6]
extends = esp32c6_base
board = heltec_rcc6
board_build.partitions = default_16MB.csv
upload_protocol = esptool
build_flags =
${esp32c6_base.build_flags}
-I variants/heltec_rcc6
-D HELTEC_RCC6=1
-D ARDUINO_USB_CDC_ON_BOOT=1
-D ARDUINO_USB_MODE=1
-D P_LORA_SCLK=21
-D P_LORA_MISO=20
-D P_LORA_MOSI=22
-D P_LORA_NSS=23
-D P_LORA_DIO_1=19
-D P_LORA_BUSY=10
-D P_LORA_RESET=8
-D PIN_USER_BTN=9
-D PIN_BOARD_SDA=-1
-D PIN_BOARD_SCL=-1
-D PIN_ADC_CTRL=5
-D ADC_CTRL_ENABLED=HIGH
-D PIN_VBAT_READ=6
-D ADC_MULTIPLIER=4.95f
-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
-D USE_SX1262
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D DISABLE_WIFI_OTA=1
build_src_filter = ${esp32c6_base.build_src_filter}
+<../variants/heltec_rcc6>
lib_deps =
${esp32c6_base.lib_deps}
[heltec_rcc6_with_display]
extends = heltec_rcc6
build_flags =
${heltec_rcc6.build_flags}
-D HELTEC_RCC6_WITH_DISPLAY=1
-D DISPLAY_CLASS=NV3001BDisplay
-D NV3001B_USE_SOFTWARE_SPI=1
-D NV3001B_USE_FAST_GPIO=1
-D PIN_TFT_SCL=4
-D PIN_TFT_SDA=15
-D PIN_TFT_CS=18
-D PIN_TFT_DC=3
-D PIN_TFT_RST=0
-D PIN_TFT_EN=2
-D PIN_TFT_EN_ACTIVE=LOW
-D PIN_TFT_BL=1
-D PIN_TFT_BL_ACTIVE=HIGH
-D DISPLAY_ROTATION=0
build_src_filter = ${heltec_rcc6.build_src_filter}
+<helpers/ui/NV3001BDisplay.cpp>
lib_deps =
${heltec_rcc6.lib_deps}
[env:heltec_rcc6_without_display_repeater]
extends = heltec_rcc6
build_src_filter = ${heltec_rcc6.build_src_filter}
+<../examples/simple_repeater/*.cpp>
build_flags =
${heltec_rcc6.build_flags}
-D ADVERT_NAME='"heltec_rcc6 Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
lib_deps =
${heltec_rcc6.lib_deps}
${esp32_ota.lib_deps}
[env:heltec_rcc6_without_display_room_server]
extends = heltec_rcc6
build_src_filter = ${heltec_rcc6.build_src_filter}
+<../examples/simple_room_server>
build_flags =
${heltec_rcc6.build_flags}
-D ADVERT_NAME='"heltec_rcc6 Room"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
lib_deps =
${heltec_rcc6.lib_deps}
${esp32_ota.lib_deps}
[env:heltec_rcc6_without_display_companion_radio_ble]
extends = heltec_rcc6
build_flags =
${heltec_rcc6.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 BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
build_src_filter = ${heltec_rcc6.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/ESPNOWRadio.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${heltec_rcc6.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:heltec_rcc6_without_display_companion_radio_usb]
extends = heltec_rcc6
build_flags =
${heltec_rcc6.build_flags}
-I examples/companion_radio/ui-new
-D DISPLAY_CLASS=NullDisplayDriver
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
build_src_filter = ${heltec_rcc6.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/ESPNOWRadio.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${heltec_rcc6.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:heltec_rcc6_without_display_companion_radio_wifi]
extends = heltec_rcc6
build_flags =
${heltec_rcc6.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 TCP_PORT=5000
-D OFFLINE_QUEUE_SIZE=256
build_src_filter = ${heltec_rcc6.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/ESPNOWRadio.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${heltec_rcc6.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:heltec_rcc6_repeater]
extends = heltec_rcc6_with_display
build_src_filter = ${heltec_rcc6_with_display.build_src_filter}
+<../examples/simple_repeater/*.cpp>
build_flags =
${heltec_rcc6_with_display.build_flags}
-D ADVERT_NAME='"heltec_rcc6 Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
lib_deps =
${heltec_rcc6_with_display.lib_deps}
${esp32_ota.lib_deps}
[env:heltec_rcc6_room_server]
extends = heltec_rcc6_with_display
build_src_filter = ${heltec_rcc6_with_display.build_src_filter}
+<../examples/simple_room_server>
build_flags =
${heltec_rcc6_with_display.build_flags}
-D ADVERT_NAME='"heltec_rcc6 Room"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
lib_deps =
${heltec_rcc6_with_display.lib_deps}
${esp32_ota.lib_deps}
[env:heltec_rcc6_companion_radio_ble]
extends = heltec_rcc6_with_display
build_flags =
${heltec_rcc6_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 BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
build_src_filter = ${heltec_rcc6_with_display.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/ESPNOWRadio.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${heltec_rcc6_with_display.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:heltec_rcc6_companion_radio_usb]
extends = heltec_rcc6_with_display
build_flags =
${heltec_rcc6_with_display.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
build_src_filter = ${heltec_rcc6_with_display.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/ESPNOWRadio.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${heltec_rcc6_with_display.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:heltec_rcc6_companion_radio_wifi]
extends = heltec_rcc6_with_display
build_flags =
${heltec_rcc6_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 TCP_PORT=5000
-D OFFLINE_QUEUE_SIZE=256
build_src_filter = ${heltec_rcc6_with_display.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/ESPNOWRadio.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${heltec_rcc6_with_display.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:heltec_rcc6_kiss_modem]
extends = heltec_rcc6
build_src_filter = ${heltec_rcc6.build_src_filter}
+<../examples/kiss_modem/>

45
variants/heltec_rcc6/target.cpp

@ -0,0 +1,45 @@
#include "target.h"
#include <Arduino.h>
HeltecRCC6Board board;
static SPIClass spi(0);
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock rtc_clock;
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
MomentaryButton user_btn(PIN_USER_BTN, 1000, true);
#endif
bool radio_init() {
rtc_clock.begin();
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
return radio.std_init(&spi);
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
radio_driver.updatePreamble(sf);
}
void radio_set_tx_power(int8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng);
}

32
variants/heltec_rcc6/target.h

@ -0,0 +1,32 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include "heltec_rcc6.h"
#include <RadioLib.h>
#include <helpers/ESP32Board.h>
#include <helpers/SensorManager.h>
#include <helpers/radiolib/CustomSX1262Wrapper.h>
#include <helpers/radiolib/RadioLibWrappers.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/MomentaryButton.h>
#ifdef HELTEC_RCC6_WITH_DISPLAY
#include <helpers/ui/NV3001BDisplay.h>
#else
#include <helpers/ui/NullDisplayDriver.h>
#endif
#endif
extern HeltecRCC6Board board;
extern WRAPPER_CLASS radio_driver;
extern ESP32RTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
extern MomentaryButton user_btn;
#endif
bool radio_init();
mesh::LocalIdentity radio_new_identity();
Loading…
Cancel
Save