Compare commits

...

9 Commits

Author SHA1 Message Date
Francesco Valla f547082cad
Merge 31d4a750d8 into 224e840841 2026-03-03 11:28:51 -05:00
Kyle Schwarz 224e840841 Device: Increase DiskFormatProgress timeout 2026-02-17 17:16:49 -05:00
Max Brombach 174c0b80d4 Device: VCAN4-IND: Add chips and bootloader information 2026-02-17 12:00:34 -05:00
Max Brombach 19092bceb6 Device: RAD-MoonT1S: Add bootloader pipeline and chip 2026-02-13 13:17:59 -05:00
Kyle Schwarz 25b673075f All: Copyright 2026 2026-02-13 10:08:09 -05:00
Max Brombach 1a7bc4df47 Device: RADJupiter: Add bootloader pipeline 2026-02-12 17:05:39 -05:00
Max Brombach 20a2474508 Device: Settings: Add missing bit-packed variables to CAN_SETTINGS 2026-02-12 16:25:57 -05:00
Thomas Stoddard d18ca9e6eb Device: RAD-Galaxy: Add support for Analog Output 2026-02-11 18:43:30 -05:00
Francesco Valla 31d4a750d8 EthernetPacketizer: do a size check on incoming bytestream
An incoming bytestream can be less than 24 bytes, leading to exceptions
when accessing its data (or allocating the vector for its payload).
Perform a size check before trying to decode the bytestream and discard
invalid incoming streams.

Signed-off-by: Francesco Valla <francesco.valla@mta.it>
2025-07-04 10:57:28 +02:00
18 changed files with 463 additions and 5 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2025 Intrepid Control Systems, Inc. Copyright (c) 2018-2026 Intrepid Control Systems, Inc.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -29,7 +29,7 @@ BEGIN
VALUE "FileDescription", "Intrepid Control Systems Open Device Communication C API" VALUE "FileDescription", "Intrepid Control Systems Open Device Communication C API"
VALUE "FileVersion", VER_FILEVERSION_STR VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "icsneoc.dll" VALUE "InternalName", "icsneoc.dll"
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2025" VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2026"
VALUE "OriginalFilename", "icsneoc.dll" VALUE "OriginalFilename", "icsneoc.dll"
VALUE "ProductName", "libicsneo" VALUE "ProductName", "libicsneo"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR VALUE "ProductVersion", VER_PRODUCTVERSION_STR

View File

