Slight rework of CH341 HAL (#5848)

* Rework of CH341 HAL

* Applied trunk fmt

* revert serial reading

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
This commit is contained in:
Patrick Siegl 2025-01-17 02:38:58 +01:00 committed by GitHub
parent b0fe5ef8ba
commit e466bf2475
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 80 deletions

View File

@ -200,15 +200,12 @@ void portduinoSetup()
// if we're using a usermode driver, we need to initialize it here, to get a serial number back for mac address // if we're using a usermode driver, we need to initialize it here, to get a serial number back for mac address
uint8_t dmac[6] = {0}; uint8_t dmac[6] = {0};
if (settingsStrings[spidev] == "ch341") { if (settingsStrings[spidev] == "ch341") {
ch341Hal = new Ch341Hal(0); try {
if (settingsStrings[lora_usb_serial_num] != "") { ch341Hal =
ch341Hal->serial = settingsStrings[lora_usb_serial_num]; new Ch341Hal(0, settingsStrings[lora_usb_serial_num], settingsMap[lora_usb_vid], settingsMap[lora_usb_pid]);
} } catch (std::exception &e) {
ch341Hal->vid = settingsMap[lora_usb_vid]; std::cerr << e.what() << std::endl;
ch341Hal->pid = settingsMap[lora_usb_pid]; std::cerr << "Could not initialize CH341 device!" << std::endl;
ch341Hal->init();
if (!ch341Hal->isInit()) {
std::cout << "Could not initialize CH341 device!" << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
char serial[9] = {0}; char serial[9] = {0};
@ -572,4 +569,4 @@ bool MAC_from_string(std::string mac_str, uint8_t *dmac)
} else { } else {
return false; return false;
} }
} }

View File

@ -5,6 +5,7 @@
#include "platform/portduino/PortduinoGlue.h" #include "platform/portduino/PortduinoGlue.h"
#include <RadioLib.h> #include <RadioLib.h>
#include <csignal> #include <csignal>
#include <iostream>
#include <libpinedio-usb.h> #include <libpinedio-usb.h>
#include <unistd.h> #include <unistd.h>
@ -26,30 +27,42 @@ class Ch341Hal : public RadioLibHal
{ {
public: public:
// default constructor - initializes the base HAL and any needed private members // default constructor - initializes the base HAL and any needed private members
explicit Ch341Hal(uint8_t spiChannel, uint32_t spiSpeed = 2000000, uint8_t spiDevice = 0, uint8_t gpioDevice = 0) explicit Ch341Hal(uint8_t spiChannel, std::string serial = "", uint32_t vid = 0x1A86, uint32_t pid = 0x5512,
uint32_t spiSpeed = 2000000, uint8_t spiDevice = 0, uint8_t gpioDevice = 0)
: RadioLibHal(PI_INPUT, PI_OUTPUT, PI_LOW, PI_HIGH, PI_RISING, PI_FALLING) : RadioLibHal(PI_INPUT, PI_OUTPUT, PI_LOW, PI_HIGH, PI_RISING, PI_FALLING)
{ {
if (serial != "") {
strncpy(pinedio.serial_number, serial.c_str(), 8);
pinedio_set_option(&pinedio, PINEDIO_OPTION_SEARCH_SERIAL, 1);
}
// LOG_INFO("USB Serial: %s", pinedio.serial_number);
// There is no vendor with 0x0 -> so check
if (vid != 0x0) {
pinedio_set_option(&pinedio, PINEDIO_OPTION_VID, vid);
pinedio_set_option(&pinedio, PINEDIO_OPTION_PID, pid);
}
int32_t ret = pinedio_init(&pinedio, NULL);
if (ret != 0) {
std::string s = "Could not open SPI: ";
throw(s + std::to_string(ret));
}
pinedio_set_option(&pinedio, PINEDIO_OPTION_AUTO_CS, 0);
pinedio_set_pin_mode(&pinedio, 3, true);
pinedio_set_pin_mode(&pinedio, 5, true);
} }
~Ch341Hal() { pinedio_deinit(&pinedio); }
void getSerialString(char *_serial, size_t len) void getSerialString(char *_serial, size_t len)
{ {
if (!pinedio_is_init) { len = len > 8 ? 8 : len;
return;
}
strncpy(_serial, pinedio.serial_number, len); strncpy(_serial, pinedio.serial_number, len);
} }
void init() override void init() override {}
{ void term() override {}
// now the SPI
spiBegin();
}
void term() override
{
// stop the SPI
spiEnd();
}
// GPIO-related methods (pinMode, digitalWrite etc.) should check // GPIO-related methods (pinMode, digitalWrite etc.) should check
// RADIOLIB_NC as an alias for non-connected pins // RADIOLIB_NC as an alias for non-connected pins
@ -79,7 +92,7 @@ class Ch341Hal : public RadioLibHal
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override
{ {
if ((interruptNum == RADIOLIB_NC)) { if (interruptNum == RADIOLIB_NC) {
return; return;
} }
// LOG_DEBUG("Attach interrupt to pin %d", interruptNum); // LOG_DEBUG("Attach interrupt to pin %d", interruptNum);
@ -88,23 +101,14 @@ class Ch341Hal : public RadioLibHal
void detachInterrupt(uint32_t interruptNum) override void detachInterrupt(uint32_t interruptNum) override
{ {
if ((interruptNum == RADIOLIB_NC)) { if (interruptNum == RADIOLIB_NC) {
return; return;
} }
// LOG_DEBUG("Detach interrupt from pin %d", interruptNum); // LOG_DEBUG("Detach interrupt from pin %d", interruptNum);
pinedio_deattach_interrupt(&this->pinedio, (pinedio_int_pin)interruptNum); pinedio_deattach_interrupt(&this->pinedio, (pinedio_int_pin)interruptNum);
} }
void delay(unsigned long ms) override void delay(unsigned long ms) override { delayMicroseconds(ms * 1000); }
{
if (ms == 0) {
sched_yield();
return;
}
usleep(ms * 1000);
}
void delayMicroseconds(unsigned long us) override void delayMicroseconds(unsigned long us) override
{ {
@ -133,62 +137,26 @@ class Ch341Hal : public RadioLibHal
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override
{ {
fprintf(stderr, "pulseIn for pin %u is not supported!\n", pin); std::cerr << "pulseIn for pin " << pin << "is not supported!" << std::endl;
return 0; return 0;
} }
void spiBegin() void spiBegin() {}
{
if (!pinedio_is_init) {
if (serial != "") {
strncpy(pinedio.serial_number, serial.c_str(), 8);
pinedio_set_option(&pinedio, PINEDIO_OPTION_SEARCH_SERIAL, 1);
}
pinedio_set_option(&pinedio, PINEDIO_OPTION_PID, pid);
pinedio_set_option(&pinedio, PINEDIO_OPTION_VID, vid);
int32_t ret = pinedio_init(&pinedio, NULL);
if (ret != 0) {
fprintf(stderr, "Could not open SPI: %d\n", ret);
} else {
pinedio_is_init = true;
// LOG_INFO("USB Serial: %s", pinedio.serial_number);
pinedio_set_option(&pinedio, PINEDIO_OPTION_AUTO_CS, 0);
pinedio_set_pin_mode(&pinedio, 3, true);
pinedio_set_pin_mode(&pinedio, 5, true);
}
}
}
void spiBeginTransaction() {} void spiBeginTransaction() {}
void spiTransfer(uint8_t *out, size_t len, uint8_t *in) void spiTransfer(uint8_t *out, size_t len, uint8_t *in)
{ {
int32_t result = pinedio_transceive(&this->pinedio, out, in, len); int32_t ret = pinedio_transceive(&this->pinedio, out, in, len);
if (result < 0) { if (ret < 0) {
fprintf(stderr, "Could not perform SPI transfer: %d\n", result); std::cerr << "Could not perform SPI transfer: " << ret << std::endl;
} }
} }
void spiEndTransaction() {} void spiEndTransaction() {}
void spiEnd() {}
void spiEnd()
{
if (pinedio_is_init) {
pinedio_deinit(&pinedio);
pinedio_is_init = false;
}
}
bool isInit() { return pinedio_is_init; }
std::string serial = "";
uint32_t pid = 0x5512;
uint32_t vid = 0x1A86;
private: private:
// the HAL can contain any additional private members
pinedio_inst pinedio = {0}; pinedio_inst pinedio = {0};
bool pinedio_is_init = false;
}; };
#endif #endif