diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 71d37bc2e..8f938ce9e 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -12,7 +12,7 @@ lint: - trufflehog@3.88.18 - yamllint@1.37.0 - bandit@1.8.3 - - checkov@3.2.392 + - checkov@3.2.394 - terrascan@1.19.9 - trivy@0.60.0 - taplo@0.9.3 diff --git a/protobufs b/protobufs index b4044f8f9..14ec20586 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit b4044f8f9f3681d4d20521dbe13ee42c96eae353 +Subproject commit 14ec205865592fcfa798065bb001a549fc77b438 diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp index 12f81353c..2363f804c 100644 --- a/src/ButtonThread.cpp +++ b/src/ButtonThread.cpp @@ -73,23 +73,28 @@ ButtonThread::ButtonThread() : OSThread("Button") userButton.setDebounceMs(1); userButton.attachDoubleClick(userButtonDoublePressed); userButton.attachMultiClick(userButtonMultiPressed, this); // Reference to instance: get click count from non-static OneButton -#ifndef T_DECK // T-Deck immediately wakes up after shutdown, so disable this function +#if !defined(T_DECK) && \ + !defined( \ + ELECROW_ThinkNode_M2) // T-Deck immediately wakes up after shutdown, Thinknode M2 has this on the smaller ALT button userButton.attachLongPressStart(userButtonPressedLongStart); userButton.attachLongPressStop(userButtonPressedLongStop); #endif #endif #ifdef BUTTON_PIN_ALT - userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true); +#if defined(ELECROW_ThinkNode_M2) + this->userButtonAlt = OneButton(BUTTON_PIN_ALT, false, false); +#else + this->userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true); +#endif #ifdef INPUT_PULLUP_SENSE // Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE); #endif - userButtonAlt.attachClick(userButtonPressed); + userButtonAlt.attachClick(userButtonPressedScreen); userButtonAlt.setClickMs(BUTTON_CLICK_MS); userButtonAlt.setPressMs(BUTTON_LONGPRESS_MS); userButtonAlt.setDebounceMs(1); - userButtonAlt.attachDoubleClick(userButtonDoublePressed); userButtonAlt.attachLongPressStart(userButtonPressedLongStart); userButtonAlt.attachLongPressStop(userButtonPressedLongStop); #endif @@ -117,6 +122,40 @@ int32_t ButtonThread::runOnce() canSleep = true; // Assume we should not keep the board awake #if defined(BUTTON_PIN) || defined(USERPREFS_BUTTON_PIN) + // #if defined(ELECROW_ThinkNode_M1) || defined(ELECROW_ThinkNode_M2) + // buzzer_updata(); + // if (buttonPressed) { + // buttonPressed = false; // 清除标志 + // LOG_INFO("PIN_BUTTON2 pressed!"); // 串口打印信息 + // // off_currentTime = millis(); + // while (digitalRead(PIN_BUTTON2) == HIGH) { + // if (cont < 40) { + // // unsigned long currentTime = millis(); // 获取当前时间 + // // if (currentTime - off_currentTime >= 1000) { + // cont++; + // // off_currentTime = currentTime; + // // } + // delay(100); + // } else { + + // currentState = OFF; + // isBuzzing = false; + // cont = 0; + // BEEP_STATE = false; + // analogWrite(M2_buzzer, 0); + // pinMode(M2_buzzer, INPUT); + // screen->setOn(false); + // cont = 0; + // LOG_INFO("GGGGGGGGGGGGGGGGGGGGGGGGG"); + // pinMode(1, OUTPUT); + // digitalWrite(1, LOW); + // pinMode(6, OUTPUT); + // digitalWrite(6, LOW); + // } + // } + // } + + // #endif userButton.tick(); canSleep &= userButton.isIdle(); #elif defined(ARCH_PORTDUINO) @@ -166,6 +205,14 @@ int32_t ButtonThread::runOnce() break; } + case BUTTON_EVENT_PRESSED_SCREEN: { + // turn screen on or off + screen_flag = !screen_flag; + if (screen) + screen->setOn(screen_flag); + break; + } + case BUTTON_EVENT_DOUBLE_PRESSED: { LOG_BUTTON("Double press!"); service->refreshLocalMeshNode(); @@ -192,7 +239,16 @@ int32_t ButtonThread::runOnce() screen->forceDisplay(true); // Force a new UI frame, then force an EInk update } break; +#elif defined(ELECROW_ThinkNode_M2) + case 3: + LOG_INFO("3 clicks: toggle buzzer"); + buzzer_flag = !buzzer_flag; + if (buzzer_flag) { + playBeep(); + } + break; #endif + #if defined(USE_EINK) && defined(PIN_EINK_EN) // i.e. T-Echo // 4 clicks: toggle backlight case 4: diff --git a/src/ButtonThread.h b/src/ButtonThread.h index 54b833d03..a8f1f77c3 100644 --- a/src/ButtonThread.h +++ b/src/ButtonThread.h @@ -24,6 +24,7 @@ class ButtonThread : public concurrency::OSThread enum ButtonEventType { BUTTON_EVENT_NONE, BUTTON_EVENT_PRESSED, + BUTTON_EVENT_PRESSED_SCREEN, BUTTON_EVENT_DOUBLE_PRESSED, BUTTON_EVENT_MULTI_PRESSED, BUTTON_EVENT_LONG_PRESSED, @@ -42,7 +43,6 @@ class ButtonThread : public concurrency::OSThread int beforeLightSleep(void *unused); int afterLightSleep(esp_sleep_wakeup_cause_t cause); #endif - private: #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN) static OneButton userButton; // Static - accessed from an interrupt @@ -64,6 +64,8 @@ class ButtonThread : public concurrency::OSThread // set during IRQ static volatile ButtonEventType btnEvent; + bool buzzer_flag = false; + bool screen_flag = true; // Store click count during callback, for later use volatile int multipressClickCount = 0; @@ -72,6 +74,12 @@ class ButtonThread : public concurrency::OSThread // IRQ callbacks static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; } + static void userButtonPressedScreen() + { + if (millis() > c_holdOffTime) { + btnEvent = BUTTON_EVENT_PRESSED_SCREEN; + } + } static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; } static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid static void userButtonPressedLongStart(); diff --git a/src/Power.cpp b/src/Power.cpp index 20447ad63..ec3550869 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -713,7 +713,7 @@ void Power::readPowerStatus() const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isCharging, batteryVoltageMv, batteryChargePercent); LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent()); -#if defined(ELECROW_ThinkNode_M1) +#if defined(ELECROW_ThinkNode_M1) || defined(POWER_CFG) power_num = powerStatus2.getBatteryVoltageMv(); #endif newStatus.notifyObservers(&powerStatus2); @@ -759,6 +759,7 @@ void Power::readPowerStatus() // If we have a battery at all and it is less than 0%, force deep sleep if we have more than 10 low readings in // a row. NOTE: min LiIon/LiPo voltage is 2.0 to 2.5V, current OCV min is set to 3100 that is large enough. // + if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) { if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) { low_voltage_counter++; @@ -781,6 +782,9 @@ void Power::readPowerStatus() low_voltage_counter_led3 = low_voltage_counter; #endif } +#ifdef POWER_CFG + low_voltage_counter_led3 = low_voltage_counter; +#endif } } diff --git a/src/buzz/buzz.cpp b/src/buzz/buzz.cpp index 8db9602bc..6ba2f4140 100644 --- a/src/buzz/buzz.cpp +++ b/src/buzz/buzz.cpp @@ -30,8 +30,11 @@ struct ToneDuration { #define NOTE_B3 247 #define NOTE_CS4 277 -const int DURATION_1_8 = 125; // 1/8 note -const int DURATION_1_4 = 250; // 1/4 note +const int DURATION_1_8 = 125; // 1/8 note +const int DURATION_1_4 = 250; // 1/4 note +const int DURATION_1_2 = 500; // 1/2 note +const int DURATION_3_4 = 750; // 1/4 note +const int DURATION_1_1 = 1000; // 1/1 note void playTones(const ToneDuration *tone_durations, int size) { @@ -55,6 +58,12 @@ void playBeep() playTones(melody, sizeof(melody) / sizeof(ToneDuration)); } +void playLongBeep() +{ + ToneDuration melody[] = {{NOTE_B3, DURATION_1_1}}; + playTones(melody, sizeof(melody) / sizeof(ToneDuration)); +} + void playGPSEnableBeep() { ToneDuration melody[] = {{NOTE_C3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_CS4, DURATION_1_4}}; diff --git a/src/buzz/buzz.h b/src/buzz/buzz.h index c52c3020c..adeaca73d 100644 --- a/src/buzz/buzz.h +++ b/src/buzz/buzz.h @@ -1,6 +1,7 @@ #pragma once void playBeep(); +void playLongBeep(); void playStartMelody(); void playShutdownMelody(); void playGPSEnableBeep(); diff --git a/src/main.cpp b/src/main.cpp index 2e0470fa1..59cd6d8e9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -262,7 +262,12 @@ void printInfo() #ifndef PIO_UNIT_TESTING void setup() { -// power on peripherals + +#ifdef POWER_CHRG + pinMode(POWER_CHRG, OUTPUT); + digitalWrite(POWER_CHRG, HIGH); +#endif + #if defined(PIN_POWER_EN) pinMode(PIN_POWER_EN, OUTPUT); digitalWrite(PIN_POWER_EN, HIGH); diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 631df0fe4..0af6d4d04 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -144,6 +144,8 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62 #elif defined(EBYTE_ESP32_S3) #define HW_VENDOR meshtastic_HardwareModel_EBYTE_ESP32_S3 +#elif defined(ELECROW_ThinkNode_M2) +#define HW_VENDOR meshtastic_HardwareModel_THINKNODE_M2 #elif defined(ESP32_S3_PICO) #define HW_VENDOR meshtastic_HardwareModel_ESP32_S3_PICO #elif defined(SENSELORA_S3) diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index d0fe31f21..ab1e5c922 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -109,6 +109,11 @@ void esp32Setup() randomSeed(seed); */ +#ifdef POWER_FULL + pinMode(POWER_FULL, INPUT); + pinMode(7, INPUT); +#endif + LOG_DEBUG("Total heap: %d", ESP.getHeapSize()); LOG_DEBUG("Free heap: %d", ESP.getFreeHeap()); LOG_DEBUG("Total PSRAM: %d", ESP.getPsramSize()); diff --git a/src/power.h b/src/power.h index 78caa8a7d..97944fef7 100644 --- a/src/power.h +++ b/src/power.h @@ -84,7 +84,7 @@ class Power : private concurrency::OSThread void setStatusHandler(meshtastic::PowerStatus *handler) { statusHandler = handler; } const uint16_t OCV[11] = {OCV_ARRAY}; -#if defined(ELECROW_ThinkNode_M1) +#if defined(ELECROW_ThinkNode_M1) || defined(POWER_CFG) uint8_t low_voltage_counter_led3; int power_num = 0; #endif diff --git a/variants/ELECROW-ThinkNode-M2/pins_arduino.h b/variants/ELECROW-ThinkNode-M2/pins_arduino.h new file mode 100644 index 000000000..46415d30f --- /dev/null +++ b/variants/ELECROW-ThinkNode-M2/pins_arduino.h @@ -0,0 +1,28 @@ +// Need this file for ESP32-S3 +// No need to modify this file, changes to pins imported from variant.h +// Most is similar to https://github.com/espressif/arduino-esp32/blob/master/variants/esp32s3/pins_arduino.h + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include +#include + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +// Serial +static const uint8_t TX = UART_TX; +static const uint8_t RX = UART_RX; + +// Default SPI will be mapped to Radio +static const uint8_t SS = LORA_CS; +static const uint8_t SCK = LORA_SCK; +static const uint8_t MOSI = LORA_MOSI; +static const uint8_t MISO = LORA_MISO; + +// The default Wire will be mapped to PMU and RTC +static const uint8_t SCL = I2C_SCL; +static const uint8_t SDA = I2C_SDA; + +#endif /* Pins_Arduino_h */ diff --git a/variants/ELECROW-ThinkNode-M2/platformio.ini b/variants/ELECROW-ThinkNode-M2/platformio.ini new file mode 100644 index 000000000..c08c94a71 --- /dev/null +++ b/variants/ELECROW-ThinkNode-M2/platformio.ini @@ -0,0 +1,7 @@ +[env:thinknode_m2] +extends = esp32s3_base +board = ESP32-S3-WROOM-1-N4 +build_flags = + ${esp32s3_base.build_flags} + -D ELECROW_ThinkNode_M2 + -I variants/ELECROW-ThinkNode-M2 diff --git a/variants/ELECROW-ThinkNode-M2/variant.h b/variants/ELECROW-ThinkNode-M2/variant.h new file mode 100644 index 000000000..801d5606f --- /dev/null +++ b/variants/ELECROW-ThinkNode-M2/variant.h @@ -0,0 +1,64 @@ +// Status +#define LED_PIN_POWER 1 +#define BIAS_T_ENABLE LED_PIN_POWER +#define BIAS_T_VALUE HIGH + +#define PIN_BUTTON1 47 // 功能键 +#define PIN_BUTTON2 4 // 电源键 + +#define POWER_CFG +#define POWER_CHRG 6 +#define POWER_FULL 42 + +#define PIN_BUZZER 5 + +#define I2C_SCL 15 +#define I2C_SDA 16 + +#define UART_TX 43 +#define UART_RX 44 + +#define VEXT_ENABLE 46 // for OLED +#define VEXT_ON_VALUE HIGH + +#define SX126X_CS 10 +#define LORA_SCK 12 +#define LORA_MOSI 11 +#define LORA_MISO 13 +#define SX126X_RESET 21 +#define SX126X_BUSY 14 +#define SX126X_DIO1 3 +#define SX126X_DIO2_AS_RF_SWITCH +// #define SX126X_DIO3 9 +#define SX126X_DIO3_TCXO_VOLTAGE 3.3 + +#define SX126X_MAX_POWER 22 // SX126xInterface.cpp defaults to 22 if not defined, but here we define it for good practice +#define USE_SX1262 +#define LORA_CS SX126X_CS // FIXME: for some reason both are used in /src +#define LORA_DIO1 SX126X_DIO1 +#define SX126X_POWER_EN 48 + +// Battery +// #define BATTERY_PIN 2 +#define BATTERY_PIN 17 +// #define ADC_CHANNEL ADC1_GPIO2_CHANNEL +#define ADC_CHANNEL ADC2_GPIO17_CHANNEL +#define BATTERY_SENSE_RESOLUTION_BITS 12 +#define BATTERY_SENSE_RESOLUTION 4096.0 +#undef AREF_VOLTAGE +#define AREF_VOLTAGE 3.0 +#define VBAT_AR_INTERNAL AR_INTERNAL_3_0 +#define ADC_MULTIPLIER (1.548F) +#define BAT_MEASURE_ADC_UNIT 2 + +#define HAS_SCREEN 1 +#define USE_SH1106 1 + +// PCF8563 RTC Module +// #define PCF8563_RTC 0x51 +// #define PIN_RTC_INT 48 // Interrupt from the PCF8563 RTC +#define HAS_RTC 0 +#define HAS_GPS 0 + +#define BUTTON_PIN PIN_BUTTON1 +#define BUTTON_PIN_ALT PIN_BUTTON2