Compare commits

...

5 Commits

Author SHA1 Message Date
Kyle Schwarz 30c009fe8f Device: Refactor online keep alive 2025-11-04 16:24:49 -05:00
Max Brombach 51e4fdc6d9 Device: Update tree structs and add size checks to non-deprecated devices 2025-11-04 14:29:37 -05:00
Yasser Yassine 39b54d8c4e Device: Fix bootloader phases 2025-11-04 12:37:19 -05:00
Kyle Schwarz 615b7d8d56 Bindings: Python: Document 3.14 support 2025-11-04 11:51:55 -05:00
Kyle Schwarz e3f4bbdc73 Device: sendEthPhyMsg(): Drop online requirement 2025-11-04 11:06:51 -05:00
44 changed files with 142 additions and 32 deletions

View File

@ -284,6 +284,7 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
case Command::RequestSerialNumber:
case Command::EnableNetworkCommunication:
case Command::EnableNetworkCommunicationEx:
case Command::KeepAlive:
case Command::GetMainVersion:
case Command::GetSecondaryVersions:
case Command::NeoReadMemory:

View File

@ -435,7 +435,13 @@ bool Device::reconnect(std::chrono::milliseconds timeout, std::chrono::milliseco
// Pause reads again
com->pauseReads();
}
return com->open();
if(com->open()) {
return true;
} else {
if(readsArePaused) {
com->resumeReads();
}
}
}
}
std::this_thread::sleep_for(interval);
@ -579,7 +585,10 @@ bool Device::goOnline() {
}
// (re)start the keeponline
keeponline = std::make_unique<Periodic>([this] { return enableNetworkCommunication(true, onlineTimeoutMs); }, std::chrono::milliseconds(onlineTimeoutMs / 4));
keeponline = std::make_unique<Periodic>([this] {
static std::vector<uint8_t> timeoutBytes = std::vector<uint8_t>((uint8_t*)&onlineTimeoutMs, (uint8_t*)&onlineTimeoutMs + sizeof(onlineTimeoutMs));
return com->sendCommand(Command::KeepAlive, timeoutBytes);
}, std::chrono::milliseconds(onlineTimeoutMs / 4));
online = true;
@ -2090,10 +2099,6 @@ std::optional<EthPhyMessage> Device::sendEthPhyMsg(const EthPhyMessage& message,
report(APIEvent::Type::EthPhyRegisterControlNotAvailable, APIEvent::Severity::Error);
return std::nullopt;
}
if(!isOnline()) {
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
return std::nullopt;
}
std::vector<uint8_t> bytes;
HardwareEthernetPhyRegisterPacket::EncodeFromMessage(message, bytes, report);

View File

@ -8,6 +8,7 @@ namespace icsneo {
enum class Command : uint8_t {
EnableNetworkCommunication = 0x07,
EnableNetworkCommunicationEx = 0x08,
KeepAlive = 0x09,
NeoReadMemory = 0x40,
NeoWriteMemory = 0x41,
ClearCoreMini = 0x42,

View File

@ -409,6 +409,14 @@ typedef struct ETHERNET10T1S_SETTINGS_EXT_t
} ETHERNET10T1S_SETTINGS_EXT;
#define ETHERNET10T1S_SETTINGS_EXT_SIZE 16
typedef struct ETHERNET10T1L_SETTINGS_t
{
uint8_t tx_mode;
uint8_t rsvd[7];
} ETHERNET10T1L_SETTINGS;
#define ETHERNET10T1L_SETTINGS_SIZE 8
#define ETHERNET_SETTINGS10G_FLAG_FULL_DUPLEX 0x01
#define ETHERNET_SETTINGS10G_FLAG_AUTO_NEG 0x02
#define ETHERNET_SETTINGS10G_FLAG_TCPIP_ENABLE 0x04

View File

@ -56,11 +56,15 @@ typedef struct {
uint32_t enablePcEthernetComm : 1;
uint32_t reserved : 29;
} flags;//4
ETHERNET_SETTINGS2 ethernet2; //16
} etherbadge_settings_t;
#pragma pack(pop)
#ifdef __cplusplus
static_assert(sizeof(etherbadge_settings_t) == 316, "EtherBadge settings size mismatch");
#include <iostream>
class EtherBADGESettings : public IDeviceSettings {

View File

@ -52,6 +52,7 @@ public:
.add<FlashPhase>(ChipID::Connect_LINUX, BootloaderCommunication::Application, false, false, false)
.add<FinalizePhase>(ChipID::Connect_ZCHIP, BootloaderCommunication::Application)
.add<FinalizePhase>(ChipID::Connect_LINUX, BootloaderCommunication::Application)
.add<EnterApplicationPhase>(ChipID::Connect_ZCHIP)
.add<ReconnectPhase>()
.addSetting(BootloaderSetting::UpdateAll, true);
}

