From a8584cf38c037ff19db87433613fc14246648a29 Mon Sep 17 00:00:00 2001 From: Senk02 Date: Wed, 6 Aug 2025 16:24:53 +0000 Subject: [PATCH 1/4] Add base generic ELRS targets --- boards/esp32-pico-d4.json | 25 +++++ variants/esp32/elrs-generic/platformio.ini | 15 +++ variants/esp32/elrs-generic/rfswitch.h | 20 ++++ variants/esp32/elrs-generic/variant.h | 125 +++++++++++++++++++++ 4 files changed, 185 insertions(+) create mode 100644 boards/esp32-pico-d4.json create mode 100644 variants/esp32/elrs-generic/platformio.ini create mode 100644 variants/esp32/elrs-generic/rfswitch.h create mode 100644 variants/esp32/elrs-generic/variant.h diff --git a/boards/esp32-pico-d4.json b/boards/esp32-pico-d4.json new file mode 100644 index 000000000..a6376c2cd --- /dev/null +++ b/boards/esp32-pico-d4.json @@ -0,0 +1,25 @@ +{ + "build": { + "core": "esp32", + "extra_flags": "-DARDUINO_ESP32_PICO_D4", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "esp32" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif ESP32-PICO-D4", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 1310720, + "require_upload_port": true, + "speed": 115200 + }, + "url": "https://www.espressif.com/en/products/socs/esp32-pico-d4", + "vendor": "Espressif" + } diff --git a/variants/esp32/elrs-generic/platformio.ini b/variants/esp32/elrs-generic/platformio.ini new file mode 100644 index 000000000..dcb06ef17 --- /dev/null +++ b/variants/esp32/elrs-generic/platformio.ini @@ -0,0 +1,15 @@ +[env:elrs-generic] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -D PRIVATE_HW + -I variants/esp32/elrs-generic + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} diff --git a/variants/esp32/elrs-generic/rfswitch.h b/variants/esp32/elrs-generic/rfswitch.h new file mode 100644 index 000000000..71508c037 --- /dev/null +++ b/variants/esp32/elrs-generic/rfswitch.h @@ -0,0 +1,20 @@ +#include "RadioLib.h" + +// This is rewritten to match the requirements of the E80-900M2213S +// The E80 does not conform to the reference Semtech switches(!) and therefore needs a custom matrix. +// See footnote #3 in "https://www.cdebyte.com/products/E80-900M2213S/2#Pin" +// RF Switch Matrix SubG RFO_HP_LF / RFO_LP_LF / RFI_[NP]_LF0 +// DIO5 -> RFSW0_V1 +// DIO6 -> RFSW1_V2 +// DIO7 -> not connected on E80 module - note that GNSS and Wifi scanning are not possible. + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, RADIOLIB_NC, + RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 DIO7 + {LR11x0::MODE_STBY, {LOW, LOW, LOW}}, {LR11x0::MODE_RX, {LOW, HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH, LOW}}, {LR11x0::MODE_TX_HP, {HIGH, LOW, LOW}}, + {LR11x0::MODE_TX_HF, {LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH}}, + {LR11x0::MODE_WIFI, {LOW, LOW, LOW}}, END_OF_MODE_TABLE, +}; diff --git a/variants/esp32/elrs-generic/variant.h b/variants/esp32/elrs-generic/variant.h new file mode 100644 index 000000000..d0a2002f1 --- /dev/null +++ b/variants/esp32/elrs-generic/variant.h @@ -0,0 +1,125 @@ +#ifndef ELRS_TARGETS_H +#define ELRS_TARGETS_H + +// Target selection - uncomment ONE of these +// #define ELRS_GENERIC_900 +#define ELRS_GENERIC_2400 +// #define ELRS_GENERIC_LR1121 // Currently only the LR1121 True Diversity target is supported + + +// #define HAS_DUAL_RADIO TODO for the funture, currently does nothing. + + +#undef HAS_GPS +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#undef EXT_NOTIFY_OUT + +//============================================================================== +// ELRS GENERIC 900 MHz TARGET +//============================================================================== +#ifdef ELRS_GENERIC_900 + +// Chip selection +#define USE_RF95 + +// Serial pins +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + +// Radio pins +#define LORA_DIO0 4 +#define LORA_DIO1 5 +#define LORA_MISO 12 +#define LORA_MOSI 13 +#define LORA_CS 15 +#define LORA_SCK 14 +#define LORA_RESET 2 + +// GPIO +#define LED_PIN 16 +#define BUTTON_PIN 0 +#define BUTTON_NEED_PULLUP + +#endif // ELRS_GENERIC_900 + +//============================================================================== +// ELRS GENERIC 2.4 GHz TARGET +//============================================================================== +#ifdef ELRS_GENERIC_2400 + +// Chip selection +#define USE_SX1280 + +// Serial pins +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + +// Radio pins +#define LORA_BUSY 5 +#define LORA_DIO1 4 +#define LORA_MISO 12 +#define LORA_MOSI 13 +#define LORA_CS 15 +#define LORA_SCK 14 +#define LORA_RESET 2 + +#define SX128X_CS LORA_CS +#define SX128X_DIO1 LORA_DIO1 +#define SX128X_BUSY LORA_BUSY +#define SX128X_RESET LORA_RESET +#define SX128X_MAX_POWER 13 + +// GPIO +#define LED_PIN 16 +#define BUTTON_PIN 0 +#define BUTTON_NEED_PULLUP + +#endif // ELRS_GENERIC_2400 + +//============================================================================== +// ELRS TRUE DIVERSITY LR1121 TARGET +//============================================================================== +#ifdef ELRS_GENERIC_LR1121 + +// Chip selection +// #define USE_SX1262 +#define USE_LR1121 + + +// Board has RGB LED 21 +#define HAS_NEOPIXEL // Enable the use of neopixels +#define NEOPIXEL_COUNT 1 // 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 + +// GPIO +#define BUTTON_PIN 0 // This is the BOOT button +#define BUTTON_NEED_PULLUP + +// Radio pins +#define LORA_MISO 33 +#define LORA_MOSI 32 +#define LORA_SCK 25 +#define LORA_CS 27 +#define LORA_RESET 26 +#define LORA_DIO1 37 + +#define LR1121_IRQ_PIN 37 +#define LR1121_NRESET_PIN 26 +#define LR1121_BUSY_PIN 36 +#define LR1121_SPI_NSS_PIN 27 +#define LR1121_SPI_SCK_PIN 25 +#define LR1121_SPI_MOSI_PIN 32 +#define LR1121_SPI_MISO_PIN 33 +#define LR11X0_DIO_AS_RF_SWITCH + +#endif // ELRS_GENERIC_LR1121 + + +// Ensure only one target is selected +#if defined(ELRS_GENERIC_900) + defined(ELRS_GENERIC_2400) + defined(ELRS_GENERIC_LR1121) != 1 +#error "Exactly one ELRS target must be defined" +#endif + +#endif // ELRS_TARGETS_H \ No newline at end of file From d981673f47d6c87840abfdeeacd5a15546e9d5e8 Mon Sep 17 00:00:00 2001 From: Senk02 Date: Thu, 14 Aug 2025 18:35:10 +0000 Subject: [PATCH 2/4] Initial commit, add python script for conversion, and add generated targets --- src/main.cpp | 5 + variants/esp32/elrs-generic/platformio.ini | 15 - variants/esp32/elrs-generic/variant.h | 125 --- variants/esp32/elrs/converter.py | 627 +++++++++++++ variants/esp32/elrs/esp32-c3/platformio.ini | 664 ++++++++++++++ .../esp32-c3}/rfswitch.h | 0 variants/esp32/elrs/esp32-c3/variant.h | 240 +++++ variants/esp32/elrs/esp32-s3/platformio.ini | 75 ++ variants/esp32/elrs/esp32-s3/rfswitch.h | 20 + variants/esp32/elrs/esp32-s3/variant.h | 145 +++ variants/esp32/elrs/esp32/platformio.ini | 866 ++++++++++++++++++ variants/esp32/elrs/esp32/rfswitch.h | 20 + variants/esp32/elrs/esp32/variant.h | 451 +++++++++ variants/esp32/elrs/rfswitch.h | 20 + 14 files changed, 3133 insertions(+), 140 deletions(-) delete mode 100644 variants/esp32/elrs-generic/platformio.ini delete mode 100644 variants/esp32/elrs-generic/variant.h create mode 100644 variants/esp32/elrs/converter.py create mode 100644 variants/esp32/elrs/esp32-c3/platformio.ini rename variants/esp32/{elrs-generic => elrs/esp32-c3}/rfswitch.h (100%) create mode 100644 variants/esp32/elrs/esp32-c3/variant.h create mode 100644 variants/esp32/elrs/esp32-s3/platformio.ini create mode 100644 variants/esp32/elrs/esp32-s3/rfswitch.h create mode 100644 variants/esp32/elrs/esp32-s3/variant.h create mode 100644 variants/esp32/elrs/esp32/platformio.ini create mode 100644 variants/esp32/elrs/esp32/rfswitch.h create mode 100644 variants/esp32/elrs/esp32/variant.h create mode 100644 variants/esp32/elrs/rfswitch.h diff --git a/src/main.cpp b/src/main.cpp index 7fc1d2cf2..f2a7db890 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -300,6 +300,11 @@ void setup() digitalWrite(PIN_POWER_EN, HIGH); #endif +#ifdef PIN_ENABLE_HIGH // This pin can be selected by each target to set high, incase a radio pin needs to be pulled high or something. Currently used only in ELRS. + pinMode(PIN_ENABLE_HIGH, OUTPUT); + digitalWrite(PIN_ENABLE_HIGH, HIGH); +#endif + #if defined(ELECROW_ThinkNode_M5) Wire.begin(48, 47); io.pinMode(PCA_PIN_EINK_EN, OUTPUT); diff --git a/variants/esp32/elrs-generic/platformio.ini b/variants/esp32/elrs-generic/platformio.ini deleted file mode 100644 index dcb06ef17..000000000 --- a/variants/esp32/elrs-generic/platformio.ini +++ /dev/null @@ -1,15 +0,0 @@ -[env:elrs-generic] -extends = esp32_base -platform = espressif32 -board = esp32-pico-d4 -framework = arduino -build_flags = - ${esp32_base.build_flags} - -D PRIVATE_HW - -I variants/esp32/elrs-generic - -O2 - -D CONFIG_DISABLE_HAL_LOCKS=1 -upload_protocol = esptool -upload_speed = 460800 -lib_deps = - ${esp32_base.lib_deps} diff --git a/variants/esp32/elrs-generic/variant.h b/variants/esp32/elrs-generic/variant.h deleted file mode 100644 index d0a2002f1..000000000 --- a/variants/esp32/elrs-generic/variant.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef ELRS_TARGETS_H -#define ELRS_TARGETS_H - -// Target selection - uncomment ONE of these -// #define ELRS_GENERIC_900 -#define ELRS_GENERIC_2400 -// #define ELRS_GENERIC_LR1121 // Currently only the LR1121 True Diversity target is supported - - -// #define HAS_DUAL_RADIO TODO for the funture, currently does nothing. - - -#undef HAS_GPS -#undef GPS_RX_PIN -#undef GPS_TX_PIN -#undef EXT_NOTIFY_OUT - -//============================================================================== -// ELRS GENERIC 900 MHz TARGET -//============================================================================== -#ifdef ELRS_GENERIC_900 - -// Chip selection -#define USE_RF95 - -// Serial pins -#define SERIAL_RX_PIN 3 -#define SERIAL_TX_PIN 1 - -// Radio pins -#define LORA_DIO0 4 -#define LORA_DIO1 5 -#define LORA_MISO 12 -#define LORA_MOSI 13 -#define LORA_CS 15 -#define LORA_SCK 14 -#define LORA_RESET 2 - -// GPIO -#define LED_PIN 16 -#define BUTTON_PIN 0 -#define BUTTON_NEED_PULLUP - -#endif // ELRS_GENERIC_900 - -//============================================================================== -// ELRS GENERIC 2.4 GHz TARGET -//============================================================================== -#ifdef ELRS_GENERIC_2400 - -// Chip selection -#define USE_SX1280 - -// Serial pins -#define SERIAL_RX_PIN 3 -#define SERIAL_TX_PIN 1 - -// Radio pins -#define LORA_BUSY 5 -#define LORA_DIO1 4 -#define LORA_MISO 12 -#define LORA_MOSI 13 -#define LORA_CS 15 -#define LORA_SCK 14 -#define LORA_RESET 2 - -#define SX128X_CS LORA_CS -#define SX128X_DIO1 LORA_DIO1 -#define SX128X_BUSY LORA_BUSY -#define SX128X_RESET LORA_RESET -#define SX128X_MAX_POWER 13 - -// GPIO -#define LED_PIN 16 -#define BUTTON_PIN 0 -#define BUTTON_NEED_PULLUP - -#endif // ELRS_GENERIC_2400 - -//============================================================================== -// ELRS TRUE DIVERSITY LR1121 TARGET -//============================================================================== -#ifdef ELRS_GENERIC_LR1121 - -// Chip selection -// #define USE_SX1262 -#define USE_LR1121 - - -// Board has RGB LED 21 -#define HAS_NEOPIXEL // Enable the use of neopixels -#define NEOPIXEL_COUNT 1 // 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 - -// GPIO -#define BUTTON_PIN 0 // This is the BOOT button -#define BUTTON_NEED_PULLUP - -// Radio pins -#define LORA_MISO 33 -#define LORA_MOSI 32 -#define LORA_SCK 25 -#define LORA_CS 27 -#define LORA_RESET 26 -#define LORA_DIO1 37 - -#define LR1121_IRQ_PIN 37 -#define LR1121_NRESET_PIN 26 -#define LR1121_BUSY_PIN 36 -#define LR1121_SPI_NSS_PIN 27 -#define LR1121_SPI_SCK_PIN 25 -#define LR1121_SPI_MOSI_PIN 32 -#define LR1121_SPI_MISO_PIN 33 -#define LR11X0_DIO_AS_RF_SWITCH - -#endif // ELRS_GENERIC_LR1121 - - -// Ensure only one target is selected -#if defined(ELRS_GENERIC_900) + defined(ELRS_GENERIC_2400) + defined(ELRS_GENERIC_LR1121) != 1 -#error "Exactly one ELRS target must be defined" -#endif - -#endif // ELRS_TARGETS_H \ No newline at end of file diff --git a/variants/esp32/elrs/converter.py b/variants/esp32/elrs/converter.py new file mode 100644 index 000000000..9d0241e3f --- /dev/null +++ b/variants/esp32/elrs/converter.py @@ -0,0 +1,627 @@ +#!/usr/bin/env python3 +""" +Simple ELRS to Meshtastic Target Converter + +Converts ELRS target definitions to Meshtastic variant.h files. +""" + +# TODO: - Add support for amplifier chips +# TODO: - Clean up names of targets to avoid names like dual-dual + +import json +import os +import sys +import argparse +import subprocess +import shutil +import tempfile +from pathlib import Path +from typing import Dict, List, Optional + +class SimpleELRSConverter: + def __init__(self): + self.targets_data = {} + self.hardware_data = {} + self.temp_repo_path = None + + # Supported ESP32 platforms + self.supported_platforms = {'esp32', 'esp32-c3', 'esp32-s3'} + + # Radio chip mappings + self.radio_chips = { + 'sx1276': {'define': 'USE_RF95', 'freq': '900', 'type': 'rf95'}, + 'sx1277': {'define': 'USE_RF95', 'freq': '900', 'type': 'rf95'}, + 'sx1280': {'define': 'USE_SX1280', 'freq': '2400', 'type': 'sx128x'}, + 'lr1121': {'define': 'USE_LR1121', 'freq': 'dual', 'type': 'lr1121'} + } + + # Pin mappings from ELRS to Meshtastic + self.pin_mappings = { + # Basic SPI pins + 'radio_mosi': 'LORA_MOSI', + 'radio_miso': 'LORA_MISO', + 'radio_sck': 'LORA_SCK', + 'radio_nss': 'LORA_CS', + 'radio_rst': 'LORA_RESET', + + # Radio specific pins + 'radio_dio0': 'LORA_DIO0', + 'radio_dio1': 'LORA_DIO1', + 'radio_busy': 'LORA_BUSY', + 'radio_txen': 'LORA_TXEN', + 'radio_rxen': 'LORA_RXEN', + + # Second radio pins (for true diversity) + 'radio_nss_2': 'LORA_CS_2', + 'radio_rst_2': 'LORA_RESET_2', + 'radio_dio0_2': 'LORA_DIO0_2', + 'radio_dio1_2': 'LORA_DIO1_2', + 'radio_busy_2': 'LORA_BUSY_2', + 'radio_txen_2': 'LORA_TXEN_2', + 'radio_rxen_2': 'LORA_RXEN_2', + + # LED pins + 'led': 'LED_PIN', + 'led_red': 'LED_PIN', + 'led_blue': 'LED_PIN', + 'led_rgb': 'NEOPIXEL_DATA', + + # Other pins + 'pin_button': 'BUTTON_PIN', + 'serial_rx': 'SERIAL_RX_PIN', + 'serial_tx': 'SERIAL_TX_PIN', + } + + def clone_elrs_repo(self) -> bool: + """Clone the ELRS targets repository to a temporary directory""" + try: + # Create temporary directory + self.temp_repo_path = Path(tempfile.mkdtemp(prefix="elrs_targets_")) + print(f"Cloning ELRS targets repository to {self.temp_repo_path}") + + # Clone the repository + result = subprocess.run([ + 'git', 'clone', '--depth', '1', + 'https://github.com/ExpressLRS/targets.git', + str(self.temp_repo_path) + ], capture_output=True, text=True) + + if result.returncode != 0: + print(f"Failed to clone repository: {result.stderr}") + return False + + print("Successfully cloned ELRS targets repository") + return True + + except Exception as e: + print(f"Error cloning repository: {e}") + return False + + def cleanup_repo(self): + """Remove the temporary repository directory""" + if self.temp_repo_path and self.temp_repo_path.exists(): + try: + shutil.rmtree(self.temp_repo_path) + print(f"Cleaned up temporary repository at {self.temp_repo_path}") + except Exception as e: + print(f"Warning: Failed to cleanup temporary directory: {e}") + + def load_elrs_data(self) -> bool: + """Load ELRS targets.json and hardware definitions from local repository""" + if not self.temp_repo_path or not self.temp_repo_path.exists(): + print("Error: Repository not cloned. Call clone_elrs_repo() first.") + return False + + print("Loading ELRS data from local repository...") + + # Load targets.json + targets_file = self.temp_repo_path / 'targets.json' + if not targets_file.exists(): + print(f"Error: targets.json not found at {targets_file}") + return False + + print(" Loading targets.json...") + with open(targets_file, 'r') as f: + self.targets_data = json.load(f) + + print(f" Loaded {len(self.targets_data)} target brands") + + # Load hardware definitions from RX directory only + hw_dir = self.temp_repo_path / 'RX' + if not hw_dir.exists(): + print(" Warning: RX directory not found") + return False + + print(" Loading RX directory...") + hw_files = list(hw_dir.glob('*.json')) + + if not hw_files: + print(" No JSON files found in RX") + return False + + print(f" Found {len(hw_files)} files") + + for hw_file in hw_files: + try: + with open(hw_file, 'r') as f: + hw_data = json.load(f) + self.hardware_data[hw_file.name] = hw_data + except Exception as e: + print(f" Warning: Failed to load {hw_file.name}: {e}") + + print(f" Successfully loaded {len(self.hardware_data)} hardware definitions") + return True + + def extract_targets(self) -> List[Dict]: + """Extract and process all supported targets""" + processed_targets = [] + + for brand, categories in self.targets_data.items(): + if not isinstance(categories, dict): + continue + + for category, targets in categories.items(): + if not isinstance(targets, dict) or not category.startswith('rx_'): + continue # Only process RX targets + + for target_name, target_data in targets.items(): + if not isinstance(target_data, dict): + continue + + # Get hardware layout file + layout_file = target_data.get('layout_file', '') + if not layout_file: + continue + + # Find the hardware definition + hw_filename = layout_file if layout_file.endswith('.json') else f"{layout_file}.json" + hw_data = self.hardware_data.get(hw_filename) + + if not hw_data: + print(f"Warning: No hardware definition found for {hw_filename}") + continue + + # Process this target + target_config = self.process_target(brand, target_name, category, target_data, hw_data) + if target_config: + processed_targets.append(target_config) + + return processed_targets + + def process_target(self, brand: str, target_name: str, category: str, target_data: Dict, hw_data: Dict) -> Optional[Dict]: + """Process a single target""" + # Get firmware info + firmware = target_data.get('firmware', '') + + # Determine platform from firmware first, then fallback to target_data + platform = self.detect_platform_from_firmware(firmware) or target_data.get('platform', '') + + # Check if platform is supported + if platform not in self.supported_platforms: + return None + + # Determine radio chip - use firmware only + radio_chip = self.detect_radio_chip(firmware) + if not radio_chip: + return None + + radio_info = self.radio_chips[radio_chip] + pins = self.extract_pins(hw_data) + is_diversity = self.detect_true_diversity(hw_data) + define_name = self.generate_define_name(brand, target_name, radio_info['freq']) + + return { + 'brand': brand, + 'name': target_name, + 'category': category, + 'platform': platform, + 'firmware': firmware, + 'define_name': define_name, + 'radio_chip': radio_chip, + 'radio_info': radio_info, + 'pins': pins, + 'is_diversity': is_diversity, + 'hw_data': hw_data + } + + def detect_radio_chip(self, firmware: str) -> Optional[str]: + """Detect radio chip from firmware ONLY""" + if not firmware: + return None + + firmware_upper = firmware.upper() + + # Check for explicit radio chip mentions first + if 'LR1121' in firmware_upper: + return 'lr1121' + elif 'SX1280' in firmware_upper: + return 'sx1280' + elif 'SX1276' in firmware_upper or 'SX127X' in firmware_upper or 'SX1277' in firmware_upper: + return 'sx1276' + + # Fall back to frequency detection + if '2400' in firmware_upper: + return 'sx1280' + elif '900' in firmware_upper: + return 'sx1276' + + return None + + def detect_platform_from_firmware(self, firmware: str) -> Optional[str]: + """Detect platform from firmware string""" + if not firmware: + return None + + firmware_upper = firmware.upper() + + # Check for platform in firmware name + if 'ESP32C3' in firmware_upper: + return 'esp32-c3' + elif 'ESP32S3' in firmware_upper: + return 'esp32-s3' + elif 'ESP32' in firmware_upper: + return 'esp32' + + return None + + def detect_true_diversity(self, hw_data: Dict) -> bool: + """Detect if this is a true diversity setup by checking for second radio pins""" + diversity_pins = ['radio_dio0_2', 'radio_dio1_2', 'radio_rst_2', 'radio_nss_2', 'radio_busy_2'] + + return any(pin in hw_data and isinstance(hw_data[pin], int) for pin in diversity_pins) + + def extract_pins(self, hw_data: Dict) -> Dict[str, int]: + """Extract pin definitions from hardware data""" + pins = {} + + for elrs_pin, meshtastic_pin in self.pin_mappings.items(): + if elrs_pin in hw_data and isinstance(hw_data[elrs_pin], int): + pins[meshtastic_pin] = hw_data[elrs_pin] + + return pins + + def generate_define_name(self, brand: str, target_name: str, freq: str) -> str: + """Generate a clean define name for the target""" + # Clean up strings and remove common noise words + brand_clean = brand.upper().replace(' ', '_').replace('-', '_') + target_clean = target_name.upper().replace(' ', '_').replace('-', '_') + freq_clean = freq.upper() + + for word in ['MODULE', 'EXPRESSLRS', 'ELRS']: + brand_clean = brand_clean.replace(word, '') + target_clean = target_clean.replace(word, '') + + # Clean up extra underscores + brand_clean = '_'.join(filter(None, brand_clean.split('_'))) + target_clean = '_'.join(filter(None, target_clean.split('_'))) + + return f"ELRS_{brand_clean}_{target_clean}_{freq_clean}" + + def group_targets_by_pins(self, targets: List[Dict]) -> Dict[str, List[Dict]]: + """Group targets that have identical pin configurations""" + pin_groups = {} + + for target in targets: + # Create a signature of the pins and radio chip for grouping + pin_sig = self.create_pin_signature(target) + + if pin_sig not in pin_groups: + pin_groups[pin_sig] = [] + pin_groups[pin_sig].append(target) + + return pin_groups + + def create_pin_signature(self, target: Dict) -> str: + """Create a unique signature for pin configuration AND radio chip AND diversity status""" + # Sort pins to create consistent signature + pin_items = sorted(target['pins'].items()) + radio_chip = target['radio_info']['type'] + is_diversity = target['is_diversity'] + return f"{pin_items}_{radio_chip}_{is_diversity}" + + def generate_variant_file(self, platform: str, pin_groups: Dict, output_dir: Path): + """Generate variant.h file for a platform""" + variant_dir = output_dir / platform + variant_dir.mkdir(parents=True, exist_ok=True) + + variant_file = variant_dir / 'variant.h' + + with open(variant_file, 'w') as f: + f.write(self.generate_variant_content(platform, pin_groups)) + + print(f"Generated {variant_file}") + + def generate_variant_content(self, platform: str, pin_groups: Dict) -> str: + """Generate the content of variant.h file""" + content = [] + + # Header + content.append("// ELRS Target Selection - automatically defined by PlatformIO environment") + + # Generate target selection defines + all_targets = [] + for targets_list in pin_groups.values(): + all_targets.extend(targets_list) + + for i, target in enumerate(all_targets): + content.append(f"// #define {target['define_name']}") + + content.append("") + content.append("// Common settings") + content.append("#undef HAS_GPS") + content.append("#undef GPS_RX_PIN") + content.append("#undef GPS_TX_PIN") + content.append("#undef EXT_NOTIFY_OUT") + content.append("") + + # Add global chip-specific mappings at the top + content.append("// Global chip-specific pin mappings") + content.append("// SX128X mappings (2.4GHz)") + content.append("#define SX128X_CS LORA_CS") + content.append("#define SX128X_DIO1 LORA_DIO1") + content.append("#define SX128X_BUSY LORA_BUSY") + content.append("#define SX128X_RESET LORA_RESET") + content.append("") + content.append("// LR1121 mappings (dual-band)") + content.append("#define LR1121_SPI_NSS_PIN LORA_CS") + content.append("#define LR1121_SPI_SCK_PIN LORA_SCK") + content.append("#define LR1121_SPI_MOSI_PIN LORA_MOSI") + content.append("#define LR1121_SPI_MISO_PIN LORA_MISO") + content.append("#define LR1121_NRESET_PIN LORA_RESET") + content.append("#define LR1121_BUSY_PIN LORA_BUSY") + content.append("#define LR1121_IRQ_PIN LORA_DIO1") + content.append("#define LR11X0_DIO_AS_RF_SWITCH") + content.append("") + content.append("// Second radio mappings for true diversity") + content.append("#define SX128X_CS_2 LORA_CS_2") + content.append("#define SX128X_DIO0_2 LORA_DIO0_2") + content.append("#define SX128X_DIO1_2 LORA_DIO1_2") + content.append("#define SX128X_BUSY_2 LORA_BUSY_2") + content.append("#define SX128X_RESET_2 LORA_RESET_2") + content.append("#define LR1121_SPI_NSS_2_PIN LORA_CS_2") + content.append("#define LR1121_NRESET_2_PIN LORA_RESET_2") + content.append("#define LR1121_BUSY_2_PIN LORA_BUSY_2") + content.append("#define LR1121_IRQ_2_PIN LORA_DIO1_2") + content.append("") + + # Generate pin configurations for each group + group_num = 1 + for pin_sig, targets_list in pin_groups.items(): + target = targets_list[0] # All targets in group have same pins/radio chip + + if len(targets_list) > 1: + content.append(f"// Pin Configuration {group_num} - Shared by multiple targets") + conditions = " || ".join([f"defined({t['define_name']})" for t in targets_list]) + content.append(f"#if {conditions}") + else: + content.append(f"// {target['brand']} {target['name']}") + content.append(f"#ifdef {target['define_name']}") + + content.append(f"#define {target['radio_info']['define']}") + + # Add TWO_RADIOS define if this is a diversity setup + if target['is_diversity']: + content.append("#define TWO_RADIOS") + + content.append("") + + # Separate pins into categories + lora_pins = {k: v for k, v in target['pins'].items() if k.startswith('LORA_') and not k.endswith('_2')} + lora2_pins = {k: v for k, v in target['pins'].items() if k.startswith('LORA_') and k.endswith('_2')} + other_pins = {k: v for k, v in target['pins'].items() if not k.startswith('LORA_')} + + # Output radio pins + if lora_pins: + content.append("// Radio pins") + content.extend(f"#define {pin_name} {pin_value}" for pin_name, pin_value in sorted(lora_pins.items())) + content.append("") + + # Output second radio pins for diversity + if lora2_pins: + content.append("// Second radio pins (true diversity)") + content.extend(f"#define {pin_name} {pin_value}" for pin_name, pin_value in sorted(lora2_pins.items())) + content.append("") + + # Output other pins + if other_pins: + content.append("// Other pins") + content.extend(f"#define {pin_name} {pin_value}" for pin_name, pin_value in sorted(other_pins.items())) + content.append("") + # Add special features + if 'NEOPIXEL_DATA' in target['pins']: + content.extend([ + "", + "// RGB LED", + "#define HAS_NEOPIXEL", + "#define NEOPIXEL_COUNT 1", + "#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800)" + ]) + + if 'BUTTON_PIN' in target['pins']: + content.append("#define BUTTON_NEED_PULLUP") + + # Close conditional block + if len(targets_list) > 1: + conditions = " || ".join([f"defined({t['define_name']})" for t in targets_list]) + content.append(f"#endif // {conditions}") + else: + content.append(f"#endif // {target['define_name']}") + content.append("") + + group_num += 1 + + # Set PIN_ENABLE_HIGH to second radio CS pin for diversity setups + has_diversity = any(target['is_diversity'] for targets_list in pin_groups.values() for target in targets_list) + if has_diversity: + # Find the CS_2 pin from any diversity target + for targets_list in pin_groups.values(): + for target in targets_list: + if target['is_diversity'] and 'LORA_CS_2' in target['pins']: + content.extend([ + "// Set second radio CS pin high at startup to disable it", + "#if defined(TWO_RADIOS)", + "#define PIN_ENABLE_HIGH LORA_CS_2", + "#endif // TWO_RADIOS", + "" + ]) + break + else: + continue + break + + # Footer - ensure only one target is selected + all_defines = [t['define_name'] for targets_list in pin_groups.values() for t in targets_list] + condition = " + ".join([f"defined({define})" for define in all_defines]) + content.extend([ + "// Ensure only one target is selected", + f"#if {condition} != 1", + '#error "Exactly one ELRS target must be defined"', + "#endif" + ]) + + return '\n'.join(content) + + def generate_platformio_ini(self, platform: str, targets: List[Dict], output_dir: Path): + """Generate platformio.ini with individual environments for each target""" + variant_dir = output_dir / platform + variant_dir.mkdir(parents=True, exist_ok=True) + + # Platform-specific configuration + platform_config = { + 'esp32': { + 'base': 'esp32_base', + 'board': 'esp32-pico-d4', + 'board_level': None + }, + 'esp32-c3': { + 'base': 'esp32c3_base', + 'board': 'esp32-c3-devkitm-1', + 'board_level': 'extra' + }, + 'esp32-s3': { + 'base': 'esp32c3_base', # Using esp32c3_base as reference from your example + 'board': 'esp32-s3-devkitc-1', + 'board_level': 'extra' + } + } + + config = platform_config.get(platform, platform_config['esp32']) + content = [] + + # Generate individual environment for each target + for target in targets: + env_name = f"elrs-{target['define_name'].lower().replace('elrs_', '').replace('_', '-')}" + target_dir = f"variants/esp32/elrs/{platform}" + + content.extend([ + f"[env:{env_name}]", + f"extends = {config['base']}", + "platform = espressif32", + f"board = {config['board']}", + "framework = arduino" + ]) + + if config['board_level']: + content.append(f"board_level = {config['board_level']}") + + content.extend([ + "build_flags =", + f" ${{{config['base']}.build_flags}}", + f" -I {target_dir}", + f" -D {target['define_name']}", + f" -D PRIVATE_HW", + " -O2", + " -D CONFIG_DISABLE_HAL_LOCKS=1" + ]) + + # Add monitor speed for non-esp32 platforms + if platform != 'esp32': + content.append("monitor_speed = 115200") + + content.extend([ + "upload_protocol = esptool", + "upload_speed = 460800" if platform == 'esp32' else "upload_speed = 921600", + "lib_deps =", + f" ${{{config['base']}.lib_deps}}", + "" + ]) + + with open(variant_dir / 'platformio.ini', 'w') as f: + f.write('\n'.join(content)) + + print(f"Generated {variant_dir / 'platformio.ini'} with {len(targets)} environments") + + def copy_rfswitch_file(self, platform: str, output_dir: Path): + """Copy rfswitch.h file to the variant directory""" + variant_dir = output_dir / platform + variant_dir.mkdir(parents=True, exist_ok=True) + + # Source rfswitch.h file (in the same directory as this script) + source_file = Path(__file__).parent / 'rfswitch.h' + target_file = variant_dir / 'rfswitch.h' + + if source_file.exists(): + shutil.copy2(source_file, target_file) + print(f"Copied rfswitch.h to {target_file}") + else: + print(f"Warning: rfswitch.h not found at {source_file}") + + def convert(self, output_dir: str) -> bool: + """Main conversion function""" + output_path = Path(output_dir) + + # Clone the repository + if not self.clone_elrs_repo(): + return False + + try: + if not self.load_elrs_data(): + return False + + targets = self.extract_targets() + if not targets: + print("No targets found to convert") + return False + + print(f"Found {len(targets)} targets to convert") + + # Group targets by platform + by_platform = {} + for target in targets: + platform = target['platform'] + by_platform.setdefault(platform, []).append(target) + + # Generate files for each platform + for platform, platform_targets in by_platform.items(): + print(f"Processing {len(platform_targets)} targets for {platform}") + + pin_groups = self.group_targets_by_pins(platform_targets) + self.generate_variant_file(platform, pin_groups, output_path) + self.generate_platformio_ini(platform, platform_targets, output_path) + self.copy_rfswitch_file(platform, output_path) + + return True + + finally: + self.cleanup_repo() + + +def main(): + parser = argparse.ArgumentParser(description='Convert ELRS targets to Meshtastic format') + parser.add_argument('--output-dir', default='.', + help='Output directory for generated files (default: current directory)') + + args = parser.parse_args() + + converter = SimpleELRSConverter() + + if converter.convert(args.output_dir): + print("Conversion completed successfully!") + return 0 + else: + print("Conversion failed!") + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/variants/esp32/elrs/esp32-c3/platformio.ini b/variants/esp32/elrs/esp32-c3/platformio.ini new file mode 100644 index 000000000..7452a6781 --- /dev/null +++ b/variants/esp32/elrs/esp32-c3/platformio.ini @@ -0,0 +1,664 @@ +[env:elrs-bayckrc-rrd1-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_RRD1_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-pwmc3-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_PWMC3_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-rrd2-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_RRD2_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-rr2-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_RR2_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-dualc3-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_DUALC3_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-single-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_SINGLE_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-pwm-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_PWM_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-ur100-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_UR100_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-ur500-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_UR500_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-bayckrc-ur1000-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BAYCKRC_UR1000_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-betafpv-superx-nano-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BETAFPV_SUPERX_NANO_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-betafpv-superx-mono-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BETAFPV_SUPERX_MONO_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-botlab-botlink1-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BOTLAB_BOTLINK1_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-brotherhobby-dualc3-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_BROTHERHOBBY_DUALC3_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-dakefpv-rx900-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_DAKEFPV_RX900_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-flycolor-c3-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_FLYCOLOR_C3_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-generic-c3-plain-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_GENERIC_C3_PLAIN_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-generic-c3-plain-pa-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_GENERIC_C3_PLAIN_PA_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-generic-c3-td-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_GENERIC_C3_TD_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-generic-c3-pwm-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_GENERIC_C3_PWM_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-generic-c3-true-diversity-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_GENERIC_C3_TRUE_DIVERSITY_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-generic-c3-plain-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_GENERIC_C3_PLAIN_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-generic-c3-pwm-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_GENERIC_C3_PWM_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-geprc-single-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_GEPRC_SINGLE_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-sub250-single-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_SUB250_SINGLE_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-hdzero-halo-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_HDZERO_HALO_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-hdzero-aio15-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_HDZERO_AIO15_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-jumper-c3-pwm6-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_JUMPER_C3_PWM6_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-newbeedrone-microg-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_NEWBEEDRONE_MICROG_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-newbeedrone-c324d-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_NEWBEEDRONE_C324D_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-radiomaster-xr2-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_RADIOMASTER_XR2_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-radiomaster-xr1-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_RADIOMASTER_XR1_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-radiomaster-xr3-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_RADIOMASTER_XR3_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-speedybee-aio-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_SPEEDYBEE_AIO_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-tunerc-tunerc-2400-nano-pa-rx-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-c3 + -D ELRS_TUNERC_TUNERC_2400_NANO_PA_RX_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} diff --git a/variants/esp32/elrs-generic/rfswitch.h b/variants/esp32/elrs/esp32-c3/rfswitch.h similarity index 100% rename from variants/esp32/elrs-generic/rfswitch.h rename to variants/esp32/elrs/esp32-c3/rfswitch.h diff --git a/variants/esp32/elrs/esp32-c3/variant.h b/variants/esp32/elrs/esp32-c3/variant.h new file mode 100644 index 000000000..e487a1bd7 --- /dev/null +++ b/variants/esp32/elrs/esp32-c3/variant.h @@ -0,0 +1,240 @@ +// ELRS Target Selection - automatically defined by PlatformIO environment +// #define ELRS_BAYCKRC_RRD1_2400 +// #define ELRS_GENERIC_C3_TD_2400 +// #define ELRS_HDZERO_HALO_2400 +// #define ELRS_BAYCKRC_PWMC3_2400 +// #define ELRS_GENERIC_C3_PWM_2400 +// #define ELRS_JUMPER_C3_PWM6_2400 +// #define ELRS_BAYCKRC_RRD2_DUAL +// #define ELRS_BAYCKRC_DUALC3_DUAL +// #define ELRS_BETAFPV_SUPERX_NANO_DUAL +// #define ELRS_BROTHERHOBBY_DUALC3_DUAL +// #define ELRS_GENERIC_C3_TRUE_DIVERSITY_DUAL +// #define ELRS_BAYCKRC_RR2_DUAL +// #define ELRS_BAYCKRC_SINGLE_DUAL +// #define ELRS_BAYCKRC_UR100_DUAL +// #define ELRS_BAYCKRC_UR500_DUAL +// #define ELRS_BAYCKRC_UR1000_DUAL +// #define ELRS_BETAFPV_SUPERX_MONO_DUAL +// #define ELRS_DAKEFPV_RX900_DUAL +// #define ELRS_GENERIC_C3_PLAIN_DUAL +// #define ELRS_GEPRC_SINGLE_DUAL +// #define ELRS_SUB250_SINGLE_DUAL +// #define ELRS_RADIOMASTER_XR2_DUAL +// #define ELRS_RADIOMASTER_XR1_DUAL +// #define ELRS_RADIOMASTER_XR3_DUAL +// #define ELRS_BAYCKRC_PWM_DUAL +// #define ELRS_GENERIC_C3_PWM_DUAL +// #define ELRS_BOTLAB_BOTLINK1_2400 +// #define ELRS_FLYCOLOR_C3_2400 +// #define ELRS_GENERIC_C3_PLAIN_2400 +// #define ELRS_GENERIC_C3_PLAIN_PA_2400 +// #define ELRS_HDZERO_AIO15_2400 +// #define ELRS_NEWBEEDRONE_MICROG_2400 +// #define ELRS_NEWBEEDRONE_C324D_2400 +// #define ELRS_SPEEDYBEE_AIO_2400 +// #define ELRS_TUNERC_TUNERC_2400_NANO_PA_RX_2400 + +// Common settings +#undef HAS_GPS +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#undef EXT_NOTIFY_OUT + +// Global chip-specific pin mappings +// SX128X mappings (2.4GHz) +#define SX128X_CS LORA_CS +#define SX128X_DIO1 LORA_DIO1 +#define SX128X_BUSY LORA_BUSY +#define SX128X_RESET LORA_RESET + +// LR1121 mappings (dual-band) +#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 +#define LR1121_NRESET_PIN LORA_RESET +#define LR1121_BUSY_PIN LORA_BUSY +#define LR1121_IRQ_PIN LORA_DIO1 +#define LR11X0_DIO_AS_RF_SWITCH + +// Second radio mappings for true diversity +#define SX128X_CS_2 LORA_CS_2 +#define SX128X_DIO0_2 LORA_DIO0_2 +#define SX128X_DIO1_2 LORA_DIO1_2 +#define SX128X_BUSY_2 LORA_BUSY_2 +#define SX128X_RESET_2 LORA_RESET_2 +#define LR1121_SPI_NSS_2_PIN LORA_CS_2 +#define LR1121_NRESET_2_PIN LORA_RESET_2 +#define LR1121_BUSY_2_PIN LORA_BUSY_2 +#define LR1121_IRQ_2_PIN LORA_DIO1_2 + +// Pin Configuration 1 - Shared by multiple targets +#if defined(ELRS_BAYCKRC_RRD1_2400) || defined(ELRS_GENERIC_C3_TD_2400) || defined(ELRS_HDZERO_HALO_2400) +#define USE_SX1280 +#define TWO_RADIOS + +// Radio pins +#define LORA_BUSY 3 +#define LORA_CS 0 +#define LORA_DIO1 1 +#define LORA_MISO 5 +#define LORA_MOSI 4 +#define LORA_RESET 2 +#define LORA_SCK 6 + +// Second radio pins (true diversity) +#define LORA_BUSY_2 8 +#define LORA_CS_2 7 +#define LORA_DIO1_2 18 +#define LORA_RESET_2 10 + +// Other pins +#define NEOPIXEL_DATA 19 +#define SERIAL_RX_PIN 20 +#define SERIAL_TX_PIN 21 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BAYCKRC_RRD1_2400) || defined(ELRS_GENERIC_C3_TD_2400) || defined(ELRS_HDZERO_HALO_2400) + +// Pin Configuration 2 - Shared by multiple targets +#if defined(ELRS_BAYCKRC_PWMC3_2400) || defined(ELRS_GENERIC_C3_PWM_2400) || defined(ELRS_JUMPER_C3_PWM6_2400) +#define USE_SX1280 + +// Radio pins +#define LORA_BUSY 3 +#define LORA_CS 7 +#define LORA_DIO1 1 +#define LORA_MISO 5 +#define LORA_MOSI 4 +#define LORA_RESET 2 +#define LORA_SCK 6 + +// Other pins +#define NEOPIXEL_DATA 8 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BAYCKRC_PWMC3_2400) || defined(ELRS_GENERIC_C3_PWM_2400) || defined(ELRS_JUMPER_C3_PWM6_2400) + +// Pin Configuration 3 - Shared by multiple targets +#if defined(ELRS_BAYCKRC_RRD2_DUAL) || defined(ELRS_BAYCKRC_DUALC3_DUAL) || defined(ELRS_BETAFPV_SUPERX_NANO_DUAL) || defined(ELRS_BROTHERHOBBY_DUALC3_DUAL) || defined(ELRS_GENERIC_C3_TRUE_DIVERSITY_DUAL) +#define USE_LR1121 +#define TWO_RADIOS + +// Radio pins +#define LORA_BUSY 3 +#define LORA_CS 0 +#define LORA_DIO1 1 +#define LORA_MISO 5 +#define LORA_MOSI 4 +#define LORA_RESET 2 +#define LORA_SCK 6 + +// Second radio pins (true diversity) +#define LORA_BUSY_2 8 +#define LORA_CS_2 7 +#define LORA_DIO1_2 18 +#define LORA_RESET_2 10 + +// Other pins +#define NEOPIXEL_DATA 19 +#define SERIAL_RX_PIN 20 +#define SERIAL_TX_PIN 21 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BAYCKRC_RRD2_DUAL) || defined(ELRS_BAYCKRC_DUALC3_DUAL) || defined(ELRS_BETAFPV_SUPERX_NANO_DUAL) || defined(ELRS_BROTHERHOBBY_DUALC3_DUAL) || defined(ELRS_GENERIC_C3_TRUE_DIVERSITY_DUAL) + +// Pin Configuration 4 - Shared by multiple targets +#if defined(ELRS_BAYCKRC_RR2_DUAL) || defined(ELRS_BAYCKRC_SINGLE_DUAL) || defined(ELRS_BAYCKRC_UR100_DUAL) || defined(ELRS_BAYCKRC_UR500_DUAL) || defined(ELRS_BAYCKRC_UR1000_DUAL) || defined(ELRS_BETAFPV_SUPERX_MONO_DUAL) || defined(ELRS_DAKEFPV_RX900_DUAL) || defined(ELRS_GENERIC_C3_PLAIN_DUAL) || defined(ELRS_GEPRC_SINGLE_DUAL) || defined(ELRS_SUB250_SINGLE_DUAL) || defined(ELRS_RADIOMASTER_XR2_DUAL) || defined(ELRS_RADIOMASTER_XR1_DUAL) || defined(ELRS_RADIOMASTER_XR3_DUAL) +#define USE_LR1121 + +// Radio pins +#define LORA_BUSY 3 +#define LORA_CS 7 +#define LORA_DIO1 1 +#define LORA_MISO 5 +#define LORA_MOSI 4 +#define LORA_RESET 2 +#define LORA_SCK 6 + +// Other pins +#define NEOPIXEL_DATA 8 +#define SERIAL_RX_PIN 20 +#define SERIAL_TX_PIN 21 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BAYCKRC_RR2_DUAL) || defined(ELRS_BAYCKRC_SINGLE_DUAL) || defined(ELRS_BAYCKRC_UR100_DUAL) || defined(ELRS_BAYCKRC_UR500_DUAL) || defined(ELRS_BAYCKRC_UR1000_DUAL) || defined(ELRS_BETAFPV_SUPERX_MONO_DUAL) || defined(ELRS_DAKEFPV_RX900_DUAL) || defined(ELRS_GENERIC_C3_PLAIN_DUAL) || defined(ELRS_GEPRC_SINGLE_DUAL) || defined(ELRS_SUB250_SINGLE_DUAL) || defined(ELRS_RADIOMASTER_XR2_DUAL) || defined(ELRS_RADIOMASTER_XR1_DUAL) || defined(ELRS_RADIOMASTER_XR3_DUAL) + +// Pin Configuration 5 - Shared by multiple targets +#if defined(ELRS_BAYCKRC_PWM_DUAL) || defined(ELRS_GENERIC_C3_PWM_DUAL) +#define USE_LR1121 + +// Radio pins +#define LORA_BUSY 3 +#define LORA_CS 7 +#define LORA_DIO1 1 +#define LORA_MISO 5 +#define LORA_MOSI 4 +#define LORA_RESET 2 +#define LORA_SCK 6 + +// Other pins +#define NEOPIXEL_DATA 8 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BAYCKRC_PWM_DUAL) || defined(ELRS_GENERIC_C3_PWM_DUAL) + +// Pin Configuration 6 - Shared by multiple targets +#if defined(ELRS_BOTLAB_BOTLINK1_2400) || defined(ELRS_FLYCOLOR_C3_2400) || defined(ELRS_GENERIC_C3_PLAIN_2400) || defined(ELRS_GENERIC_C3_PLAIN_PA_2400) || defined(ELRS_HDZERO_AIO15_2400) || defined(ELRS_NEWBEEDRONE_MICROG_2400) || defined(ELRS_NEWBEEDRONE_C324D_2400) || defined(ELRS_SPEEDYBEE_AIO_2400) || defined(ELRS_TUNERC_TUNERC_2400_NANO_PA_RX_2400) +#define USE_SX1280 + +// Radio pins +#define LORA_BUSY 3 +#define LORA_CS 7 +#define LORA_DIO1 1 +#define LORA_MISO 5 +#define LORA_MOSI 4 +#define LORA_RESET 2 +#define LORA_SCK 6 + +// Other pins +#define NEOPIXEL_DATA 8 +#define SERIAL_RX_PIN 20 +#define SERIAL_TX_PIN 21 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BOTLAB_BOTLINK1_2400) || defined(ELRS_FLYCOLOR_C3_2400) || defined(ELRS_GENERIC_C3_PLAIN_2400) || defined(ELRS_GENERIC_C3_PLAIN_PA_2400) || defined(ELRS_HDZERO_AIO15_2400) || defined(ELRS_NEWBEEDRONE_MICROG_2400) || defined(ELRS_NEWBEEDRONE_C324D_2400) || defined(ELRS_SPEEDYBEE_AIO_2400) || defined(ELRS_TUNERC_TUNERC_2400_NANO_PA_RX_2400) + +// Set second radio CS pin high at startup to disable it +#if defined(TWO_RADIOS) +#define PIN_ENABLE_HIGH LORA_CS_2 +#endif // TWO_RADIOS + +// Ensure only one target is selected +#if defined(ELRS_BAYCKRC_RRD1_2400) + defined(ELRS_GENERIC_C3_TD_2400) + defined(ELRS_HDZERO_HALO_2400) + defined(ELRS_BAYCKRC_PWMC3_2400) + defined(ELRS_GENERIC_C3_PWM_2400) + defined(ELRS_JUMPER_C3_PWM6_2400) + defined(ELRS_BAYCKRC_RRD2_DUAL) + defined(ELRS_BAYCKRC_DUALC3_DUAL) + defined(ELRS_BETAFPV_SUPERX_NANO_DUAL) + defined(ELRS_BROTHERHOBBY_DUALC3_DUAL) + defined(ELRS_GENERIC_C3_TRUE_DIVERSITY_DUAL) + defined(ELRS_BAYCKRC_RR2_DUAL) + defined(ELRS_BAYCKRC_SINGLE_DUAL) + defined(ELRS_BAYCKRC_UR100_DUAL) + defined(ELRS_BAYCKRC_UR500_DUAL) + defined(ELRS_BAYCKRC_UR1000_DUAL) + defined(ELRS_BETAFPV_SUPERX_MONO_DUAL) + defined(ELRS_DAKEFPV_RX900_DUAL) + defined(ELRS_GENERIC_C3_PLAIN_DUAL) + defined(ELRS_GEPRC_SINGLE_DUAL) + defined(ELRS_SUB250_SINGLE_DUAL) + defined(ELRS_RADIOMASTER_XR2_DUAL) + defined(ELRS_RADIOMASTER_XR1_DUAL) + defined(ELRS_RADIOMASTER_XR3_DUAL) + defined(ELRS_BAYCKRC_PWM_DUAL) + defined(ELRS_GENERIC_C3_PWM_DUAL) + defined(ELRS_BOTLAB_BOTLINK1_2400) + defined(ELRS_FLYCOLOR_C3_2400) + defined(ELRS_GENERIC_C3_PLAIN_2400) + defined(ELRS_GENERIC_C3_PLAIN_PA_2400) + defined(ELRS_HDZERO_AIO15_2400) + defined(ELRS_NEWBEEDRONE_MICROG_2400) + defined(ELRS_NEWBEEDRONE_C324D_2400) + defined(ELRS_SPEEDYBEE_AIO_2400) + defined(ELRS_TUNERC_TUNERC_2400_NANO_PA_RX_2400) != 1 +#error "Exactly one ELRS target must be defined" +#endif \ No newline at end of file diff --git a/variants/esp32/elrs/esp32-s3/platformio.ini b/variants/esp32/elrs/esp32-s3/platformio.ini new file mode 100644 index 000000000..6f668b008 --- /dev/null +++ b/variants/esp32/elrs/esp32-s3/platformio.ini @@ -0,0 +1,75 @@ +[env:elrs-bsip-superx-mono-dual] +extends = esp32c3_base +platform = espressif32 +board = esp32-s3-devkitc-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-s3 + -D ELRS_BSIP_SUPERX_MONO_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-diy-true-diversity-pwm16-s3-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-s3-devkitc-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-s3 + -D ELRS_DIY_TRUE_DIVERSITY_PWM16_S3_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-diy-true-diversity-vtx-pwm11-s3-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-s3-devkitc-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-s3 + -D ELRS_DIY_TRUE_DIVERSITY_VTX_PWM11_S3_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} + +[env:elrs-spracing-rxg1-2400] +extends = esp32c3_base +platform = espressif32 +board = esp32-s3-devkitc-1 +framework = arduino +board_level = extra +build_flags = + ${esp32c3_base.build_flags} + -I variants/esp32/elrs/esp32-s3 + -D ELRS_SPRACING_RXG1_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +monitor_speed = 115200 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32c3_base.lib_deps} diff --git a/variants/esp32/elrs/esp32-s3/rfswitch.h b/variants/esp32/elrs/esp32-s3/rfswitch.h new file mode 100644 index 000000000..71508c037 --- /dev/null +++ b/variants/esp32/elrs/esp32-s3/rfswitch.h @@ -0,0 +1,20 @@ +#include "RadioLib.h" + +// This is rewritten to match the requirements of the E80-900M2213S +// The E80 does not conform to the reference Semtech switches(!) and therefore needs a custom matrix. +// See footnote #3 in "https://www.cdebyte.com/products/E80-900M2213S/2#Pin" +// RF Switch Matrix SubG RFO_HP_LF / RFO_LP_LF / RFI_[NP]_LF0 +// DIO5 -> RFSW0_V1 +// DIO6 -> RFSW1_V2 +// DIO7 -> not connected on E80 module - note that GNSS and Wifi scanning are not possible. + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, RADIOLIB_NC, + RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 DIO7 + {LR11x0::MODE_STBY, {LOW, LOW, LOW}}, {LR11x0::MODE_RX, {LOW, HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH, LOW}}, {LR11x0::MODE_TX_HP, {HIGH, LOW, LOW}}, + {LR11x0::MODE_TX_HF, {LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH}}, + {LR11x0::MODE_WIFI, {LOW, LOW, LOW}}, END_OF_MODE_TABLE, +}; diff --git a/variants/esp32/elrs/esp32-s3/variant.h b/variants/esp32/elrs/esp32-s3/variant.h new file mode 100644 index 000000000..5be9fbc0c --- /dev/null +++ b/variants/esp32/elrs/esp32-s3/variant.h @@ -0,0 +1,145 @@ +// ELRS Target Selection - automatically defined by PlatformIO environment +// #define ELRS_BSIP_SUPERX_MONO_DUAL +// #define ELRS_DIY_TRUE_DIVERSITY_PWM16_S3_2400 +// #define ELRS_DIY_TRUE_DIVERSITY_VTX_PWM11_S3_2400 +// #define ELRS_SPRACING_RXG1_2400 + +// Common settings +#undef HAS_GPS +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#undef EXT_NOTIFY_OUT + +// Global chip-specific pin mappings +// SX128X mappings (2.4GHz) +#define SX128X_CS LORA_CS +#define SX128X_DIO1 LORA_DIO1 +#define SX128X_BUSY LORA_BUSY +#define SX128X_RESET LORA_RESET + +// LR1121 mappings (dual-band) +#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 +#define LR1121_NRESET_PIN LORA_RESET +#define LR1121_BUSY_PIN LORA_BUSY +#define LR1121_IRQ_PIN LORA_DIO1 +#define LR11X0_DIO_AS_RF_SWITCH + +// Second radio mappings for true diversity +#define SX128X_CS_2 LORA_CS_2 +#define SX128X_DIO0_2 LORA_DIO0_2 +#define SX128X_DIO1_2 LORA_DIO1_2 +#define SX128X_BUSY_2 LORA_BUSY_2 +#define SX128X_RESET_2 LORA_RESET_2 +#define LR1121_SPI_NSS_2_PIN LORA_CS_2 +#define LR1121_NRESET_2_PIN LORA_RESET_2 +#define LR1121_BUSY_2_PIN LORA_BUSY_2 +#define LR1121_IRQ_2_PIN LORA_DIO1_2 + +// bsip superx-mono +#ifdef ELRS_BSIP_SUPERX_MONO_DUAL +#define USE_LR1121 +#define TWO_RADIOS + +// Radio pins +#define LORA_BUSY 14 +#define LORA_CS 4 +#define LORA_DIO1 11 +#define LORA_MISO 7 +#define LORA_MOSI 6 +#define LORA_RESET 12 +#define LORA_SCK 5 + +// Second radio pins (true diversity) +#define LORA_BUSY_2 36 +#define LORA_CS_2 13 +#define LORA_DIO1_2 21 +#define LORA_RESET_2 33 + +// Other pins +#define NEOPIXEL_DATA 2 +#define SERIAL_RX_PIN 44 +#define SERIAL_TX_PIN 43 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // ELRS_BSIP_SUPERX_MONO_DUAL + +// Pin Configuration 2 - Shared by multiple targets +#if defined(ELRS_DIY_TRUE_DIVERSITY_PWM16_S3_2400) || defined(ELRS_DIY_TRUE_DIVERSITY_VTX_PWM11_S3_2400) +#define USE_SX1280 +#define TWO_RADIOS + +// Radio pins +#define LORA_BUSY 4 +#define LORA_CS 17 +#define LORA_DIO1 5 +#define LORA_MISO 15 +#define LORA_MOSI 16 +#define LORA_RESET 6 +#define LORA_SCK 7 + +// Second radio pins (true diversity) +#define LORA_BUSY_2 18 +#define LORA_CS_2 46 +#define LORA_DIO1_2 8 +#define LORA_RESET_2 3 + +// Other pins +#define NEOPIXEL_DATA 48 +#define SERIAL_RX_PIN 44 +#define SERIAL_TX_PIN 43 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_DIY_TRUE_DIVERSITY_PWM16_S3_2400) || defined(ELRS_DIY_TRUE_DIVERSITY_VTX_PWM11_S3_2400) + +// spracing rxg1 +#ifdef ELRS_SPRACING_RXG1_2400 +#define USE_SX1280 +#define TWO_RADIOS + +// Radio pins +#define LORA_BUSY 7 +#define LORA_CS 10 +#define LORA_DIO1 6 +#define LORA_MISO 13 +#define LORA_MOSI 11 +#define LORA_RESET 9 +#define LORA_SCK 12 + +// Second radio pins (true diversity) +#define LORA_BUSY_2 5 +#define LORA_CS_2 8 +#define LORA_DIO1_2 4 +#define LORA_RESET_2 46 + +// Other pins +#define NEOPIXEL_DATA 38 +#define SERIAL_RX_PIN 44 +#define SERIAL_TX_PIN 43 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // ELRS_SPRACING_RXG1_2400 + +// Set second radio CS pin high at startup to disable it +#if defined(TWO_RADIOS) +#define PIN_ENABLE_HIGH LORA_CS_2 +#endif // TWO_RADIOS + +// Ensure only one target is selected +#if defined(ELRS_BSIP_SUPERX_MONO_DUAL) + defined(ELRS_DIY_TRUE_DIVERSITY_PWM16_S3_2400) + defined(ELRS_DIY_TRUE_DIVERSITY_VTX_PWM11_S3_2400) + defined(ELRS_SPRACING_RXG1_2400) != 1 +#error "Exactly one ELRS target must be defined" +#endif \ No newline at end of file diff --git a/variants/esp32/elrs/esp32/platformio.ini b/variants/esp32/elrs/esp32/platformio.ini new file mode 100644 index 000000000..b595e47ea --- /dev/null +++ b/variants/esp32/elrs/esp32/platformio.ini @@ -0,0 +1,866 @@ +[env:elrs-anyleaf-dual-radio-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_ANYLEAF_DUAL_RADIO_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-bayckrc-dual-core-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_BAYCKRC_DUAL_CORE_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-bayckrc-dual-core-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_BAYCKRC_DUAL_CORE_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-bayckrc-dual-dual] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_BAYCKRC_DUAL_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-betafpv-superd-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_BETAFPV_SUPERD_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-betafpv-superp-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_BETAFPV_SUPERP_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-betafpv-superd-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_BETAFPV_SUPERD_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-betafpv-superp-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_BETAFPV_SUPERP_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-diy-ttgov1-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_DIY_TTGOV1_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-diy-ttgov2-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_DIY_TTGOV2_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-foxeer-td-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_FOXEER_TD_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-true-diversity-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_TRUE_DIVERSITY_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-true-diversity-pa-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_TRUE_DIVERSITY_PA_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-true-diversity-pwm16-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_TRUE_DIVERSITY_PWM16_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-pwm-vario-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_PWM_VARIO_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-frank-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_FRANK_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-rx-vtx-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_RX_VTX_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-true-diversity-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_TRUE_DIVERSITY_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-diversity-pa-vtx-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_DIVERSITY_PA_VTX_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-diversity-vtx-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_DIVERSITY_VTX_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-true-diversity-pwm16-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_TRUE_DIVERSITY_PWM16_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-true-diversity-pwm14-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_TRUE_DIVERSITY_PWM14_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-generic-true-diversity-dual] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GENERIC_TRUE_DIVERSITY_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-geprc-dual-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GEPRC_DUAL_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-geprc-dual500-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GEPRC_DUAL500_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-geprc-geprc-dual-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GEPRC_GEPRC_DUAL_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-geprc-dual-dual] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_GEPRC_DUAL_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-happymodel-es900-dual-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_HAPPYMODEL_ES900_DUAL_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-happymodel-ep-dual-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_HAPPYMODEL_EP_DUAL_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-happymodel-aio-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_HAPPYMODEL_AIO_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-helloradio-hr8e-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_HELLORADIO_HR8E_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-helloradio-hr7e-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_HELLORADIO_HR7E_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-hglrc-dual-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_HGLRC_DUAL_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-hglrc-dual-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_HGLRC_DUAL_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-iflight-dual500-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_IFLIGHT_DUAL500_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-iflight-dual250-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_IFLIGHT_DUAL250_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-bandit-nano-rx-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_BANDIT_NANO_RX_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-er6-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_ER6_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-er6g-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_ER6G_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-er6gv-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_ER6GV_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-er8-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_ER8_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-er8g-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_ER8G_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-er8gv-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_ER8GV_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-rp4-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_RP4_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-rp4m-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_RP4M_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-nexus-xr-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_NEXUS_XR_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-dbr4-dual] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_DBR4_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-radiomaster-xr4-dual] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_RADIOMASTER_XR4_DUAL + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-sequre-dual-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_SEQURE_DUAL_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-sequre-dual-900] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_SEQURE_DUAL_900 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} + +[env:elrs-spracing-rxn1-2400] +extends = esp32_base +platform = espressif32 +board = esp32-pico-d4 +framework = arduino +build_flags = + ${esp32_base.build_flags} + -I variants/esp32/elrs/esp32 + -D ELRS_SPRACING_RXN1_2400 + -D PRIVATE_HW + -O2 + -D CONFIG_DISABLE_HAL_LOCKS=1 +upload_protocol = esptool +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} diff --git a/variants/esp32/elrs/esp32/rfswitch.h b/variants/esp32/elrs/esp32/rfswitch.h new file mode 100644 index 000000000..71508c037 --- /dev/null +++ b/variants/esp32/elrs/esp32/rfswitch.h @@ -0,0 +1,20 @@ +#include "RadioLib.h" + +// This is rewritten to match the requirements of the E80-900M2213S +// The E80 does not conform to the reference Semtech switches(!) and therefore needs a custom matrix. +// See footnote #3 in "https://www.cdebyte.com/products/E80-900M2213S/2#Pin" +// RF Switch Matrix SubG RFO_HP_LF / RFO_LP_LF / RFI_[NP]_LF0 +// DIO5 -> RFSW0_V1 +// DIO6 -> RFSW1_V2 +// DIO7 -> not connected on E80 module - note that GNSS and Wifi scanning are not possible. + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, RADIOLIB_NC, + RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 DIO7 + {LR11x0::MODE_STBY, {LOW, LOW, LOW}}, {LR11x0::MODE_RX, {LOW, HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH, LOW}}, {LR11x0::MODE_TX_HP, {HIGH, LOW, LOW}}, + {LR11x0::MODE_TX_HF, {LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH}}, + {LR11x0::MODE_WIFI, {LOW, LOW, LOW}}, END_OF_MODE_TABLE, +}; diff --git a/variants/esp32/elrs/esp32/variant.h b/variants/esp32/elrs/esp32/variant.h new file mode 100644 index 000000000..ddc1b2d70 --- /dev/null +++ b/variants/esp32/elrs/esp32/variant.h @@ -0,0 +1,451 @@ +// ELRS Target Selection - automatically defined by PlatformIO environment +// #define ELRS_ANYLEAF_DUAL_RADIO_2400 +// #define ELRS_BAYCKRC_DUAL_CORE_2400 +// #define ELRS_BETAFPV_SUPERD_2400 +// #define ELRS_GENERIC_TRUE_DIVERSITY_2400 +// #define ELRS_GENERIC_DIVERSITY_PA_VTX_2400 +// #define ELRS_GENERIC_DIVERSITY_VTX_2400 +// #define ELRS_GEPRC_GEPRC_DUAL_2400 +// #define ELRS_HAPPYMODEL_EP_DUAL_2400 +// #define ELRS_HGLRC_DUAL_2400 +// #define ELRS_IFLIGHT_DUAL250_2400 +// #define ELRS_RADIOMASTER_RP4_2400 +// #define ELRS_RADIOMASTER_RP4M_2400 +// #define ELRS_RADIOMASTER_NEXUS_XR_2400 +// #define ELRS_SEQURE_DUAL_2400 +// #define ELRS_BAYCKRC_DUAL_CORE_900 +// #define ELRS_BETAFPV_SUPERD_900 +// #define ELRS_FOXEER_TD_900 +// #define ELRS_GENERIC_TRUE_DIVERSITY_900 +// #define ELRS_GENERIC_TRUE_DIVERSITY_PA_900 +// #define ELRS_GEPRC_DUAL_900 +// #define ELRS_GEPRC_DUAL500_900 +// #define ELRS_HAPPYMODEL_ES900_DUAL_900 +// #define ELRS_HGLRC_DUAL_900 +// #define ELRS_IFLIGHT_DUAL500_900 +// #define ELRS_SEQURE_DUAL_900 +// #define ELRS_BAYCKRC_DUAL_DUAL +// #define ELRS_GENERIC_TRUE_DIVERSITY_DUAL +// #define ELRS_GEPRC_DUAL_DUAL +// #define ELRS_RADIOMASTER_DBR4_DUAL +// #define ELRS_RADIOMASTER_XR4_DUAL +// #define ELRS_BETAFPV_SUPERP_900 +// #define ELRS_GENERIC_TRUE_DIVERSITY_PWM16_900 +// #define ELRS_BETAFPV_SUPERP_2400 +// #define ELRS_GENERIC_TRUE_DIVERSITY_PWM16_2400 +// #define ELRS_GENERIC_TRUE_DIVERSITY_PWM14_2400 +// #define ELRS_DIY_TTGOV1_900 +// #define ELRS_DIY_TTGOV2_900 +// #define ELRS_GENERIC_PWM_VARIO_2400 +// #define ELRS_RADIOMASTER_ER6G_2400 +// #define ELRS_RADIOMASTER_ER6GV_2400 +// #define ELRS_GENERIC_FRANK_2400 +// #define ELRS_GENERIC_RX_VTX_2400 +// #define ELRS_HAPPYMODEL_AIO_2400 +// #define ELRS_HELLORADIO_HR8E_2400 +// #define ELRS_HELLORADIO_HR7E_2400 +// #define ELRS_RADIOMASTER_BANDIT_NANO_RX_900 +// #define ELRS_RADIOMASTER_ER6_2400 +// #define ELRS_RADIOMASTER_ER8_2400 +// #define ELRS_RADIOMASTER_ER8G_2400 +// #define ELRS_RADIOMASTER_ER8GV_2400 +// #define ELRS_SPRACING_RXN1_2400 + +// Common settings +#undef HAS_GPS +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#undef EXT_NOTIFY_OUT + +// Global chip-specific pin mappings +// SX128X mappings (2.4GHz) +#define SX128X_CS LORA_CS +#define SX128X_DIO1 LORA_DIO1 +#define SX128X_BUSY LORA_BUSY +#define SX128X_RESET LORA_RESET + +// LR1121 mappings (dual-band) +#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 +#define LR1121_NRESET_PIN LORA_RESET +#define LR1121_BUSY_PIN LORA_BUSY +#define LR1121_IRQ_PIN LORA_DIO1 +#define LR11X0_DIO_AS_RF_SWITCH + +// Second radio mappings for true diversity +#define SX128X_CS_2 LORA_CS_2 +#define SX128X_DIO0_2 LORA_DIO0_2 +#define SX128X_DIO1_2 LORA_DIO1_2 +#define SX128X_BUSY_2 LORA_BUSY_2 +#define SX128X_RESET_2 LORA_RESET_2 +#define LR1121_SPI_NSS_2_PIN LORA_CS_2 +#define LR1121_NRESET_2_PIN LORA_RESET_2 +#define LR1121_BUSY_2_PIN LORA_BUSY_2 +#define LR1121_IRQ_2_PIN LORA_DIO1_2 + +// Pin Configuration 1 - Shared by multiple targets +#if defined(ELRS_ANYLEAF_DUAL_RADIO_2400) || defined(ELRS_BAYCKRC_DUAL_CORE_2400) || defined(ELRS_BETAFPV_SUPERD_2400) || defined(ELRS_GENERIC_TRUE_DIVERSITY_2400) || defined(ELRS_GENERIC_DIVERSITY_PA_VTX_2400) || defined(ELRS_GENERIC_DIVERSITY_VTX_2400) || defined(ELRS_GEPRC_GEPRC_DUAL_2400) || defined(ELRS_HAPPYMODEL_EP_DUAL_2400) || defined(ELRS_HGLRC_DUAL_2400) || defined(ELRS_IFLIGHT_DUAL250_2400) || defined(ELRS_RADIOMASTER_RP4_2400) || defined(ELRS_RADIOMASTER_RP4M_2400) || defined(ELRS_RADIOMASTER_NEXUS_XR_2400) || defined(ELRS_SEQURE_DUAL_2400) +#define USE_SX1280 +#define TWO_RADIOS + +// Radio pins +#define LORA_BUSY 36 +#define LORA_CS 27 +#define LORA_DIO1 37 +#define LORA_MISO 33 +#define LORA_MOSI 32 +#define LORA_RESET 26 +#define LORA_SCK 25 + +// Second radio pins (true diversity) +#define LORA_BUSY_2 39 +#define LORA_CS_2 13 +#define LORA_DIO1_2 34 +#define LORA_RESET_2 21 + +// Other pins +#define NEOPIXEL_DATA 22 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_ANYLEAF_DUAL_RADIO_2400) || defined(ELRS_BAYCKRC_DUAL_CORE_2400) || defined(ELRS_BETAFPV_SUPERD_2400) || defined(ELRS_GENERIC_TRUE_DIVERSITY_2400) || defined(ELRS_GENERIC_DIVERSITY_PA_VTX_2400) || defined(ELRS_GENERIC_DIVERSITY_VTX_2400) || defined(ELRS_GEPRC_GEPRC_DUAL_2400) || defined(ELRS_HAPPYMODEL_EP_DUAL_2400) || defined(ELRS_HGLRC_DUAL_2400) || defined(ELRS_IFLIGHT_DUAL250_2400) || defined(ELRS_RADIOMASTER_RP4_2400) || defined(ELRS_RADIOMASTER_RP4M_2400) || defined(ELRS_RADIOMASTER_NEXUS_XR_2400) || defined(ELRS_SEQURE_DUAL_2400) + +// Pin Configuration 2 - Shared by multiple targets +#if defined(ELRS_BAYCKRC_DUAL_CORE_900) || defined(ELRS_BETAFPV_SUPERD_900) || defined(ELRS_FOXEER_TD_900) || defined(ELRS_GENERIC_TRUE_DIVERSITY_900) || defined(ELRS_GENERIC_TRUE_DIVERSITY_PA_900) || defined(ELRS_GEPRC_DUAL_900) || defined(ELRS_GEPRC_DUAL500_900) || defined(ELRS_HAPPYMODEL_ES900_DUAL_900) || defined(ELRS_HGLRC_DUAL_900) || defined(ELRS_IFLIGHT_DUAL500_900) || defined(ELRS_SEQURE_DUAL_900) +#define USE_RF95 +#define TWO_RADIOS + +// Radio pins +#define LORA_CS 27 +#define LORA_DIO0 36 +#define LORA_DIO1 37 +#define LORA_MISO 33 +#define LORA_MOSI 32 +#define LORA_RESET 26 +#define LORA_SCK 25 + +// Second radio pins (true diversity) +#define LORA_CS_2 13 +#define LORA_DIO0_2 39 +#define LORA_DIO1_2 34 +#define LORA_RESET_2 21 + +// Other pins +#define NEOPIXEL_DATA 22 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BAYCKRC_DUAL_CORE_900) || defined(ELRS_BETAFPV_SUPERD_900) || defined(ELRS_FOXEER_TD_900) || defined(ELRS_GENERIC_TRUE_DIVERSITY_900) || defined(ELRS_GENERIC_TRUE_DIVERSITY_PA_900) || defined(ELRS_GEPRC_DUAL_900) || defined(ELRS_GEPRC_DUAL500_900) || defined(ELRS_HAPPYMODEL_ES900_DUAL_900) || defined(ELRS_HGLRC_DUAL_900) || defined(ELRS_IFLIGHT_DUAL500_900) || defined(ELRS_SEQURE_DUAL_900) + +// Pin Configuration 3 - Shared by multiple targets +#if defined(ELRS_BAYCKRC_DUAL_DUAL) || defined(ELRS_GENERIC_TRUE_DIVERSITY_DUAL) || defined(ELRS_GEPRC_DUAL_DUAL) || defined(ELRS_RADIOMASTER_DBR4_DUAL) || defined(ELRS_RADIOMASTER_XR4_DUAL) +#define USE_LR1121 +#define TWO_RADIOS + +// Radio pins +#define LORA_BUSY 36 +#define LORA_CS 27 +#define LORA_DIO1 37 +#define LORA_MISO 33 +#define LORA_MOSI 32 +#define LORA_RESET 26 +#define LORA_SCK 25 + +// Second radio pins (true diversity) +#define LORA_BUSY_2 39 +#define LORA_CS_2 13 +#define LORA_DIO1_2 34 +#define LORA_RESET_2 21 + +// Other pins +#define NEOPIXEL_DATA 22 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BAYCKRC_DUAL_DUAL) || defined(ELRS_GENERIC_TRUE_DIVERSITY_DUAL) || defined(ELRS_GEPRC_DUAL_DUAL) || defined(ELRS_RADIOMASTER_DBR4_DUAL) || defined(ELRS_RADIOMASTER_XR4_DUAL) + +// Pin Configuration 4 - Shared by multiple targets +#if defined(ELRS_BETAFPV_SUPERP_900) || defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM16_900) +#define USE_RF95 +#define TWO_RADIOS + +// Radio pins +#define LORA_CS 26 +#define LORA_DIO0 37 +#define LORA_DIO1 38 +#define LORA_MISO 35 +#define LORA_MOSI 32 +#define LORA_RESET 25 +#define LORA_SCK 33 + +// Second radio pins (true diversity) +#define LORA_CS_2 27 +#define LORA_DIO0_2 39 +#define LORA_DIO1_2 34 + +// Other pins +#define NEOPIXEL_DATA 21 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BETAFPV_SUPERP_900) || defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM16_900) + +// Pin Configuration 5 - Shared by multiple targets +#if defined(ELRS_BETAFPV_SUPERP_2400) || defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM16_2400) || defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM14_2400) +#define USE_SX1280 +#define TWO_RADIOS + +// Radio pins +#define LORA_BUSY 37 +#define LORA_CS 26 +#define LORA_DIO1 38 +#define LORA_MISO 35 +#define LORA_MOSI 32 +#define LORA_RESET 25 +#define LORA_SCK 33 + +// Second radio pins (true diversity) +#define LORA_BUSY_2 39 +#define LORA_CS_2 27 +#define LORA_DIO1_2 34 + +// Other pins +#define NEOPIXEL_DATA 21 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_BETAFPV_SUPERP_2400) || defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM16_2400) || defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM14_2400) + +// diy ttgov1 +#ifdef ELRS_DIY_TTGOV1_900 +#define USE_RF95 + +// Radio pins +#define LORA_CS 18 +#define LORA_DIO0 26 +#define LORA_MISO 19 +#define LORA_MOSI 27 +#define LORA_RESET 14 +#define LORA_SCK 5 + +// Other pins +#define LED_PIN 2 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + +#endif // ELRS_DIY_TTGOV1_900 + +// diy ttgov2 +#ifdef ELRS_DIY_TTGOV2_900 +#define USE_RF95 + +// Radio pins +#define LORA_CS 18 +#define LORA_DIO0 26 +#define LORA_MISO 19 +#define LORA_MOSI 27 +#define LORA_RESET 23 +#define LORA_SCK 5 + +// Other pins +#define LED_PIN 25 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + +#endif // ELRS_DIY_TTGOV2_900 + +// Pin Configuration 8 - Shared by multiple targets +#if defined(ELRS_GENERIC_PWM_VARIO_2400) || defined(ELRS_RADIOMASTER_ER6G_2400) || defined(ELRS_RADIOMASTER_ER6GV_2400) +#define USE_SX1280 + +// Radio pins +#define LORA_BUSY 36 +#define LORA_CS 27 +#define LORA_DIO1 37 +#define LORA_MISO 33 +#define LORA_MOSI 32 +#define LORA_RESET 13 +#define LORA_SCK 25 + +// Other pins +#define LED_PIN 21 + +#endif // defined(ELRS_GENERIC_PWM_VARIO_2400) || defined(ELRS_RADIOMASTER_ER6G_2400) || defined(ELRS_RADIOMASTER_ER6GV_2400) + +// generic frank +#ifdef ELRS_GENERIC_FRANK_2400 +#define USE_SX1280 + +// Radio pins +#define LORA_BUSY 36 +#define LORA_CS 10 +#define LORA_DIO1 39 +#define LORA_MISO 38 +#define LORA_MOSI 23 +#define LORA_RESET 9 +#define LORA_SCK 18 + +// Other pins +#define NEOPIXEL_DATA 2 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // ELRS_GENERIC_FRANK_2400 + +// Pin Configuration 10 - Shared by multiple targets +#if defined(ELRS_GENERIC_RX_VTX_2400) || defined(ELRS_HAPPYMODEL_AIO_2400) +#define USE_SX1280 + +// Radio pins +#define LORA_BUSY 36 +#define LORA_CS 27 +#define LORA_DIO1 37 +#define LORA_MISO 33 +#define LORA_MOSI 32 +#define LORA_RESET 26 +#define LORA_SCK 25 + +// Other pins +#define NEOPIXEL_DATA 22 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_GENERIC_RX_VTX_2400) || defined(ELRS_HAPPYMODEL_AIO_2400) + +// Pin Configuration 11 - Shared by multiple targets +#if defined(ELRS_HELLORADIO_HR8E_2400) || defined(ELRS_HELLORADIO_HR7E_2400) +#define USE_SX1280 + +// Radio pins +#define LORA_BUSY 37 +#define LORA_CS 26 +#define LORA_DIO1 38 +#define LORA_MISO 35 +#define LORA_MOSI 32 +#define LORA_RESET 25 +#define LORA_SCK 33 + +// Other pins +#define NEOPIXEL_DATA 21 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_HELLORADIO_HR8E_2400) || defined(ELRS_HELLORADIO_HR7E_2400) + +// radiomaster bandit-nano-rx +#ifdef ELRS_RADIOMASTER_BANDIT_NANO_RX_900 +#define USE_RF95 + +// Radio pins +#define LORA_CS 4 +#define LORA_DIO0 22 +#define LORA_DIO1 21 +#define LORA_MISO 19 +#define LORA_MOSI 23 +#define LORA_RESET 5 +#define LORA_SCK 18 + +// Other pins +#define LED_PIN 15 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + +#endif // ELRS_RADIOMASTER_BANDIT_NANO_RX_900 + +// Pin Configuration 13 - Shared by multiple targets +#if defined(ELRS_RADIOMASTER_ER6_2400) || defined(ELRS_RADIOMASTER_ER8_2400) || defined(ELRS_RADIOMASTER_ER8G_2400) || defined(ELRS_RADIOMASTER_ER8GV_2400) +#define USE_SX1280 + +// Radio pins +#define LORA_BUSY 36 +#define LORA_CS 27 +#define LORA_DIO1 37 +#define LORA_MISO 33 +#define LORA_MOSI 32 +#define LORA_RESET 13 +#define LORA_SCK 25 + +// Other pins +#define NEOPIXEL_DATA 21 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // defined(ELRS_RADIOMASTER_ER6_2400) || defined(ELRS_RADIOMASTER_ER8_2400) || defined(ELRS_RADIOMASTER_ER8G_2400) || defined(ELRS_RADIOMASTER_ER8GV_2400) + +// spracing rxn1 +#ifdef ELRS_SPRACING_RXN1_2400 +#define USE_SX1280 + +// Radio pins +#define LORA_BUSY 36 +#define LORA_CS 27 +#define LORA_DIO1 37 +#define LORA_MISO 4 +#define LORA_MOSI 32 +#define LORA_RESET 22 +#define LORA_SCK 33 + +// Other pins +#define NEOPIXEL_DATA 2 +#define SERIAL_RX_PIN 3 +#define SERIAL_TX_PIN 1 + + +// RGB LED +#define HAS_NEOPIXEL +#define NEOPIXEL_COUNT 1 +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) +#endif // ELRS_SPRACING_RXN1_2400 + +// Set second radio CS pin high at startup to disable it +#if defined(TWO_RADIOS) +#define PIN_ENABLE_HIGH LORA_CS_2 +#endif // TWO_RADIOS + +// Ensure only one target is selected +#if defined(ELRS_ANYLEAF_DUAL_RADIO_2400) + defined(ELRS_BAYCKRC_DUAL_CORE_2400) + defined(ELRS_BETAFPV_SUPERD_2400) + defined(ELRS_GENERIC_TRUE_DIVERSITY_2400) + defined(ELRS_GENERIC_DIVERSITY_PA_VTX_2400) + defined(ELRS_GENERIC_DIVERSITY_VTX_2400) + defined(ELRS_GEPRC_GEPRC_DUAL_2400) + defined(ELRS_HAPPYMODEL_EP_DUAL_2400) + defined(ELRS_HGLRC_DUAL_2400) + defined(ELRS_IFLIGHT_DUAL250_2400) + defined(ELRS_RADIOMASTER_RP4_2400) + defined(ELRS_RADIOMASTER_RP4M_2400) + defined(ELRS_RADIOMASTER_NEXUS_XR_2400) + defined(ELRS_SEQURE_DUAL_2400) + defined(ELRS_BAYCKRC_DUAL_CORE_900) + defined(ELRS_BETAFPV_SUPERD_900) + defined(ELRS_FOXEER_TD_900) + defined(ELRS_GENERIC_TRUE_DIVERSITY_900) + defined(ELRS_GENERIC_TRUE_DIVERSITY_PA_900) + defined(ELRS_GEPRC_DUAL_900) + defined(ELRS_GEPRC_DUAL500_900) + defined(ELRS_HAPPYMODEL_ES900_DUAL_900) + defined(ELRS_HGLRC_DUAL_900) + defined(ELRS_IFLIGHT_DUAL500_900) + defined(ELRS_SEQURE_DUAL_900) + defined(ELRS_BAYCKRC_DUAL_DUAL) + defined(ELRS_GENERIC_TRUE_DIVERSITY_DUAL) + defined(ELRS_GEPRC_DUAL_DUAL) + defined(ELRS_RADIOMASTER_DBR4_DUAL) + defined(ELRS_RADIOMASTER_XR4_DUAL) + defined(ELRS_BETAFPV_SUPERP_900) + defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM16_900) + defined(ELRS_BETAFPV_SUPERP_2400) + defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM16_2400) + defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM14_2400) + defined(ELRS_DIY_TTGOV1_900) + defined(ELRS_DIY_TTGOV2_900) + defined(ELRS_GENERIC_PWM_VARIO_2400) + defined(ELRS_RADIOMASTER_ER6G_2400) + defined(ELRS_RADIOMASTER_ER6GV_2400) + defined(ELRS_GENERIC_FRANK_2400) + defined(ELRS_GENERIC_RX_VTX_2400) + defined(ELRS_HAPPYMODEL_AIO_2400) + defined(ELRS_HELLORADIO_HR8E_2400) + defined(ELRS_HELLORADIO_HR7E_2400) + defined(ELRS_RADIOMASTER_BANDIT_NANO_RX_900) + defined(ELRS_RADIOMASTER_ER6_2400) + defined(ELRS_RADIOMASTER_ER8_2400) + defined(ELRS_RADIOMASTER_ER8G_2400) + defined(ELRS_RADIOMASTER_ER8GV_2400) + defined(ELRS_SPRACING_RXN1_2400) != 1 +#error "Exactly one ELRS target must be defined" +#endif \ No newline at end of file diff --git a/variants/esp32/elrs/rfswitch.h b/variants/esp32/elrs/rfswitch.h new file mode 100644 index 000000000..71508c037 --- /dev/null +++ b/variants/esp32/elrs/rfswitch.h @@ -0,0 +1,20 @@ +#include "RadioLib.h" + +// This is rewritten to match the requirements of the E80-900M2213S +// The E80 does not conform to the reference Semtech switches(!) and therefore needs a custom matrix. +// See footnote #3 in "https://www.cdebyte.com/products/E80-900M2213S/2#Pin" +// RF Switch Matrix SubG RFO_HP_LF / RFO_LP_LF / RFI_[NP]_LF0 +// DIO5 -> RFSW0_V1 +// DIO6 -> RFSW1_V2 +// DIO7 -> not connected on E80 module - note that GNSS and Wifi scanning are not possible. + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, RADIOLIB_NC, + RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 DIO7 + {LR11x0::MODE_STBY, {LOW, LOW, LOW}}, {LR11x0::MODE_RX, {LOW, HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH, LOW}}, {LR11x0::MODE_TX_HP, {HIGH, LOW, LOW}}, + {LR11x0::MODE_TX_HF, {LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH}}, + {LR11x0::MODE_WIFI, {LOW, LOW, LOW}}, END_OF_MODE_TABLE, +}; From 824cb97f93e1d861b097a86fcf9f105b46a70989 Mon Sep 17 00:00:00 2001 From: Senk02 Date: Thu, 14 Aug 2025 18:56:15 +0000 Subject: [PATCH 3/4] Fix lr1121 dio switch define --- variants/esp32/elrs/converter.py | 12 +- variants/esp32/elrs/esp32-c3/variant.h | 6 +- variants/esp32/elrs/esp32-s3/variant.h | 6 +- variants/esp32/elrs/esp32/variant.h | 6 +- variants/esp32/elrs/simple_converter_v2.py | 630 +++++++++++++++++++++ 5 files changed, 656 insertions(+), 4 deletions(-) create mode 100644 variants/esp32/elrs/simple_converter_v2.py diff --git a/variants/esp32/elrs/converter.py b/variants/esp32/elrs/converter.py index 9d0241e3f..4e14387b7 100644 --- a/variants/esp32/elrs/converter.py +++ b/variants/esp32/elrs/converter.py @@ -370,7 +370,6 @@ class SimpleELRSConverter: content.append("#define LR1121_NRESET_PIN LORA_RESET") content.append("#define LR1121_BUSY_PIN LORA_BUSY") content.append("#define LR1121_IRQ_PIN LORA_DIO1") - content.append("#define LR11X0_DIO_AS_RF_SWITCH") content.append("") content.append("// Second radio mappings for true diversity") content.append("#define SX128X_CS_2 LORA_CS_2") @@ -469,6 +468,17 @@ class SimpleELRSConverter: continue break + # Set LR11X0_DIO_AS_RF_SWITCH only if USE_LR1121 is defined + has_lr1121 = any(target['radio_chip'] == 'lr1121' for targets_list in pin_groups.values() for target in targets_list) + if has_lr1121: + content.extend([ + "// LR1121 RF switch control", + "#if defined(USE_LR1121)", + "#define LR11X0_DIO_AS_RF_SWITCH", + "#endif // USE_LR1121", + "" + ]) + # Footer - ensure only one target is selected all_defines = [t['define_name'] for targets_list in pin_groups.values() for t in targets_list] condition = " + ".join([f"defined({define})" for define in all_defines]) diff --git a/variants/esp32/elrs/esp32-c3/variant.h b/variants/esp32/elrs/esp32-c3/variant.h index e487a1bd7..d49b9569d 100644 --- a/variants/esp32/elrs/esp32-c3/variant.h +++ b/variants/esp32/elrs/esp32-c3/variant.h @@ -56,7 +56,6 @@ #define LR1121_NRESET_PIN LORA_RESET #define LR1121_BUSY_PIN LORA_BUSY #define LR1121_IRQ_PIN LORA_DIO1 -#define LR11X0_DIO_AS_RF_SWITCH // Second radio mappings for true diversity #define SX128X_CS_2 LORA_CS_2 @@ -234,6 +233,11 @@ #define PIN_ENABLE_HIGH LORA_CS_2 #endif // TWO_RADIOS +// LR1121 RF switch control +#if defined(USE_LR1121) +#define LR11X0_DIO_AS_RF_SWITCH +#endif // USE_LR1121 + // Ensure only one target is selected #if defined(ELRS_BAYCKRC_RRD1_2400) + defined(ELRS_GENERIC_C3_TD_2400) + defined(ELRS_HDZERO_HALO_2400) + defined(ELRS_BAYCKRC_PWMC3_2400) + defined(ELRS_GENERIC_C3_PWM_2400) + defined(ELRS_JUMPER_C3_PWM6_2400) + defined(ELRS_BAYCKRC_RRD2_DUAL) + defined(ELRS_BAYCKRC_DUALC3_DUAL) + defined(ELRS_BETAFPV_SUPERX_NANO_DUAL) + defined(ELRS_BROTHERHOBBY_DUALC3_DUAL) + defined(ELRS_GENERIC_C3_TRUE_DIVERSITY_DUAL) + defined(ELRS_BAYCKRC_RR2_DUAL) + defined(ELRS_BAYCKRC_SINGLE_DUAL) + defined(ELRS_BAYCKRC_UR100_DUAL) + defined(ELRS_BAYCKRC_UR500_DUAL) + defined(ELRS_BAYCKRC_UR1000_DUAL) + defined(ELRS_BETAFPV_SUPERX_MONO_DUAL) + defined(ELRS_DAKEFPV_RX900_DUAL) + defined(ELRS_GENERIC_C3_PLAIN_DUAL) + defined(ELRS_GEPRC_SINGLE_DUAL) + defined(ELRS_SUB250_SINGLE_DUAL) + defined(ELRS_RADIOMASTER_XR2_DUAL) + defined(ELRS_RADIOMASTER_XR1_DUAL) + defined(ELRS_RADIOMASTER_XR3_DUAL) + defined(ELRS_BAYCKRC_PWM_DUAL) + defined(ELRS_GENERIC_C3_PWM_DUAL) + defined(ELRS_BOTLAB_BOTLINK1_2400) + defined(ELRS_FLYCOLOR_C3_2400) + defined(ELRS_GENERIC_C3_PLAIN_2400) + defined(ELRS_GENERIC_C3_PLAIN_PA_2400) + defined(ELRS_HDZERO_AIO15_2400) + defined(ELRS_NEWBEEDRONE_MICROG_2400) + defined(ELRS_NEWBEEDRONE_C324D_2400) + defined(ELRS_SPEEDYBEE_AIO_2400) + defined(ELRS_TUNERC_TUNERC_2400_NANO_PA_RX_2400) != 1 #error "Exactly one ELRS target must be defined" diff --git a/variants/esp32/elrs/esp32-s3/variant.h b/variants/esp32/elrs/esp32-s3/variant.h index 5be9fbc0c..3bc25d41e 100644 --- a/variants/esp32/elrs/esp32-s3/variant.h +++ b/variants/esp32/elrs/esp32-s3/variant.h @@ -25,7 +25,6 @@ #define LR1121_NRESET_PIN LORA_RESET #define LR1121_BUSY_PIN LORA_BUSY #define LR1121_IRQ_PIN LORA_DIO1 -#define LR11X0_DIO_AS_RF_SWITCH // Second radio mappings for true diversity #define SX128X_CS_2 LORA_CS_2 @@ -139,6 +138,11 @@ #define PIN_ENABLE_HIGH LORA_CS_2 #endif // TWO_RADIOS +// LR1121 RF switch control +#if defined(USE_LR1121) +#define LR11X0_DIO_AS_RF_SWITCH +#endif // USE_LR1121 + // Ensure only one target is selected #if defined(ELRS_BSIP_SUPERX_MONO_DUAL) + defined(ELRS_DIY_TRUE_DIVERSITY_PWM16_S3_2400) + defined(ELRS_DIY_TRUE_DIVERSITY_VTX_PWM11_S3_2400) + defined(ELRS_SPRACING_RXG1_2400) != 1 #error "Exactly one ELRS target must be defined" diff --git a/variants/esp32/elrs/esp32/variant.h b/variants/esp32/elrs/esp32/variant.h index ddc1b2d70..714e21219 100644 --- a/variants/esp32/elrs/esp32/variant.h +++ b/variants/esp32/elrs/esp32/variant.h @@ -72,7 +72,6 @@ #define LR1121_NRESET_PIN LORA_RESET #define LR1121_BUSY_PIN LORA_BUSY #define LR1121_IRQ_PIN LORA_DIO1 -#define LR11X0_DIO_AS_RF_SWITCH // Second radio mappings for true diversity #define SX128X_CS_2 LORA_CS_2 @@ -445,6 +444,11 @@ #define PIN_ENABLE_HIGH LORA_CS_2 #endif // TWO_RADIOS +// LR1121 RF switch control +#if defined(USE_LR1121) +#define LR11X0_DIO_AS_RF_SWITCH +#endif // USE_LR1121 + // Ensure only one target is selected #if defined(ELRS_ANYLEAF_DUAL_RADIO_2400) + defined(ELRS_BAYCKRC_DUAL_CORE_2400) + defined(ELRS_BETAFPV_SUPERD_2400) + defined(ELRS_GENERIC_TRUE_DIVERSITY_2400) + defined(ELRS_GENERIC_DIVERSITY_PA_VTX_2400) + defined(ELRS_GENERIC_DIVERSITY_VTX_2400) + defined(ELRS_GEPRC_GEPRC_DUAL_2400) + defined(ELRS_HAPPYMODEL_EP_DUAL_2400) + defined(ELRS_HGLRC_DUAL_2400) + defined(ELRS_IFLIGHT_DUAL250_2400) + defined(ELRS_RADIOMASTER_RP4_2400) + defined(ELRS_RADIOMASTER_RP4M_2400) + defined(ELRS_RADIOMASTER_NEXUS_XR_2400) + defined(ELRS_SEQURE_DUAL_2400) + defined(ELRS_BAYCKRC_DUAL_CORE_900) + defined(ELRS_BETAFPV_SUPERD_900) + defined(ELRS_FOXEER_TD_900) + defined(ELRS_GENERIC_TRUE_DIVERSITY_900) + defined(ELRS_GENERIC_TRUE_DIVERSITY_PA_900) + defined(ELRS_GEPRC_DUAL_900) + defined(ELRS_GEPRC_DUAL500_900) + defined(ELRS_HAPPYMODEL_ES900_DUAL_900) + defined(ELRS_HGLRC_DUAL_900) + defined(ELRS_IFLIGHT_DUAL500_900) + defined(ELRS_SEQURE_DUAL_900) + defined(ELRS_BAYCKRC_DUAL_DUAL) + defined(ELRS_GENERIC_TRUE_DIVERSITY_DUAL) + defined(ELRS_GEPRC_DUAL_DUAL) + defined(ELRS_RADIOMASTER_DBR4_DUAL) + defined(ELRS_RADIOMASTER_XR4_DUAL) + defined(ELRS_BETAFPV_SUPERP_900) + defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM16_900) + defined(ELRS_BETAFPV_SUPERP_2400) + defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM16_2400) + defined(ELRS_GENERIC_TRUE_DIVERSITY_PWM14_2400) + defined(ELRS_DIY_TTGOV1_900) + defined(ELRS_DIY_TTGOV2_900) + defined(ELRS_GENERIC_PWM_VARIO_2400) + defined(ELRS_RADIOMASTER_ER6G_2400) + defined(ELRS_RADIOMASTER_ER6GV_2400) + defined(ELRS_GENERIC_FRANK_2400) + defined(ELRS_GENERIC_RX_VTX_2400) + defined(ELRS_HAPPYMODEL_AIO_2400) + defined(ELRS_HELLORADIO_HR8E_2400) + defined(ELRS_HELLORADIO_HR7E_2400) + defined(ELRS_RADIOMASTER_BANDIT_NANO_RX_900) + defined(ELRS_RADIOMASTER_ER6_2400) + defined(ELRS_RADIOMASTER_ER8_2400) + defined(ELRS_RADIOMASTER_ER8G_2400) + defined(ELRS_RADIOMASTER_ER8GV_2400) + defined(ELRS_SPRACING_RXN1_2400) != 1 #error "Exactly one ELRS target must be defined" diff --git a/variants/esp32/elrs/simple_converter_v2.py b/variants/esp32/elrs/simple_converter_v2.py new file mode 100644 index 000000000..24b9822c4 --- /dev/null +++ b/variants/esp32/elrs/simple_converter_v2.py @@ -0,0 +1,630 @@ +#!/usr/bin/env python3 +""" +Simple ELRS to Meshtastic Target Converter + +Converts ELRS target definitions to Meshtastic variant.h files. +""" + +# TODO: - Add support for amplifier chips +# TODO: - Clean up names of targets to avoid names like dual-dual + +import json +import os +import sys +import argparse +import subprocess +import shutil +import tempfile +from pathlib import Path +from typing import Dict, List, Optional + +class SimpleELRSConverter: + def __init__(self): + self.targets_data = {} + self.hardware_data = {} + self.temp_repo_path = None + + # Supported ESP32 platforms + self.supported_platforms = {'esp32', 'esp32-c3', 'esp32-s3'} + + # Radio chip mappings + self.radio_chips = { + 'sx1276': {'define': 'USE_RF95', 'freq': '900', 'type': 'rf95'}, + 'sx1277': {'define': 'USE_RF95', 'freq': '900', 'type': 'rf95'}, + 'sx1280': {'define': 'USE_SX1280', 'freq': '2400', 'type': 'sx128x'}, + 'lr1121': {'define': 'USE_LR1121', 'freq': 'dual', 'type': 'lr1121'} + } + + # Pin mappings from ELRS to Meshtastic + self.pin_mappings = { + # Basic SPI pins + 'radio_mosi': 'LORA_MOSI', + 'radio_miso': 'LORA_MISO', + 'radio_sck': 'LORA_SCK', + 'radio_nss': 'LORA_CS', + 'radio_rst': 'LORA_RESET', + + # Radio specific pins + 'radio_dio0': 'LORA_DIO0', + 'radio_dio1': 'LORA_DIO1', + 'radio_busy': 'LORA_BUSY', + 'radio_txen': 'LORA_TXEN', + 'radio_rxen': 'LORA_RXEN', + + # Second radio pins (for true diversity) + 'radio_nss_2': 'LORA_CS_2', + 'radio_rst_2': 'LORA_RESET_2', + 'radio_dio0_2': 'LORA_DIO0_2', + 'radio_dio1_2': 'LORA_DIO1_2', + 'radio_busy_2': 'LORA_BUSY_2', + 'radio_txen_2': 'LORA_TXEN_2', + 'radio_rxen_2': 'LORA_RXEN_2', + + # LED pins + 'led': 'LED_PIN', + 'led_red': 'LED_PIN', + 'led_blue': 'LED_PIN', + 'led_rgb': 'NEOPIXEL_DATA', + + # Other pins + 'pin_button': 'BUTTON_PIN', + 'serial_rx': 'SERIAL_RX_PIN', + 'serial_tx': 'SERIAL_TX_PIN', + } + + def clone_elrs_repo(self) -> bool: + """Clone the ELRS targets repository to a temporary directory""" + try: + # Create temporary directory + self.temp_repo_path = Path(tempfile.mkdtemp(prefix="elrs_targets_")) + print(f"Cloning ELRS targets repository to {self.temp_repo_path}") + + # Clone the repository + result = subprocess.run([ + 'git', 'clone', '--depth', '1', + 'https://github.com/ExpressLRS/targets.git', + str(self.temp_repo_path) + ], capture_output=True, text=True) + + if result.returncode != 0: + print(f"Failed to clone repository: {result.stderr}") + return False + + print("Successfully cloned ELRS targets repository") + return True + + except Exception as e: + print(f"Error cloning repository: {e}") + return False + + def cleanup_repo(self): + """Remove the temporary repository directory""" + if self.temp_repo_path and self.temp_repo_path.exists(): + try: + shutil.rmtree(self.temp_repo_path) + print(f"Cleaned up temporary repository at {self.temp_repo_path}") + except Exception as e: + print(f"Warning: Failed to cleanup temporary directory: {e}") + + def load_elrs_data(self) -> bool: + """Load ELRS targets.json and hardware definitions from local repository""" + if not self.temp_repo_path or not self.temp_repo_path.exists(): + print("Error: Repository not cloned. Call clone_elrs_repo() first.") + return False + + print("Loading ELRS data from local repository...") + + # Load targets.json + targets_file = self.temp_repo_path / 'targets.json' + if not targets_file.exists(): + print(f"Error: targets.json not found at {targets_file}") + return False + + print(" Loading targets.json...") + with open(targets_file, 'r') as f: + self.targets_data = json.load(f) + + print(f" Loaded {len(self.targets_data)} target brands") + + # Load hardware definitions from RX directory only + hw_dir = self.temp_repo_path / 'RX' + if not hw_dir.exists(): + print(" Warning: RX directory not found") + return False + + print(" Loading RX directory...") + hw_files = list(hw_dir.glob('*.json')) + + if not hw_files: + print(" No JSON files found in RX") + return False + + print(f" Found {len(hw_files)} files") + + for hw_file in hw_files: + try: + with open(hw_file, 'r') as f: + hw_data = json.load(f) + self.hardware_data[hw_file.name] = hw_data + except Exception as e: + print(f" Warning: Failed to load {hw_file.name}: {e}") + + print(f" Successfully loaded {len(self.hardware_data)} hardware definitions") + return True + + def extract_targets(self) -> List[Dict]: + """Extract and process all supported targets""" + processed_targets = [] + + for brand, categories in self.targets_data.items(): + if not isinstance(categories, dict): + continue + + for category, targets in categories.items(): + if not isinstance(targets, dict) or not category.startswith('rx_'): + continue # Only process RX targets + + for target_name, target_data in targets.items(): + if not isinstance(target_data, dict): + continue + + # Get hardware layout file + layout_file = target_data.get('layout_file', '') + if not layout_file: + continue + + # Find the hardware definition + hw_filename = layout_file if layout_file.endswith('.json') else f"{layout_file}.json" + hw_data = self.hardware_data.get(hw_filename) + + if not hw_data: + print(f"Warning: No hardware definition found for {hw_filename}") + continue + + # Process this target + target_config = self.process_target(brand, target_name, category, target_data, hw_data) + if target_config: + processed_targets.append(target_config) + + return processed_targets + + def process_target(self, brand: str, target_name: str, category: str, target_data: Dict, hw_data: Dict) -> Optional[Dict]: + """Process a single target""" + # Get firmware info + firmware = target_data.get('firmware', '') + + # Determine platform from firmware first, then fallback to target_data + platform = self.detect_platform_from_firmware(firmware) or target_data.get('platform', '') + + # Check if platform is supported + if platform not in self.supported_platforms: + return None + + # Determine radio chip - use firmware only + radio_chip = self.detect_radio_chip(firmware) + if not radio_chip: + return None + + radio_info = self.radio_chips[radio_chip] + pins = self.extract_pins(hw_data) + is_diversity = self.detect_true_diversity(hw_data) + define_name = self.generate_define_name(brand, target_name, radio_info['freq']) + + return { + 'brand': brand, + 'name': target_name, + 'category': category, + 'platform': platform, + 'firmware': firmware, + 'define_name': define_name, + 'radio_chip': radio_chip, + 'radio_info': radio_info, + 'pins': pins, + 'is_diversity': is_diversity, + 'hw_data': hw_data + } + + def detect_radio_chip(self, firmware: str) -> Optional[str]: + """Detect radio chip from firmware ONLY""" + if not firmware: + return None + + firmware_upper = firmware.upper() + + # Check for explicit radio chip mentions first + if 'LR1121' in firmware_upper: + return 'lr1121' + elif 'SX1280' in firmware_upper: + return 'sx1280' + elif 'SX1276' in firmware_upper or 'SX127X' in firmware_upper or 'SX1277' in firmware_upper: + return 'sx1276' + + # Fall back to frequency detection + if '2400' in firmware_upper: + return 'sx1280' + elif '900' in firmware_upper: + return 'sx1276' + + return None + + def detect_platform_from_firmware(self, firmware: str) -> Optional[str]: + """Detect platform from firmware string""" + if not firmware: + return None + + firmware_upper = firmware.upper() + + # Check for platform in firmware name + if 'ESP32C3' in firmware_upper: + return 'esp32-c3' + elif 'ESP32S3' in firmware_upper: + return 'esp32-s3' + elif 'ESP32' in firmware_upper: + return 'esp32' + + return None + + def detect_true_diversity(self, hw_data: Dict) -> bool: + """Detect if this is a true diversity setup by checking for second radio pins""" + diversity_pins = ['radio_dio0_2', 'radio_dio1_2', 'radio_rst_2', 'radio_nss_2', 'radio_busy_2'] + + return any(pin in hw_data and isinstance(hw_data[pin], int) for pin in diversity_pins) + + def extract_pins(self, hw_data: Dict) -> Dict[str, int]: + """Extract pin definitions from hardware data""" + pins = {} + + for elrs_pin, meshtastic_pin in self.pin_mappings.items(): + if elrs_pin in hw_data and isinstance(hw_data[elrs_pin], int): + pins[meshtastic_pin] = hw_data[elrs_pin] + + return pins + + def generate_define_name(self, brand: str, target_name: str, freq: str) -> str: + """Generate a clean define name for the target""" + # Clean up strings and remove common noise words + brand_clean = brand.upper().replace(' ', '_').replace('-', '_') + target_clean = target_name.upper().replace(' ', '_').replace('-', '_') + freq_clean = freq.upper() + + for word in ['MODULE', 'EXPRESSLRS', 'ELRS']: + brand_clean = brand_clean.replace(word, '') + target_clean = target_clean.replace(word, '') + + # Clean up extra underscores + brand_clean = '_'.join(filter(None, brand_clean.split('_'))) + target_clean = '_'.join(filter(None, target_clean.split('_'))) + + return f"ELRS_{brand_clean}_{target_clean}_{freq_clean}" + + def group_targets_by_pins(self, targets: List[Dict]) -> Dict[str, List[Dict]]: + """Group targets that have identical pin configurations""" + pin_groups = {} + + for target in targets: + # Create a signature of the pins and radio chip for grouping + pin_sig = self.create_pin_signature(target) + + if pin_sig not in pin_groups: + pin_groups[pin_sig] = [] + pin_groups[pin_sig].append(target) + + return pin_groups + + def create_pin_signature(self, target: Dict) -> str: + """Create a unique signature for pin configuration AND radio chip AND diversity status""" + # Sort pins to create consistent signature + pin_items = sorted(target['pins'].items()) + radio_chip = target['radio_info']['type'] + is_diversity = target['is_diversity'] + return f"{pin_items}_{radio_chip}_{is_diversity}" + + def generate_variant_file(self, platform: str, pin_groups: Dict, output_dir: Path): + """Generate variant.h file for a platform""" + variant_dir = output_dir / platform + variant_dir.mkdir(parents=True, exist_ok=True) + + variant_file = variant_dir / 'variant.h' + + with open(variant_file, 'w') as f: + f.write(self.generate_variant_content(platform, pin_groups)) + + print(f"Generated {variant_file}") + + def generate_variant_content(self, platform: str, pin_groups: Dict) -> str: + """Generate the content of variant.h file""" + content = [] + + # Header + content.append("// ELRS Target Selection - automatically defined by PlatformIO environment") + + # Generate target selection defines + all_targets = [] + for targets_list in pin_groups.values(): + all_targets.extend(targets_list) + + for i, target in enumerate(all_targets): + content.append(f"// #define {target['define_name']}") + + content.append("") + content.append("// Common settings") + content.append("#undef HAS_GPS") + content.append("#undef GPS_RX_PIN") + content.append("#undef GPS_TX_PIN") + content.append("#undef EXT_NOTIFY_OUT") + content.append("") + + # Add global chip-specific mappings at the top + content.append("// Global chip-specific pin mappings") + content.append("// SX128X mappings (2.4GHz)") + content.append("#define SX128X_CS LORA_CS") + content.append("#define SX128X_DIO1 LORA_DIO1") + content.append("#define SX128X_BUSY LORA_BUSY") + content.append("#define SX128X_RESET LORA_RESET") + content.append("") + content.append("// LR1121 mappings (dual-band)") + content.append("#define LR1121_SPI_NSS_PIN LORA_CS") + content.append("#define LR1121_SPI_SCK_PIN LORA_SCK") + content.append("#define LR1121_SPI_MOSI_PIN LORA_MOSI") + content.append("#define LR1121_SPI_MISO_PIN LORA_MISO") + content.append("#define LR1121_NRESET_PIN LORA_RESET") + content.append("#define LR1121_BUSY_PIN LORA_BUSY") + content.append("#define LR1121_IRQ_PIN LORA_DIO1") + content.append("") + content.append("// Second radio mappings for true diversity") + content.append("#define SX128X_CS_2 LORA_CS_2") + content.append("#define SX128X_DIO0_2 LORA_DIO0_2") + content.append("#define SX128X_DIO1_2 LORA_DIO1_2") + content.append("#define SX128X_BUSY_2 LORA_BUSY_2") + content.append("#define SX128X_RESET_2 LORA_RESET_2") + content.append("#define LR1121_SPI_NSS_2_PIN LORA_CS_2") + content.append("#define LR1121_NRESET_2_PIN LORA_RESET_2") + content.append("#define LR1121_BUSY_2_PIN LORA_BUSY_2") + content.append("#define LR1121_IRQ_2_PIN LORA_DIO1_2") + content.append("") + + # Generate pin configurations for each group + group_num = 1 + for pin_sig, targets_list in pin_groups.items(): + target = targets_list[0] # All targets in group have same pins/radio chip + + if len(targets_list) > 1: + content.append(f"// Pin Configuration {group_num} - Shared by multiple targets") + conditions = " || ".join([f"defined({t['define_name']})" for t in targets_list]) + content.append(f"#if {conditions}") + else: + content.append(f"// {target['brand']} {target['name']}") + content.append(f"#ifdef {target['define_name']}") + + content.append(f"#define {target['radio_info']['define']}") + + # Add TWO_RADIOS define if this is a diversity setup + if target['is_diversity']: + content.append("#define TWO_RADIOS") + + # Add LR11X0_DIO_AS_RF_SWITCH if using LR1121 + if target['radio_chip'] == 'lr1121': + content.append("#define LR11X0_DIO_AS_RF_SWITCH") + + content.append("") + + # Separate pins into categories + lora_pins = {k: v for k, v in target['pins'].items() if k.startswith('LORA_') and not k.endswith('_2')} + lora2_pins = {k: v for k, v in target['pins'].items() if k.startswith('LORA_') and k.endswith('_2')} + other_pins = {k: v for k, v in target['pins'].items() if not k.startswith('LORA_')} + + # Output radio pins + if lora_pins: + content.append("// Radio pins") + content.extend(f"#define {pin_name} {pin_value}" for pin_name, pin_value in sorted(lora_pins.items())) + content.append("") + + # Output second radio pins for diversity + if lora2_pins: + content.append("// Second radio pins (true diversity)") + content.extend(f"#define {pin_name} {pin_value}" for pin_name, pin_value in sorted(lora2_pins.items())) + content.append("") + + # Output other pins + if other_pins: + content.append("// Other pins") + content.extend(f"#define {pin_name} {pin_value}" for pin_name, pin_value in sorted(other_pins.items())) + content.append("") + # Add special features + if 'NEOPIXEL_DATA' in target['pins']: + content.extend([ + "", + "// RGB LED", + "#define HAS_NEOPIXEL", + "#define NEOPIXEL_COUNT 1", + "#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800)" + ]) + + if 'BUTTON_PIN' in target['pins']: + content.append("#define BUTTON_NEED_PULLUP") + + # Close conditional block + if len(targets_list) > 1: + conditions = " || ".join([f"defined({t['define_name']})" for t in targets_list]) + content.append(f"#endif // {conditions}") + else: + content.append(f"#endif // {target['define_name']}") + content.append("") + + group_num += 1 + + # Set PIN_ENABLE_HIGH to second radio CS pin for diversity setups + has_diversity = any(target['is_diversity'] for targets_list in pin_groups.values() for target in targets_list) + if has_diversity: + # Find the CS_2 pin from any diversity target + for targets_list in pin_groups.values(): + for target in targets_list: + if target['is_diversity'] and 'LORA_CS_2' in target['pins']: + content.extend([ + "// Set second radio CS pin high at startup to disable it", + "#if defined(TWO_RADIOS)", + "#define PIN_ENABLE_HIGH LORA_CS_2", + "#endif // TWO_RADIOS", + "" + ]) + break + else: + continue + break + + # Footer - ensure only one target is selected + all_defines = [t['define_name'] for targets_list in pin_groups.values() for t in targets_list] + condition = " + ".join([f"defined({define})" for define in all_defines]) + content.extend([ + "// Ensure only one target is selected", + f"#if {condition} != 1", + '#error "Exactly one ELRS target must be defined"', + "#endif" + ]) + + return '\n'.join(content) + + def generate_platformio_ini(self, platform: str, targets: List[Dict], output_dir: Path): + """Generate platformio.ini with individual environments for each target""" + variant_dir = output_dir / platform + variant_dir.mkdir(parents=True, exist_ok=True) + + # Platform-specific configuration + platform_config = { + 'esp32': { + 'base': 'esp32_base', + 'board': 'esp32-pico-d4', + 'board_level': None + }, + 'esp32-c3': { + 'base': 'esp32c3_base', + 'board': 'esp32-c3-devkitm-1', + 'board_level': 'extra' + }, + 'esp32-s3': { + 'base': 'esp32c3_base', # Using esp32c3_base as reference from your example + 'board': 'esp32-s3-devkitc-1', + 'board_level': 'extra' + } + } + + config = platform_config.get(platform, platform_config['esp32']) + content = [] + + # Generate individual environment for each target + for target in targets: + env_name = f"elrs-{target['define_name'].lower().replace('elrs_', '').replace('_', '-')}" + target_dir = f"variants/esp32/elrs/{platform}" + + content.extend([ + f"[env:{env_name}]", + f"extends = {config['base']}", + "platform = espressif32", + f"board = {config['board']}", + "framework = arduino" + ]) + + if config['board_level']: + content.append(f"board_level = {config['board_level']}") + + content.extend([ + "build_flags =", + f" ${{{config['base']}.build_flags}}", + f" -I {target_dir}", + f" -D {target['define_name']}", + f" -D PRIVATE_HW", + " -O2", + " -D CONFIG_DISABLE_HAL_LOCKS=1" + ]) + + # Add monitor speed for non-esp32 platforms + if platform != 'esp32': + content.append("monitor_speed = 115200") + + content.extend([ + "upload_protocol = esptool", + "upload_speed = 460800" if platform == 'esp32' else "upload_speed = 921600", + "lib_deps =", + f" ${{{config['base']}.lib_deps}}", + "" + ]) + + with open(variant_dir / 'platformio.ini', 'w') as f: + f.write('\n'.join(content)) + + print(f"Generated {variant_dir / 'platformio.ini'} with {len(targets)} environments") + + def copy_rfswitch_file(self, platform: str, output_dir: Path): + """Copy rfswitch.h file to the variant directory""" + variant_dir = output_dir / platform + variant_dir.mkdir(parents=True, exist_ok=True) + + # Source rfswitch.h file (in the same directory as this script) + source_file = Path(__file__).parent / 'rfswitch.h' + target_file = variant_dir / 'rfswitch.h' + + if source_file.exists(): + shutil.copy2(source_file, target_file) + print(f"Copied rfswitch.h to {target_file}") + else: + print(f"Warning: rfswitch.h not found at {source_file}") + + def convert(self, output_dir: str) -> bool: + """Main conversion function""" + output_path = Path(output_dir) + + # Clone the repository + if not self.clone_elrs_repo(): + return False + + try: + if not self.load_elrs_data(): + return False + + targets = self.extract_targets() + if not targets: + print("No targets found to convert") + return False + + print(f"Found {len(targets)} targets to convert") + + # Group targets by platform + by_platform = {} + for target in targets: + platform = target['platform'] + by_platform.setdefault(platform, []).append(target) + + # Generate files for each platform + for platform, platform_targets in by_platform.items(): + print(f"Processing {len(platform_targets)} targets for {platform}") + + pin_groups = self.group_targets_by_pins(platform_targets) + self.generate_variant_file(platform, pin_groups, output_path) + self.generate_platformio_ini(platform, platform_targets, output_path) + self.copy_rfswitch_file(platform, output_path) + + return True + + finally: + self.cleanup_repo() + + +def main(): + parser = argparse.ArgumentParser(description='Convert ELRS targets to Meshtastic format') + parser.add_argument('--output-dir', default='.', + help='Output directory for generated files (default: current directory)') + + args = parser.parse_args() + + converter = SimpleELRSConverter() + + if converter.convert(args.output_dir): + print("Conversion completed successfully!") + return 0 + else: + print("Conversion failed!") + return 1 + + +if __name__ == '__main__': + sys.exit(main()) From 793eaa2e8f6808b75a022282e04141b1eae6e1fd Mon Sep 17 00:00:00 2001 From: Senk02 Date: Thu, 14 Aug 2025 20:09:33 +0000 Subject: [PATCH 4/4] Edit variants to add nested ELRS folder --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index 62bbf8a24..5afba5020 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,6 +8,7 @@ extra_configs = arch/*/*.ini variants/*/*/platformio.ini variants/*/diy/*/platformio.ini + variants/*/elrs/*/platformio.ini src/graphics/niche/InkHUD/PlatformioConfig.ini description = Meshtastic