diff --git a/boards/ThinkNode-M3.json b/boards/ThinkNode-M3.json new file mode 100644 index 000000000..ff21e046a --- /dev/null +++ b/boards/ThinkNode-M3.json @@ -0,0 +1,53 @@ +{ + "build": { + "arduino": { + "ldscript": "nrf52840_s140_v6.ld" + }, + "core": "nRF5", + "cpu": "cortex-m4", + "extra_flags": "-DNRF52840_XXAA", + "f_cpu": "64000000L", + "hwids": [ + ["0x239A", "0x4405"], + ["0x239A", "0x0029"], + ["0x239A", "0x002A"] + ], + "usb_product": "elecrow_eink", + "mcu": "nrf52840", + "variant": "ELECROW-ThinkNode-M3", + "variants_dir": "variants", + "bsp": { + "name": "adafruit" + }, + "softdevice": { + "sd_flags": "-DS140", + "sd_name": "s140", + "sd_version": "6.1.1", + "sd_fwid": "0x00B6" + }, + "bootloader": { + "settings_addr": "0xFF000" + } + }, + "connectivity": ["bluetooth"], + "debug": { + "jlink_device": "nRF52840_xxAA", + "onboard_tools": ["jlink"], + "svd_path": "nrf52840.svd", + "openocd_target": "nrf52840-mdk-rs" + }, + "frameworks": ["arduino"], + "name": "elecrow nrf", + "upload": { + "maximum_ram_size": 248832, + "maximum_size": 815104, + "speed": 115200, + "protocol": "nrfutil", + "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"], + "use_1200bps_touch": true, + "require_upload_port": true, + "wait_for_upload_port": true + }, + "url": "", + "vendor": "ELECROW" +} diff --git a/src/BluetoothStatus.h b/src/BluetoothStatus.h index 680aec929..8091100de 100644 --- a/src/BluetoothStatus.h +++ b/src/BluetoothStatus.h @@ -94,6 +94,9 @@ class BluetoothStatus : public Status #else digitalWrite(BLE_LED, HIGH); #endif +#endif +#if defined(ELECROW_ThinkNode_M3) + digitalWrite(LED_POWER, LED_STATE_OFF); #endif break; @@ -105,6 +108,10 @@ class BluetoothStatus : public Status #else digitalWrite(BLE_LED, LOW); #endif +#endif +#if defined(ELECROW_ThinkNode_M3) + digitalWrite(LED_POWER, LED_STATE_ON); + #endif break; } diff --git a/src/main.cpp b/src/main.cpp index 689e80e35..23759e003 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -309,7 +309,36 @@ void setup() pinMode(PIN_POWER_EN, OUTPUT); digitalWrite(PIN_POWER_EN, HIGH); #endif +#if defined(ELECROW_ThinkNode_M3) + pinMode(KEY_POWER, OUTPUT); + digitalWrite(KEY_POWER, HIGH); + pinMode(RGB_POWER, OUTPUT); + digitalWrite(RGB_POWER, HIGH); + pinMode(GPS_STD_POWER, OUTPUT); + digitalWrite(GPS_STD_POWER, HIGH); + pinMode(green_LED_PIN, OUTPUT); + pinMode(LED_BLUE, OUTPUT); + pinMode(PIN_POWER_USB, INPUT); + pinMode(PIN_POWER_DONE, INPUT); + pinMode(PIN_POWER_CHRG, INPUT); + pinMode(BUTTON_PIN, INPUT_PULLUP); + pinMode(EEPROM_POWER, OUTPUT); + digitalWrite(EEPROM_POWER, HIGH); + pinMode(PIN_EN1, OUTPUT); + digitalWrite(PIN_EN1, HIGH); + pinMode(PIN_EN2, OUTPUT); + digitalWrite(PIN_EN2, HIGH); + pinMode(ACC_POWER, OUTPUT); + digitalWrite(ACC_POWER, LOW); + pinMode(DHT_POWER, OUTPUT); + digitalWrite(DHT_POWER, HIGH); + pinMode(Battery_POWER, OUTPUT); + digitalWrite(Battery_POWER, HIGH); + pinMode(GPS_POWER, OUTPUT); + digitalWrite(GPS_POWER, HIGH); + +#endif #if defined(ELECROW_ThinkNode_M5) Wire.begin(48, 47); io.pinMode(PCA_PIN_EINK_EN, OUTPUT); diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index a9ec8f6a8..27ab9c782 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -64,7 +64,7 @@ SerialModule *serialModule; SerialModuleRadio *serialModuleRadio; #if defined(TTGO_T_ECHO) || defined(CANARYONE) || defined(MESHLINK) || defined(ELECROW_ThinkNode_M1) || \ - defined(ELECROW_ThinkNode_M5) || defined(HELTEC_MESH_SOLAR) || defined(T_ECHO_LITE) + defined(ELECROW_ThinkNode_M5) || defined(HELTEC_MESH_SOLAR) || defined(T_ECHO_LITE) || defined(ELECROW_ThinkNode_M3) SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("Serial") {} static Print *serialPrint = &Serial; #elif defined(CONFIG_IDF_TARGET_ESP32C6) || defined(RAK3172) || defined(EBYTE_E77_MBL) @@ -195,7 +195,7 @@ int32_t SerialModule::runOnce() Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); } #elif !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(MESHLINK) && \ - !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5) + !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { #ifdef ARCH_RP2040 Serial2.setFIFOSize(RX_BUFFER); @@ -252,7 +252,7 @@ int32_t SerialModule::runOnce() } #if !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(MESHLINK) && \ - !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5) + !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) else if ((moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85)) { processWXSerial(); @@ -527,7 +527,8 @@ ParsedLine parseLine(const char *line) void SerialModule::processWXSerial() { #if !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) && \ - !defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5) && !defined(ARCH_STM32WL) + !defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) && \ + !defined(ARCH_STM32WL) static unsigned int lastAveraged = 0; static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded. static double dir_sum_sin = 0; diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h index cee0e5a10..00c62d667 100644 --- a/src/platform/nrf52/architecture.h +++ b/src/platform/nrf52/architecture.h @@ -126,7 +126,9 @@ #endif +#ifdef PIN_LED1 #define LED_PIN PIN_LED1 // LED1 on nrf52840-DK +#endif #ifdef PIN_BUTTON1 #define BUTTON_PIN PIN_BUTTON1 diff --git a/src/platform/nrf52/main-nrf52.cpp b/src/platform/nrf52/main-nrf52.cpp index 8ce74d5f7..4376f2534 100644 --- a/src/platform/nrf52/main-nrf52.cpp +++ b/src/platform/nrf52/main-nrf52.cpp @@ -352,7 +352,67 @@ void cpuDeepSleep(uint32_t msecToWake) NRF_GPIO->DIRCLR = (1 << pin); } #endif +#ifdef ELECROW_ThinkNode_M3 + digitalWrite(red_LED_PIN, HIGH); + digitalWrite(green_LED_PIN, HIGH); + digitalWrite(LED_BLUE, HIGH); + digitalWrite(PIN_EN1, LOW); + digitalWrite(PIN_EN2, LOW); + digitalWrite(EEPROM_POWER, LOW); + digitalWrite(KEY_POWER, LOW); + digitalWrite(GPS_STD_POWER, LOW); + digitalWrite(DHT_POWER, LOW); + digitalWrite(ACC_POWER, LOW); + digitalWrite(Battery_POWER, LOW); + digitalWrite(GPS_POWER, LOW); + for (int pin = 0; pin < 48; pin++) { + if (pin == PIN_POWER_USB || pin == BUTTON_PIN || pin == PIN_EN1 || pin == PIN_EN2 || pin == GPS_STD_POWER || + pin == DHT_POWER || pin == ACC_POWER || pin == Battery_POWER || pin == GPS_POWER || pin == LR1110_SPI_MISO_PIN || + pin == LR1110_SPI_MOSI_PIN || pin == LR1110_SPI_SCK_PIN || pin == LR1110_SPI_NSS_PIN || pin == LR1110_BUSY_PIN || + pin == LR1110_NRESET_PIN || pin == LR1110_IRQ_PIN || pin == GPS_TX_PIN || pin == GPS_RX_PIN || pin == green_LED_PIN || + pin == red_LED_PIN || pin == LED_BLUE) { + continue; + } + pinMode(pin, OUTPUT); + } + for (int pin = 0; pin < 48; pin++) { + if (pin == PIN_POWER_USB || pin == BUTTON_PIN || pin == PIN_EN1 || pin == PIN_EN2 || pin == GPS_STD_POWER || + pin == DHT_POWER || pin == ACC_POWER || pin == Battery_POWER || pin == GPS_POWER || pin == LR1110_SPI_MISO_PIN || + pin == LR1110_SPI_MOSI_PIN || pin == LR1110_SPI_SCK_PIN || pin == LR1110_SPI_NSS_PIN || pin == LR1110_BUSY_PIN || + pin == LR1110_NRESET_PIN || pin == LR1110_IRQ_PIN || pin == GPS_TX_PIN || pin == GPS_RX_PIN || pin == green_LED_PIN || + pin == red_LED_PIN || pin == LED_BLUE) { + continue; + } + digitalWrite(pin, LOW); + } + for (int pin = 0; pin < 48; pin++) { + if (pin == PIN_POWER_USB || pin == BUTTON_PIN || pin == PIN_EN1 || pin == PIN_EN2 || pin == GPS_STD_POWER || + pin == DHT_POWER || pin == ACC_POWER || pin == Battery_POWER || pin == GPS_POWER || pin == LR1110_SPI_MISO_PIN || + pin == LR1110_SPI_MOSI_PIN || pin == LR1110_SPI_SCK_PIN || pin == LR1110_SPI_NSS_PIN || pin == LR1110_BUSY_PIN || + pin == LR1110_NRESET_PIN || pin == LR1110_IRQ_PIN || pin == GPS_TX_PIN || pin == GPS_RX_PIN || pin == green_LED_PIN || + pin == red_LED_PIN || pin == LED_BLUE) { + continue; + } + NRF_GPIO->DIRCLR = (1 << pin); + } + + if (digitalRead(PIN_POWER_USB)) { + delay(25); + if (digitalRead(PIN_POWER_USB)) { + NVIC_SystemReset(); + } + } + + nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); // Configure the pin to be woken up as an input + nrf_gpio_pin_sense_t sense1 = NRF_GPIO_PIN_SENSE_LOW; + nrf_gpio_cfg_sense_set(BUTTON_PIN, sense1); + + nrf_gpio_cfg_input(PIN_POWER_USB, NRF_GPIO_PIN_PULLDOWN); // Configure the pin to be woken up as an input + nrf_gpio_pin_sense_t sense2 = NRF_GPIO_PIN_SENSE_HIGH; + nrf_gpio_cfg_sense_set(PIN_POWER_USB, sense2); + +#endif // Sleepy trackers or sensors can low power "sleep" // Don't enter this if we're sleeping portMAX_DELAY, since that's a shutdown event if (msecToWake != portMAX_DELAY && diff --git a/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini b/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini new file mode 100644 index 000000000..348940d3c --- /dev/null +++ b/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini @@ -0,0 +1,16 @@ +[env:thinknode_m3] +extends = nrf52840_base +board = ThinkNode-M3 +board_check = true +debug_tool = jlink +build_flags = + ${nrf52840_base.build_flags} + -Ivariants/nrf52840/ELECROW-ThinkNode-M3 + -DELECROW_ThinkNode_M3 + -DGPS_POWER_TOGGLE + -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/ELECROW-ThinkNode-M3> +lib_deps = + ${nrf52840_base.lib_deps} + khoih-prog/nRF52_PWM@^1.0.1 + lewisxhe/PCF8563_Library@^1.0.1 diff --git a/variants/nrf52840/ELECROW-ThinkNode-M3/rfswitch.h b/variants/nrf52840/ELECROW-ThinkNode-M3/rfswitch.h new file mode 100644 index 000000000..cda6364f5 --- /dev/null +++ b/variants/nrf52840/ELECROW-ThinkNode-M3/rfswitch.h @@ -0,0 +1,15 @@ +#include "RadioLib.h" +#include "nrf.h" + +// set RF switch configuration for Wio WM1110 +// Wio WM1110 uses DIO5 and DIO6 for RF switching + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, +}; diff --git a/variants/nrf52840/ELECROW-ThinkNode-M3/variant.cpp b/variants/nrf52840/ELECROW-ThinkNode-M3/variant.cpp new file mode 100644 index 000000000..0b74c1bfc --- /dev/null +++ b/variants/nrf52840/ELECROW-ThinkNode-M3/variant.cpp @@ -0,0 +1,31 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018, Adafruit Industries (adafruit.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" +#include "nrf.h" +#include "wiring_constants.h" +#include "wiring_digital.h" + +const uint32_t g_ADigitalPinMap[] = { + // P0 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + + // P1 + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; diff --git a/variants/nrf52840/ELECROW-ThinkNode-M3/variant.h b/variants/nrf52840/ELECROW-ThinkNode-M3/variant.h new file mode 100644 index 000000000..cb1bac991 --- /dev/null +++ b/variants/nrf52840/ELECROW-ThinkNode-M3/variant.h @@ -0,0 +1,117 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018, Adafruit Industries (adafruit.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_ELECROW_EINK_V1_0_ +#define _VARIANT_ELECROW_EINK_V1_0_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include "WVariant.h" + +#define VARIANT_MCK (64000000ul) +#define USE_LFXO // Board uses 32khz crystal for LF + +#define ELECROW_ThinkNode_M3 1 +// Number of pins defined in PinDescription array +#define PINS_COUNT (48) +#define NUM_DIGITAL_PINS (48) +#define NUM_ANALOG_INPUTS (1) +#define NUM_ANALOG_OUTPUTS (0) + +// Power Pin +#define NRF_APM +#define GPS_STD_POWER 6 +#define GPS_POWER 14 +#define PIN_POWER_USB 31 +// #define PIN_POWER_USB 29 +#define PIN_POWER_DONE 24 +#define PIN_POWER_CHRG 32 +#define KEY_POWER 16 +#define ACC_POWER 2 +#define DHT_POWER 3 +#define Battery_POWER 17 +#define RGB_POWER 29 +#define EEPROM_POWER 7 +// LED +#define red_LED_PIN 33 +#define LED_POWER red_LED_PIN +#define green_LED_PIN 35 +#define LED_BLUE 37 + +#define LED_BUILTIN green_LED_PIN +#define LED_STATE_ON LOW +#define LED_STATE_OFF HIGH +#define BLE_LED LED_BLUE +#define BLE_LED_INVERTED +// BUZZER +#define PIN_BUZZER 23 +#define PIN_EN1 36 +#define PIN_EN2 34 +/*Wire Interfaces*/ +#define WIRE_INTERFACES_COUNT 1 +#define PIN_WIRE_SDA 26 +#define PIN_WIRE_SCL 27 +/*GPS pins*/ +#define HAS_GPS 1 +#define GPS_BAUDRATE 9600 +#define PIN_GPS_RESET 25 +#define PIN_GPS_STANDBY 21 +#define GPS_TX_PIN 20 +#define GPS_RX_PIN 22 +#define GPS_THREAD_INTERVAL 50 +#define PIN_SERIAL1_RX GPS_TX_PIN +#define PIN_SERIAL1_TX GPS_RX_PIN +// Button +#define BUTTON_PIN 12 +#define BUTTON_PIN_ALT (0 + 12) +// Battery +#define BATTERY_PIN 5 +#define BATTERY_SENSE_RESOLUTION_BITS 12 +#define BATTERY_SENSE_RESOLUTION 4096.0 +#undef AREF_VOLTAGE +#define AREF_VOLTAGE 2.4 +#define VBAT_AR_INTERNAL AR_INTERNAL_2_4 +#define ADC_MULTIPLIER (1.75) +/*SPI Interfaces*/ +#define SPI_INTERFACES_COUNT 1 +#define PIN_SPI_MISO (32 + 15) // P1.15 47 +#define PIN_SPI_MOSI (32 + 14) // P1.14 46 +#define PIN_SPI_SCK (32 + 13) // P1.13 45 +#define PIN_SPI_NSS (32 + 12) // P1.12 44 +/*LORA Interfaces*/ +#define USE_LR1110 +#define LR1110_IRQ_PIN 40 +#define LR1110_NRESET_PIN 42 +#define LR1110_BUSY_PIN 43 +#define LR1110_SPI_NSS_PIN 44 +#define LR1110_SPI_SCK_PIN 45 +#define LR1110_SPI_MOSI_PIN 46 +#define LR1110_SPI_MISO_PIN 47 +#define LR11X0_DIO3_TCXO_VOLTAGE 3.3 +#define LR11X0_DIO_AS_RF_SWITCH + +// PCF8563 RTC Module +#define PCF8563_RTC 0x51 + +#ifdef __cplusplus +} +#endif + +#endif