View File

@ -51,8 +51,6 @@ typedef struct {
uint16_t iso_msg_termination_2;
ETHERNET_SETTINGS ethernet_1;
ETHERNET_SETTINGS2 ethernet2_1;
ETHERNET_SETTINGS ethernet_2;
ETHERNET_SETTINGS2 ethernet2_2;
STextAPISettings text_api;
DISK_SETTINGS disk;
uint16_t misc_io_report_period;
@ -84,6 +82,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(neoviconnect_settings_t) == 628, "NeoVIConnect settings size mismatch");
#include <iostream>
class NeoVIConnectSettings : public IDeviceSettings {

View File

@ -95,6 +95,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(neovifire_settings_t) == 744, "NeoVIFire settings size mismatch");
#include <iostream>
class NeoVIFIRESettings : public IDeviceSettings {

View File

@ -105,6 +105,7 @@ typedef struct {
uint16_t digitalIoThresholdEnable;
TIMESYNC_ICSHARDWARE_SETTINGS timeSync;
DISK_SETTINGS disk;
ETHERNET_SETTINGS2 ethernet2; // supercedes ethernet settings
} neovifire2_settings_t;
typedef struct {
@ -118,6 +119,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(neovifire2_settings_t) == 936, "NeoVIFire2 settings size mismatch");
#include <iostream>
class NeoVIFIRE2Settings : public IDeviceSettings {

View File

@ -75,6 +75,7 @@ public:
.add<FinalizePhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application)
.add<FinalizePhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application)
.add<FinalizePhase>(ChipID::VEM_01_8DW_ZCHIP, BootloaderCommunication::Application)
.add<EnterApplicationPhase>(ChipID::neoVIFIRE3_ZCHIP)
.add<ReconnectPhase>()
.addSetting(BootloaderSetting::UpdateAll, true);
}

View File

@ -160,6 +160,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(neovifire3_settings_t) == 1722, "NeoVIFire3 settings size mismatch");
#include <iostream>
class NeoVIFIRE3Settings : public IDeviceSettings {

View File

@ -80,6 +80,7 @@ public:
.add<FinalizePhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application)
.add<FinalizePhase>(ChipID::VEM_02_FR_FCHIP, BootloaderCommunication::Application)
.add<FinalizePhase>(ChipID::VEM_02_FR_ZCHIP, BootloaderCommunication::Application)
.add<EnterApplicationPhase>(ChipID::neoVIFIRE3_ZCHIP)
.add<ReconnectPhase>()
.addSetting(BootloaderSetting::UpdateAll, true);
}

View File

@ -143,6 +143,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(neovifire3flexray_settings_t) == 1372, "NeoVIFire3Flexray settings size mismatch");
#include <iostream>
class NeoVIFIRE3FlexRaySettings : public IDeviceSettings {

View File

@ -152,6 +152,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(neovifire3t1slin_settings_t) == 1594, "NeoVIFire3T1SLIN settings size mismatch");
#include <iostream>
class NeoVIFIRE3T1SLINSettings : public IDeviceSettings {

View File

@ -58,6 +58,7 @@ public:
.add<FinalizePhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application)
.add<FinalizePhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application)
.add<FinalizePhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application)
.add<EnterApplicationPhase>(ChipID::neoVIFIRE3_ZCHIP)
.add<ReconnectPhase>()
.addSetting(BootloaderSetting::UpdateAll, true);
}

View File

@ -105,6 +105,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(neovired2_settings_t) == 918, "NeoVIRED2 settings size mismatch");
#include <iostream>
class NeoVIRED2Settings : public IDeviceSettings {

View File

@ -58,7 +58,7 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADA2B_ZCHIP, BootloaderCommunication::RAD)
.add<ReconnectPhase>()
// .add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
}
protected:

