diff --git a/bin/config.d/lora-RAK6421-13300-slot1.yaml b/bin/config.d/lora-RAK6421-13300-slot1.yaml index 6f65f9ccd..628198887 100644 --- a/bin/config.d/lora-RAK6421-13300-slot1.yaml +++ b/bin/config.d/lora-RAK6421-13300-slot1.yaml @@ -6,6 +6,9 @@ Lora: Reset: 16 # IO4 Busy: 24 # IO5 # Ant_sw: 13 # IO3 + Enable_Pins: + - 12 + - 13 DIO3_TCXO_VOLTAGE: true DIO2_AS_RF_SWITCH: true spidev: spidev0.0 diff --git a/bin/config.d/lora-RAK6421-13300-slot2.yaml b/bin/config.d/lora-RAK6421-13300-slot2.yaml index cbc794d39..f890f0467 100644 --- a/bin/config.d/lora-RAK6421-13300-slot2.yaml +++ b/bin/config.d/lora-RAK6421-13300-slot2.yaml @@ -4,5 +4,8 @@ Lora: Reset: 24 # IO4 Busy: 19 # IO5 # Ant_sw: 23 # IO3 + Enable_Pins: + - 26 + - 23 spidev: spidev0.1 # CS: 7 \ No newline at end of file diff --git a/bin/config.d/lora-RAK6421-13302-slot1.yaml b/bin/config.d/lora-RAK6421-13302-slot1.yaml new file mode 100644 index 000000000..7922f5182 --- /dev/null +++ b/bin/config.d/lora-RAK6421-13302-slot1.yaml @@ -0,0 +1,16 @@ +Lora: + + ### RAK13300in Slot 1 + Module: sx1262 + IRQ: 22 #IO6 + Reset: 16 # IO4 + Busy: 24 # IO5 + # Ant_sw: 13 # IO3 + Enable_Pins: + - 12 + - 13 + DIO3_TCXO_VOLTAGE: true + DIO2_AS_RF_SWITCH: true + spidev: spidev0.0 + # CS: 8 + TX_GAIN_LORA: [8] \ No newline at end of file diff --git a/bin/config.d/lora-RAK6421-13302-slot2.yaml b/bin/config.d/lora-RAK6421-13302-slot2.yaml new file mode 100644 index 000000000..362df93a6 --- /dev/null +++ b/bin/config.d/lora-RAK6421-13302-slot2.yaml @@ -0,0 +1,12 @@ +Lora: + ### RAK13300in Slot 2 pins + IRQ: 18 #IO6 + Reset: 24 # IO4 + Busy: 19 # IO5 + # Ant_sw: 23 # IO3 + Enable_Pins: + - 26 + - 23 + spidev: spidev0.1 + # CS: 7 + TX_GAIN_LORA: [8] \ No newline at end of file diff --git a/bin/config.d/lora-hat-rak-6421-pi-hat.yaml b/bin/config.d/lora-hat-rak-6421-pi-hat.yaml index 80df34ca7..10b72d9d2 100644 --- a/bin/config.d/lora-hat-rak-6421-pi-hat.yaml +++ b/bin/config.d/lora-hat-rak-6421-pi-hat.yaml @@ -5,9 +5,11 @@ Lora: IRQ: 22 #IO6 Reset: 16 # IO4 Busy: 24 # IO5 - # Ant_sw: 13 # IO3 + Enable_Pins: + - 12 + - 13 DIO3_TCXO_VOLTAGE: true DIO2_AS_RF_SWITCH: true spidev: spidev0.0 - GPIO_DETECT_PA: 13 - TX_GAIN_LORA: [8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 8, 8, 7] \ No newline at end of file + # GPIO_DETECT_PA: 13 + TX_GAIN_LORA: [8] \ No newline at end of file diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index 2cf23332c..24fc11078 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -277,6 +278,24 @@ void portduinoSetup() std::cout << "autoconf: Found Pi HAT+ " << hat_vendor << " " << autoconf_product << " at /proc/device-tree/hat" << std::endl; + // check for custom data fields + int i = 0; + while (access(("/proc/device-tree/hat/custom_" + std::to_string(i)).c_str(), R_OK) == 0) { + std::ifstream customFieldFile(("/proc/device-tree/hat/custom_" + std::to_string(i)).c_str()); + if (customFieldFile.is_open()) { + std::string customFieldName; + std::string customFieldValue; + getline(customFieldFile, customFieldName, ' '); + getline(customFieldFile, customFieldValue, ' '); + customFieldFile.close(); + + printf("autoconf: Found hat+ custom field %s: %s\n", customFieldName.c_str(), customFieldValue.c_str()); + portduino_config.hat_plus_custom_fields[customFieldName] = customFieldValue; + } + + i++; + } + // potential TODO: Validate that this is a real UUID std::ifstream hatUUID("/proc/device-tree/hat/uuid"); char uuid[38] = {0}; @@ -496,14 +515,19 @@ void portduinoSetup() randomSeed(time(NULL)); std::string defaultGpioChipName = gpioChipName + std::to_string(portduino_config.lora_default_gpiochip); + + std::set used_pins; + for (const auto *i : portduino_config.all_pins) { - if (i->enabled && i->pin > max_GPIO) + if (i->enabled && i->pin > max_GPIO) { max_GPIO = i->pin; + } } for (auto i : portduino_config.extra_pins) { - if (i.enabled && i.pin > max_GPIO) + if (i.enabled && i.pin > max_GPIO) { max_GPIO = i.pin; + } } gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need. @@ -517,12 +541,18 @@ void portduinoSetup() continue; } if (i->enabled) { - if (initGPIOPin(i->pin, gpioChipName + std::to_string(i->gpiochip), i->line) != ERRNO_OK) { - printf("Error setting pin number %d. It may not exist, or may already be in use.\n", i->line); - exit(EXIT_FAILURE); + if (used_pins.find(i->pin) != used_pins.end()) { + printf("Pin %d is in use for multiple purposes\n", i->pin); + } else { + if (initGPIOPin(i->pin, gpioChipName + std::to_string(i->gpiochip), i->line) != ERRNO_OK) { + printf("Error setting pin number %d. It may not exist, or may already be in use.\n", i->line); + exit(EXIT_FAILURE); + } + used_pins.insert(i->pin); } } } + printf("Initializing extra pins\n"); for (auto i : portduino_config.extra_pins) { // In the case of a ch341 Lora device, we don't want to touch the system GPIO lines for Lora // Those GPIO are handled in our usermode driver instead. @@ -530,9 +560,14 @@ void portduinoSetup() continue; } if (i.enabled) { - if (initGPIOPin(i.pin, gpioChipName + std::to_string(i.gpiochip), i.line) != ERRNO_OK) { - printf("Error setting pin number %d. It may not exist, or may already be in use.\n", i.line); - exit(EXIT_FAILURE); + if (used_pins.find(i.pin) != used_pins.end()) { + printf("Pin %d is in use for multiple purposes\n", i.pin); + } else { + if (initGPIOPin(i.pin, gpioChipName + std::to_string(i.gpiochip), i.line) != ERRNO_OK) { + printf("Error setting pin number %d. It may not exist, or may already be in use.\n", i.line); + exit(EXIT_FAILURE); + } + used_pins.insert(i.pin); } } } @@ -556,6 +591,25 @@ void portduinoSetup() // disable bias once finished pinMode(portduino_config.lora_pa_detect_pin.pin, INPUT); + } else if (portduino_config.hat_plus_custom_fields.find("io_slot1") != portduino_config.hat_plus_custom_fields.end()) { + printf("Hat+ io_slot1 is %s\n", portduino_config.hat_plus_custom_fields["io_slot1"].c_str()); + if (portduino_config.hat_plus_custom_fields["io_slot1"] != "RAK13302") { + std::cout << "Hat+ io_slot1 is not RAK13302, skipping PA curve" << std::endl; + portduino_config.num_pa_points = 1; + portduino_config.tx_gain_lora[0] = 0; + } + } + + for (auto i : portduino_config.extra_pins) { + // In the case of a ch341 Lora device, we don't want to touch the system GPIO lines for Lora + // Those GPIO are handled in our usermode driver instead. + if (i.config_section == "Lora" && portduino_config.lora_spi_dev == "ch341") { + continue; + } + if (i.enabled && i.default_high) { + pinMode(i.pin, OUTPUT); + digitalWrite(i.pin, HIGH); + } } // Only initialize the radio pins when dealing with real, kernel controlled SPI hardware @@ -712,6 +766,17 @@ bool loadConfig(const char *configPath) } } + if (yamlConfig["Lora"]["Enable_Pins"]) { + for (auto extra_pin : yamlConfig["Lora"]["Enable_Pins"]) { + portduino_config.extra_pins.push_back(pinMapping()); + portduino_config.extra_pins.back().config_section = "Lora"; + portduino_config.extra_pins.back().config_name = "Enable_Pins"; + portduino_config.extra_pins.back().enabled = true; + portduino_config.extra_pins.back().default_high = true; + readGPIOFromYaml(extra_pin, portduino_config.extra_pins.back()); + } + } + portduino_config.spiSpeed = yamlConfig["Lora"]["spiSpeed"].as(2000000); portduino_config.lora_usb_serial_num = yamlConfig["Lora"]["USB_Serialnum"].as(""); portduino_config.lora_usb_pid = yamlConfig["Lora"]["USB_PID"].as(0x5512); diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 0bd3582de..8cc5146c6 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -52,6 +52,7 @@ struct pinMapping { int gpiochip; int line; bool enabled = false; + bool default_high = false; }; extern std::ofstream traceFile; @@ -195,6 +196,8 @@ extern struct portduino_config_struct { int maxtophone = 100; int MaxNodes = 200; + std::unordered_map hat_plus_custom_fields; + pinMapping *all_pins[21] = {&lora_cs_pin, &lora_irq_pin, &lora_busy_pin,