diff --git a/device/device.cpp b/device/device.cpp index 8878a4e..498e13f 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -207,6 +207,71 @@ bool Device::refreshComponentVersions() { return false; } +std::vector Device::getChipVersions(bool refreshComponents) { + if(refreshComponents) { + refreshComponentVersions(); + } + std::vector chipVersions; + + if (supportsComponentVersions()) { + const auto& compVersions = getComponentVersions(); + auto disectVersion = [](uint32_t dotVersion) { + std::array result = {0,0,0,0}; + size_t i = 0; + + if(dotVersion & 0xFF000000ul) { + result[i++] = (uint8_t)((dotVersion & 0xFF000000ul) >> 24); + result[i++] = (uint8_t)((dotVersion & 0x00FF0000ul) >> 16); + } else if(dotVersion & 0x00FF0000ul) { + result[i++] = (uint8_t)((dotVersion & 0x00FF0000ul) >> 16); + } + result[i++] = (uint8_t)((dotVersion & 0x0000FF00ul) >> 8); + result[i] = (uint8_t)((dotVersion & 0x000000FFul) >> 0); + return result; + }; + for(const auto& chipInfo : getChipInfo()) { + for(const auto& component : compVersions) { + if(component.identifier == (uint32_t)chipInfo.id) { + chipVersions.emplace_back(); + auto& version = chipVersions.back(); + + auto disectedVersion = disectVersion(component.dotVersion); + version.id = chipInfo.id; + version.name = chipInfo.name; + version.major = disectedVersion[0]; + version.minor = disectedVersion[1]; + version.maintenance = disectedVersion[2]; + version.build = disectedVersion[3]; + } + } + } + } else { + const auto& appVersions = getVersions(); + for(const auto& chipInfo : getChipInfo()) { + if(!chipInfo.defaultEnabled) { + continue; + } + if(appVersions.size() <= chipInfo.versionIndex) { + continue; + } + const auto& appVer = appVersions[chipInfo.versionIndex]; + if(!appVer) { + continue; + } + chipVersions.emplace_back(); + auto& version = chipVersions.back(); + + version.id = chipInfo.id; + version.name = chipInfo.name; + version.major = appVer->major; + version.minor = appVer->minor; + version.maintenance = 0; + version.build = 0; + } + } + return chipVersions; +} + bool Device::open(OpenFlags flags, OpenStatusHandler handler) { if(!com) { report(APIEvent::Type::Unknown, APIEvent::Severity::Error); diff --git a/include/icsneo/device/bootloaderpipeline.h b/include/icsneo/device/bootloaderpipeline.h new file mode 100644 index 0000000..71476e4 --- /dev/null +++ b/include/icsneo/device/bootloaderpipeline.h @@ -0,0 +1,117 @@ +#ifndef __BOOTLOADER_PIPELINE_H_ +#define __BOOTLOADER_PIPELINE_H_ + +#ifdef __cplusplus + +#include "icsneo/device/chipid.h" + +#include +#include +#include +#include + +namespace icsneo { + +enum class BootloaderCommunication { + RAD, + RED, + REDCore, + RADGalaxy2Peripheral, + RADMultiChip, + Application, + Invalid +}; + +struct BootloaderPhase { + enum class Type { + Flash, + Finalize, + Reconnect, + EnterBootloader, + Wait + }; + + virtual Type getType() const = 0; + virtual ~BootloaderPhase() = default; +}; + +struct ReconnectPhase : public BootloaderPhase { + Type getType() const override { + return Type::Reconnect; + } + + ReconnectPhase() = default; +}; + +struct FinalizePhase : public BootloaderPhase { + Type getType() const override { + return Type::Finalize; + } + + ChipID chip; + BootloaderCommunication comm; + + FinalizePhase(ChipID chip, BootloaderCommunication comm) : chip(chip), comm(comm) {} +}; + +struct WaitPhase : public BootloaderPhase { + Type getType() const override { + return Type::Wait; + } + + std::chrono::milliseconds timeout; + + WaitPhase(std::chrono::milliseconds timeout) : timeout(timeout) {} +}; + +struct EnterBootloaderPhase : public BootloaderPhase { + Type getType() const override { + return Type::EnterBootloader; + } +}; + +struct FlashPhase : public BootloaderPhase { + Type getType() const override { + return Type::Flash; + } + + ChipID chip; + BootloaderCommunication comm; + bool authenticate = true; + bool encrypt = true; + bool checkOutOfDate = true; + + FlashPhase(ChipID chip, BootloaderCommunication comm, bool authenticate = true, bool encrypt = true, bool checkOutOfDate = true) + : chip(chip), comm(comm), authenticate(authenticate), encrypt(encrypt), checkOutOfDate(checkOutOfDate) {} +}; + +enum class BootloaderSetting { + UpdateAll +}; + +struct BootloaderPipeline { + std::vector> phases; + std::unordered_map> settings; + + template + BootloaderPipeline& add(Args... args) { + phases.emplace_back(std::make_shared(std::forward(args)...)); + return *this; + } + + BootloaderPipeline& addSetting(BootloaderSetting type, const std::variant& setting) { + settings.insert({type, setting}); + return *this; + } + + operator bool() const { + return !phases.empty(); + } + +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/device/chipid.h b/include/icsneo/device/chipid.h new file mode 100644 index 0000000..3471e8d --- /dev/null +++ b/include/icsneo/device/chipid.h @@ -0,0 +1,139 @@ +#ifndef __CHIP_ID_H_ +#define __CHIP_ID_H_ + +#ifdef __cplusplus + +#include + +namespace icsneo { + +enum class ChipID : uint8_t { + neoVIFIRE_MCHIP = 0, + neoVIFIRE_LCHIP = 1, + neoVIFIRE_UCHIP = 2, + neoVIFIRE_JCHIP = 3, + ValueCAN3_MCHIP = 4, + neoVIECU_MPIC = 6, + neoVIIEVB_MPIC = 7, + neoVIPENDANT_MPIC = 8, + neoVIFIRE_VNET_MCHIP = 9, + neoVIFIRE_VNET_LCHIP = 10, + neoVIPLASMA_Core = 11, + neoVIPLASMA_HID = 12, + neoVIANALOG_MPIC = 13, + neoVIPLASMA_ANALOG_Core = 14, + neoVIPLASMA_FlexRay_Core = 15, + neoVIPLASMA_Core_1_12 = 16, + neoVIFIRE_Slave_VNET_MCHIP = 17, + neoVIFIRE_Slave_VNET_LCHIP = 18, + neoVIION_Core = 19, + neoVIION_HID = 20, + neoVIION_Core_Loader = 21, + neoVIION_HID_Loader = 22, + neoVIION_FPGA_BIT = 23, + neoVIFIRE_VNET_EP_MCHIP = 24, + neoVIFIRE_VNET_EP_LCHIP = 25, + neoVIAnalogOut_MCHIP = 26, + neoVIMOST25_MCHIP = 27, + neoVIMOST50_MCHIP = 28, + neoVIMOST150_MCHIP = 29, + ValueCAN4_4_MCHIP = 30, + ValueCAN4_4_SCHIP = 31, + cmProbe_ZYNQ = 33, + EEVB_STM32 = 34, + neoVIFIRE_Slave_VNET_EP_MCHIP = 35, + neoVIFIRE_Slave_VNET_EP_LCHIP = 36, + RADStar_MCHIP = 37, + ValueCANrf_MCHIP = 38, + neoVIFIRE2_MCHIP = 39, + neoVIFIRE2_CCHIP = 40, + neoVIFIRE2_Core = 41, + neoVIFIRE2_BLECHIP = 42, + neoVIFIRE2_ZYNQ = 43, // FIRE2 MVNET Z - Zynq + neoVIFIRE2_SECURITYCHIP = 44, + RADGalaxy_ZYNQ = 45, + neoVIFIRE2_VNET_MCHIP = 46, + neoVIFIRE2_Slave_VNET_A_MCHIP = 47, + neoVIFIRE2_Slave_VNET_A_CCHIP = 48, + neoVIFIRE2_VNET_CCHIP = 49, + neoVIFIRE2_VNET_Core = 50, + RADStar2_ZYNQ = 51, + VividCAN_MCHIP = 52, + neoOBD2SIM_MCHIP = 53, + neoVIFIRE2_VNETZ_MCHIP = 54, + neoVIFIRE2_VNETZ_ZYNQ = 55, + neoVIFIRE2_Slave_VNETZ_A_MCHIP = 56, + neoVIFIRE2_Slave_VNETZ_A_ZYNQ = 57, + VividCAN_EXT_FLASH = 58, + VividCAN_NRF52 = 59, + cmProbe_ZYNQ_Unused = 60, // Double defined + neoOBD2PRO_MCHIP = 61, + ValueCAN4_1_MCHIP = 62, + ValueCAN4_2_MCHIP = 63, + ValueCAN4_4_2EL_Core = 64, + neoOBD2PRO_SCHIP = 65, + ValueCAN4_2EL_MCHIP = 67, + neoECUAVBTSN_MCHIP = 68, + neoOBD2PRO_Core = 69, + RADSupermoon_ZYNQ = 70, + RADMoon2_ZYNQ = 71, + VividCANPRO_MCHIP = 72, + VividCANPRO_EXT_FLASH = 73, + RADPluto_MCHIP = 74, + RADMars_ZYNQ = 75, + neoECU12_MCHIP = 76, + RADIOCANHUB_MCHIP = 77, + FlexRay_VNETZ_ZCHIP = 78, + neoOBD2_LCBADGE_MCHIP = 79, + neoOBD2_LCBADGE_SCHIP = 80, + RADMoonDuo_MCHIP = 81, + neoVIFIRE3_ZCHIP = 82, + FlexRay_VNETZ_FCHIP = 83, + RADJupiter_MCHIP = 84, + ValueCAN4Industrial_MCHIP = 85, + EtherBADGE_MCHIP = 86, + RADMars_3_ZYNQ = 87, + RADGigastar_USBZ_ZYNQ = 88, + RADGigastar_ZYNQ = 89, + RAD4G_MCHIP = 90, + neoVIFIRE3_SCHIP = 91, + RADEpsilon_MCHIP = 92, + RADA2B_ZCHIP = 93, + neoOBD2Dev_MCHIP = 94, + neoOBD2Dev_SCHIP = 95, + neoOBD2SIMDoIP_MCHIP = 96, + SFPModule_MCHIP = 97, + RADEpsilonT_MCHIP = 98, + RADEpsilonExpress_MCHIP = 99, + RADProxima_MCHIP = 100, + NewDevice57_ZCHIP = 101, + RAD_GALAXY_2_ZMPCHIP_ID = 102, + NewDevice59_MCHIP = 103, + RADMoon2_Z7010_ZYNQ = 104, + neoVIFIRE2_CORE_SG4 = 105, + RADBMS_MCHIP = 106, + RADMoon2_ZL_MCHIP = 107, + RADGigastar_USBZ_Z7010_ZYNQ = 108, + neoVIFIRE3_LINUX = 109, + RADGigastar_USBZ_Z7007S_ZYNQ = 110, + VEM_01_8DW_ZCHIP = 111, + RADGalaxy_FFG_Zynq = 112, + RADMoon3_MCHIP = 113, + RADComet_ZYNQ = 114, + VEM_02_FR_ZCHIP = 115, + RADA2B_REVB_ZCHIP = 116, + RADGigastar_FFG_ZYNQ = 117, + VEM_02_FR_FCHIP = 118, + Connect_ZCHIP = 121, + RADGALAXY2_SYSMON_CHIP = 123, + RADCOMET3_ZCHIP = 125, + Connect_LINUX = 126, + RADGigastar2_ZYNQ = 131, + Invalid = 255 +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/device/chipinfo.h b/include/icsneo/device/chipinfo.h new file mode 100644 index 0000000..0ab2976 --- /dev/null +++ b/include/icsneo/device/chipinfo.h @@ -0,0 +1,59 @@ +#ifndef __CHIP_INFO_H_ +#define __CHIP_INFO_H_ + +#ifdef __cplusplus + +#include "icsneo/device/chipid.h" + +#include + +namespace icsneo { + +enum class FirmwareType { + IEF, + Zip +}; + +struct ChipInfo { + /** + * The default enabled field is for devices which can't deduce the specific ChipID of a device + * until entering the bootloader. + * + * If defaultEnabled is set to true, the bootloader and version retrieval functions assume that + * the chip is enabled, so it will perform version deduction based on the default enabled chip. If + * defaultEnabled is set to false, then this chip info may or may not apply to this device + * + * Example: RADA2B RevA and RevB chips + * + * Sometimes we can't deduce whether we have a RevA or RevB chip before entering the bootloader if the + * device does not support component versions. These chips track the same version, so we assume that the + * chip is RevA (RevA defaultEnabled=true, RevB defaultEnabled=false) and check during the bootloader + * if this chip is RevA or RevB. + */ + ChipID id; + bool defaultEnabled = false; + const char* name = nullptr; // Chip user displayable name + const char* iefName = nullptr; // IEF name for a single segment chip (example RADA2B ZCHIP) + size_t versionIndex = 0; // Main and Secondary version index + FirmwareType fwType; // Firmwaare storagae type + std::vector iefSegments; // IEF names for a multi segment chip (example RADGalaxy2 ZCHIP) + + ChipInfo() = default; + + ChipInfo(ChipID id, bool defaultEnabled, const char* name, const char* iefName, size_t versionIndex, FirmwareType fwType) + : id(id), defaultEnabled(defaultEnabled), name(name), iefName(iefName), versionIndex(versionIndex), fwType(fwType) {} + + ChipInfo(ChipID id, bool defaultEnabled, const char* name, const char* iefName, const std::vector& iefSegments, size_t versionIndex, FirmwareType fwType) + : id(id), defaultEnabled(defaultEnabled), name(name), iefName(iefName), versionIndex(versionIndex), fwType(fwType), iefSegments(iefSegments) {} + + bool isMultiIEF() const { + return !iefSegments.empty(); + } + +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index a61a4b5..c9c7a80 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -24,6 +24,9 @@ #include "icsneo/device/deviceversion.h" #include "icsneo/device/founddevice.h" #include "icsneo/device/coremini.h" +#include "icsneo/device/bootloaderpipeline.h" +#include "icsneo/device/chipinfo.h" +#include "icsneo/device/versionreport.h" #include "icsneo/disk/diskreaddriver.h" #include "icsneo/disk/diskwritedriver.h" #include "icsneo/disk/nulldiskdriver.h" @@ -86,6 +89,77 @@ class Device { public: virtual ~Device(); + enum class ProductID : uint8_t { + neoVIRED = 0, + neoVIFIRE = 1, + ValueCAN3 = 2, + VividCANPro = 3, // Previously neoVI Yellow + neoECU = 4, + IEVB = 5, + Pendant = 6, + neoAnalog = 7, + neoECU12 = 8, + neoVIPLASMA = 10, + neoVIION = 11, + ValueCAN4_2EL_4 = 12, + cmProbe = 14, + EEVB = 15, + RADStar = 16, + ValueCANrf = 17, + neoVIFIRE2 = 18, + RADGalaxy = 19, + RADStar2 = 20, + VividCAN = 21, + neoOBD2Sim = 22, + neoOBD2Pro = 23, + ValueCAN4_1_2 = 24, + neoECUAVBTSN = 25, + RADSupermoon = 26, + RADMoon2 = 27, + RADPluto = 28, + RADMars = 29, + RADIOCANHUB = 30, + neoOBD2LCBadge = 31, + RADMoonDuo = 32, + neoVIFIRE3 = 33, + RADJupiter = 34, + ValueCAN4Industrial = 35, + RADGigastar = 36, + VividCANProUnused = 37, // The VividCAN Pro was double allocated + EtherBADGE = 38, + RADEpsilon = 39, + RADA2B = 40, + SFPModule = 41, + RADGalaxy2 = 47, + RADMoon3 = 49, + RADComet = 50, + Connect = 51, + RADComet3 = 54, + RADMoonT1S = 56, + RADGigastar2 = 57 + }; + + virtual ProductID getProductID() const = 0; + + /** + * Returns information for all potential chips, note some chips + * might not apply to a specific device depending on different + * hardware versions + */ + virtual const std::vector& getChipInfo() const { + static std::vector placeHolder; + return placeHolder; // TODO: Make pure virtual maybe? + } + + /** + * Returns bootloader instructions + */ + virtual BootloaderPipeline getBootloader() { + return {}; + } + + bool hasBootloader() { return !!getBootloader(); } + static std::string SerialNumToString(uint32_t serial); static uint32_t SerialStringToNum(const std::string& serial); static bool SerialStringIsNumeric(const std::string& serial); @@ -586,10 +660,13 @@ public: bool refreshComponentVersions(); /** - * For use by extensions only. A more stable API will be provided in the future. + * For use by extensions only. */ const std::vector>& getVersions() const { return versions; } const std::vector& getComponentVersions() const { return componentVersions; } + + virtual std::vector getChipVersions(bool refreshComponents = true); + /** * Some alternate communication protocols do not support DFU diff --git a/include/icsneo/device/tree/etherbadge/etherbadge.h b/include/icsneo/device/tree/etherbadge/etherbadge.h index 47c9de4..665270b 100644 --- a/include/icsneo/device/tree/etherbadge/etherbadge.h +++ b/include/icsneo/device/tree/etherbadge/etherbadge.h @@ -26,6 +26,10 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::EtherBADGE; + } + protected: EtherBADGE(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neoobd2pro/neoobd2pro.h b/include/icsneo/device/tree/neoobd2pro/neoobd2pro.h index 269c12e..a81c130 100644 --- a/include/icsneo/device/tree/neoobd2pro/neoobd2pro.h +++ b/include/icsneo/device/tree/neoobd2pro/neoobd2pro.h @@ -22,6 +22,10 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::neoOBD2Pro; + } + private: NeoOBD2PRO(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neoobd2sim/neoobd2sim.h b/include/icsneo/device/tree/neoobd2sim/neoobd2sim.h index 90e907f..46d74f7 100644 --- a/include/icsneo/device/tree/neoobd2sim/neoobd2sim.h +++ b/include/icsneo/device/tree/neoobd2sim/neoobd2sim.h @@ -21,7 +21,10 @@ public: }; return supportedNetworks; } - + + ProductID getProductID() const override { + return ProductID::neoOBD2Sim; + } private: NeoOBD2SIM(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neoviconnect/neoviconnect.h b/include/icsneo/device/tree/neoviconnect/neoviconnect.h index 15141a1..250f6f7 100644 --- a/include/icsneo/device/tree/neoviconnect/neoviconnect.h +++ b/include/icsneo/device/tree/neoviconnect/neoviconnect.h @@ -34,6 +34,28 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::Connect; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::Connect_ZCHIP, true, "ZCHIP", "neovi_connect_zchip_ief", 0, FirmwareType::IEF}, + {ChipID::Connect_LINUX, true, "Linux Flash", "neovi_connect_lnx_flash_ief", 1, FirmwareType::IEF}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add(ChipID::Connect_ZCHIP, BootloaderCommunication::Application, true, false, false) + .add(ChipID::Connect_LINUX, BootloaderCommunication::Application, false, false, false) + .add(ChipID::Connect_ZCHIP, BootloaderCommunication::Application) + .add(ChipID::Connect_LINUX, BootloaderCommunication::Application) + .add() + .addSetting(BootloaderSetting::UpdateAll, true); + } + protected: NeoVIConnect(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neovifire/neovifire.h b/include/icsneo/device/tree/neovifire/neovifire.h index 331f9e0..1ac7eaa 100644 --- a/include/icsneo/device/tree/neovifire/neovifire.h +++ b/include/icsneo/device/tree/neovifire/neovifire.h @@ -57,6 +57,9 @@ public: return true; } + ProductID getProductID() const override { + return ProductID::neoVIFIRE; + } private: NeoVIFIRE(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neovifire2/neovifire2.h b/include/icsneo/device/tree/neovifire2/neovifire2.h index 79a6d0e..e44d712 100644 --- a/include/icsneo/device/tree/neovifire2/neovifire2.h +++ b/include/icsneo/device/tree/neovifire2/neovifire2.h @@ -87,6 +87,28 @@ public: }; } + ProductID getProductID() const override { + return ProductID::neoVIFIRE2; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::neoVIFIRE2_MCHIP, true, "MCHIP", "fire2_mchip_ief", 0, FirmwareType::IEF}, + {ChipID::neoVIFIRE2_ZYNQ, true, "ZCHIP", "fire2_zchip_ief", 1, FirmwareType::IEF}, + {ChipID::neoVIFIRE2_Core, true, "Core", "fire2_core", 2, FirmwareType::IEF}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::neoVIFIRE2_MCHIP, BootloaderCommunication::RED) + .add(ChipID::neoVIFIRE2_ZYNQ, BootloaderCommunication::RED, false, true) + .add(ChipID::neoVIFIRE2_Core, BootloaderCommunication::REDCore, false, false) + .add(); + } + protected: NeoVIFIRE2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neovifire3/neovifire3.h b/include/icsneo/device/tree/neovifire3/neovifire3.h index db85a81..7d7562a 100644 --- a/include/icsneo/device/tree/neovifire3/neovifire3.h +++ b/include/icsneo/device/tree/neovifire3/neovifire3.h @@ -50,6 +50,34 @@ public: return supportedNetworks; } size_t getEthernetActivationLineCount() const override { return 2; } + + ProductID getProductID() const override { + return ProductID::neoVIFIRE3; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::neoVIFIRE3_ZCHIP, true, "ZCHIP", "fire3_zchip_ief", 0, FirmwareType::IEF}, + {ChipID::neoVIFIRE3_SCHIP, true, "SCHIP", "fire3_schip_ief", 1, FirmwareType::IEF}, + {ChipID::neoVIFIRE3_LINUX, true, "Linux Flash", "fire3_lnx_flash_ief", 2, FirmwareType::IEF}, + {ChipID::VEM_01_8DW_ZCHIP, true, "VEM-01-Z", "vem_01_8dw_zchip_ief", 3, FirmwareType::IEF} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false) + .add(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true) + .add(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false) + .add(ChipID::VEM_01_8DW_ZCHIP, BootloaderCommunication::Application, false, false) + .add(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application) + .add(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application) + .add(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application) + .add(ChipID::VEM_01_8DW_ZCHIP, BootloaderCommunication::Application) + .add() + .addSetting(BootloaderSetting::UpdateAll, true); + } protected: NeoVIFIRE3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neovifire3flexray/neovifire3flexray.h b/include/icsneo/device/tree/neovifire3flexray/neovifire3flexray.h index 73d8c55..6226d4c 100644 --- a/include/icsneo/device/tree/neovifire3flexray/neovifire3flexray.h +++ b/include/icsneo/device/tree/neovifire3flexray/neovifire3flexray.h @@ -53,6 +53,36 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::neoVIFIRE3; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::neoVIFIRE3_ZCHIP, true, "ZCHIP", "fire3_zchip_ief", 0, FirmwareType::IEF}, + {ChipID::neoVIFIRE3_SCHIP, true, "SCHIP", "fire3_schip_ief", 1, FirmwareType::IEF}, + {ChipID::neoVIFIRE3_LINUX, true, "Linux Flash", "fire3_lnx_flash_ief", 2, FirmwareType::IEF}, + {ChipID::VEM_02_FR_ZCHIP, true, "VEM-02-Z", "vem_02_fr_zchip_ief", 3, FirmwareType::IEF}, + {ChipID::VEM_02_FR_FCHIP, true, "VEM-02-F", "vem_02_fr_fchip_ief", 4, FirmwareType::IEF}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false) + .add(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true) + .add(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false) + .add(ChipID::VEM_02_FR_FCHIP, BootloaderCommunication::Application, false, false) + .add(ChipID::VEM_02_FR_ZCHIP, BootloaderCommunication::Application, false, false) + .add(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application) + .add(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application) + .add(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application) + .add(ChipID::VEM_02_FR_FCHIP, BootloaderCommunication::Application) + .add(ChipID::VEM_02_FR_ZCHIP, BootloaderCommunication::Application) + .add() + .addSetting(BootloaderSetting::UpdateAll, true); + } protected: NeoVIFIRE3FlexRay(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neovifire3t1slin/neovifire3t1slin.h b/include/icsneo/device/tree/neovifire3t1slin/neovifire3t1slin.h index 99f111d..529a8ed 100644 --- a/include/icsneo/device/tree/neovifire3t1slin/neovifire3t1slin.h +++ b/include/icsneo/device/tree/neovifire3t1slin/neovifire3t1slin.h @@ -59,6 +59,9 @@ public: bool supportsTC10() const override { return true; } + ProductID getProductID() const override { + return ProductID::neoVIFIRE3; + } protected: NeoVIFIRE3T1SLIN(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/neovired2/neovired2.h b/include/icsneo/device/tree/neovired2/neovired2.h index 8be3aaa..aad3728 100644 --- a/include/icsneo/device/tree/neovired2/neovired2.h +++ b/include/icsneo/device/tree/neovired2/neovired2.h @@ -37,6 +37,30 @@ public: bool supportsGPTP() const override { return true; } + ProductID getProductID() const override { + return ProductID::neoVIFIRE3; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::neoVIFIRE3_ZCHIP, true, "ZCHIP", "fire3_zchip_ief", 0, FirmwareType::IEF}, + {ChipID::neoVIFIRE3_SCHIP, true, "SCHIP", "fire3_schip_ief", 1, FirmwareType::IEF}, + {ChipID::neoVIFIRE3_LINUX, true, "Linux Flash", "fire3_lnx_flash_ief", 2, FirmwareType::IEF} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false) + .add(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true) + .add(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false) + .add(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application) + .add(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application) + .add(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application) + .add() + .addSetting(BootloaderSetting::UpdateAll, true); + } protected: NeoVIRED2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/plasion/neoviion.h b/include/icsneo/device/tree/plasion/neoviion.h index 9cf5405..4f91f5f 100644 --- a/include/icsneo/device/tree/plasion/neoviion.h +++ b/include/icsneo/device/tree/plasion/neoviion.h @@ -15,6 +15,9 @@ public: // USB PID is 0x0901, standard driver is DXX ICSNEO_FINDABLE_DEVICE(NeoVIION, DeviceType::ION, "40"); + ProductID getProductID() const override { + return ProductID::neoVIION; + } private: NeoVIION(neodevice_t neodevice, const driver_factory_t& makeDriver) : Plasion(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/plasion/neoviplasma.h b/include/icsneo/device/tree/plasion/neoviplasma.h index 22bcfd0..4367336 100644 --- a/include/icsneo/device/tree/plasion/neoviplasma.h +++ b/include/icsneo/device/tree/plasion/neoviplasma.h @@ -13,6 +13,9 @@ public: // USB PID is 0x0801, standard driver is DXX ICSNEO_FINDABLE_DEVICE(NeoVIPLASMA, DeviceType::PLASMA, "30"); + ProductID getProductID() const override { + return ProductID::neoVIPLASMA; + } private: NeoVIPLASMA(neodevice_t neodevice, const driver_factory_t& makeDriver) : Plasion(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/rada2b/rada2b.h b/include/icsneo/device/tree/rada2b/rada2b.h index 2a1dfb9..3337ed5 100644 --- a/include/icsneo/device/tree/rada2b/rada2b.h +++ b/include/icsneo/device/tree/rada2b/rada2b.h @@ -42,11 +42,32 @@ public: size_t getEthernetActivationLineCount() const override { return 1; } bool supportsGPTP() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADA2B; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADA2B_ZCHIP, true, "ZCHIP", "RADA2B_SW_bin", 0, FirmwareType::Zip}, + {ChipID::RADA2B_REVB_ZCHIP, false, "ZCHIP", "RADA2B_REVB_SW_bin", 0, FirmwareType::Zip} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADA2B_ZCHIP, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } protected: RADA2B(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); } + + void setupPacketizer(Packetizer& packetizer) override { Device::setupPacketizer(packetizer); packetizer.disableChecksum = true; diff --git a/include/icsneo/device/tree/radcomet/radcometbase.h b/include/icsneo/device/tree/radcomet/radcometbase.h index 5035699..71be654 100644 --- a/include/icsneo/device/tree/radcomet/radcometbase.h +++ b/include/icsneo/device/tree/radcomet/radcometbase.h @@ -30,6 +30,25 @@ public: bool getEthPhyRegControlSupported() const override { return true; } bool supportsGPTP() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADComet; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADComet_ZYNQ, true, "ZCHIP", "RADComet_SW_bin", 0, FirmwareType::Zip}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADComet_ZYNQ, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } + protected: using Device::Device; diff --git a/include/icsneo/device/tree/radcomet3/radcomet3.h b/include/icsneo/device/tree/radcomet3/radcomet3.h index 55f70ee..09ff634 100644 --- a/include/icsneo/device/tree/radcomet3/radcomet3.h +++ b/include/icsneo/device/tree/radcomet3/radcomet3.h @@ -54,6 +54,25 @@ public: bool supportsTC10() const override { return true; } bool supportsGPTP() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADComet3; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADCOMET3_ZCHIP, true, "ZCHIP", "RADComet3_SW_bin", 0, FirmwareType::Zip}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADCOMET3_ZCHIP, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } + protected: RADComet3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radepsilon/radepsilon.h b/include/icsneo/device/tree/radepsilon/radepsilon.h index 3394bcc..0b4903f 100644 --- a/include/icsneo/device/tree/radepsilon/radepsilon.h +++ b/include/icsneo/device/tree/radepsilon/radepsilon.h @@ -29,6 +29,24 @@ public: bool getEthPhyRegControlSupported() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADEpsilon; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADEpsilon_MCHIP, true, "MCHIP", "epsilon_mchip_ief", 0, FirmwareType::IEF}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADEpsilon_MCHIP, BootloaderCommunication::RED) + .add(); + } + protected: RADEpsilon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h b/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h index 604659d..62d0843 100644 --- a/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h +++ b/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h @@ -28,6 +28,23 @@ public: bool supportsComponentVersions() const override { return true; } bool getEthPhyRegControlSupported() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADEpsilon; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADProxima_MCHIP, true, "MCHIP", "epsilon_mchip_ief", 0, FirmwareType::IEF}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADProxima_MCHIP, BootloaderCommunication::RED) + .add(); + } protected: RADEpsilonXL(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { @@ -58,6 +75,10 @@ protected: bool supportsEraseMemory() const override { return true; } + + size_t getDiskCount() const override { + return 1; + } }; }; // namespace icsneo diff --git a/include/icsneo/device/tree/radgalaxy/radgalaxy.h b/include/icsneo/device/tree/radgalaxy/radgalaxy.h index a79a36b..14fba21 100644 --- a/include/icsneo/device/tree/radgalaxy/radgalaxy.h +++ b/include/icsneo/device/tree/radgalaxy/radgalaxy.h @@ -63,6 +63,26 @@ public: size_t getEthernetActivationLineCount() const override { return 1; } bool supportsGPTP() const override { return true; } + + ProductID getProductID() const override { + return ProductID::RADGalaxy; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADGalaxy_ZYNQ, true, "ZCHIP", "RADGalaxy_SG2_SW_bin", 0, FirmwareType::Zip}, + {ChipID::RADGalaxy_FFG_Zynq, false, "ZCHIP", "RADGalaxy_SG2_FFG_SW_bin", 0, FirmwareType::Zip} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADGalaxy_ZYNQ, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } protected: RADGalaxy(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radgalaxy2/radgalaxy2.h b/include/icsneo/device/tree/radgalaxy2/radgalaxy2.h index ca97037..5ef3b5d 100644 --- a/include/icsneo/device/tree/radgalaxy2/radgalaxy2.h +++ b/include/icsneo/device/tree/radgalaxy2/radgalaxy2.h @@ -67,6 +67,28 @@ public: bool supportsTC10() const override { return true; } bool supportsGPTP() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADGalaxy2; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RAD_GALAXY_2_ZMPCHIP_ID, true, "ZCHIP", "RADGalaxy2_SW_bin_p1", {"RADGalaxy2_SW_bin_p1", "RADGalaxy2_SW_bin_p2"}, 0, FirmwareType::Zip}, + {ChipID::RADGALAXY2_SYSMON_CHIP, true, "MCHIP", "galaxy2_sysmon_ief", 1, FirmwareType::IEF} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RAD_GALAXY_2_ZMPCHIP_ID, BootloaderCommunication::RAD) + .add() + .add(ChipID::RADGALAXY2_SYSMON_CHIP, BootloaderCommunication::RADGalaxy2Peripheral) + .add() + .add(std::chrono::milliseconds(3000)); + } + protected: RADGalaxy2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radgigastar/radgigastar.h b/include/icsneo/device/tree/radgigastar/radgigastar.h index ae2d976..eca9196 100644 --- a/include/icsneo/device/tree/radgigastar/radgigastar.h +++ b/include/icsneo/device/tree/radgigastar/radgigastar.h @@ -24,6 +24,88 @@ public: bool supportsTC10() const override { return true; } bool supportsGPTP() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADGigastar; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADGigastar_ZYNQ, true, "ZCHIP", "RADGigastar2_T1S_LIN_SW_bin", 1, FirmwareType::Zip}, + {ChipID::RADGigastar_FFG_ZYNQ, false, "ZCHIP", "RADGigastar_FFG_SW_bin", 1, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_ZYNQ, true, "USB ZCHIP", "RADGigastar_USBz_SW_bin", 2, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_Z7010_ZYNQ, false, "USB ZCHIP", "RADGigastar_USBz_Z7010_SW_bin", 2, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_Z7007S_ZYNQ, false, "USB ZCHIP", "RADGigastar_USBz_Z7007s_SW_bin", 2, FirmwareType::Zip}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + if(supportsComponentVersions()) { + auto chipVersions = getChipVersions(); + auto mainVersion = std::find_if(chipVersions.begin(), chipVersions.end(), [](const auto& ver) { return ver.name == "ZCHIP"; }); + if(mainVersion != chipVersions.end()) { + static constexpr uint8_t NewBootloaderMajor = 0; + static constexpr uint8_t NewBootloaderMinor = 0; + + if( + mainVersion->major > NewBootloaderMajor || + (mainVersion->major == NewBootloaderMajor && mainVersion->minor > NewBootloaderMinor) + ) { + BootloaderPipeline pipeline; + for(const auto& version : chipVersions) { + pipeline.add(version.id, BootloaderCommunication::RADMultiChip); + } + pipeline.add(); + pipeline.add(std::chrono::milliseconds(3000)); + return pipeline; + } + } + } + // If we've reached this point, then we use the legacy flashing + if(com->driver->isEthernet()) { + return BootloaderPipeline() + .add(ChipID::RADGigastar_ZYNQ, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } + return BootloaderPipeline() + .add(ChipID::RADGigastar_USBZ_ZYNQ, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } + + std::vector getChipVersions(bool refreshComponents = true) override { + if(refreshComponents) { + refreshComponentVersions(); + } + if(supportsComponentVersions()) { + return Device::getChipVersions(false); + } + static constexpr size_t MainPeriphIndex = 1; + static constexpr size_t USBPeriphIndex = 2; + + std::vector chipVersions; + auto& appVersions = getVersions(); + + if(appVersions.size() < 3 && !appVersions.empty()) { + if(appVersions[0]) { + chipVersions.push_back({ChipID::RADGigastar_ZYNQ, "ZCHIP", appVersions[0]->major, appVersions[0]->minor, 0, 0}); + } + } else { + if(MainPeriphIndex < appVersions.size()) { + if(appVersions[MainPeriphIndex]) { + chipVersions.push_back({ChipID::RADGigastar_ZYNQ, "ZCHIP", appVersions[MainPeriphIndex]->major, appVersions[MainPeriphIndex]->minor, 0, 0}); + } + } + if(USBPeriphIndex < appVersions.size()) { + if(appVersions[USBPeriphIndex]) { + chipVersions.push_back({ChipID::RADGigastar_USBZ_ZYNQ, "USB ZCHIP", appVersions[USBPeriphIndex]->major, appVersions[USBPeriphIndex]->minor, 0, 0}); + } + } + } + return chipVersions; + } + protected: RADGigastar(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radgigastar2/radgigastar2.h b/include/icsneo/device/tree/radgigastar2/radgigastar2.h index 723a062..bfe7f26 100644 --- a/include/icsneo/device/tree/radgigastar2/radgigastar2.h +++ b/include/icsneo/device/tree/radgigastar2/radgigastar2.h @@ -12,138 +12,259 @@ namespace icsneo { - class RADGigastar2 : public Device - { - public: - // Serial numbers start with GT - // USB PID is 0x1210, standard driver is DXX - // Ethernet MAC allocation is 0x22, standard driver is Raw - ICSNEO_FINDABLE_DEVICE(RADGigastar2, DeviceType::RADGigastar2, "GT"); - - static const std::vector &GetSupportedNetworks() - { - static std::vector supportedNetworks = { - Network::NetID::DWCAN_01, - Network::NetID::DWCAN_02, - Network::NetID::DWCAN_03, - Network::NetID::DWCAN_04, - - Network::NetID::ETHERNET_01, - Network::NetID::ETHERNET_02, - - Network::NetID::AE_01, - Network::NetID::AE_02, - Network::NetID::AE_03, - Network::NetID::AE_04, - Network::NetID::AE_05, - Network::NetID::AE_06, - Network::NetID::AE_07, - Network::NetID::AE_08, - Network::NetID::AE_09, - Network::NetID::AE_10, - - Network::NetID::LIN_01, - Network::NetID::LIN_02, - Network::NetID::LIN_03, - Network::NetID::LIN_04, - Network::NetID::LIN_05, - Network::NetID::LIN_06, - Network::NetID::LIN_07, - Network::NetID::LIN_08, - Network::NetID::LIN_09, - Network::NetID::LIN_10, - Network::NetID::LIN_11, - Network::NetID::LIN_12, - Network::NetID::LIN_13, - Network::NetID::LIN_14, - Network::NetID::LIN_15, - Network::NetID::LIN_16, - - Network::NetID::I2C_01, - Network::NetID::I2C_02, - - Network::NetID::MDIO_01, - Network::NetID::MDIO_02, - - Network::NetID::SPI_01, - Network::NetID::SPI_02, - Network::NetID::SPI_03, - Network::NetID::SPI_04, - Network::NetID::SPI_05, - Network::NetID::SPI_06, - Network::NetID::SPI_07, - Network::NetID::SPI_08, - }; - return supportedNetworks; - } - - size_t getEthernetActivationLineCount() const override { return 1; } - - bool getEthPhyRegControlSupported() const override { return true; } - - bool supportsTC10() const override { return true; } - bool supportsGPTP() const override { return true; } - - protected: - RADGigastar2(neodevice_t neodevice, const driver_factory_t &makeDriver) : Device(neodevice) - { - initialize(makeDriver); - } - - void setupPacketizer(Packetizer &packetizer) override - { - Device::setupPacketizer(packetizer); - packetizer.disableChecksum = true; - packetizer.align16bit = false; - } - - void setupDecoder(Decoder &decoder) override - { - Device::setupDecoder(decoder); - decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns - } - - void setupEncoder(Encoder &encoder) override - { - Device::setupEncoder(encoder); - encoder.supportCANFD = true; - encoder.supportEthPhy = true; - } - - void setupSupportedRXNetworks(std::vector &rxNetworks) override - { - for (auto &netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector &txNetworks) override { setupSupportedRXNetworks(txNetworks); } - - void handleDeviceStatus(const std::shared_ptr &message) override - { - if (message->data.size() < sizeof(radgigastar2_status_t)) - return; - std::lock_guard lk(ioMutex); - const radgigastar2_status_t *status = reinterpret_cast(message->data.data()); - ethActivationStatus = status->ethernetActivationLineEnabled; - } - - std::optional getCoreminiStartAddressFlash() const override - { - return 512 * 4; - } - - std::optional getCoreminiStartAddressSD() const override - { - return 0; - } - - size_t getDiskCount() const override - { - return 1; - } +class RADGigastar2 : public Device { +public: + enum class FirmwareVariant { + T1Sx6_CANx1_LINx16, + T1Sx8_CANx4_LINx6, + Invalid }; + // Serial numbers start with GT + // USB PID is 0x1210, standard driver is DXX + // Ethernet MAC allocation is 0x22, standard driver is Raw + ICSNEO_FINDABLE_DEVICE(RADGigastar2, DeviceType::RADGigastar2, "GT"); + + static const std::vector &GetSupportedNetworks() + { + static std::vector supportedNetworks = { + Network::NetID::DWCAN_01, + Network::NetID::DWCAN_02, + Network::NetID::DWCAN_03, + Network::NetID::DWCAN_04, + + Network::NetID::ETHERNET_01, + Network::NetID::ETHERNET_02, + + Network::NetID::AE_01, + Network::NetID::AE_02, + Network::NetID::AE_03, + Network::NetID::AE_04, + Network::NetID::AE_05, + Network::NetID::AE_06, + Network::NetID::AE_07, + Network::NetID::AE_08, + Network::NetID::AE_09, + Network::NetID::AE_10, + + Network::NetID::LIN_01, + Network::NetID::LIN_02, + Network::NetID::LIN_03, + Network::NetID::LIN_04, + Network::NetID::LIN_05, + Network::NetID::LIN_06, + Network::NetID::LIN_07, + Network::NetID::LIN_08, + Network::NetID::LIN_09, + Network::NetID::LIN_10, + Network::NetID::LIN_11, + Network::NetID::LIN_12, + Network::NetID::LIN_13, + Network::NetID::LIN_14, + Network::NetID::LIN_15, + Network::NetID::LIN_16, + + Network::NetID::I2C_01, + Network::NetID::I2C_02, + + Network::NetID::MDIO_01, + Network::NetID::MDIO_02, + + Network::NetID::SPI_01, + Network::NetID::SPI_02, + Network::NetID::SPI_03, + Network::NetID::SPI_04, + Network::NetID::SPI_05, + Network::NetID::SPI_06, + Network::NetID::SPI_07, + Network::NetID::SPI_08, + }; + return supportedNetworks; + } + + size_t getEthernetActivationLineCount() const override { return 1; } + + bool getEthPhyRegControlSupported() const override { return true; } + + bool supportsTC10() const override { return true; } + bool supportsGPTP() const override { return true; } + + ProductID getProductID() const override { + return ProductID::RADGigastar2; + } + + FirmwareVariant variantToFlash = FirmwareVariant::Invalid; + void setVariantToFlash(FirmwareVariant variant) { + variantToFlash = variant; + } + + FirmwareVariant getCurrentVariant() { + if(supportsComponentVersions()) { + const auto& components = getComponentVersions(); + for(const auto& component : components) { + if(!component.valid) { + continue; + } + + if(component.identifier == static_cast(ChipID::RADGigastar2_ZYNQ)) { + auto res = static_cast(std::clamp(component.componentInfo, 0, 2)); + if(variantToFlash == FirmwareVariant::Invalid) { + variantToFlash = res; // Set the variantToFlash if it hasn't been set yet, we always flash the same firmware variant as the current if it is unspecified + } + return res; + } + } + } + return FirmwareVariant::Invalid; + } + + const std::vector& getChipInfo() const override { + static std::vector linChips = { + {ChipID::RADGigastar2_ZYNQ, true, "ZCHIP", "RADGigastar2_T1S_LIN_SW_bin", 1, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_ZYNQ, true, "USB ZCHIP", "RADGigastar_USBz_SW_bin", 2, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_Z7010_ZYNQ, false, "USB ZCHIP", "RADGigastar_USBz_Z7010_SW_bin", 2, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_Z7007S_ZYNQ, false, "USB ZCHIP", "RADGigastar_USBz_Z7007s_SW_bin", 2, FirmwareType::Zip}, + }; + + static std::vector t1sChips = { + {ChipID::RADGigastar2_ZYNQ, true, "ZCHIP", "RADGigastar2_T1S_CAN_SW_bin", 1, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_ZYNQ, true, "USB ZCHIP", "RADGigastar_USBz_SW_bin", 2, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_Z7010_ZYNQ, false, "USB ZCHIP", "RADGigastar_USBz_Z7010_SW_bin", 2, FirmwareType::Zip}, + {ChipID::RADGigastar_USBZ_Z7007S_ZYNQ, false, "USB ZCHIP", "RADGigastar_USBz_Z7007s_SW_bin", 2, FirmwareType::Zip}, + }; + + if(variantToFlash == FirmwareVariant::T1Sx8_CANx4_LINx6) { + return t1sChips; + } + return linChips; // Assume linChips even if variantToFlash is invalid + } + + BootloaderPipeline getBootloader() override { + if(supportsComponentVersions()) { + auto chipVersions = getChipVersions(); + auto mainVersion = std::find_if(chipVersions.begin(), chipVersions.end(), [](const auto& ver) { return ver.name == "ZCHIP"; }); + if(mainVersion != chipVersions.end()) { + static constexpr uint8_t NewBootloaderMajor = 0; + static constexpr uint8_t NewBootloaderMinor = 0; + + if( + mainVersion->major > NewBootloaderMajor || + (mainVersion->major == NewBootloaderMajor && mainVersion->minor > NewBootloaderMinor) + ) { + BootloaderPipeline pipeline; + for(const auto& version : chipVersions) { + pipeline.add(version.id, BootloaderCommunication::RADMultiChip); + } + pipeline.add(); + pipeline.add(std::chrono::milliseconds(3000)); + return pipeline; + } + } + } + // If we've reached this point, then we use the legacy flashing + if(com->driver->isEthernet()) { + return BootloaderPipeline() + .add(ChipID::RADGigastar2_ZYNQ, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } + return BootloaderPipeline() + .add(ChipID::RADGigastar_USBZ_ZYNQ, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } + + std::vector getChipVersions(bool refreshComponents = true) override { + if(refreshComponents) { + refreshComponentVersions(); + } + if(supportsComponentVersions()) { + return Device::getChipVersions(false); + } + static constexpr size_t MainPeriphIndex = 1; + static constexpr size_t USBPeriphIndex = 2; + + std::vector chipVersions; + auto& appVersions = getVersions(); + + if(appVersions.size() < 3 && !appVersions.empty()) { + if(appVersions[0]) { + chipVersions.push_back({ChipID::RADGigastar2_ZYNQ, "ZCHIP", appVersions[0]->major, appVersions[0]->minor, 0, 0}); + } + } else { + if(MainPeriphIndex < appVersions.size()) { + if(appVersions[MainPeriphIndex]) { + chipVersions.push_back({ChipID::RADGigastar2_ZYNQ, "ZCHIP", appVersions[MainPeriphIndex]->major, appVersions[MainPeriphIndex]->minor, 0, 0}); + } + } + if(USBPeriphIndex < appVersions.size()) { + if(appVersions[USBPeriphIndex]) { + chipVersions.push_back({ChipID::RADGigastar_USBZ_ZYNQ, "USB ZCHIP", appVersions[USBPeriphIndex]->major, appVersions[USBPeriphIndex]->minor, 0, 0}); + } + } + } + return chipVersions; + } +protected: + RADGigastar2(neodevice_t neodevice, const driver_factory_t &makeDriver) : Device(neodevice) + { + initialize(makeDriver); + } + + void setupPacketizer(Packetizer &packetizer) override + { + Device::setupPacketizer(packetizer); + packetizer.disableChecksum = true; + packetizer.align16bit = false; + } + + void setupDecoder(Decoder &decoder) override + { + Device::setupDecoder(decoder); + decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns + } + + void setupEncoder(Encoder &encoder) override + { + Device::setupEncoder(encoder); + encoder.supportCANFD = true; + encoder.supportEthPhy = true; + } + + void setupSupportedRXNetworks(std::vector &rxNetworks) override + { + for (auto &netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector &txNetworks) override { setupSupportedRXNetworks(txNetworks); } + + void handleDeviceStatus(const std::shared_ptr &message) override + { + if (message->data.size() < sizeof(radgigastar2_status_t)) + return; + std::lock_guard lk(ioMutex); + const radgigastar2_status_t *status = reinterpret_cast(message->data.data()); + ethActivationStatus = status->ethernetActivationLineEnabled; + } + + std::optional getCoreminiStartAddressFlash() const override + { + return 512 * 4; + } + + std::optional getCoreminiStartAddressSD() const override + { + return 0; + } + + size_t getDiskCount() const override + { + return 1; + } +}; + } #endif // __cplusplus diff --git a/include/icsneo/device/tree/radjupiter/radjupiter.h b/include/icsneo/device/tree/radjupiter/radjupiter.h index 2e6160c..0c6dceb 100644 --- a/include/icsneo/device/tree/radjupiter/radjupiter.h +++ b/include/icsneo/device/tree/radjupiter/radjupiter.h @@ -29,6 +29,10 @@ public: bool getEthPhyRegControlSupported() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADJupiter; + } + protected: RADJupiter(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radmars/radmars.h b/include/icsneo/device/tree/radmars/radmars.h index d0e5fbe..abde177 100644 --- a/include/icsneo/device/tree/radmars/radmars.h +++ b/include/icsneo/device/tree/radmars/radmars.h @@ -21,6 +21,9 @@ public: size_t getEthernetActivationLineCount() const override { return 1; } bool supportsGPTP() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADMars; + } protected: RADMars(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radmoon2/radmoon2.h b/include/icsneo/device/tree/radmoon2/radmoon2.h index 5133735..656cb18 100644 --- a/include/icsneo/device/tree/radmoon2/radmoon2.h +++ b/include/icsneo/device/tree/radmoon2/radmoon2.h @@ -16,6 +16,26 @@ public: uint8_t getPhyAddrOrPort() const override { return 6; }; + + ProductID getProductID() const override { + return ProductID::RADMoon2; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADMoon2_ZYNQ, true, "ZCHIP", "RADMoon2_SW_bin", 0, FirmwareType::Zip}, + {ChipID::RADMoon2_Z7010_ZYNQ, false, "ZCHIP", "RADMoon2_Z7010_SW_bin", 0, FirmwareType::Zip} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADMoon2_ZYNQ, BootloaderCommunication::RAD) + .add() + .add(std::chrono::milliseconds(3000)); + } protected: RADMoon2(neodevice_t neodevice, const driver_factory_t& makeDriver) : RADMoon2Base(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radmoon2/radmoon2zl.h b/include/icsneo/device/tree/radmoon2/radmoon2zl.h index 27ae008..ee8382b 100644 --- a/include/icsneo/device/tree/radmoon2/radmoon2zl.h +++ b/include/icsneo/device/tree/radmoon2/radmoon2zl.h @@ -18,6 +18,23 @@ public: bool supportsTC10() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADMoon2; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADMoon2_ZL_MCHIP, true, "MCHIP", "radmoon2_zl_mchip_ief", 0, FirmwareType::IEF} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADMoon2_ZL_MCHIP, BootloaderCommunication::RED) + .add(); + } protected: RADMoon2ZL(neodevice_t neodevice, const driver_factory_t& makeDriver) : RADMoon2Base(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radmoon3/radmoon3.h b/include/icsneo/device/tree/radmoon3/radmoon3.h index f8f7422..c5268a0 100644 --- a/include/icsneo/device/tree/radmoon3/radmoon3.h +++ b/include/icsneo/device/tree/radmoon3/radmoon3.h @@ -30,6 +30,24 @@ public: bool supportsTC10() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADMoon3; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::RADMoon3_MCHIP, true, "MCHIP", "radmoon3_mchip_ief", 0, FirmwareType::IEF}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::RADMoon3_MCHIP, BootloaderCommunication::RED) + .add() + .add(std::chrono::milliseconds(3000)); + } protected: RADMoon3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radmoonduo/radmoonduo.h b/include/icsneo/device/tree/radmoonduo/radmoonduo.h index ec83366..553cbe8 100644 --- a/include/icsneo/device/tree/radmoonduo/radmoonduo.h +++ b/include/icsneo/device/tree/radmoonduo/radmoonduo.h @@ -25,6 +25,10 @@ public: bool getEthPhyRegControlSupported() const override { return true; } + + ProductID getProductID() const override { + return ProductID::RADMoonDuo; + } protected: RADMoonDuo(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radmoont1s/radmoont1s.h b/include/icsneo/device/tree/radmoont1s/radmoont1s.h index 5ab376f..71e6ae0 100644 --- a/include/icsneo/device/tree/radmoont1s/radmoont1s.h +++ b/include/icsneo/device/tree/radmoont1s/radmoont1s.h @@ -34,6 +34,9 @@ public: bool supportsTC10() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADMoonT1S; + } protected: RADMoonT1S(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radpluto/radpluto.h b/include/icsneo/device/tree/radpluto/radpluto.h index 66c16dc..9768474 100644 --- a/include/icsneo/device/tree/radpluto/radpluto.h +++ b/include/icsneo/device/tree/radpluto/radpluto.h @@ -34,6 +34,9 @@ public: bool getEthPhyRegControlSupported() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADPluto; + } protected: RADPluto(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radstar2/radstar2.h b/include/icsneo/device/tree/radstar2/radstar2.h index f511957..93bc47d 100644 --- a/include/icsneo/device/tree/radstar2/radstar2.h +++ b/include/icsneo/device/tree/radstar2/radstar2.h @@ -32,6 +32,9 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::RADStar2; + } protected: RADStar2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radsupermoon/radsupermoon.h b/include/icsneo/device/tree/radsupermoon/radsupermoon.h index dc2c1fd..1676e23 100644 --- a/include/icsneo/device/tree/radsupermoon/radsupermoon.h +++ b/include/icsneo/device/tree/radsupermoon/radsupermoon.h @@ -50,6 +50,9 @@ public: bool getEthPhyRegControlSupported() const override { return true; } + ProductID getProductID() const override { + return ProductID::RADSupermoon; + } protected: RADSupermoon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/valuecan3/valuecan3.h b/include/icsneo/device/tree/valuecan3/valuecan3.h index 337fb35..7b4985d 100644 --- a/include/icsneo/device/tree/valuecan3/valuecan3.h +++ b/include/icsneo/device/tree/valuecan3/valuecan3.h @@ -22,6 +22,9 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::ValueCAN3; + } private: ValueCAN3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/valuecan4/valuecan4-1.h b/include/icsneo/device/tree/valuecan4/valuecan4-1.h index d69d35b..e2e0463 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4-1.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4-1.h @@ -21,6 +21,24 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::ValueCAN4_1_2; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::ValueCAN4_1_MCHIP, true, "MCHIP", "vcan41_mchip_ief", 0, FirmwareType::IEF}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::ValueCAN4_1_MCHIP, BootloaderCommunication::RED) + .add(); + } + protected: ValueCAN4_1(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/valuecan4/valuecan4-2.h b/include/icsneo/device/tree/valuecan4/valuecan4-2.h index cbfc44c..57ba487 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4-2.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4-2.h @@ -46,6 +46,25 @@ public: return Device::getProductName(); } + ProductID getProductID() const override { + return ProductID::ValueCAN4_1_2; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::ValueCAN4_2_MCHIP, true, "MCHIP", "vcan42_mchip_ief", 0, FirmwareType::IEF}, + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::ValueCAN4_2_MCHIP, BootloaderCommunication::RED) + .add() + .add(std::chrono::milliseconds(3000)); + } + protected: ValueCAN4_2(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/valuecan4/valuecan4-2el.h b/include/icsneo/device/tree/valuecan4/valuecan4-2el.h index b2a01d9..8723c04 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4-2el.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4-2el.h @@ -60,6 +60,25 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::ValueCAN4_2EL_4; + } + + const std::vector& getChipInfo() const override { + static std::vector chips = { + {ChipID::ValueCAN4_2EL_MCHIP, true, "MCHIP", "vcan44_mchip_ief", 0, FirmwareType::IEF} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::ValueCAN4_2EL_MCHIP, BootloaderCommunication::RED) + .add(); + } + + protected: ValueCAN4_2EL(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/valuecan4/valuecan4-4.h b/include/icsneo/device/tree/valuecan4/valuecan4-4.h index e8d6df7..b881412 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4-4.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4-4.h @@ -57,6 +57,25 @@ public: return Device::getProductName(); } + ProductID getProductID() const override { + return ProductID::ValueCAN4_2EL_4; + } + + const std::vector& getChipInfo() const override { + static std::vector 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} + }; + return chips; + } + + BootloaderPipeline getBootloader() override { + return BootloaderPipeline() + .add() + .add(ChipID::ValueCAN4_4_MCHIP, BootloaderCommunication::RED) + .add(ChipID::ValueCAN4_4_SCHIP, BootloaderCommunication::RED, false, true) + .add(); + } protected: ValueCAN4_4(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/valuecan4/valuecan4industrial.h b/include/icsneo/device/tree/valuecan4/valuecan4industrial.h index 4a1690b..607ef17 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4industrial.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4industrial.h @@ -27,6 +27,9 @@ public: return supportedNetworks; } + ProductID getProductID() const override { + return ProductID::ValueCAN4Industrial; + } protected: ValueCAN4Industrial(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/vividcan/vividcan.h b/include/icsneo/device/tree/vividcan/vividcan.h index 6bdd1ea..4b5d2e0 100644 --- a/include/icsneo/device/tree/vividcan/vividcan.h +++ b/include/icsneo/device/tree/vividcan/vividcan.h @@ -28,6 +28,10 @@ public: } bool isOnlineSupported() const override { return false; } + + ProductID getProductID() const override { + return ProductID::VividCAN; + } protected: VividCAN(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/versionreport.h b/include/icsneo/device/versionreport.h new file mode 100644 index 0000000..c8d1fa6 --- /dev/null +++ b/include/icsneo/device/versionreport.h @@ -0,0 +1,26 @@ +#ifndef __VERSION_REPORT_H_ +#define __VERSION_REPORT_H_ + +#ifdef __cplusplus + +#include "icsneo/device/chipid.h" + +#include +#include + +namespace icsneo { + +struct VersionReport { + ChipID id; + std::string name; + uint8_t major; + uint8_t minor; + uint8_t maintenance; + uint8_t build; +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file