View File

@ -59,12 +59,14 @@ typedef struct {
ETHERNET_SETTINGS2 ethernet;
RAD_GPTP_SETTINGS gPTP;
uint64_t network_enables_5;
CMP_GLOBAL_DATA cmp_global_data;
CMP_NETWORK_DATA cmp_stream_data[CMP_STREAMS_A2B];
} rada2b_settings_t;
#pragma pack(pop)
#ifdef __cplusplus
static_assert(sizeof(rada2b_settings_t) == 340, "RAD-A2B settings size mismatch");
static_assert(sizeof(rada2b_settings_t) == 416, "RAD-A2B settings size mismatch");
#include <iostream>

View File

@ -45,8 +45,8 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADComet_ZYNQ, BootloaderCommunication::RAD)
.add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected:

View File

@ -69,8 +69,8 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADCOMET3_ZCHIP, BootloaderCommunication::RAD)
.add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
.add<WaitPhase>(std::chrono::milliseconds(5000))
.add<ReconnectPhase>();
}
protected:

View File

@ -40,6 +40,7 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADEpsilon_MCHIP, BootloaderCommunication::RED)
.add<EnterApplicationPhase>(ChipID::RADEpsilon_MCHIP)
.add<ReconnectPhase>();
}
bool supportsComponentVersions() const override { return true; }

View File

@ -80,6 +80,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(radepsilon_settings_t) == 400, "RADEpsilon settings size mismatch");
#include <iostream>
class RADEpsilonSettings : public IDeviceSettings {

View File

@ -92,6 +92,7 @@ typedef struct {
uint16_t network_enables_4;
RAD_GPTP_SETTINGS gPTP;
uint64_t network_enables_5;
} radgalaxy_settings_t;
typedef struct {
@ -102,6 +103,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(radgalaxy_settings_t) == 776, "RADGalaxy settings size mismatch");
#include <iostream>
class RADGalaxySettings : public IDeviceSettings {

View File

@ -85,6 +85,7 @@ public:
.add<FlashPhase>(ChipID::RAD_GALAXY_2_ZMPCHIP_ID, BootloaderCommunication::RAD)
.add<ReconnectPhase>()
.add<FlashPhase>(ChipID::RADGALAXY2_SYSMON_CHIP, BootloaderCommunication::RADGalaxy2Peripheral)
.add<EnterApplicationPhase>(ChipID::RAD_GALAXY_2_ZMPCHIP_ID)
.add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
}

View File

@ -103,6 +103,11 @@ typedef struct {
uint64_t network_enables_5;
LIN_SETTINGS lin2;
uint16_t iso_9141_kwp_enable_reserved_2;
ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_2;
uint16_t iso_parity_2;
uint16_t iso_msg_termination_2;
} radgalaxy2_settings_t;
typedef struct {
@ -114,6 +119,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(radgalaxy2_settings_t) == 960, "RADGalaxy2 settings size mismatch");
#include <iostream>
class RADGalaxy2Settings : public IDeviceSettings {

View File

@ -36,6 +36,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(radgemini_settings_t) == 86, "RADGemini settings size mismatch");
#include <iostream>
class RADGeminiSettings : public IDeviceSettings {

View File

@ -84,8 +84,8 @@ public:
pipeline.add<FlashPhase>(version.id, BootloaderCommunication::RADMultiChip);
}
pipeline.add<EnterApplicationPhase>(mainChipID);
pipeline.add<ReconnectPhase>();
pipeline.add<WaitPhase>(std::chrono::milliseconds(3000));
pipeline.add<ReconnectPhase>();
return pipeline;
}
}
@ -93,13 +93,13 @@ public:
if(com->driver->isEthernet()) {
return BootloaderPipeline()
.add<FlashPhase>(ChipID::RADGigastar_ZYNQ, BootloaderCommunication::RAD)
.add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
return BootloaderPipeline()
.add<FlashPhase>(ChipID::RADGigastar_USBZ_ZYNQ, BootloaderCommunication::RAD)
.add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
std::vector<VersionReport> getChipVersions(bool refreshComponents = true) override {

View File

@ -84,12 +84,24 @@ typedef struct {
RAD_GPTP_SETTINGS gPTP;
uint64_t network_enables_5;
// SFP T1S
ETHERNET10T1S_SETTINGS sfp_t1s_1;
ETHERNET10T1S_SETTINGS_EXT sfp_t1s_ext_1;
ETHERNET10T1S_SETTINGS sfp_t1s_2;
ETHERNET10T1S_SETTINGS_EXT sfp_t1s_ext_2;
CMP_GLOBAL_DATA cmp_global_data;
CMP_NETWORK_DATA cmp_stream_data[CMP_STREAMS_GIGASTAR];
// SFP T1L
ETHERNET10T1L_SETTINGS sfp_t1l_1;
ETHERNET10T1L_SETTINGS sfp_t1l_2;
} radgigastar_settings_t;
#pragma pack(pop)
#ifdef __cplusplus
static_assert(sizeof(radgigastar_settings_t) == 710, "RADGigastar settings size mismatch");
static_assert(sizeof(radgigastar_settings_t) == 1026, "RADGigastar settings size mismatch");
#include <iostream>

View File

@ -163,8 +163,8 @@ public:
pipeline.add<FlashPhase>(version.id, BootloaderCommunication::RADMultiChip);
}
pipeline.add<EnterApplicationPhase>(mainChipID);
pipeline.add<ReconnectPhase>();
pipeline.add<WaitPhase>(std::chrono::milliseconds(3000));
pipeline.add<ReconnectPhase>();
return pipeline;
}

