For each GPIO PIN, allow to specify gpiochip and line

This commit is contained in:
Patrick Siegl 2025-01-04 19:12:24 +00:00
parent 9afadde2f4
commit 6659e8f582
6 changed files with 202 additions and 236 deletions

View File

@ -825,116 +825,62 @@ void setup()
#endif #endif
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
if (settingsMap[use_sx1262]) { const struct { configNames cfgName;
if (!rIf) { std::string strName;
LOG_DEBUG("Activate sx1262 radio on SPI port %s", settingsStrings[spidev].c_str()); bool ch341halsupport;
if (settingsStrings[spidev] == "ch341") { } loraModules[] = {
RadioLibHAL = ch341Hal; { use_rf95, "RF95", false },
} else { { use_sx1262, "sx1262", true },
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); { use_sx1268, "sx1268", false },
} { use_sx1280, "sx1280", false },
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], { use_lr1110, "lr1110", false },
settingsMap[busy]); { use_lr1120, "lr1120", false },
if (!rIf->init()) { { use_lr1121, "lr1121", false }
LOG_WARN("No SX1262 radio"); };
delete rIf; // as one can't use a function pointer to the class constructor:
exit(EXIT_FAILURE); auto loraModuleInterface = [](configNames cfgName, LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy) {
} else { switch (cfgName) {
LOG_INFO("SX1262 init success"); case use_rf95:
} return (RadioInterface*)new RF95Interface(hal, cs, irq, rst, busy);
} case use_sx1262:
} else if (settingsMap[use_rf95]) { return (RadioInterface*)new SX1262Interface(hal, cs, irq, rst, busy);
if (!rIf) { case use_sx1268:
LOG_DEBUG("Activate rf95 radio on SPI port %s", settingsStrings[spidev].c_str()); return (RadioInterface*)new SX1268Interface(hal, cs, irq, rst, busy);
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); case use_sx1280:
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], return (RadioInterface*)new SX1280Interface(hal, cs, irq, rst, busy);
settingsMap[busy]); case use_lr1110:
if (!rIf->init()) { return (RadioInterface*)new LR1110Interface(hal, cs, irq, rst, busy);
LOG_WARN("No RF95 radio"); case use_lr1120:
delete rIf; return (RadioInterface*)new LR1120Interface(hal, cs, irq, rst, busy);
rIf = NULL; case use_lr1121:
exit(EXIT_FAILURE); return (RadioInterface*)new LR1121Interface(hal, cs, irq, rst, busy);
} else { default:
LOG_INFO("RF95 init success"); assert(0); // shouldn't happen
} return (RadioInterface*)nullptr;
} }
} else if (settingsMap[use_sx1280]) { };
if (!rIf) { for (auto& loraModule : loraModules) {
LOG_DEBUG("Activate sx1280 radio on SPI port %s", settingsStrings[spidev].c_str()); if (settingsMap[loraModule.cfgName]) {
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); if (!rIf) {
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], LOG_DEBUG("Activate %s radio on SPI port %s", loraModule.strName, settingsStrings[spidev].c_str());
settingsMap[busy]); if (loraModule.ch341halsupport
if (!rIf->init()) { && settingsStrings[spidev] == "ch341") {
LOG_WARN("No SX1280 radio"); RadioLibHAL = ch341Hal;
delete rIf; } else {
rIf = NULL; RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
exit(EXIT_FAILURE); }
} else { rIf = loraModuleInterface(loraModule.cfgName, (LockingArduinoHal *)RadioLibHAL, settingsMap[cs_pin], settingsMap[irq_pin], settingsMap[reset_pin], settingsMap[busy_pin]);
LOG_INFO("SX1280 init success"); if (!rIf->init()) {
} LOG_WARN("No %s radio", loraModule.strName);
} delete rIf;
} else if (settingsMap[use_lr1110]) { rIf = NULL;
if (!rIf) { exit(EXIT_FAILURE);
LOG_DEBUG("Activate lr1110 radio on SPI port %s", settingsStrings[spidev].c_str()); } else {
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); LOG_INFO("%s init success", loraModule.strName);
rIf = new LR1110Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], }
settingsMap[busy]);
if (!rIf->init()) {
LOG_WARN("No LR1110 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("LR1110 init success");
}
}
} else if (settingsMap[use_lr1120]) {
if (!rIf) {
LOG_DEBUG("Activate lr1120 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new LR1120Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_WARN("No LR1120 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("LR1120 init success");
}
}
} else if (settingsMap[use_lr1121]) {
if (!rIf) {
LOG_DEBUG("Activate lr1121 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new LR1121Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_WARN("No LR1121 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("LR1121 init success");
}
}
} else if (settingsMap[use_sx1268]) {
if (!rIf) {
LOG_DEBUG("Activate sx1268 radio on SPI port %s", settingsStrings[spidev].c_str());
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_WARN("No SX1268 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("SX1268 init success");
} }
} }
} }
#elif defined(HW_SPI1_DEVICE) #elif defined(HW_SPI1_DEVICE)
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings); LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings);
#else // HW_SPI1_DEVICE #else // HW_SPI1_DEVICE

