diff --git a/platformio.ini b/platformio.ini index ea4de4db12..d97c904672 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,6 +24,7 @@ build_flags = -Wno-missing-field-initializers -DUSE_THREAD_NAMES -DTINYGPS_OPTION_NO_CUSTOM_FIELDS -DPB_ENABLE_MALLOC=1 + -DRADIOLIB_LOW_LEVEL=1 -DRADIOLIB_EXCLUDE_CC1101=1 -DRADIOLIB_EXCLUDE_NRF24=1 -DRADIOLIB_EXCLUDE_RF69=1 diff --git a/src/main.cpp b/src/main.cpp index 24fc717493..ba84513f22 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -168,6 +168,8 @@ bool pauseBluetoothLogging = false; bool pmu_found; +uint8_t pa_fan_percentage = 50; + #if !MESHTASTIC_EXCLUDE_I2C // Array map of sensor types with i2c address and wire as we'll find in the i2c scan std::pair nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {}; @@ -1072,16 +1074,36 @@ void setup() mqttInit(); #endif -#ifdef RF95_FAN_EN - // Ability to disable FAN if PIN has been set with RF95_FAN_EN. +#ifdef RADIO_FAN_EN + // Ability to disable FAN if PIN has been set with RADIO_FAN_EN. // Make sure LoRa has been started before disabling FAN. - if (config.lora.pa_fan_disabled) - digitalWrite(RF95_FAN_EN, LOW ^ 0); +#ifdef RADIO_FAN_PWM +#if defined(ARCH_ESP32) + // Set up PWM at Channel 1 at 25KHz, using 8-bit resolution + // Turn ON/OFF fan to the specified value if enabled by config. + // code by https://github.com/gjelsoe/ + if (ledcSetup(1, 25000, 8)) { + ledcAttachPin(RADIO_FAN_EN, 1); + LOG_INFO("PWM init C1 P%d\n", RADIO_FAN_EN); + // Set PWM duty cycle based on fan disabled state + ledcWrite(1, config.lora.pa_fan_disabled ? 0 : (pa_fan_percentage * 2.55)); + } else { + LOG_WARN("PWM init fail P%d\n", RADIO_FAN_EN); + } +#elif defined(ARCH_NRF52) + pinMode(RADIO_FAN_EN, OUTPUT); + analogWrite(RADIO_FAN_EN, config.lora.pa_fan_disabled ? 0 : (pa_fan_percentage * 2.55)); +#endif +#else + // Set up as ON/OFF switch of fan + pinMode(RADIO_FAN_EN, OUTPUT); + digitalWrite(RADIO_FAN_EN, LOW ^ 0); +#endif #endif #ifndef ARCH_PORTDUINO - // Initialize Wifi + // Initialize Wifi #if HAS_WIFI initWifi(); #endif diff --git a/src/main.h b/src/main.h index b3f58ae4b3..252f0e3eec 100644 --- a/src/main.h +++ b/src/main.h @@ -71,6 +71,8 @@ extern uint32_t shutdownAtMsec; extern uint32_t serialSinceMsec; +extern uint8_t pa_fan_percentage; + // If a thread does something that might need for it to be rescheduled ASAP it can set this flag // This will suppress the current delay and instead try to run ASAP. extern bool runASAP; diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index ce4f912ba6..ebde410170 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -3,6 +3,7 @@ #include "Throttle.h" #include "configuration.h" #include "error.h" +#include "main.h" #include "mesh/NodeDB.h" #ifdef LR11X0_DIO_AS_RF_SWITCH #include "rfswitch.h" @@ -48,6 +49,8 @@ template bool LR11x0Interface::init() digitalWrite(LR11X0_POWER_EN, HIGH); #endif + enableFan(); + #if ARCH_PORTDUINO float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000; // FIXME: correct logic to default to not using TCXO if no voltage is specified for LR11x0_DIO3_TCXO_VOLTAGE @@ -277,6 +280,19 @@ template bool LR11x0Interface::isActivelyReceiving() RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED); } +template void LR11x0Interface::regulateFan() +{ + float pa_temp = 0; + lora.getTemp(&pa_temp); + if (pa_temp > 40) { + pa_fan_percentage = max(pa_fan_percentage + 1, 100); + enableFan(); + } else { + pa_fan_percentage = max(pa_fan_percentage - 1, 100); + enableFan(); + } +} + template bool LR11x0Interface::sleep() { // \todo Display actual typename of the adapter, not just `LR11x0` diff --git a/src/mesh/LR11x0Interface.h b/src/mesh/LR11x0Interface.h index 4829ddc1df..355acf7f67 100644 --- a/src/mesh/LR11x0Interface.h +++ b/src/mesh/LR11x0Interface.h @@ -65,5 +65,7 @@ template class LR11x0Interface : public RadioLibInterface virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override; virtual void setStandby() override; + + void regulateFan(); }; #endif \ No newline at end of file diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index d4d9ad23c6..433bcc9323 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -154,10 +154,7 @@ bool RF95Interface::init() digitalWrite(RF95_TXEN, 0); #endif -#ifdef RF95_FAN_EN - pinMode(RF95_FAN_EN, OUTPUT); - digitalWrite(RF95_FAN_EN, 1); -#endif + enableFan(); #ifdef RF95_RXEN pinMode(RF95_RXEN, OUTPUT); @@ -330,10 +327,7 @@ bool RF95Interface::sleep() // put chipset into sleep mode setStandby(); // First cancel any active receiving/sending lora->sleep(); - -#ifdef RF95_FAN_EN - digitalWrite(RF95_FAN_EN, 0); -#endif + disableFan(); return true; } diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index e31f0b3e2d..3eae23d27a 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -511,4 +511,37 @@ bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp) return res == RADIOLIB_ERR_NONE; } +} + +void RadioLibInterface::enableFan() +{ +#ifdef RADIO_FAN_EN + +#ifdef RADIO_FAN_PWM +#if defined(ARCH_ESP32) + ledcWrite(1, config.lora.pa_fan_disabled ? 0 : (pa_fan_percentage * 2.55)); +#elif defined(ARCH_NRF52) + analogWrite(RADIO_FAN_EN, config.lora.pa_fan_disabled ? 0 : (pa_fan_percentage * 2.55)); +#endif +#else + pinMode(RADIO_FAN_EN, OUTPUT); + digitalWrite(RADIO_FAN_EN, 1); +#endif +#endif +} + +void RadioLibInterface::disableFan() +{ +#ifdef RADIO_FAN_EN +#ifdef RADIO_FAN_PWM +#if defined(ARCH_ESP32) + ledcWrite(1, 0); +#elif defined(ARCH_NRF52) + analogWrite(RADIO_FAN_EN, 0); +#endif +#else + pinMode(RADIO_FAN_EN, OUTPUT); + digitalWrite(RADIO_FAN_EN, 0); +#endif +#endif } \ No newline at end of file diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index dff58c9add..877cc761ad 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -135,6 +135,9 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified /** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */ virtual bool cancelSending(NodeNum from, PacketId id) override; + void enableFan(); + void disableFan(); + private: /** if we have something waiting to send, start a short (random) timer so we can come check for collision before actually * doing the transmit */ diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 8a7bc76708..45f65440c3 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -49,6 +49,8 @@ template bool SX126xInterface::init() pinMode(SX126X_POWER_EN, OUTPUT); #endif + enableFan(); + #if ARCH_PORTDUINO float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000; if (settingsMap[sx126x_ant_sw_pin] != RADIOLIB_NC) { diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp index ee34084569..b9921fc879 100644 --- a/src/mesh/SX128xInterface.cpp +++ b/src/mesh/SX128xInterface.cpp @@ -32,10 +32,7 @@ template bool SX128xInterface::init() digitalWrite(SX128X_POWER_EN, HIGH); #endif -#ifdef RF95_FAN_EN - pinMode(RF95_FAN_EN, OUTPUT); - digitalWrite(RF95_FAN_EN, 1); -#endif + enableFan(); #if ARCH_PORTDUINO if (settingsMap[rxen_pin] != RADIOLIB_NC) { diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 7906b410bc..ea03de8e79 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -588,13 +588,21 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) requiresReboot = false; } -#ifdef RF95_FAN_EN +#ifdef RADIO_FAN_EN +#ifdef RADIO_FAN_PWM +#if defined(ARCH_ESP32) + ledcWrite(1, c.payload_variant.lora.pa_fan_disabled ? 0 : (pa_fan_percentage * 2.55)); +#elif defined(ARCH_NFR52) + analogWrite(RADIO_FAN_EN, c.payload_variant.lora.pa_fan_disabled ? 0 : (pa_fan_percentage * 2.55)); +#endif +#else // Turn PA off if disabled by config if (c.payload_variant.lora.pa_fan_disabled) { - digitalWrite(RF95_FAN_EN, LOW ^ 0); + digitalWrite(RADIO_FAN_EN, LOW ^ 0); } else { - digitalWrite(RF95_FAN_EN, HIGH ^ 0); + digitalWrite(RADIO_FAN_EN, HIGH ^ 0); } +#endif #endif config.lora = c.payload_variant.lora; // If we're setting region for the first time, init the region diff --git a/variants/betafpv_2400_tx_micro/variant.h b/variants/betafpv_2400_tx_micro/variant.h index 67699e7c87..9e3503bd59 100644 --- a/variants/betafpv_2400_tx_micro/variant.h +++ b/variants/betafpv_2400_tx_micro/variant.h @@ -12,7 +12,7 @@ #define LORA_MISO 19 #define LORA_MOSI 23 #define LORA_CS 5 -#define RF95_FAN_EN 17 +#define RADIO_FAN_EN 17 // #define LED_PIN 16 // This is a LED_WS2812 not a standard LED #define HAS_NEOPIXEL // Enable the use of neopixels diff --git a/variants/radiomaster_900_bandit/variant.h b/variants/radiomaster_900_bandit/variant.h index 0c7417cacd..a84a1ca4ad 100644 --- a/variants/radiomaster_900_bandit/variant.h +++ b/variants/radiomaster_900_bandit/variant.h @@ -46,7 +46,8 @@ FAN is active at 250mW on it's ExpressLRS Firmware. This FAN has TACHO signal on Pin 27 for use with PWM. */ -#define RF95_FAN_EN 2 +#define RADIO_FAN_EN 2 +#define RADIO_FAN_PWM /* LED PIN setup and it has a NeoPixel LED. diff --git a/variants/radiomaster_900_bandit_nano/variant.h b/variants/radiomaster_900_bandit_nano/variant.h index 1b6bba126e..d960dd9eff 100644 --- a/variants/radiomaster_900_bandit_nano/variant.h +++ b/variants/radiomaster_900_bandit_nano/variant.h @@ -32,7 +32,7 @@ This unit has a FAN built-in. FAN is active at 250mW on it's ExpressLRS Firmware. */ -#define RF95_FAN_EN 2 +#define RADIO_FAN_EN 2 /* LED PIN setup. diff --git a/variants/radiomaster_nomad_gemini/platformio.ini b/variants/radiomaster_nomad_gemini/platformio.ini new file mode 100644 index 0000000000..96ea42e504 --- /dev/null +++ b/variants/radiomaster_nomad_gemini/platformio.ini @@ -0,0 +1,20 @@ +[env:radiomaster_nomad_gemini] +extends = esp32_base +board = esp32doit-devkit-v1 +build_flags = + ${esp32_base.build_flags} + -DRADIOMASTER_NOMAD_GEMINI + -DPRIVATE_HW + -DVTABLES_IN_FLASH=1 + -DCONFIG_DISABLE_HAL_LOCKS=1 + -O2 + -Ivariants/radiomaster_nomad_gemini + -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR=1 + -DMESHTASTIC_EXCLUDE_I2C=1 + -DRADIOLIB_EXCLUDE_SX128X=1 + -DRADIOLIB_EXCLUDE_SX127X=1 + -DRADIOLIB_EXCLUDE_SX126X=1 +board_build.f_cpu = 240000000L +upload_protocol = esptool +lib_deps = + ${esp32_base.lib_deps} diff --git a/variants/radiomaster_nomad_gemini/rfswitch.h b/variants/radiomaster_nomad_gemini/rfswitch.h new file mode 100644 index 0000000000..a84f62fdeb --- /dev/null +++ b/variants/radiomaster_nomad_gemini/rfswitch.h @@ -0,0 +1,21 @@ +#include "RadioLib.h" + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, + RADIOLIB_LR11X0_DIO8, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 DIO7 DIO8 + {LR11x0::MODE_STBY, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_RX, {LOW, LOW, HIGH, LOW}}, + {LR11x0::MODE_TX, {LOW, LOW, LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, LOW, LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, HIGH, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW, LOW, LOW}}, END_OF_MODE_TABLE, +}; + +/* + +DIO5: RXEN 2.4GHz +DIO6: TXEN 2.4GHz +DIO7: RXEN 900MHz +DIO8: TXEN 900MHz + +*/ \ No newline at end of file diff --git a/variants/radiomaster_nomad_gemini/variant.h b/variants/radiomaster_nomad_gemini/variant.h new file mode 100644 index 0000000000..25e7579182 --- /dev/null +++ b/variants/radiomaster_nomad_gemini/variant.h @@ -0,0 +1,59 @@ +#define HAS_SCREEN 0 +#define HAS_WIRE 0 +#define HAS_GPS 0 +#undef GPS_RX_PIN +#undef GPS_TX_PIN + +#define PIN_SPI_MISO 33 +#define PIN_SPI_MOSI 32 +#define PIN_SPI_SCK 25 +#define PIN_SPI_NSS 27 + +#define LORA_RESET 15 +#define LORA_DIO1 37 +#define LORA_DIO2 36 +#define LORA_SCK PIN_SPI_SCK +#define LORA_MISO PIN_SPI_MISO +#define LORA_MOSI PIN_SPI_MOSI +#define LORA_CS PIN_SPI_NSS + +// supported modules list +#define USE_LR1121 + +#define LR1121_IRQ_PIN LORA_DIO1 +#define LR1121_NRESET_PIN LORA_RESET +#define LR1121_BUSY_PIN LORA_DIO2 +#define LR1121_SPI_NSS_PIN LORA_CS +#define LR1121_SPI_SCK_PIN LORA_SCK +#define LR1121_SPI_MOSI_PIN LORA_MOSI +#define LR1121_SPI_MISO_PIN LORA_MISO + +// not yet implemented +#define JANUS_RADIO +#define LR1121_IRQ2_PIN 34 +#define LR1121_NRESET2_PIN 21 +#define LR1121_BUSY2_PIN 39 +#define LR1121_SPI_NSS2_PIN 13 + +// #define LR11X0_DIO3_TCXO_VOLTAGE 1.6 +#define LR11X0_DIO_AS_RF_SWITCH + +#define HAS_NEOPIXEL // Enable the use of neopixels +#define NEOPIXEL_COUNT 2 // How many neopixels are connected +#define NEOPIXEL_DATA 22 // GPIO pin used to send data to the neopixels +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // Type of neopixels in use +#define ENABLE_AMBIENTLIGHTING // Turn on Ambient Lighting + +#define BUTTON_PIN 34 +#define BUTTON_NEED_PULLUP + +#undef EXT_NOTIFY_OUT + +// #define BAT_MEASURE_ADC_UNIT +// #define BATTERY_PIN 26 +// #define ADC_CHANNEL ADC2_GPIO26_CHANNEL +// #define BATTERY_SENSE_SAMPLES 30 + +#define RADIO_FAN_EN 2 +// this board does need PWM on the FAN PIN +#define RADIO_FAN_PWM