@ -40,6 +40,14 @@ void init_idevicesettings(pybind11::module_& m) {
.value("Normal", LINMode::NORMAL_MODE) .value("Normal", LINMode::NORMAL_MODE)
.value("Fast", LINMode::FAST_MODE); .value("Fast", LINMode::FAST_MODE);
pybind11::enum_<MiscIOAnalogVoltage>(settings, "MiscIOAnalogVoltage")
.value("V0", MiscIOAnalogVoltage::V0)
.value("V1", MiscIOAnalogVoltage::V1)
.value("V2", MiscIOAnalogVoltage::V2)
.value("V3", MiscIOAnalogVoltage::V3)
.value("V4", MiscIOAnalogVoltage::V4)
.value("V5", MiscIOAnalogVoltage::V5);
pybind11::classh<IDeviceSettings>(m, "IDeviceSettings") pybind11::classh<IDeviceSettings>(m, "IDeviceSettings")
.def("apply", &IDeviceSettings::apply, pybind11::arg("temporary") = 0, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("apply", &IDeviceSettings::apply, pybind11::arg("temporary") = 0, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("apply_defaults", &IDeviceSettings::applyDefaults, pybind11::arg("temporary") = 0, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("apply_defaults", &IDeviceSettings::applyDefaults, pybind11::arg("temporary") = 0, pybind11::call_guard<pybind11::gil_scoped_release>())
@ -97,6 +105,9 @@ void init_idevicesettings(pybind11::module_& m) {
.def("get_t1s_burst_timer", &IDeviceSettings::getT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("get_t1s_burst_timer", &IDeviceSettings::getT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_t1s_burst_timer", &IDeviceSettings::setT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("set_t1s_burst_timer", &IDeviceSettings::setT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_misc_io_analog_output_enabled", &IDeviceSettings::setMiscIOAnalogOutputEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_misc_io_analog_output", &IDeviceSettings::setMiscIOAnalogOutput, pybind11::call_guard<pybind11::gil_scoped_release>())
// Status properties // Status properties
.def_readonly("disabled", &IDeviceSettings::disabled) .def_readonly("disabled", &IDeviceSettings::disabled)
.def_readonly("readonly", &IDeviceSettings::readonly); .def_readonly("readonly", &IDeviceSettings::readonly);

View File

@ -133,6 +133,10 @@ EthernetPacketizer::EthernetPacket::EthernetPacket(const uint8_t* data, size_t s
int EthernetPacketizer::EthernetPacket::loadBytestream(const std::vector<uint8_t>& bytestream) { int EthernetPacketizer::EthernetPacket::loadBytestream(const std::vector<uint8_t>& bytestream) {
errorWhileDecodingFromBytestream = 0; errorWhileDecodingFromBytestream = 0;
if (bytestream.size() < 24) {
errorWhileDecodingFromBytestream = 1;
return errorWhileDecodingFromBytestream;
}
for(size_t i = 0; i < 6; i++) for(size_t i = 0; i < 6; i++)
destMAC[i] = bytestream[i]; destMAC[i] = bytestream[i];
for(size_t i = 0; i < 6; i++) for(size_t i = 0; i < 6; i++)

View File

@ -3817,7 +3817,7 @@ bool Device::formatDisk(const DiskDetails& config, const DiskFormatProgress& han
return com->sendCommand(ExtendedCommand::DiskFormatProgress, {}); return com->sendCommand(ExtendedCommand::DiskFormatProgress, {});
}, },
std::make_shared<ExtendedResponseFilter>(ExtendedCommand::DiskFormatProgress), std::make_shared<ExtendedResponseFilter>(ExtendedCommand::DiskFormatProgress),
std::chrono::milliseconds(200) std::chrono::milliseconds(1000)
); );
if(!response) { if(!response) {

View File

@ -945,4 +945,18 @@ template<typename T> bool IDeviceSettings::applyStructure(const T& newStructure)
memcpy(settings.data(), &newStructure, structSize); memcpy(settings.data(), &newStructure, structSize);
return apply(); return apply();
}
bool IDeviceSettings::setMiscIOAnalogOutputEnabled(uint8_t pin, bool enabled) {
(void)pin;
(void)enabled;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
return false;
}
bool IDeviceSettings::setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage voltage) {
(void)pin;
(void)voltage;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
return false;
} }

View File

@ -12,7 +12,7 @@ subprocess.call('cd ..; doxygen docs/icsneoc/Doxyfile', shell=True)
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'libicsneo' project = 'libicsneo'
copyright = '2024-2025, Intrepid Control Systems, Inc.' copyright = '2024-2026, Intrepid Control Systems, Inc.'
author = 'Intrepid Control Systems, Inc.' author = 'Intrepid Control Systems, Inc.'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------

View File

@ -91,3 +91,11 @@ SPI Example for 10BASE-T1S
.. literalinclude:: ../../examples/python/spi/spi_example.py .. literalinclude:: ../../examples/python/spi/spi_example.py
:language: python :language: python
Analog Output Control
=====================
:download:`Download example <../../examples/python/analog_out/analog_out_basic.py>`
.. literalinclude:: ../../examples/python/analog_out/analog_out_basic.py
:language: python

View File

@ -14,6 +14,7 @@ option(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE "Build the macsec example" ON)
option(LIBICSNEO_BUILD_CPP_FLEXRAY_EXAMPLE "Build the FlexRay example." ON) option(LIBICSNEO_BUILD_CPP_FLEXRAY_EXAMPLE "Build the FlexRay example." ON)
option(LIBICSNEO_BUILD_CPP_SPI_EXAMPLE "Build the SPI example." ON) option(LIBICSNEO_BUILD_CPP_SPI_EXAMPLE "Build the SPI example." ON)
option(LIBICSNEO_BUILD_CPP_MUTEX_EXAMPLE "Build the NetworkMutex example." ON) option(LIBICSNEO_BUILD_CPP_MUTEX_EXAMPLE "Build the NetworkMutex example." ON)
option(LIBICSNEO_BUILD_CPP_ANALOG_OUT_EXAMPLE "Build the analog output example." ON)
add_compile_options(${LIBICSNEO_COMPILER_WARNINGS}) add_compile_options(${LIBICSNEO_COMPILER_WARNINGS})
@ -80,3 +81,7 @@ endif()
if(LIBICSNEO_BUILD_CPP_MUTEX_EXAMPLE) if(LIBICSNEO_BUILD_CPP_MUTEX_EXAMPLE)
add_subdirectory(cpp/mutex) add_subdirectory(cpp/mutex)
endif() endif()
if(LIBICSNEO_BUILD_CPP_ANALOG_OUT_EXAMPLE)
add_subdirectory(cpp/analog_out)
endif()

View File

@ -0,0 +1,2 @@
add_executable(libicsneocpp-analog-out src/analog_out.cpp)
target_link_libraries(libicsneocpp-analog-out icsneocpp)

View File

@ -0,0 +1,157 @@
/**
* libicsneo Analog Output example
*
* Demonstrates how to configure and control analog outputs on supported devices
*
* Usage: libicsneo-analog-out <pin> <voltage> [deviceSerial] [--yes]
*
* Arguments:
* pin: Pin number (1-3 for RAD Galaxy)
* voltage: Voltage level (0-5)
* deviceSerial: 6 character string for device serial (optional)
* --yes: Skip confirmation prompt
*/
#include <iostream>
#include <thread>
#include <chrono>
#include <string_view>
#include <cstdlib>
#include "icsneo/icsneocpp.h"
static const std::string usage = "Usage: libicsneo-analog-out <pin> <voltage> [deviceSerial] [--yes]\n\n"
"Arguments:\n"
"pin: Pin number (1-3 for RAD Galaxy)\n"
"voltage: Voltage level (0-5)\n"
"deviceSerial: 6 character string for device serial (optional)\n"
"--yes: Skip confirmation prompt\n";
int main(int argc, const char** argv) {
std::vector<std::string_view> args(argv, argv + argc);
// Parse arguments
if(args.size() < 3) {
std::cerr << "Error: Missing required arguments\n" << std::endl;
std::cerr << usage;
return -1;
}
char* endPtr;
long pinNum = std::strtol(args[1].data(), &endPtr, 10);
if(endPtr != args[1].data() + args[1].size() || pinNum < 1 || pinNum > 3) {
std::cerr << "Error: Invalid pin number (must be 1-3)" << std::endl;
return -1;
}
long voltageLevel = std::strtol(args[2].data(), &endPtr, 10);
if(endPtr != args[2].data() + args[2].size() || voltageLevel < 0 || voltageLevel > 5) {
std::cerr << "Error: Invalid voltage level (must be 0-5)" << std::endl;
return -1;
}
icsneo::MiscIOAnalogVoltage voltage = static_cast<icsneo::MiscIOAnalogVoltage>(voltageLevel);
uint8_t pin = static_cast<uint8_t>(pinNum);
// Check for optional arguments
bool skipConfirm = false;
std::string_view serial;
for(size_t i = 3; i < args.size(); i++) {
if(args[i] == "--yes") {
skipConfirm = true;
} else if(serial.empty() && args[i].size() == 6) {
serial = args[i];
}
}
// Confirmation prompt
if(!skipConfirm) {
std::cout << "WARNING: This will set analog output pin " << static_cast<int>(pin)
<< " to " << voltageLevel << "V" << std::endl;
std::cout << "Make sure nothing sensitive is connected to this pin." << std::endl;
std::cout << "Continue? (yes/no): ";
std::string response;
std::getline(std::cin, response);
if(response != "yes") {
std::cout << "Aborted." << std::endl;
return 0;
}
}
std::shared_ptr<icsneo::Device> device = nullptr;
if(!serial.empty()) {
// Find device by serial
auto devices = icsneo::FindAllDevices();
for(auto& dev : devices) {
if(dev->getSerial() == serial) {
device = dev;
break;
}
}
if(!device) {
std::cerr << "Device with serial " << serial << " not found" << std::endl;
return -1;
}
} else {
// Use first available device
auto devices = icsneo::FindAllDevices();
if(devices.empty()) {
std::cerr << "No devices found" << std::endl;
return -1;
}
device = devices[0];
}
std::cout << "Using device: " << device->describe() << std::endl;
if(!device->open()) {
std::cerr << "Failed to open device" << std::endl;
return -1;
}
auto settings = device->settings;
if(!settings) {
std::cerr << "Device settings not available" << std::endl;
device->close();
return -1;
}
std::cout << "Refreshing device settings..." << std::endl;
if(!settings->refresh()) {
std::cerr << "Failed to refresh settings" << std::endl;
device->close();
return -1;
}
// Enable analog output on specified pin
std::cout << "Enabling analog output on pin " << static_cast<int>(pin) << "..." << std::endl;
if(!settings->setMiscIOAnalogOutputEnabled(pin, true)) {
std::cerr << "Failed to enable analog output on pin " << static_cast<int>(pin) << std::endl;
device->close();
return -1;
}
// Set pin to specified voltage
std::cout << "Setting pin " << static_cast<int>(pin) << " to " << voltageLevel << "V..." << std::endl;
if(!settings->setMiscIOAnalogOutput(pin, voltage)) {
std::cerr << "Failed to set voltage on pin " << static_cast<int>(pin) << std::endl;
device->close();
return -1;
}
// Apply settings
std::cout << "Applying settings..." << std::endl;
if(!settings->apply()) {
std::cerr << "Failed to apply settings" << std::endl;
device->close();
return -1;
}
std::cout << "Analog output configured successfully!" << std::endl;
std::cout << "Pin " << static_cast<int>(pin) << ": Enabled at " << voltageLevel << "V" << std::endl;
device->close();
return 0;
}

View File

@ -0,0 +1,107 @@
"""
Basic analog output control example using icsneopy library.
Demonstrates how to configure and control analog outputs on supported devices.
Usage: python analog_out_basic.py <pin> <voltage> [--yes]
Arguments:
pin: Pin number (1-3 for RAD Galaxy)
voltage: Voltage level (0-5)
--yes: Skip confirmation prompt
"""
import sys
import icsneopy
def analog_output_example(pin: int, voltage: int, skip_confirm: bool = False):
"""Configure and control analog outputs."""
# Confirmation prompt
if not skip_confirm:
print(f"WARNING: This will set analog output pin {pin} to {voltage}V")
print("Make sure nothing sensitive is connected to this pin.")
response = input("Continue? (yes/no): ")
if response.lower() != "yes":
print("Aborted.")
return
devices = icsneopy.find_all_devices()
if not devices:
raise RuntimeError("No devices found")
device = devices[0]
try:
if not device.open():
raise RuntimeError("Failed to open device")
settings = device.settings
if not settings:
raise RuntimeError("Device settings not available")
print("Refreshing device settings...")
if not settings.refresh():
raise RuntimeError("Failed to refresh settings")
# Enable analog output on specified pin
print(f"Enabling analog output on pin {pin}...")
if not settings.set_misc_io_analog_output_enabled(pin, True):
raise RuntimeError(f"Failed to enable analog output on pin {pin}")
# Map voltage level to enum
voltage_map = {
0: icsneopy.Settings.MiscIOAnalogVoltage.V0,
1: icsneopy.Settings.MiscIOAnalogVoltage.V1,
2: icsneopy.Settings.MiscIOAnalogVoltage.V2,
3: icsneopy.Settings.MiscIOAnalogVoltage.V3,
4: icsneopy.Settings.MiscIOAnalogVoltage.V4,
5: icsneopy.Settings.MiscIOAnalogVoltage.V5
}
voltage_enum = voltage_map[voltage]
# Set pin to specified voltage
print(f"Setting pin {pin} to {voltage}V...")
if not settings.set_misc_io_analog_output(pin, voltage_enum):
raise RuntimeError(f"Failed to set voltage on pin {pin}")
# Apply settings
print("Applying settings...")
if not settings.apply():
raise RuntimeError("Failed to apply settings")
print("Analog output configured successfully!")
print(f"Pin {pin}: Enabled at {voltage}V")
finally:
device.close()
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Error: Missing required arguments\n")
print("Usage: python analog_out_basic.py <pin> <voltage> [--yes]")
print("\nArguments:")
print(" pin: Pin number (1-3 for RAD Galaxy)")
print(" voltage: Voltage level (0-5)")
print(" --yes: Skip confirmation prompt")
sys.exit(1)
try:
pin = int(sys.argv[1])
if pin < 1 or pin > 3:
print("Error: Invalid pin number (must be 1-3)")
sys.exit(1)
voltage = int(sys.argv[2])
if voltage < 0 or voltage > 5:
print("Error: Invalid voltage level (must be 0-5)")
sys.exit(1)
skip_confirm = "--yes" in sys.argv
analog_output_example(pin, voltage, skip_confirm)
except ValueError:
print("Error: Pin and voltage must be integers")
sys.exit(1)

View File

@ -128,6 +128,7 @@ enum class ChipID : uint8_t {
RADGALAXY2_SYSMON_CHIP = 123, RADGALAXY2_SYSMON_CHIP = 123,
RADCOMET3_ZCHIP = 125, RADCOMET3_ZCHIP = 125,
Connect_LINUX = 126, Connect_LINUX = 126,
RADMOONT1S_ZCHIP = 130,
RADGigastar2_ZYNQ = 131, RADGigastar2_ZYNQ = 131,
RADGemini_MCHIP = 135, RADGemini_MCHIP = 135,
Invalid = 255 Invalid = 255

View File

@ -89,7 +89,10 @@ typedef struct
uint8_t TqSync; uint8_t TqSync;
uint16_t BRP; uint16_t BRP;
uint8_t auto_baud; uint8_t auto_baud;
uint8_t innerFrameDelay25us; uint8_t innerFrameDelay25us : 4;
uint8_t rsvd : 1;
uint8_t disableRetransmission : 1;
uint8_t canClk : 2;
} CAN_SETTINGS; } CAN_SETTINGS;
#define CAN_SETTINGS_SIZE 12 #define CAN_SETTINGS_SIZE 12
static_assert(sizeof(CAN_SETTINGS) == CAN_SETTINGS_SIZE, "CAN_SETTINGS is the wrong size!"); static_assert(sizeof(CAN_SETTINGS) == CAN_SETTINGS_SIZE, "CAN_SETTINGS is the wrong size!");
@ -747,6 +750,16 @@ typedef struct
namespace icsneo { namespace icsneo {
enum class MiscIOAnalogVoltage : uint8_t
{
V0 = 0,
V1 = 1,
V2 = 2,
V3 = 3,
V4 = 4,
V5 = 5
};
class IDeviceSettings { class IDeviceSettings {
public: public:
using TerminationGroup = std::vector<Network>; using TerminationGroup = std::vector<Network>;
@ -1180,6 +1193,9 @@ public:
return false; return false;
} }
virtual bool setMiscIOAnalogOutputEnabled(uint8_t pin, bool enabled);
virtual bool setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage voltage);
const void* getRawStructurePointer() const { return settingsInDeviceRAM.data(); } const void* getRawStructurePointer() const { return settingsInDeviceRAM.data(); }
void* getMutableRawStructurePointer() { return settings.data(); } void* getMutableRawStructurePointer() { return settings.data(); }
template<typename T> const T* getStructurePointer() const { return reinterpret_cast<const T*>(getRawStructurePointer()); } template<typename T> const T* getStructurePointer() const { return reinterpret_cast<const T*>(getRawStructurePointer()); }

View File

@ -185,6 +185,92 @@ public:
return nullptr; return nullptr;
} }
} }
bool setMiscIOAnalogOutputEnabled(uint8_t pin, bool enabled) override {
if(!settingsLoaded) {
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
return false;
}
if(disabled) {
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
return false;
}
if(readonly) {
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
return false;
}
if(pin < 1 || pin > 2) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
auto cfg = getMutableStructurePointer<radgalaxy_settings_t>();
if(cfg == nullptr) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
return false;
}
const uint16_t bitMask = 1 << (pin - 1);
if(enabled) {
// Set pin as output and enable analog mode
cfg->misc_io_initial_ddr |= bitMask;
cfg->misc_io_analog_enable |= bitMask;
} else {
// Disable analog mode (leave DDR as-is)
cfg->misc_io_analog_enable &= ~bitMask;
}
return true;
}
bool setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage voltage) override {
if(!settingsLoaded) {
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
return false;
}
if(disabled) {
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
return false;
}
if(readonly) {
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
return false;
}
if(pin < 1 || pin > 2) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
auto cfg = getMutableStructurePointer<radgalaxy_settings_t>();
if(cfg == nullptr) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
return false;
}
const uint8_t dacValue = static_cast<uint8_t>(voltage);
if(dacValue > 5) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
if(pin == 1) {
// Update low nibble of high byte (bits 8-11), preserve pin 2 value
cfg->misc_io_initial_latch = (cfg->misc_io_initial_latch & 0xF0FF) | (static_cast<uint16_t>(dacValue) << 8);
} else { // pin == 2
// Update high nibble of high byte (bits 12-15), preserve pin 1 value
cfg->misc_io_initial_latch = (cfg->misc_io_initial_latch & 0x0FFF) | (static_cast<uint16_t>(dacValue) << 12);
}
return true;
}
}; };
} }