View File

@ -127,18 +127,29 @@ namespace icsneo
ETHERNET_SETTINGS2 ethT1s8;
ETHERNET10T1S_SETTINGS t1s8;
ETHERNET10T1S_SETTINGS_EXT t1s8Ext;
// SFP T1S
ETHERNET10T1S_SETTINGS sfp_t1s_1;
ETHERNET10T1S_SETTINGS_EXT sfp_t1s_ext_1;
ETHERNET10T1S_SETTINGS sfp_t1s_2;
ETHERNET10T1S_SETTINGS_EXT sfp_t1s_ext_2;
LIN_SETTINGS lin11;
LIN_SETTINGS lin12;
LIN_SETTINGS lin13;
LIN_SETTINGS lin14;
LIN_SETTINGS lin15;
LIN_SETTINGS lin16;
// SFP T1L
ETHERNET10T1L_SETTINGS sfp_t1l_1;
ETHERNET10T1L_SETTINGS sfp_t1l_2;
} radgigastar2_settings_t;
#pragma pack(pop)
#ifdef __cplusplus
static_assert(sizeof(radgigastar2_settings_t) == 2084, "RADGigastar2 settings size mismatch");
static_assert(sizeof(radgigastar2_settings_t) == 2156, "RADGigastar2 settings size mismatch");
#include <iostream>

View File

@ -33,8 +33,9 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADMoon2_ZYNQ, BootloaderCommunication::RAD)
.add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
.add<EnterApplicationPhase>(ChipID::RADMoon2_ZYNQ)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected:
RADMoon2(neodevice_t neodevice, const driver_factory_t& makeDriver) : RADMoon2Base(neodevice) {

View File

@ -36,6 +36,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(radmoon2_settings_t) == 170, "RADMoon2 settings size mismatch");
#include <iostream>
class RADMoon2Settings : public IDeviceSettings {

View File

@ -33,6 +33,8 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADMoon2_ZL_MCHIP, BootloaderCommunication::RED)
.add<EnterApplicationPhase>(ChipID::RADMoon2_ZL_MCHIP)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected:

View File