View File

@ -91,16 +91,16 @@ void RF95Interface::setTransmitEnable(bool txon)
#ifdef RF95_TXEN #ifdef RF95_TXEN
digitalWrite(RF95_TXEN, txon ? 1 : 0); digitalWrite(RF95_TXEN, txon ? 1 : 0);
#elif ARCH_PORTDUINO #elif ARCH_PORTDUINO
if (settingsMap[txen] != RADIOLIB_NC) { if (settingsMap[txen_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[txen], txon ? 1 : 0); digitalWrite(settingsMap[txen_pin], txon ? 1 : 0);
} }
#endif #endif
#ifdef RF95_RXEN #ifdef RF95_RXEN
digitalWrite(RF95_RXEN, txon ? 0 : 1); digitalWrite(RF95_RXEN, txon ? 0 : 1);
#elif ARCH_PORTDUINO #elif ARCH_PORTDUINO
if (settingsMap[rxen] != RADIOLIB_NC) { if (settingsMap[rxen_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[rxen], txon ? 0 : 1); digitalWrite(settingsMap[rxen_pin], txon ? 0 : 1);
} }
#endif #endif
} }
@ -164,13 +164,13 @@ bool RF95Interface::init()
digitalWrite(RF95_RXEN, 1); digitalWrite(RF95_RXEN, 1);
#endif #endif
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
if (settingsMap[txen] != RADIOLIB_NC) { if (settingsMap[txen_pin] != RADIOLIB_NC) {
pinMode(settingsMap[txen], OUTPUT); pinMode(settingsMap[txen_pin], OUTPUT);
digitalWrite(settingsMap[txen], 0); digitalWrite(settingsMap[txen_pin], 0);
} }
if (settingsMap[rxen] != RADIOLIB_NC) { if (settingsMap[rxen_pin] != RADIOLIB_NC) {
pinMode(settingsMap[rxen], OUTPUT); pinMode(settingsMap[rxen_pin], OUTPUT);
digitalWrite(settingsMap[rxen], 0); digitalWrite(settingsMap[rxen_pin], 0);
} }
#endif #endif
setTransmitEnable(false); setTransmitEnable(false);
@ -337,4 +337,4 @@ bool RF95Interface::sleep()
return true; return true;
} }
#endif #endif

View File

@ -51,9 +51,9 @@ template <typename T> bool SX126xInterface<T>::init()
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000; float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000;
if (settingsMap[sx126x_ant_sw] != RADIOLIB_NC) { if (settingsMap[sx126x_ant_sw_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[sx126x_ant_sw], HIGH); digitalWrite(settingsMap[sx126x_ant_sw_pin], HIGH);
pinMode(settingsMap[sx126x_ant_sw], OUTPUT); pinMode(settingsMap[sx126x_ant_sw_pin], OUTPUT);
} }
// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE // FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE
#elif !defined(SX126X_DIO3_TCXO_VOLTAGE) #elif !defined(SX126X_DIO3_TCXO_VOLTAGE)
@ -121,8 +121,8 @@ template <typename T> bool SX126xInterface<T>::init()
// no effect // no effect
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
if (res == RADIOLIB_ERR_NONE) { if (res == RADIOLIB_ERR_NONE) {
LOG_DEBUG("Use MCU pin %i as RXEN and pin %i as TXEN to control RF switching", settingsMap[rxen], settingsMap[txen]); LOG_DEBUG("Use MCU pin %i as RXEN and pin %i as TXEN to control RF switching", settingsMap[rxen_pin], settingsMap[txen_pin]);
lora.setRfSwitchPins(settingsMap[rxen], settingsMap[txen]); lora.setRfSwitchPins(settingsMap[rxen_pin], settingsMap[txen_pin]);
} }
#else #else
#ifndef SX126X_RXEN #ifndef SX126X_RXEN
@ -341,4 +341,4 @@ template <typename T> bool SX126xInterface<T>::sleep()
return true; return true;
} }
#endif #endif