View File

@ -27,6 +27,21 @@ public:
return supportedNetworks; return supportedNetworks;
} }
const std::vector<ChipInfo>& getChipInfo() const override {
static std::vector<ChipInfo> chips = {
{ChipID::RADJupiter_MCHIP, true, "MCHIP", "jupiter_mchip_ief", 1, FirmwareType::IEF}
};
return chips;
}
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADJupiter_MCHIP, BootloaderCommunication::RED)
.add<EnterApplicationPhase>(ChipID::RADJupiter_MCHIP)
.add<ReconnectPhase>();
}
bool getEthPhyRegControlSupported() const override { return true; } bool getEthPhyRegControlSupported() const override { return true; }
ProductID getProductID() const override { ProductID getProductID() const override {

View File

@ -37,6 +37,22 @@ public:
ProductID getProductID() const override { ProductID getProductID() const override {
return ProductID::RADMoonT1S; return ProductID::RADMoonT1S;
} }
const std::vector<ChipInfo>& getChipInfo() const override {
static std::vector<ChipInfo> chips = {
{ChipID::RADMOONT1S_ZCHIP, true, "ZCHIP", "RADMoonT1S_SW_bin", 1, FirmwareType::Zip}
};
return chips;
}
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADMOONT1S_ZCHIP, BootloaderCommunication::RAD)
.add<EnterApplicationPhase>(ChipID::RADMOONT1S_ZCHIP)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected: protected:
RADMoonT1S(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { RADMoonT1S(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<RADMoonT1SSettings>(makeDriver); initialize<RADMoonT1SSettings>(makeDriver);

View File

@ -30,6 +30,22 @@ public:
ProductID getProductID() const override { ProductID getProductID() const override {
return ProductID::ValueCAN4Industrial; return ProductID::ValueCAN4Industrial;
} }
const std::vector<ChipInfo>& getChipInfo() const override {
static std::vector<ChipInfo> chips = {
{ChipID::ValueCAN4Industrial_MCHIP, true, "MCHIP", "vcan4_ind_mchip_ief", 0, FirmwareType::IEF}
};
return chips;
}
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::ValueCAN4Industrial_MCHIP, BootloaderCommunication::RED)
.add<EnterApplicationPhase>(ChipID::ValueCAN4Industrial_MCHIP)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected: protected:
ValueCAN4Industrial(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { ValueCAN4Industrial(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
initialize<ValueCAN4IndustrialSettings>(makeDriver); initialize<ValueCAN4IndustrialSettings>(makeDriver);