diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index 7cca8bc189..f5159fd839 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -26,7 +26,7 @@ lib_deps = ${radiolib_base.lib_deps} rweather/Crypto@^0.4.0 https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805 - https://github.com/jp-bennett/libch341-spi-userspace#d7dc112f796a55d61cb591f53e8ab418bb914795 + https://github.com/jp-bennett/libch341-spi-userspace#3b9aa09e6496ffdfce4011528697d482e29b4de0 build_flags = ${arduino_base.build_flags} diff --git a/bin/config.d/lora-meshstick-1262.yaml b/bin/config.d/lora-meshstick-1262.yaml index 6b5ec8732f..3f8d6c617a 100644 --- a/bin/config.d/lora-meshstick-1262.yaml +++ b/bin/config.d/lora-meshstick-1262.yaml @@ -5,4 +5,7 @@ Lora: Reset: 2 Busy: 4 spidev: ch341 - DIO3_TCXO_VOLTAGE: true \ No newline at end of file + DIO3_TCXO_VOLTAGE: true +# USB_Serialnum: 12345678 + USB_PID: 0x5512 + USB_VID: 0x1A86 diff --git a/src/main.cpp b/src/main.cpp index 8cb31e325d..0bf20c6a82 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -824,7 +824,7 @@ void setup() if (!rIf) { LOG_DEBUG("Activate sx1262 radio on SPI port %s", settingsStrings[spidev].c_str()); if (settingsStrings[spidev] == "ch341") { - RadioLibHAL = new Ch341Hal(0); + RadioLibHAL = ch341Hal; } else { RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); } diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index c236f37543..1414e76a54 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -21,9 +21,12 @@ #include #include +#include "platform/portduino/USBHal.h" + std::map settingsMap; std::map settingsStrings; std::ofstream traceFile; +Ch341Hal *ch341Hal = nullptr; char *configPath = nullptr; char *optionMac = nullptr; @@ -200,8 +203,36 @@ void portduinoSetup() } } } - + // 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}; + if (settingsStrings[spidev] == "ch341") { + ch341Hal = new Ch341Hal(0); + if (settingsStrings[lora_usb_serial_num] != "") { + ch341Hal->serial = settingsStrings[lora_usb_serial_num]; + } + ch341Hal->vid = settingsMap[lora_usb_vid]; + ch341Hal->pid = settingsMap[lora_usb_pid]; + ch341Hal->init(); + if (!ch341Hal->isInit()) { + std::cout << "Could not initialize CH341 device!" << std::endl; + exit(EXIT_FAILURE); + } + char serial[9] = {0}; + ch341Hal->getSerialString(serial, 8); + std::cout << "Serial " << serial << std::endl; + if (strlen(serial) == 8 && settingsStrings[mac_address].length() < 12) { + uint8_t hash[32] = {0}; + memcpy(hash, serial, 8); + crypto->hash(hash, 8); + dmac[0] = (hash[0] << 4) | 2; + dmac[1] = hash[1]; + dmac[2] = hash[2]; + dmac[3] = hash[3]; + dmac[4] = hash[4]; + dmac[5] = hash[5]; + } + } + getMacAddr(dmac); if (dmac[0] == 0 && dmac[1] == 0 && dmac[2] == 0 && dmac[3] == 0 && dmac[4] == 0 && dmac[5] == 0) { std::cout << "*** Blank MAC Address not allowed!" << std::endl; @@ -375,6 +406,9 @@ bool loadConfig(const char *configPath) settingsMap[sx126x_ant_sw] = yamlConfig["Lora"]["SX126X_ANT_SW"].as(RADIOLIB_NC); settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as(0); settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as(2000000); + settingsStrings[lora_usb_serial_num] = yamlConfig["Lora"]["USB_Serialnum"].as(""); + settingsMap[lora_usb_pid] = yamlConfig["Lora"]["USB_PID"].as(0x5512); + settingsMap[lora_usb_vid] = yamlConfig["Lora"]["USB_VID"].as(0x1A86); settingsStrings[spidev] = yamlConfig["Lora"]["spidev"].as("spidev0.0"); if (settingsStrings[spidev] != "ch341") { diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 5690211fc1..9cf9b66788 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -2,6 +2,8 @@ #include #include +#include "platform/portduino/USBHal.h" + enum configNames { use_sx1262, cs, @@ -19,6 +21,9 @@ enum configNames { use_lr1120, use_lr1121, use_sx1268, + lora_usb_serial_num, + lora_usb_pid, + lora_usb_vid, user, gpiochip, spidev, @@ -68,6 +73,7 @@ enum { level_error, level_warn, level_info, level_debug, level_trace }; extern std::map settingsMap; extern std::map settingsStrings; extern std::ofstream traceFile; +extern Ch341Hal *ch341Hal; int initGPIOPin(int pinNum, std::string gpioChipname); bool loadConfig(const char *configPath); static bool ends_with(std::string_view str, std::string_view suffix); diff --git a/src/platform/portduino/USBHal.h b/src/platform/portduino/USBHal.h index 5afea8e4ab..2a57c9a64d 100644 --- a/src/platform/portduino/USBHal.h +++ b/src/platform/portduino/USBHal.h @@ -2,6 +2,7 @@ #define PI_HAL_LGPIO_H // include RadioLib +#include "platform/portduino/PortduinoGlue.h" #include #include #include @@ -29,6 +30,14 @@ class Ch341Hal : public RadioLibHal { } + void getSerialString(char *_serial, size_t len) + { + if (!pinedio_is_init) { + return; + } + strncpy(_serial, pinedio.serial_number, len); + } + void init() override { // now the SPI @@ -72,7 +81,7 @@ class Ch341Hal : public RadioLibHal if ((interruptNum == RADIOLIB_NC)) { return; } - LOG_DEBUG("Attach interrupt to pin %d", interruptNum); + // LOG_DEBUG("Attach interrupt to pin %d", interruptNum); pinedio_attach_interrupt(&this->pinedio, (pinedio_int_pin)interruptNum, (pinedio_int_mode)mode, interruptCb); } @@ -81,7 +90,7 @@ class Ch341Hal : public RadioLibHal if ((interruptNum == RADIOLIB_NC)) { 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); } @@ -129,11 +138,18 @@ class Ch341Hal : public RadioLibHal 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); @@ -161,9 +177,15 @@ class Ch341Hal : public RadioLibHal } } + bool isInit() { return pinedio_is_init; } + + std::string serial = ""; + uint32_t pid = 0x5512; + uint32_t vid = 0x1A86; + private: // the HAL can contain any additional private members - pinedio_inst pinedio; + pinedio_inst pinedio = {0}; bool pinedio_is_init = false; };