diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index 05b4a7b0a..333d6eadc 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -52,6 +52,8 @@ Lora: # TXen: x # TX and RX enable pins # RXen: x +# ch341_quirk: true # Uncomment this to use the chunked SPI transfer that seems to fix the ch341 + ### Set gpio chip to use in /dev/. Defaults to 0. ### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4 # gpiochip: 4 diff --git a/src/main.cpp b/src/main.cpp index b7bc4892b..7814ea596 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -738,7 +738,8 @@ void setup() if (settingsMap[use_sx1262]) { if (!rIf) { LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str()); - LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); + LockingArduinoHal *RadioLibHAL = + new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC)); rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], settingsMap[busy]); if (!rIf->init()) { @@ -752,7 +753,8 @@ void setup() } else if (settingsMap[use_rf95]) { if (!rIf) { LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str()); - LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); + LockingArduinoHal *RadioLibHAL = + new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC)); rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], settingsMap[busy]); if (!rIf->init()) { diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index fc1563ee3..a4ceac9f1 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -25,7 +25,31 @@ void LockingArduinoHal::spiEndTransaction() #if ARCH_PORTDUINO void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in) { - spi->transfer(out, in, len); + if (busy == RADIOLIB_NC) { + spi->transfer(out, in, len); + } else { + uint16_t offset = 0; + + while (len) { + uint8_t block_size = (len < 20 ? len : 20); + spi->transfer((out != NULL ? out + offset : NULL), (in != NULL ? in + offset : NULL), block_size); + if (block_size == len) + return; + + // ensure GPIO is low + + uint32_t start = millis(); + while (digitalRead(busy)) { + if (millis() - start >= 2000) { + LOG_ERROR("GPIO mid-transfer timeout, is it connected?"); + return; + } + } + + offset += block_size; + len -= block_size; + } + } } #endif @@ -414,4 +438,4 @@ void RadioLibInterface::startSend(meshtastic_MeshPacket *txp) // bits enableInterrupt(isrTxLevel0); } -} +} \ No newline at end of file diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index 62720cfc9..2c841a19e 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -21,12 +21,20 @@ class LockingArduinoHal : public ArduinoHal { public: - LockingArduinoHal(SPIClass &spi, SPISettings spiSettings) : ArduinoHal(spi, spiSettings){}; + LockingArduinoHal(SPIClass &spi, SPISettings spiSettings, RADIOLIB_PIN_TYPE _busy = RADIOLIB_NC) + : ArduinoHal(spi, spiSettings) + { +#if ARCH_PORTDUINO + busy = _busy; +#endif + }; void spiBeginTransaction() override; void spiEndTransaction() override; #if ARCH_PORTDUINO + RADIOLIB_PIN_TYPE busy; void spiTransfer(uint8_t *out, size_t len, uint8_t *in) override; + #endif }; @@ -179,4 +187,4 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) = 0; virtual void setStandby() = 0; -}; +}; \ No newline at end of file diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index 7c5086ac2..4077a27bc 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -168,6 +168,7 @@ void portduinoSetup() settingsMap[txen] = yamlConfig["Lora"]["TXen"].as(RADIOLIB_NC); settingsMap[rxen] = yamlConfig["Lora"]["RXen"].as(RADIOLIB_NC); settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as(0); + settingsMap[ch341Quirk] = yamlConfig["Lora"]["ch341_quirk"].as(false); gpioChipName += std::to_string(settingsMap[gpiochip]); settingsStrings[spidev] = "/dev/" + yamlConfig["Lora"]["spidev"].as("spidev0.0"); diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 995793a21..ca935ea3b 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -11,6 +11,7 @@ enum configNames { rxen, dio2_as_rf_switch, dio3_tcxo_voltage, + ch341Quirk, use_rf95, use_sx1280, use_sx1268,