diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index c6ef3484679..7a3e5432338 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -307,7 +307,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) type = AHT10; break; #endif -#if !defined(M5STACK_UNITC6L) +#if !defined(M5STACK_UNITC6L) && !defined(ARDUINO_NESSO_N1) case INA_ADDR: case INA_ADDR_ALTERNATE: case INA_ADDR_WAVESHARE_UPS: diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 12fac4f34a5..1b2653c6c58 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -16,6 +16,10 @@ extern SX1509 gpioExtender; #endif +#ifdef TFT_BL_EXT +#include "GpioExtLogic.h" +#endif + #ifdef TFT_MESH_OVERRIDE uint16_t TFT_MESH = TFT_MESH_OVERRIDE; #else @@ -485,7 +489,7 @@ class LGFX : public lgfx::LGFX_Device lgfx::Bus_SPI _bus_instance; lgfx::Light_PWM _light_instance; #if HAS_TOUCHSCREEN -#if defined(T_WATCH_S3) || defined(ELECROW) +#if defined(T_WATCH_S3) || defined(ELECROW) || defined(ARDUINO_NESSO_N1) lgfx::Touch_FT5x06 _touch_instance; #elif defined(HELTEC_V4_TFT) lgfx::TOUCH_CHSC6X _touch_instance; @@ -1163,6 +1167,8 @@ TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY g virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio p = virtPin; } +#elif defined(TFT_BL_EXT) + GpioPin *p = new GpioExtPin(TFT_BL_EXT); #else GpioPin *p = new GpioVirtPin(); // Just simulate a pin #endif diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index c5a4106e775..8849d203b24 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -2097,7 +2097,7 @@ void menuHandler::TFTColorPickerMenu(OLEDDisplay *display) } #if defined(HELTEC_MESH_NODE_T114) || defined(HELTEC_VISION_MASTER_T190) || defined(T_DECK) || defined(T_LORA_PAGER) || \ - HAS_TFT || defined(HACKADAY_COMMUNICATOR) + HAS_TFT || defined(HACKADAY_COMMUNICATOR) || defined(ARDUINO_NESSO_N1) const ScreenColor &color = option.value; if (color.useVariant) { LOG_INFO("Setting color to system default or defined variant"); @@ -2358,7 +2358,7 @@ void menuHandler::screenOptionsMenu() // Only show screen color for TFT displays #if defined(HELTEC_MESH_NODE_T114) || defined(HELTEC_VISION_MASTER_T190) || defined(T_DECK) || defined(T_LORA_PAGER) || \ - HAS_TFT || defined(HACKADAY_COMMUNICATOR) + HAS_TFT || defined(HACKADAY_COMMUNICATOR) || defined(ARDUINO_NESSO_N1) optionsArray[options] = "Screen Color"; optionsEnumArray[options++] = ScreenColor; #endif diff --git a/src/input/i2cButton.cpp b/src/input/i2cButton.cpp index d874146cde1..ef49421d684 100644 --- a/src/input/i2cButton.cpp +++ b/src/input/i2cButton.cpp @@ -2,7 +2,7 @@ #include "meshUtils.h" #include "configuration.h" -#if defined(M5STACK_UNITC6L) +#if defined(M5STACK_UNITC6L) || defined(ARDUINO_NESSO_N1) #include "MeshService.h" #include "RadioLibInterface.h" @@ -92,4 +92,4 @@ int32_t i2cButtonThread::runOnce() } return 50; } -#endif \ No newline at end of file +#endif diff --git a/src/input/i2cButton.h b/src/input/i2cButton.h index 1ad9086061c..992efd5c437 100644 --- a/src/input/i2cButton.h +++ b/src/input/i2cButton.h @@ -4,7 +4,7 @@ #include "OneButton.h" #include "concurrency/OSThread.h" #include "configuration.h" -#if defined(M5STACK_UNITC6L) +#if defined(M5STACK_UNITC6L) || defined(ARDUINO_NESSO_N1) class i2cButtonThread : public Observable, public concurrency::OSThread { diff --git a/src/main.cpp b/src/main.cpp index c1096a240ea..4f3c42ac7fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -625,7 +625,7 @@ void setup() #endif #endif -#if defined(M5STACK_UNITC6L) +#if defined(M5STACK_UNITC6L) || defined(ARDUINO_NESSO_N1) pinMode(LORA_CS, OUTPUT); digitalWrite(LORA_CS, 1); c6l_init(); diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index e17868bafd6..8542afb22c2 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -203,7 +203,7 @@ void setupModules() #endif cardKbI2cImpl = new CardKbI2cImpl(); cardKbI2cImpl->init(); -#if defined(M5STACK_UNITC6L) +#if defined(M5STACK_UNITC6L) || defined(ARDUINO_NESSO_N1) i2cButton = new i2cButtonThread("i2cButtonThread"); #endif #ifdef INPUTBROKER_MATRIX_TYPE diff --git a/variants/esp32c6/arduino_nesso_n1/GpioExtLogic.cpp b/variants/esp32c6/arduino_nesso_n1/GpioExtLogic.cpp new file mode 100644 index 00000000000..b09dded537a --- /dev/null +++ b/variants/esp32c6/arduino_nesso_n1/GpioExtLogic.cpp @@ -0,0 +1,12 @@ +#include "GpioExtLogic.h" +#include + +void GpioExtPin::set(bool value) +{ + gpio_ext_set(this->address, this->pin, value); +} + +uint8_t GpioExtPin::get() +{ + return gpio_ext_get(this->address, this->pin); +} diff --git a/variants/esp32c6/arduino_nesso_n1/GpioExtLogic.h b/variants/esp32c6/arduino_nesso_n1/GpioExtLogic.h new file mode 100644 index 00000000000..85236cbb86c --- /dev/null +++ b/variants/esp32c6/arduino_nesso_n1/GpioExtLogic.h @@ -0,0 +1,14 @@ +#include "GpioLogic.h" + +class GpioExtPin : public GpioPin +{ + uint32_t num; + + public: + GpioExtPin(uint16_t _pin) : pin(_pin & 0x3F), address(_pin & 0x100 ? 0x44 : 0x43){}; + uint8_t pin; + uint8_t address; + + void set(bool value); + uint8_t get(); +}; diff --git a/variants/esp32c6/arduino_nesso_n1/pins_arduino.h b/variants/esp32c6/arduino_nesso_n1/pins_arduino.h new file mode 100644 index 00000000000..9cb528913db --- /dev/null +++ b/variants/esp32c6/arduino_nesso_n1/pins_arduino.h @@ -0,0 +1,22 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_VID 0x303A +#define USB_PID 0x1001 + +static const uint8_t TX = -1; +static const uint8_t RX = -1; + +static const uint8_t SDA = 10; +static const uint8_t SCL = 8; + +// Default SPI will be mapped to Radio +static const uint8_t MOSI = 21; +static const uint8_t MISO = 22; +static const uint8_t SCK = 20; +static const uint8_t SS = 23; + +#endif /* Pins_Arduino_h */ + diff --git a/variants/esp32c6/arduino_nesso_n1/platformio.ini b/variants/esp32c6/arduino_nesso_n1/platformio.ini new file mode 100644 index 00000000000..ab454e1fc02 --- /dev/null +++ b/variants/esp32c6/arduino_nesso_n1/platformio.ini @@ -0,0 +1,35 @@ +[env:arduino-nesso-n1] +extends = esp32c6_base +board = esp32-c6-devkitc-1 +upload_protocol = esptool +build_unflags = + -D HAS_BLUETOOTH + -D MESHTASTIC_EXCLUDE_BLUETOOTH + -D HAS_WIFI +lib_deps = + ${esp32c6_base.lib_deps} + h2zero/NimBLE-Arduino@^2.3.6 + lovyan03/LovyanGFX@^1.2.0 + https://github.com/mverch67/BQ27220/archive/07d92be846abd8a0258a50c23198dac0858b22ed.zip +build_flags = + ${esp32c6_base.build_flags} + -D PRIVATE_HW + -D ARDUINO_NESSO_N1 + -I variants/esp32c6/arduino_nesso_n1 + -DMESHTASTIC_EXCLUDE_PAXCOUNTER=1 + -DSOC_USB_OTG_SUPPORTED=1 + -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_MODE=1 + -D HAS_BLUETOOTH=1 + -D HAS_WIRE=1 + -DCONFIG_BT_NIMBLE_EXT_ADV=1 + -DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2 + -D NIMBLE_TWO + -D CORE_DEBUG_LEVEL=5 + -D _ESP_LOGLEVEL_=5 +monitor_speed=115200 +lib_ignore = + NonBlockingRTTTL + libpax +build_src_filter = + ${esp32c6_base.build_src_filter} +<../variants/esp32c6/arduino_nesso_n1> diff --git a/variants/esp32c6/arduino_nesso_n1/variant.cpp b/variants/esp32c6/arduino_nesso_n1/variant.cpp new file mode 100644 index 00000000000..aa4166b5b82 --- /dev/null +++ b/variants/esp32c6/arduino_nesso_n1/variant.cpp @@ -0,0 +1,127 @@ +#include "driver/gpio.h" +#include +#include +// I2C device addr +#define PI4IO_M_ADDR 0x43 +#define PI4IO_M_ADDR2 0x44 + +// PI4IO registers +#define PI4IO_REG_CHIP_RESET 0x01 +#define PI4IO_REG_IO_DIR 0x03 +#define PI4IO_REG_OUT_SET 0x05 +#define PI4IO_REG_OUT_H_IM 0x07 +#define PI4IO_REG_IN_DEF_STA 0x09 +#define PI4IO_REG_PULL_EN 0x0B +#define PI4IO_REG_PULL_SEL 0x0D +#define PI4IO_REG_IN_STA 0x0F +#define PI4IO_REG_INT_MASK 0x11 +#define PI4IO_REG_IRQ_STA 0x13 +// PI4IO + +#define setbit(x, y) x |= (0x01 << y) +#define clrbit(x, y) x &= ~(0x01 << y) +#define reversebit(x, y) x ^= (0x01 << y) +#define getbit(x, y) ((x) >> (y)&0x01) + +void i2c_read_byte(uint8_t addr, uint8_t reg, uint8_t *value) +{ + Wire.beginTransmission(addr); + Wire.write(reg); + Wire.endTransmission(); + Wire.requestFrom(addr, 1); + *value = Wire.read(); +} + +/*******************************************************************/ +void i2c_write_byte(uint8_t addr, uint8_t reg, uint8_t value) +{ + Wire.beginTransmission(addr); + Wire.write(reg); + Wire.write(value); + Wire.endTransmission(); +} +/*******************************************************************/ +void c6l_init() +{ + // P7 LoRa Reset + // P6 RF Switch + // P5 LNA Enable + // P1 KEY2 + // P0 KEY1 + // P107 LED_BUILTIN + // P106 LCD_BACKLIGHT + // P105 VIN_DETECT + // P102 GROVE_POWER_EN + // P101 LCD_RESET + // P100 POWEROFF + + printf("pi4io_init\n"); + uint8_t in_data; + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_CHIP_RESET, 0xFF); + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_read_byte(PI4IO_M_ADDR, PI4IO_REG_CHIP_RESET, &in_data); + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_IO_DIR, 0b11100000); // 0: input 1: output + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_OUT_H_IM, 0b00011100); // Output High-Impedance, 1 high-impedance + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_PULL_SEL, 0b11100011); // pull up/down select, 0 down, 1 up + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_PULL_EN, 0b11100011); // pull up/down enable, 0 disable, 1 enable + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_IN_DEF_STA, 0b00000011); // P0 P1 Default state HIGH, interrupt when pressed + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_INT_MASK, 0b11111100); // P0 P1 Interrupt 0 enable, 1 disable + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_OUT_SET, 0b11100000); // default output to 0 + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_read_byte(PI4IO_M_ADDR, PI4IO_REG_IRQ_STA, &in_data); // Read IRQ_STA clear register + + i2c_read_byte(PI4IO_M_ADDR, PI4IO_REG_OUT_SET, &in_data); + setbit(in_data, 6); // HIGH + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_OUT_SET, in_data); + + i2c_write_byte(PI4IO_M_ADDR2, PI4IO_REG_CHIP_RESET, 0xFF); + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_read_byte(PI4IO_M_ADDR2, PI4IO_REG_CHIP_RESET, &in_data); + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR2, PI4IO_REG_IO_DIR, 0b11000110); // 0: input 1: output + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR2, PI4IO_REG_OUT_H_IM, 0b00111000); // Output High-Impedance, 1 high-impedance + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR2, PI4IO_REG_PULL_SEL, 0b11000111); // pull up/down select, 0 down, 1 up + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR2, PI4IO_REG_PULL_EN, 0b11000111); // pull up/down enable, 0 disable, 1 enable + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR2, PI4IO_REG_IN_DEF_STA, 0b00000000); // P0 P1 Default state HIGH, interrupt when pressed + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR2, PI4IO_REG_INT_MASK, 0b11111111); // P0 P1 Interrupt 0 enable, 1 disable + vTaskDelay(10 / portTICK_PERIOD_MS); + i2c_write_byte(PI4IO_M_ADDR2, PI4IO_REG_OUT_SET, 0b11000110); // default output to 0 + + // AW32001E - address 0x49 + // charge current 256mA (default 128mA) + i2c_write_byte(0x49, 0x2, 0x1f); + // charge voltage 4.200(default) + // disable watch dog timer (default: 0x1f) + i2c_write_byte(0x49, 0x5, 0x1a); + // UVLO: 2.580 (default: 2.760), charge enable, disable HIZ (default: 0xac) + i2c_write_byte(0x49, 0x1, 0xa2); + // DPM 4.520 (default) + i2c_write_byte(0x49, 0x0, 0x8f); +} + +void gpio_ext_set(uint8_t address, uint8_t pin, bool value) +{ + uint8_t in_data; + i2c_read_byte(address, PI4IO_REG_OUT_SET, &in_data); + value ? setbit(in_data, pin) : clrbit(in_data, pin); + i2c_write_byte(address, PI4IO_REG_OUT_SET, in_data); +} + +uint8_t gpio_ext_get(uint8_t address, uint8_t pin) +{ + uint8_t in_data; + i2c_read_byte(address, PI4IO_REG_OUT_SET, &in_data); + return getbit(in_data, pin); +} diff --git a/variants/esp32c6/arduino_nesso_n1/variant.h b/variants/esp32c6/arduino_nesso_n1/variant.h new file mode 100644 index 00000000000..1e55a300677 --- /dev/null +++ b/variants/esp32c6/arduino_nesso_n1/variant.h @@ -0,0 +1,87 @@ +void c6l_init(); +void gpio_ext_set(uint8_t address, uint8_t pin, bool value); +uint8_t gpio_ext_get(uint8_t address, uint8_t pin); + +#define HAS_GPS 0 +#define GPS_RX_PIN -1 +#define GPS_TX_PIN -1 + +#define I2C_SDA 10 +#define I2C_SCL 8 + +#define LCD_CS 17 +#define LCD_RS 16 +#define SYS_IRQ 3 + +#define MOSI 21 +#define MISO 22 +#define SCK 20 + +#define PIN_BUZZER 11 + +#define IO_EXPANDER 0x40 +#define LCD_BACKLIGHT 0x106 + +// #define BUTTON_PIN 9 +#define BUTTON_EXTENDER + +#undef LORA_SCK +#undef LORA_MISO +#undef LORA_MOSI +#undef LORA_CS + +// battery charger BQ25896 +// #define HAS_PPM 1 +// #define XPOWERS_CHIP_BQ25896 + +// battery quality management BQ27220 +#define HAS_BQ27220 1 +#define BQ27220_I2C_SDA I2C_SDA +#define BQ27220_I2C_SCL I2C_SCL +#define BQ27220_DESIGN_CAPACITY 250 + +// WaveShare Core1262-868M OK +// https://www.waveshare.com/wiki/Core1262-868M +#define USE_SX1262 + +#define LORA_MISO 22 +#define LORA_SCK 20 +#define LORA_MOSI 21 +#define LORA_CS 23 +#define LORA_RESET RADIOLIB_NC +#define LORA_DIO1 15 +#define LORA_BUSY 19 +#define SX126X_CS LORA_CS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY LORA_BUSY +#define SX126X_RESET LORA_RESET +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 3.0 + +#define USE_TFTDISPLAY 1 +#define ST7789_DRIVER +#define ST7789_CS 17 +#define ST7789_RS 16 +#define ST7789_SDA 21 +#define ST7789_SCK 20 +#define ST7789_RESET -1 +#define ST7789_MISO 22 +#define ST7789_BUSY -1 +#define ST7789_SPI_HOST SPI2_HOST +#define SPI_FREQUENCY 60000000 +#define SPI_READ_FREQUENCY 16000000 +#define TFT_HEIGHT 240 +#define TFT_WIDTH 135 +#define TFT_OFFSET_X -52 +#define TFT_OFFSET_Y 40 +#define TFT_OFFSET_ROTATION 2 +#define SCREEN_ROTATE +#define SCREEN_TRANSITION_FRAMERATE 5 +#define BRIGHTNESS_DEFAULT 130 +#define TFT_MESH_OVERRIDE COLOR565(20, 240, 220) + +#define HAS_TOUCHSCREEN 1 +#define TOUCH_I2C_PORT 0 +#define TOUCH_SLAVE_ADDRESS 0x38 +#define SCREEN_TOUCH_INT 3 +#define TFT_BL_EXT (LCD_BACKLIGHT | IO_EXPANDER)