@ -45,8 +45,9 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADMoon3_MCHIP, BootloaderCommunication::RED)
.add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
.add<EnterApplicationPhase>(ChipID::RADMoon3_MCHIP)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected:
RADMoon3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {

View File

@ -33,6 +33,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(radmoon3_settings_t) == 68, "RADMoon3 settings size mismatch");
#include <iostream>
class RADMoon3Settings : public IDeviceSettings {

View File

@ -32,11 +32,16 @@ typedef struct {
// 10T1S
ETHERNET_SETTINGS2 ethT1s;
ETHERNET10T1S_SETTINGS t1s;
// 10T1S Extended Settings
ETHERNET10T1S_SETTINGS_EXT t1sExt;
RAD_GPTP_SETTINGS gPTP;
} radmoont1s_settings_t;
#pragma pack(pop)
#ifdef __cplusplus
static_assert(sizeof(radmoont1s_settings_t) == 160, "RADMoonT1S settings size mismatch");
#include <iostream>
class RADMoonT1SSettings : public IDeviceSettings {

View File

@ -60,11 +60,17 @@ typedef struct {
TIMESYNC_ICSHARDWARE_SETTINGS timeSyncSettings;
uint16_t hwComLatencyTestEn;
RAD_REPORTING_SETTINGS reporting;
ETHERNET_SETTINGS2 ethernet;
RAD_GPTP_SETTINGS gPTP;
uint64_t network_enables_5;
} radstar2_settings_t;
#pragma pack(pop)
#ifdef __cplusplus
static_assert(sizeof(radstar2_settings_t) == 422, "RADStar2 settings size mismatch");
#include <iostream>
class RADStar2Settings : public IDeviceSettings {

View File

@ -31,6 +31,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(valuecan3_settings_t) == 40, "ValueCAN3 settings size mismatch");
#include <iostream>
class ValueCAN3Settings : public IDeviceSettings {

View File

@ -31,11 +31,13 @@ public:
};
return chips;
}
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::ValueCAN4_1_MCHIP, BootloaderCommunication::RED)
.add<EnterApplicationPhase>(ChipID::ValueCAN4_1_MCHIP)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}

View File

@ -61,8 +61,9 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::ValueCAN4_2_MCHIP, BootloaderCommunication::RED)
.add<ReconnectPhase>()
.add<WaitPhase>(std::chrono::milliseconds(3000));
.add<EnterApplicationPhase>(ChipID::ValueCAN4_2_MCHIP)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected:

View File

@ -66,7 +66,7 @@ public:
const std::vector<ChipInfo>& getChipInfo() const override {
static std::vector<ChipInfo> chips = {
{ChipID::ValueCAN4_2EL_MCHIP, true, "MCHIP", "vcan44_mchip_ief", 0, FirmwareType::IEF}
{ChipID::ValueCAN4_2EL_MCHIP, true, "MCHIP", "vcan44_mchip_ief", 0, FirmwareType::IEF},
};
return chips;
}
@ -75,6 +75,8 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::ValueCAN4_2EL_MCHIP, BootloaderCommunication::RED)
.add<EnterApplicationPhase>(ChipID::ValueCAN4_2EL_MCHIP)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}

View File

@ -64,7 +64,8 @@ public:
const std::vector<ChipInfo>& getChipInfo() const override {
static std::vector<ChipInfo> chips = {
{ChipID::ValueCAN4_4_MCHIP, true, "MCHIP", "vcan44_mchip_ief", 0, FirmwareType::IEF},
{ChipID::ValueCAN4_4_SCHIP, true, "SCHIP", "vcan44_schip_ief", 1, FirmwareType::IEF}
{ChipID::ValueCAN4_4_SCHIP, true, "SCHIP", "vcan44_schip_ief", 1, FirmwareType::IEF},
{ChipID::ValueCAN4_4_2EL_Core, true, "Core", "vcan44_core_ief", 2, FirmwareType::IEF}
};
return chips;
}
@ -73,7 +74,10 @@ public:
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::ValueCAN4_4_MCHIP, BootloaderCommunication::RED)
.add<FlashPhase>(ChipID::ValueCAN4_4_SCHIP, BootloaderCommunication::RED, false, true)
.add<FlashPhase>(ChipID::ValueCAN4_4_SCHIP, BootloaderCommunication::RED)
.add<FlashPhase>(ChipID::ValueCAN4_4_2EL_Core, BootloaderCommunication::REDCore)
.add<EnterApplicationPhase>(ChipID::ValueCAN4_4_MCHIP)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected:

View File

@ -42,6 +42,8 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(vividcan_settings_t) == 64, "VividCAN settings size mismatch");
#include <iostream>
class VividCANSettings : public IDeviceSettings {

View File

@ -23,6 +23,7 @@ classifiers = [
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: Implementation :: CPython',
'Operating System :: Microsoft :: Windows',