From cdafa87cefac890ae2398885cc9052b6aaa0e4d7 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 28 Aug 2024 09:51:00 -0700 Subject: [PATCH] add lateInitVariant() as a concept. see below for docs (from src/extra_variants/README.md) This directory tree is designed to solve two problems. - The ESP32 arduino/platformio project doesn't support the nice "if initVariant() is found, call that after init" behavior of the nrf52 builds (they use initVariant() internally). - Over the years a lot of 'board specific' init code has been added to init() in main.cpp. It would be great to have a general/clean mechanism to allow developers to specify board specific/unique code in a clean fashion without mucking in main. So we are borrowing the initVariant() ideas here (by using weak gcc references). You can now define lateInitVariant() if your board needs it. If you'd like a board specific variant to be run, add the variant.cpp file to an appropriately named subdirectory and check for \_VARIANT_boardname in the cpp file (so that your code is only built for your board). You'll need to define \_VARIANT_boardname in your corresponding variant.h file. See existing boards for examples. This approach has no added runtime cost. --- src/main.cpp | 7 ++++ src/platform/extra_variants/README.md | 15 ++++++++ .../heltec_wireless_tracker/variant.cpp | 34 +++++++++++++++++++ variants/heltec_wireless_tracker/variant.h | 4 ++- 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/platform/extra_variants/README.md create mode 100644 src/platform/extra_variants/heltec_wireless_tracker/variant.cpp diff --git a/src/main.cpp b/src/main.cpp index 7520667dd6..8f64960bba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -224,6 +224,11 @@ __attribute__((weak, noinline)) bool loopCanSleep() return true; } +// Weak empty variant initialization function. +// May be redefined by variant files. +void lateInitVariant() __attribute__((weak)); +void lateInitVariant() {} + /** * Print info as a structured log message (for automated log processing) */ @@ -1003,6 +1008,8 @@ void setup() } } + lateInitVariant(); // Do board specific init (see extra_variants/README.md for documentation) + #if !MESHTASTIC_EXCLUDE_MQTT mqttInit(); #endif diff --git a/src/platform/extra_variants/README.md b/src/platform/extra_variants/README.md new file mode 100644 index 0000000000..e558502f09 --- /dev/null +++ b/src/platform/extra_variants/README.md @@ -0,0 +1,15 @@ +# About extra_variants + +This directory tree is designed to solve two problems. + +- The ESP32 arduino/platformio project doesn't support the nice "if initVariant() is found, call that after init" behavior of the nrf52 builds (they use initVariant() internally). +- Over the years a lot of 'board specific' init code has been added to init() in main.cpp. It would be great to have a general/clean mechanism to allow developers to specify board specific/unique code in a clean fashion without mucking in main. + +So we are borrowing the initVariant() ideas here (by using weak gcc references). You can now define lateInitVariant() if your board needs it. + +If you'd like a board specific variant to be run, add the variant.cpp file to an appropriately named +subdirectory and check for \_VARIANT_boardname in the cpp file (so that your code is only built for your board). +You'll need to define \_VARIANT_boardname in your corresponding variant.h file. +See existing boards for examples. + +This approach has no added runtime cost. diff --git a/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp b/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp new file mode 100644 index 0000000000..84264ef587 --- /dev/null +++ b/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp @@ -0,0 +1,34 @@ +#include "configuration.h" + +#ifdef _VARIANT_HELTEC_WIRELESS_TRACKER + +#include "GPS.h" +#include "GpioLogic.h" +#include "graphics/TFTDisplay.h" + +// Heltec tracker specific init +void lateInitVariant() +{ + // LOG_DEBUG("Heltec tracker initVariant\n"); +#ifdef VEXT_ENABLE + GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE); + GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin(); + + // On this board we are actually using the backlightEnable signal to already be controlling a physical enable to the + // display controller. But we'd _ALSO_ like to have that signal drive a virtual GPIO. So nest it as needed. + GpioVirtPin *virtScreenEnable = new GpioVirtPin(); + if (TFTDisplay::backlightEnable) { + GpioPin *physScreenEnable = TFTDisplay::backlightEnable; + GpioPin *splitter = new GpioSplitter(virtScreenEnable, physScreenEnable); + TFTDisplay::backlightEnable = splitter; + + // Assume screen is initially powered + splitter->set(true); + } + + // If either the GPS or the screen is on, turn on the external power regulator + new GpioBinaryTransformer(virtGpsEnable, virtScreenEnable, hwEnable, GpioBinaryTransformer::Or); +#endif +} + +#endif \ No newline at end of file diff --git a/variants/heltec_wireless_tracker/variant.h b/variants/heltec_wireless_tracker/variant.h index 46e922eb59..79fa0e8010 100644 --- a/variants/heltec_wireless_tracker/variant.h +++ b/variants/heltec_wireless_tracker/variant.h @@ -1,5 +1,6 @@ #define LED_PIN 18 +#define _VARIANT_HELTEC_WIRELESS_TRACKER #define HELTEC_TRACKER_V1_X // I2C @@ -31,7 +32,8 @@ // GPS UC6580: GPS V_DET(8), VDD_IO(7), DCDC_IN(21), pulls up RESETN(17), D_SEL(33) and BOOT_MODE(34) through 10kR // GPS LNA SW7125DE: VCC(4), pulls up SHDN(5) through 10kR // LED: VDD, LEDA (through diode) -#define VEXT_ENABLE 3 // active HIGH - powers the GPS, GPS LNA and OLED VDD/anode + +#define VEXT_ENABLE 3 // active HIGH - powers the GPS, GPS LNA and OLED #define VEXT_ON_VALUE HIGH #define BUTTON_PIN 0