View File

@ -38,13 +38,13 @@ template <typename T> bool SX128xInterface<T>::init()
#endif #endif
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
if (settingsMap[rxen] != RADIOLIB_NC) { if (settingsMap[rxen_pin] != RADIOLIB_NC) {
pinMode(settingsMap[rxen], OUTPUT); pinMode(settingsMap[rxen_pin], OUTPUT);
digitalWrite(settingsMap[rxen], LOW); // Set low before becoming an output digitalWrite(settingsMap[rxen_pin], LOW); // Set low before becoming an output
} }
if (settingsMap[txen] != RADIOLIB_NC) { if (settingsMap[txen_pin] != RADIOLIB_NC) {
pinMode(settingsMap[txen], OUTPUT); pinMode(settingsMap[txen_pin], OUTPUT);
digitalWrite(settingsMap[txen], LOW); // Set low before becoming an output digitalWrite(settingsMap[txen_pin], LOW); // Set low before becoming an output
} }
#else #else
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode
@ -93,8 +93,8 @@ template <typename T> bool SX128xInterface<T>::init()
lora.setRfSwitchPins(SX128X_RXEN, SX128X_TXEN); lora.setRfSwitchPins(SX128X_RXEN, SX128X_TXEN);
} }
#elif ARCH_PORTDUINO #elif ARCH_PORTDUINO
if (res == RADIOLIB_ERR_NONE && settingsMap[rxen] != RADIOLIB_NC && settingsMap[txen] != RADIOLIB_NC) { if (res == RADIOLIB_ERR_NONE && settingsMap[rxen_pin] != RADIOLIB_NC && settingsMap[txen_pin] != RADIOLIB_NC) {
lora.setRfSwitchPins(settingsMap[rxen], settingsMap[txen]); lora.setRfSwitchPins(settingsMap[rxen_pin], settingsMap[txen_pin]);
} }
#endif #endif
@ -174,11 +174,11 @@ template <typename T> void SX128xInterface<T>::setStandby()
LOG_ERROR("SX128x standby %s%d", radioLibErr, err); LOG_ERROR("SX128x standby %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE); assert(err == RADIOLIB_ERR_NONE);
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
if (settingsMap[rxen] != RADIOLIB_NC) { if (settingsMap[rxen_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[rxen], LOW); digitalWrite(settingsMap[rxen_pin], LOW);
} }
if (settingsMap[txen] != RADIOLIB_NC) { if (settingsMap[txen_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[txen], LOW); digitalWrite(settingsMap[txen_pin], LOW);
} }
#else #else
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn off RX and TX power #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn off RX and TX power
@ -210,11 +210,11 @@ template <typename T> void SX128xInterface<T>::addReceiveMetadata(meshtastic_Mes
template <typename T> void SX128xInterface<T>::configHardwareForSend() template <typename T> void SX128xInterface<T>::configHardwareForSend()
{ {
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
if (settingsMap[txen] != RADIOLIB_NC) { if (settingsMap[txen_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[txen], HIGH); digitalWrite(settingsMap[txen_pin], HIGH);
} }
if (settingsMap[rxen] != RADIOLIB_NC) { if (settingsMap[rxen_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[rxen], LOW); digitalWrite(settingsMap[rxen_pin], LOW);
} }
#else #else
@ -241,11 +241,11 @@ template <typename T> void SX128xInterface<T>::startReceive()
setStandby(); setStandby();
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
if (settingsMap[rxen] != RADIOLIB_NC) { if (settingsMap[rxen_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[rxen], HIGH); digitalWrite(settingsMap[rxen_pin], HIGH);
} }
if (settingsMap[txen] != RADIOLIB_NC) { if (settingsMap[txen_pin] != RADIOLIB_NC) {
digitalWrite(settingsMap[txen], LOW); digitalWrite(settingsMap[txen_pin], LOW);
} }
#else #else
@ -315,4 +315,4 @@ template <typename T> bool SX128xInterface<T>::sleep()
return true; return true;
} }
#endif #endif

View File

@ -134,13 +134,13 @@ void portduinoSetup()
{ {
printf("Set up Meshtastic on Portduino...\n"); printf("Set up Meshtastic on Portduino...\n");
int max_GPIO = 0; int max_GPIO = 0;
const configNames GPIO_lines[] = {cs, const configNames GPIO_lines[] = {cs_pin,
irq, irq_pin,
busy, busy_pin,
reset, reset_pin,
sx126x_ant_sw, sx126x_ant_sw_pin,
txen, txen_pin,
rxen, rxen_pin,
displayDC, displayDC,
displayCS, displayCS,
displayBacklight, displayBacklight,
@ -247,7 +247,7 @@ void portduinoSetup()
// Rather important to set this, if not running simulated. // Rather important to set this, if not running simulated.
randomSeed(time(NULL)); randomSeed(time(NULL));
gpioChipName += std::to_string(settingsMap[gpiochip]); std::string defaultGpioChipName = gpioChipName + std::to_string(settingsMap[default_gpiochip]);
for (configNames i : GPIO_lines) { for (configNames i : GPIO_lines) {
if (settingsMap.count(i) && settingsMap[i] > max_GPIO) if (settingsMap.count(i) && settingsMap[i] > max_GPIO)
@ -260,62 +260,46 @@ void portduinoSetup()
// TODO: Can we do this in the for loop above? // TODO: Can we do this in the for loop above?
// TODO: If one of these fails, we should log and terminate // TODO: If one of these fails, we should log and terminate
if (settingsMap.count(user) > 0 && settingsMap[user] != RADIOLIB_NC) { if (settingsMap.count(user) > 0 && settingsMap[user] != RADIOLIB_NC) {
if (initGPIOPin(settingsMap[user], gpioChipName) != ERRNO_OK) { if (initGPIOPin(settingsMap[user], defaultGpioChipName, settingsMap[user]) != ERRNO_OK) {
settingsMap[user] = RADIOLIB_NC; settingsMap[user] = RADIOLIB_NC;
} }
} }
if (settingsMap[displayPanel] != no_screen) { if (settingsMap[displayPanel] != no_screen) {
if (settingsMap[displayCS] > 0) if (settingsMap[displayCS] > 0)
initGPIOPin(settingsMap[displayCS], gpioChipName); initGPIOPin(settingsMap[displayCS], defaultGpioChipName, settingsMap[displayCS]);
if (settingsMap[displayDC] > 0) if (settingsMap[displayDC] > 0)
initGPIOPin(settingsMap[displayDC], gpioChipName); initGPIOPin(settingsMap[displayDC], defaultGpioChipName, settingsMap[displayDC]);
if (settingsMap[displayBacklight] > 0) if (settingsMap[displayBacklight] > 0)
initGPIOPin(settingsMap[displayBacklight], gpioChipName); initGPIOPin(settingsMap[displayBacklight], defaultGpioChipName, settingsMap[displayBacklight]);
if (settingsMap[displayReset] > 0) if (settingsMap[displayReset] > 0)
initGPIOPin(settingsMap[displayReset], gpioChipName); initGPIOPin(settingsMap[displayReset], defaultGpioChipName, settingsMap[displayReset]);
} }
if (settingsMap[touchscreenModule] != no_touchscreen) { if (settingsMap[touchscreenModule] != no_touchscreen) {
if (settingsMap[touchscreenCS] > 0) if (settingsMap[touchscreenCS] > 0)
initGPIOPin(settingsMap[touchscreenCS], gpioChipName); initGPIOPin(settingsMap[touchscreenCS], defaultGpioChipName, settingsMap[touchscreenCS]);
if (settingsMap[touchscreenIRQ] > 0) if (settingsMap[touchscreenIRQ] > 0)
initGPIOPin(settingsMap[touchscreenIRQ], gpioChipName); initGPIOPin(settingsMap[touchscreenIRQ], defaultGpioChipName, settingsMap[touchscreenIRQ]);
} }
// Only initialize the radio pins when dealing with real, kernel controlled SPI hardware // Only initialize the radio pins when dealing with real, kernel controlled SPI hardware
if (settingsStrings[spidev] != "" && settingsStrings[spidev] != "ch341") { if (settingsStrings[spidev] != "" && settingsStrings[spidev] != "ch341") {
if (settingsMap.count(cs) > 0 && settingsMap[cs] != RADIOLIB_NC) { const struct { configNames pin; configNames gpiochip; configNames line; } pinMappings[] = {
if (initGPIOPin(settingsMap[cs], gpioChipName) != ERRNO_OK) { { cs_pin, cs_gpiochip, cs_line },
settingsMap[cs] = RADIOLIB_NC; { irq_pin, irq_gpiochip, irq_line },
} { busy_pin, busy_gpiochip, busy_line },
} { reset_pin, reset_gpiochip, reset_line },
if (settingsMap.count(irq) > 0 && settingsMap[irq] != RADIOLIB_NC) { { rxen_pin, rxen_gpiochip, rxen_line },
if (initGPIOPin(settingsMap[irq], gpioChipName) != ERRNO_OK) { { txen_pin, txen_gpiochip, txen_line },
settingsMap[irq] = RADIOLIB_NC; { sx126x_ant_sw_pin, sx126x_ant_sw_gpiochip, sx126x_ant_sw_line }
} };
} for (auto& pinMap : pinMappings) {
if (settingsMap.count(busy) > 0 && settingsMap[busy] != RADIOLIB_NC) { auto setMapIter = settingsMap.find(pinMap.pin);
if (initGPIOPin(settingsMap[busy], gpioChipName) != ERRNO_OK) { if (setMapIter != settingsMap.end() && setMapIter->second != RADIOLIB_NC) {
settingsMap[busy] = RADIOLIB_NC; if (initGPIOPin(setMapIter->second, gpioChipName + std::to_string(settingsMap[pinMap.gpiochip]), settingsMap[pinMap.line] ) != ERRNO_OK) {
} settingsMap[pinMap.pin] = RADIOLIB_NC;
} settingsMap[pinMap.gpiochip] = RADIOLIB_NC;
if (settingsMap.count(reset) > 0 && settingsMap[reset] != RADIOLIB_NC) { settingsMap[pinMap.line] = RADIOLIB_NC;
if (initGPIOPin(settingsMap[reset], gpioChipName) != ERRNO_OK) { }
settingsMap[reset] = RADIOLIB_NC;
}
}
if (settingsMap.count(sx126x_ant_sw) > 0 && settingsMap[sx126x_ant_sw] != RADIOLIB_NC) {
if (initGPIOPin(settingsMap[sx126x_ant_sw], gpioChipName) != ERRNO_OK) {
settingsMap[sx126x_ant_sw] = RADIOLIB_NC;
}
}
if (settingsMap.count(rxen) > 0 && settingsMap[rxen] != RADIOLIB_NC) {
if (initGPIOPin(settingsMap[rxen], gpioChipName) != ERRNO_OK) {
settingsMap[rxen] = RADIOLIB_NC;
}
}
if (settingsMap.count(txen) > 0 && settingsMap[txen] != RADIOLIB_NC) {
if (initGPIOPin(settingsMap[txen], gpioChipName) != ERRNO_OK) {
settingsMap[txen] = RADIOLIB_NC;
} }
} }
SPI.begin(settingsStrings[spidev].c_str()); SPI.begin(settingsStrings[spidev].c_str());
@ -332,13 +316,13 @@ void portduinoSetup()
return; return;
} }
int initGPIOPin(int pinNum, const std::string gpioChipName) int initGPIOPin(int pinNum, const std::string gpioChipName, int line)
{ {
#ifdef PORTDUINO_LINUX_HARDWARE #ifdef PORTDUINO_LINUX_HARDWARE
std::string gpio_name = "GPIO" + std::to_string(pinNum); std::string gpio_name = "GPIO" + std::to_string(pinNum);
try { try {
GPIOPin *csPin; GPIOPin *csPin;
csPin = new LinuxGPIOPin(pinNum, gpioChipName.c_str(), pinNum, gpio_name.c_str()); csPin = new LinuxGPIOPin(pinNum, gpioChipName.c_str(), line, gpio_name.c_str());
csPin->setSilent(); csPin->setSilent();
gpioBind(csPin); gpioBind(csPin);
return ERRNO_OK; return ERRNO_OK;
@ -376,42 +360,64 @@ bool loadConfig(const char *configPath)
} }
} }
if (yamlConfig["Lora"]) { if (yamlConfig["Lora"]) {
settingsMap[use_sx1262] = false; const struct { configNames cfgName; std::string strName; } loraModules[] = {
settingsMap[use_rf95] = false; { use_rf95, "RF95" },
settingsMap[use_sx1280] = false; { use_sx1262, "sx1262" },
settingsMap[use_lr1110] = false; { use_sx1268, "sx1268" },
settingsMap[use_lr1120] = false; { use_sx1280, "sx1280" },
settingsMap[use_lr1121] = false; { use_lr1110, "lr1110" },
settingsMap[use_sx1268] = false; { use_lr1120, "lr1120" },
{ use_lr1121, "lr1121" }
if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1262") { };
settingsMap[use_sx1262] = true; for (auto& loraModule : loraModules) {
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "RF95") { settingsMap[loraModule.cfgName] = false;
settingsMap[use_rf95] = true;
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1280") {
settingsMap[use_sx1280] = true;
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "lr1110") {
settingsMap[use_lr1110] = true;
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "lr1120") {
settingsMap[use_lr1120] = true;
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "lr1121") {
settingsMap[use_lr1121] = true;
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1268") {
settingsMap[use_sx1268] = true;
} }
if (yamlConfig["Lora"]["Module"]) {
for (auto& loraModule : loraModules) {
if (yamlConfig["Lora"]["Module"].as<std::string>("") == loraModule.strName) {
settingsMap[loraModule.cfgName] = true;
break;
}
}
}
settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false); settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false);
settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<float>(0) * 1000; settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<float>(0) * 1000;
if (settingsMap[dio3_tcxo_voltage] == 0 && yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<bool>(false)) { if (settingsMap[dio3_tcxo_voltage] == 0 && yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<bool>(false)) {
settingsMap[dio3_tcxo_voltage] = 1800; // default millivolts for "true" settingsMap[dio3_tcxo_voltage] = 1800; // default millivolts for "true"
} }
settingsMap[cs] = yamlConfig["Lora"]["CS"].as<int>(RADIOLIB_NC);
settingsMap[irq] = yamlConfig["Lora"]["IRQ"].as<int>(RADIOLIB_NC); // backwards API compatibility and to globally set gpiochip once
settingsMap[busy] = yamlConfig["Lora"]["Busy"].as<int>(RADIOLIB_NC); int defaultGpioChip = settingsMap[default_gpiochip] = yamlConfig["Lora"]["gpiochip"].as<int>(0);
settingsMap[reset] = yamlConfig["Lora"]["Reset"].as<int>(RADIOLIB_NC);
settingsMap[txen] = yamlConfig["Lora"]["TXen"].as<int>(RADIOLIB_NC); const struct { configNames pin;
settingsMap[rxen] = yamlConfig["Lora"]["RXen"].as<int>(RADIOLIB_NC); configNames gpiochip;
settingsMap[sx126x_ant_sw] = yamlConfig["Lora"]["SX126X_ANT_SW"].as<int>(RADIOLIB_NC); configNames line;
settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as<int>(0); std::string strName; } pinMappings[] = {
{ cs_pin, cs_gpiochip, cs_line, "CS" },
{ irq_pin, irq_gpiochip, irq_line, "IRQ" },
{ busy_pin, busy_gpiochip, busy_line, "Busy" },
{ reset_pin, reset_gpiochip, reset_line, "Reset" },
{ txen_pin, txen_gpiochip, txen_line, "TXen" },
{ rxen_pin, rxen_gpiochip, rxen_line, "RXen" },
{ sx126x_ant_sw_pin, sx126x_ant_sw_gpiochip, sx126x_ant_sw_line, "SX126X_ANT_SW" },
};
for (auto& pinMap : pinMappings) {
if (yamlConfig["Lora"][pinMap.strName].IsMap()
&& (yamlConfig["Lora"][pinMap.strName]["pin"]
|| yamlConfig["Lora"][pinMap.strName]["line"]
|| yamlConfig["Lora"][pinMap.strName]["gpiochip"])) {
settingsMap[pinMap.pin] = yamlConfig["Lora"][pinMap.strName]["pin"].as<int>(RADIOLIB_NC);
settingsMap[pinMap.line] = yamlConfig["Lora"][pinMap.strName]["line"].as<int>(settingsMap[pinMap.pin]);
settingsMap[pinMap.gpiochip] = yamlConfig["Lora"][pinMap.strName]["gpiochip"].as<int>(defaultGpioChip);
}
else { // backwards API compatibility
settingsMap[pinMap.pin] = yamlConfig["Lora"][pinMap.strName].as<int>(RADIOLIB_NC);
settingsMap[pinMap.line] = settingsMap[pinMap.pin];
settingsMap[pinMap.gpiochip] = defaultGpioChip;
}
}
settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as<int>(2000000); settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as<int>(2000000);
settingsStrings[lora_usb_serial_num] = yamlConfig["Lora"]["USB_Serialnum"].as<std::string>(""); settingsStrings[lora_usb_serial_num] = yamlConfig["Lora"]["USB_Serialnum"].as<std::string>("");
settingsMap[lora_usb_pid] = yamlConfig["Lora"]["USB_PID"].as<int>(0x5512); settingsMap[lora_usb_pid] = yamlConfig["Lora"]["USB_PID"].as<int>(0x5512);

View File

@ -5,27 +5,41 @@
#include "platform/portduino/USBHal.h" #include "platform/portduino/USBHal.h"
enum configNames { enum configNames {
use_sx1262, default_gpiochip,
cs, cs_pin,
irq, cs_line,
busy, cs_gpiochip,
reset, irq_pin,
sx126x_ant_sw, irq_line,
txen, irq_gpiochip,
rxen, busy_pin,
busy_line,
busy_gpiochip,
reset_pin,
reset_line,
reset_gpiochip,
txen_pin,
txen_line,
txen_gpiochip,
rxen_pin,
rxen_line,
rxen_gpiochip,
sx126x_ant_sw_pin,
sx126x_ant_sw_line,
sx126x_ant_sw_gpiochip,
dio2_as_rf_switch, dio2_as_rf_switch,
dio3_tcxo_voltage, dio3_tcxo_voltage,
use_rf95, use_rf95,
use_sx1262,
use_sx1268,
use_sx1280, use_sx1280,
use_lr1110, use_lr1110,
use_lr1120, use_lr1120,
use_lr1121, use_lr1121,
use_sx1268,
lora_usb_serial_num, lora_usb_serial_num,
lora_usb_pid, lora_usb_pid,
lora_usb_vid, lora_usb_vid,
user, user,
gpiochip,
spidev, spidev,
spiSpeed, spiSpeed,
i2cdev, i2cdev,
@ -75,7 +89,7 @@ extern std::map<configNames, int> settingsMap;
extern std::map<configNames, std::string> settingsStrings; extern std::map<configNames, std::string> settingsStrings;
extern std::ofstream traceFile; extern std::ofstream traceFile;
extern Ch341Hal *ch341Hal; extern Ch341Hal *ch341Hal;
int initGPIOPin(int pinNum, std::string gpioChipname); int initGPIOPin(int pinNum, std::string gpioChipname, int line);
bool loadConfig(const char *configPath); bool loadConfig(const char *configPath);
static bool ends_with(std::string_view str, std::string_view suffix); static bool ends_with(std::string_view str, std::string_view suffix);
void getMacAddr(uint8_t *dmac); void getMacAddr(uint8_t *dmac);