Add portduino_status, assign hardware device IDs... (#9441)

* Add portduino_status, assign hardware device IDs, and try to recover a CH341 device on a USB error

* Minor fixes suggested by Copilot
This commit is contained in:
Jonathan Bennett
2026-01-27 18:00:20 -06:00
committed by GitHub
parent fd498bebad
commit 69a42e1fd2
8 changed files with 129 additions and 11 deletions

View File

@@ -9,6 +9,8 @@
#include <libpinedio-usb.h>
#include <unistd.h>
extern uint32_t rebootAtMsec;
// include the library for Raspberry GPIO pins
#define PI_RISING (PINEDIO_INT_MODE_RISING)
@@ -45,7 +47,7 @@ class Ch341Hal : public RadioLibHal
int32_t ret = pinedio_init(&pinedio, NULL);
if (ret != 0) {
std::string s = "Could not open SPI: ";
throw(s + std::to_string(ret));
throw std::runtime_error(s + std::to_string(ret));
}
pinedio_set_option(&pinedio, PINEDIO_OPTION_AUTO_CS, 0);
@@ -74,30 +76,55 @@ class Ch341Hal : public RadioLibHal
// RADIOLIB_NC as an alias for non-connected pins
void pinMode(uint32_t pin, uint32_t mode) override
{
if (checkError()) {
return;
}
if (pin == RADIOLIB_NC) {
return;
}
pinedio_set_pin_mode(&pinedio, pin, mode);
auto res = pinedio_set_pin_mode(&pinedio, pin, mode);
if (res < 0 && rebootAtMsec == 0) {
LOG_ERROR("USBHal pinMode: Could not set pin %u mode to %u: %d", pin, mode, res);
}
}
void digitalWrite(uint32_t pin, uint32_t value) override
{
if (checkError()) {
return;
}
if (pin == RADIOLIB_NC) {
return;
}
pinedio_digital_write(&pinedio, pin, value);
auto res = pinedio_digital_write(&pinedio, pin, value);
if (res < 0 && rebootAtMsec == 0) {
LOG_ERROR("USBHal digitalWrite: Could not write pin %u: %d", pin, res);
portduino_status.LoRa_in_error = true;
}
}
uint32_t digitalRead(uint32_t pin) override
{
if (checkError()) {
return 0;
}
if (pin == RADIOLIB_NC) {
return 0;
}
return pinedio_digital_read(&pinedio, pin);
auto res = pinedio_digital_read(&pinedio, pin);
if (res < 0 && rebootAtMsec == 0) {
LOG_ERROR("USBHal digitalRead: Could not read pin %u: %d", pin, res);
portduino_status.LoRa_in_error = true;
return 0;
}
return res;
}
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override
{
if (checkError()) {
return;
}
if (interruptNum == RADIOLIB_NC) {
return;
}
@@ -107,6 +134,9 @@ class Ch341Hal : public RadioLibHal
void detachInterrupt(uint32_t interruptNum) override
{
if (checkError()) {
return;
}
if (interruptNum == RADIOLIB_NC) {
return;
}
@@ -152,6 +182,9 @@ class Ch341Hal : public RadioLibHal
void spiTransfer(uint8_t *out, size_t len, uint8_t *in)
{
if (checkError()) {
return;
}
int32_t ret = pinedio_transceive(&this->pinedio, out, in, len);
if (ret < 0) {
std::cerr << "Could not perform SPI transfer: " << ret << std::endl;
@@ -160,9 +193,22 @@ class Ch341Hal : public RadioLibHal
void spiEndTransaction() {}
void spiEnd() {}
bool checkError()
{
if (pinedio.in_error) {
if (!has_warned)
LOG_ERROR("USBHal: libch341 in_error detected");
portduino_status.LoRa_in_error = true;
has_warned = true;
return true;
}
has_warned = false;
return false;
}
private:
pinedio_inst pinedio = {0};
bool has_warned = false;
};
#endif