mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-23 06:33:57 -06:00
FirmwareUpdater: MMU 2.0 / Caterina flashing
This commit is contained in:
parent
a7eaf38853
commit
a32bd17b75
8 changed files with 496 additions and 109 deletions
|
@ -11,12 +11,14 @@
|
|||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#if _WIN32
|
||||
#include <Windows.h>
|
||||
#include <Setupapi.h>
|
||||
#include <initguid.h>
|
||||
#include <devguid.h>
|
||||
#include <regex>
|
||||
// Undefine min/max macros incompatible with the standard library
|
||||
// For example, std::numeric_limits<std::streamsize>::max()
|
||||
// produces some weird errors
|
||||
|
@ -51,6 +53,8 @@
|
|||
#include <asm-generic/ioctls.h>
|
||||
#endif
|
||||
|
||||
using boost::optional;
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
namespace Utils {
|
||||
|
@ -60,15 +64,43 @@ static bool looks_like_printer(const std::string &friendly_name)
|
|||
return friendly_name.find("Original Prusa") != std::string::npos;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static std::string get_tty_friendly_name(const std::string &path, const std::string &name)
|
||||
#if _WIN32
|
||||
void parse_hardware_id(const std::string &hardware_id, SerialPortInfo &spi)
|
||||
{
|
||||
const auto sysfs_product = (boost::format("/sys/class/tty/%1%/device/../product") % name).str();
|
||||
std::ifstream file(sysfs_product);
|
||||
std::string product;
|
||||
unsigned vid, pid;
|
||||
std::regex pattern("USB\\\\.*VID_([[:xdigit:]]+)&PID_([[:xdigit:]]+).*");
|
||||
std::smatch matches;
|
||||
if (std::regex_match(hardware_id, matches, pattern)) {
|
||||
try {
|
||||
vid = std::stoul(matches[1].str(), 0, 16);
|
||||
pid = std::stoul(matches[2].str(), 0, 16);
|
||||
spi.id_vendor = vid;
|
||||
spi.id_product = pid;
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::getline(file, product);
|
||||
return file.good() ? (boost::format("%1% (%2%)") % product % path).str() : path;
|
||||
#ifdef __linux__
|
||||
optional<std::string> sysfs_tty_prop(const std::string &tty_dev, const std::string &name)
|
||||
{
|
||||
const auto prop_path = (boost::format("/sys/class/tty/%1%/device/../%2%") % tty_dev % name).str();
|
||||
std::ifstream file(prop_path);
|
||||
std::string res;
|
||||
|
||||
std::getline(file, res);
|
||||
if (file.good()) { return res; }
|
||||
else { return boost::none; }
|
||||
}
|
||||
|
||||
optional<unsigned long> sysfs_tty_prop_hex(const std::string &tty_dev, const std::string &name)
|
||||
{
|
||||
auto prop = sysfs_tty_prop(tty_dev, name);
|
||||
if (!prop) { return boost::none; }
|
||||
|
||||
try { return std::stoul(*prop, 0, 16); }
|
||||
catch (...) { return boost::none; }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -98,6 +130,7 @@ std::vector<SerialPortInfo> scan_serial_ports_extended()
|
|||
if (port_info.port.empty())
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the size required to hold the device info.
|
||||
DWORD regDataType;
|
||||
DWORD reqSize = 0;
|
||||
|
@ -106,7 +139,8 @@ std::vector<SerialPortInfo> scan_serial_ports_extended()
|
|||
// Now store it in a buffer.
|
||||
if (! SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, ®DataType, (BYTE*)hardware_id.data(), reqSize, nullptr))
|
||||
continue;
|
||||
port_info.hardware_id = boost::nowide::narrow(hardware_id.data());
|
||||
parse_hardware_id(boost::nowide::narrow(hardware_id.data()), port_info);
|
||||
|
||||
// Find the size required to hold the friendly name.
|
||||
reqSize = 0;
|
||||
SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, nullptr, 0, &reqSize);
|
||||
|
@ -138,6 +172,8 @@ std::vector<SerialPortInfo> scan_serial_ports_extended()
|
|||
if (result) {
|
||||
SerialPortInfo port_info;
|
||||
port_info.port = path;
|
||||
|
||||
// Attempt to read out the device friendly name
|
||||
if ((cf_property = IORegistryEntrySearchCFProperty(port, kIOServicePlane,
|
||||
CFSTR("USB Interface Name"), kCFAllocatorDefault,
|
||||
kIORegistryIterateRecursively | kIORegistryIterateParents)) ||
|
||||
|
@ -159,6 +195,23 @@ std::vector<SerialPortInfo> scan_serial_ports_extended()
|
|||
}
|
||||
if (port_info.friendly_name.empty())
|
||||
port_info.friendly_name = port_info.port;
|
||||
|
||||
// Attempt to read out the VID & PID
|
||||
int vid, pid;
|
||||
auto cf_vendor = IORegistryEntrySearchCFProperty(port, kIOServicePlane, CFSTR("idVendor"),
|
||||
kCFAllocatorDefault, kIORegistryIterateRecursively | kIORegistryIterateParents);
|
||||
auto cf_product = IORegistryEntrySearchCFProperty(port, kIOServicePlane, CFSTR("idProduct"),
|
||||
kCFAllocatorDefault, kIORegistryIterateRecursively | kIORegistryIterateParents);
|
||||
if (cf_vendor && cf_product) {
|
||||
if (CFNumberGetValue((CFNumberRef)cf_vendor, kCFNumberIntType, &vid) &&
|
||||
CFNumberGetValue((CFNumberRef)cf_product, kCFNumberIntType, &pid)) {
|
||||
port_info.id_vendor = vid;
|
||||
port_info.id_product = pid;
|
||||
}
|
||||
}
|
||||
if (cf_vendor) { CFRelease(cf_vendor); }
|
||||
if (cf_product) { CFRelease(cf_product); }
|
||||
|
||||
output.emplace_back(std::move(port_info));
|
||||
}
|
||||
}
|
||||
|
@ -176,9 +229,15 @@ std::vector<SerialPortInfo> scan_serial_ports_extended()
|
|||
const auto path = dir_entry.path().string();
|
||||
SerialPortInfo spi;
|
||||
spi.port = path;
|
||||
spi.hardware_id = path;
|
||||
#ifdef __linux__
|
||||
spi.friendly_name = get_tty_friendly_name(path, name);
|
||||
auto friendly_name = sysfs_tty_prop(name, "product");
|
||||
spi.friendly_name = friendly_name ? (boost::format("%1% (%2%)") % *friendly_name % path).str() : path;
|
||||
auto vid = sysfs_tty_prop_hex(name, "idVendor");
|
||||
auto pid = sysfs_tty_prop_hex(name, "idProduct");
|
||||
if (vid && pid) {
|
||||
spi.id_vendor = *vid;
|
||||
spi.id_product = *pid;
|
||||
}
|
||||
#else
|
||||
spi.friendly_name = path;
|
||||
#endif
|
||||
|
@ -221,7 +280,7 @@ Serial::Serial(asio::io_service& io_service) :
|
|||
Serial::Serial(asio::io_service& io_service, const std::string &name, unsigned baud_rate) :
|
||||
asio::serial_port(io_service, name)
|
||||
{
|
||||
printer_setup(baud_rate);
|
||||
set_baud_rate(baud_rate);
|
||||
}
|
||||
|
||||
Serial::~Serial() {}
|
||||
|
@ -359,9 +418,8 @@ bool Serial::read_line(unsigned timeout, std::string &line, error_code &ec)
|
|||
}
|
||||
}
|
||||
|
||||
void Serial::printer_setup(unsigned baud_rate)
|
||||
void Serial::printer_setup()
|
||||
{
|
||||
set_baud_rate(baud_rate);
|
||||
printer_reset();
|
||||
write_string("\r\r\r\r\r\r\r\r\r\r"); // Gets rid of line noise, if any
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue