10 Commits
Author SHA1 Message Date
Gowtham NanjukuttyandGitHub 18a3bfafc7 Merge 0c9f1c5f3e into 8af6d5f2a8 2026-06-24 09:03:11 +00:00
David RebbeandKyle Schwarz 8af6d5f2a8 FIRE3: Add reboot support 2026-06-19 17:58:49 -04:00
David RebbeandKyle Schwarz 54fb89b675 Settings: Add Linux options 2026-06-19 17:12:42 -04:00
Thomas StoddardandKyle Schwarz 299766403f Settings: Add GPTP 2026-06-18 22:23:13 -04:00
Max Brombach 2d0b0c63ed Device: RAD-Star 2: Add bootloader pipeline and chip info 2026-06-18 15:30:21 +00:00
Bryant JonesandKyle Schwarz 30606be7a8 Settings: Add PerfTest 2026-06-18 11:12:13 -04:00
Kyle Schwarz 4dd97f734a Servd: Disable signal on send failure 2026-06-18 10:21:35 -04:00
Bryant JonesandKyle Schwarz 44d0e3de64 Gigastar2: Fix loading coremini 2026-06-10 18:08:02 -04:00
Kyle Schwarz 023f5aa089 Bindings: Python: Add AppError 2026-06-10 16:59:43 -04:00
Gowtham Nanjukutty (XC-CP/ECC2.3) 0c9f1c5f3e darwin: fix CDCACM device detection on macOS 12+
On macOS 12 and later, Apple replaced IOUSBDevice with IOUSBHostDevice
in the USB host stack. When walking the IORegistry parent chain to find
the USB device providing a serial port, the existing code only checked
IOObjectConformsTo(parent, kIOUSBDeviceClassName). On macOS 12+, this
check fails because the USB device node conforms to IOUSBHostDevice
instead.

Fix by also checking IOObjectConformsTo(parent, "IOUSBHostDevice"),
so CDCACM device discovery works on both old and new macOS.

Verified on macOS 26 (Tahoe, arm64) with a ValueCAN 4-2 (V2D805).
2026-05-22 09:12:58 -04:00
55 changed files with 2227 additions and 6 deletions
+62
View File
@@ -12,6 +12,7 @@
#include <map> #include <map>
#include <algorithm> #include <algorithm>
#include <optional> #include <optional>
#include <chrono>
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <cstring> #include <cstring>
@@ -787,6 +788,67 @@ icsneoc2_error_t icsneoc2_device_tc10_status_get(const icsneoc2_device_t* device
return icsneoc2_error_success; return icsneoc2_error_success;
} }
icsneoc2_error_t icsneoc2_device_supports_gptp(const icsneoc2_device_t* device, bool* supported) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!supported) {
return icsneoc2_error_invalid_parameters;
}
*supported = device->device->supportsGPTP();
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_gptp_status_get(const icsneoc2_device_t* device, uint32_t timeout_ms, icsneoc2_gptp_status_t* status) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!status) {
return icsneoc2_error_invalid_parameters;
}
auto cpp_status = device->device->getGPTPStatus(std::chrono::milliseconds(timeout_ms));
if(!cpp_status.has_value()) {
return icsneoc2_error_get_settings_failure;
}
status->current_time_seconds = cpp_status->currentTime.seconds;
status->current_time_nanoseconds = cpp_status->currentTime.nanoseconds;
status->ms_offset_ns = cpp_status->msOffsetNs;
status->is_sync = cpp_status->isSync;
status->link_status = cpp_status->linkStatus;
status->link_delay_ns = cpp_status->linkDelayNS;
status->selected_role = cpp_status->selectedRole;
status->as_capable = cpp_status->asCapable;
status->is_syntonized = cpp_status->isSyntonized;
status->short_format = cpp_status->shortFormat;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_supports_reboot(const icsneoc2_device_t* device, bool* supported) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!supported) {
return icsneoc2_error_invalid_parameters;
}
*supported = device->device->supportsReboot();
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_reboot(const icsneoc2_device_t* device, bool safe) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!device->device->reboot(safe)) {
return icsneoc2_error_transmit_message_failed;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_digital_io_get(const icsneoc2_device_t* device, icsneoc2_io_type_t type, uint32_t number, bool* value) { icsneoc2_error_t icsneoc2_device_digital_io_get(const icsneoc2_device_t* device, icsneoc2_io_type_t type, uint32_t number, bool* value) {
auto res = icsneoc2_device_is_valid(device); auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) { if(res != icsneoc2_error_success) {
+194
View File
@@ -867,6 +867,90 @@ icsneoc2_error_t icsneoc2_settings_misc_io_analog_output_set(icsneoc2_device_t*
return icsneoc2_error_success; return icsneoc2_error_success;
} }
icsneoc2_error_t icsneoc2_settings_linux_boot_enabled_get(icsneoc2_device_t* device, bool* value) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!value) {
return icsneoc2_error_invalid_parameters;
}
if(auto result = device->device->settings->getLinuxBootEnabled(); result.has_value()) {
*value = result.value();
return icsneoc2_error_success;
}
return icsneoc2_error_get_settings_failure;
}
icsneoc2_error_t icsneoc2_settings_linux_boot_enabled_set(icsneoc2_device_t* device, bool value) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!device->device->settings->setLinuxBootEnabled(value)) {
return icsneoc2_error_set_settings_failure;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_external_wifi_antenna_enabled_get(icsneoc2_device_t* device, bool* value) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!value) {
return icsneoc2_error_invalid_parameters;
}
if(auto result = device->device->settings->getExternalWifiAntennaEnabled(); result.has_value()) {
*value = result.value();
return icsneoc2_error_success;
}
return icsneoc2_error_get_settings_failure;
}
icsneoc2_error_t icsneoc2_settings_external_wifi_antenna_enabled_set(icsneoc2_device_t* device, bool value) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!device->device->settings->setExternalWifiAntennaEnabled(value)) {
return icsneoc2_error_set_settings_failure;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_linux_configuration_port_get(icsneoc2_device_t* device, icsneoc2_linux_configuration_port_t* value) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!value) {
return icsneoc2_error_invalid_parameters;
}
if(auto result = device->device->settings->getLinuxConfigurationPort(); result.has_value()) {
*value = static_cast<icsneoc2_linux_configuration_port_t>(result.value());
return icsneoc2_error_success;
}
return icsneoc2_error_get_settings_failure;
}
icsneoc2_error_t icsneoc2_settings_linux_configuration_port_set(icsneoc2_device_t* device, icsneoc2_linux_configuration_port_t value) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!device->device->settings->setLinuxConfigurationPort(static_cast<LinuxConfigurationPort>(value))) {
return icsneoc2_error_set_settings_failure;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_disabled_get(icsneoc2_device_t* device, bool* value) { icsneoc2_error_t icsneoc2_settings_disabled_get(icsneoc2_device_t* device, bool* value) {
if(!value) { if(!value) {
return icsneoc2_error_invalid_parameters; return icsneoc2_error_invalid_parameters;
@@ -892,3 +976,113 @@ icsneoc2_error_t icsneoc2_settings_readonly_get(icsneoc2_device_t* device, bool*
*value = device->device->settings->readonly; *value = device->device->settings->readonly;
return icsneoc2_error_success; return icsneoc2_error_success;
} }
icsneoc2_error_t icsneoc2_settings_gptp_profile_get(icsneoc2_device_t* device, icsneoc2_gptp_profile_t* value) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!value) {
return icsneoc2_error_invalid_parameters;
}
if(auto result = device->device->settings->getGPTPProfile(); result.has_value()) {
*value = static_cast<icsneoc2_gptp_profile_t>(result.value());
return icsneoc2_error_success;
}
return icsneoc2_error_get_settings_failure;
}
icsneoc2_error_t icsneoc2_settings_gptp_profile_set(icsneoc2_device_t* device, icsneoc2_gptp_profile_t value) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(value >= icsneoc2_gptp_profile_maxsize) {
return icsneoc2_error_invalid_parameters;
}
if(!device->device->settings->setGPTPProfile(static_cast<RADGPTPProfile>(value))) {
return icsneoc2_error_set_settings_failure;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_gptp_role_get(icsneoc2_device_t* device, icsneoc2_gptp_role_t* value) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!value) {
return icsneoc2_error_invalid_parameters;
}
if(auto result = device->device->settings->getGPTPRole(); result.has_value()) {
*value = static_cast<icsneoc2_gptp_role_t>(result.value());
return icsneoc2_error_success;
}
return icsneoc2_error_get_settings_failure;
}
icsneoc2_error_t icsneoc2_settings_gptp_role_set(icsneoc2_device_t* device, icsneoc2_gptp_role_t value) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(value >= icsneoc2_gptp_role_maxsize) {
return icsneoc2_error_invalid_parameters;
}
if(!device->device->settings->setGPTPRole(static_cast<RADGPTPRole>(value))) {
return icsneoc2_error_set_settings_failure;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_gptp_enabled_port_get(icsneoc2_device_t* device, uint8_t* value) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!value) {
return icsneoc2_error_invalid_parameters;
}
if(auto result = device->device->settings->getGPTPEnabledPort(); result.has_value()) {
*value = result.value();
return icsneoc2_error_success;
}
return icsneoc2_error_get_settings_failure;
}
icsneoc2_error_t icsneoc2_settings_gptp_enabled_port_set(icsneoc2_device_t* device, uint8_t value) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!device->device->settings->setGPTPEnabledPort(value)) {
return icsneoc2_error_set_settings_failure;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_gptp_clock_syntonization_enabled_get(icsneoc2_device_t* device, bool* value) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!value) {
return icsneoc2_error_invalid_parameters;
}
if(auto result = device->device->settings->isGPTPClockSyntonizationEnabled(); result.has_value()) {
*value = result.value();
return icsneoc2_error_success;
}
return icsneoc2_error_get_settings_failure;
}
icsneoc2_error_t icsneoc2_settings_gptp_clock_syntonization_enabled_set(icsneoc2_device_t* device, bool value) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!device->device->settings->setGPTPClockSyntonizationEnabled(value)) {
return icsneoc2_error_set_settings_failure;
}
return icsneoc2_error_success;
}
+1
View File
@@ -32,6 +32,7 @@ pybind11_add_module(icsneopy
icsneopy/communication/message/mdiomessage.cpp icsneopy/communication/message/mdiomessage.cpp
icsneopy/communication/message/gptpstatusmessage.cpp icsneopy/communication/message/gptpstatusmessage.cpp
icsneopy/communication/message/allmacaddressesmessage.cpp icsneopy/communication/message/allmacaddressesmessage.cpp
icsneopy/communication/message/apperrormessage.cpp
icsneopy/communication/message/ethernetstatusmessage.cpp icsneopy/communication/message/ethernetstatusmessage.cpp
icsneopy/communication/message/spimessage.cpp icsneopy/communication/message/spimessage.cpp
icsneopy/communication/message/scriptstatusmessage.cpp icsneopy/communication/message/scriptstatusmessage.cpp
@@ -0,0 +1,71 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/native_enum.h>
#include "icsneo/communication/message/apperrormessage.h"
namespace icsneo {
void init_errortypes(pybind11::module_& m) {
pybind11::native_enum<AppErrorType>(m, "AppErrorType", "enum.IntEnum")
.value("RxMessagesFull", AppErrorType::AppErrorRxMessagesFull)
.value("TxMessagesFull", AppErrorType::AppErrorTxMessagesFull)
.value("TxReportMessagesFull", AppErrorType::AppErrorTxReportMessagesFull)
.value("BadCommWithDspIC", AppErrorType::AppErrorBadCommWithDspIC)
.value("DriverOverflow", AppErrorType::AppErrorDriverOverflow)
.value("PCBuffOverflow", AppErrorType::AppErrorPCBuffOverflow)
.value("PCChksumError", AppErrorType::AppErrorPCChksumError)
.value("PCMissedByte", AppErrorType::AppErrorPCMissedByte)
.value("PCOverrunError", AppErrorType::AppErrorPCOverrunError)
.value("SettingFailure", AppErrorType::AppErrorSettingFailure)
.value("TooManySelectedNetworks", AppErrorType::AppErrorTooManySelectedNetworks)
.value("NetworkNotEnabled", AppErrorType::AppErrorNetworkNotEnabled)
.value("RtcNotCorrect", AppErrorType::AppErrorRtcNotCorrect)
.value("LoadedDefaultSettings", AppErrorType::AppErrorLoadedDefaultSettings)
.value("FeatureNotUnlocked", AppErrorType::AppErrorFeatureNotUnlocked)
.value("FeatureRtcCmdDropped", AppErrorType::AppErrorFeatureRtcCmdDropped)
.value("TxMessagesFlushed", AppErrorType::AppErrorTxMessagesFlushed)
.value("TxMessagesHalfFull", AppErrorType::AppErrorTxMessagesHalfFull)
.value("NetworkNotValid", AppErrorType::AppErrorNetworkNotValid)
.value("TxInterfaceNotImplemented", AppErrorType::AppErrorTxInterfaceNotImplemented)
.value("TxMessagesCommEnableIsOff", AppErrorType::AppErrorTxMessagesCommEnableIsOff)
.value("RxFilterMatchCountExceeded", AppErrorType::AppErrorRxFilterMatchCountExceeded)
.value("EthPreemptionNotEnabled", AppErrorType::AppErrorEthPreemptionNotEnabled)
.value("TxNotSupportedInMode", AppErrorType::AppErrorTxNotSupportedInMode)
.value("JumboFramesNotSupported", AppErrorType::AppErrorJumboFramesNotSupported)
.value("EthernetIpFragment", AppErrorType::AppErrorEthernetIpFragment)
.value("TxMessagesUnderrun", AppErrorType::AppErrorTxMessagesUnderrun)
.value("DeviceFanFailure", AppErrorType::AppErrorDeviceFanFailure)
.value("DeviceOvertemperature", AppErrorType::AppErrorDeviceOvertemperature)
.value("TxMessageIndexOutOfRange", AppErrorType::AppErrorTxMessageIndexOutOfRange)
.value("UndersizedFrameDropped", AppErrorType::AppErrorUndersizedFrameDropped)
.value("OversizedFrameDropped", AppErrorType::AppErrorOversizedFrameDropped)
.value("WatchdogEvent", AppErrorType::AppErrorWatchdogEvent)
.value("SystemClockFailure", AppErrorType::AppErrorSystemClockFailure)
.value("SystemClockRecovered", AppErrorType::AppErrorSystemClockRecovered)
.value("SystemPeripheralReset", AppErrorType::AppErrorSystemPeripheralReset)
.value("SystemCommunicationFailure", AppErrorType::AppErrorSystemCommunicationFailure)
.value("TxMessagesUnsupportedSourceOrPacketId", AppErrorType::AppErrorTxMessagesUnsupportedSourceOrPacketId)
.value("WbmsManagerConnectFailed", AppErrorType::AppErrorWbmsManagerConnectFailed)
.value("WbmsManagerConnectBadState", AppErrorType::AppErrorWbmsManagerConnectBadState)
.value("WbmsManagerConnectTimeout", AppErrorType::AppErrorWbmsManagerConnectTimeout)
.value("FailedToInitializeLoggerDisk", AppErrorType::AppErrorFailedToInitializeLoggerDisk)
.value("InvalidSetting", AppErrorType::AppErrorInvalidSetting)
.value("SystemFailureRequestedReset", AppErrorType::AppErrorSystemFailureRequestedReset)
.value("PortKeyMistmatch", AppErrorType::AppErrorPortKeyMistmatch)
.value("BusFailure", AppErrorType::AppErrorBusFailure)
.value("TapOverflow", AppErrorType::AppErrorTapOverflow)
.value("EthTxNoLink", AppErrorType::AppErrorEthTxNoLink)
.value("ErrorBufferOverflow", AppErrorType::AppErrorErrorBufferOverflow)
.value("NoError", AppErrorType::AppNoError)
.finalize();
}
void init_apperrormessage(pybind11::module_& m) {
init_errortypes(m);
pybind11::classh<AppErrorMessage, Message>(m, "AppErrorMessage")
.def("get_app_error_type", &AppErrorMessage::getAppErrorType)
.def("get_app_error_string", &AppErrorMessage::getAppErrorString);
}
} // namespace icsneo
@@ -52,9 +52,11 @@ void init_device(pybind11::module_& m) {
.def("set_digital_io", pybind11::overload_cast<IO, size_t, bool>(&Device::setDigitalIO), pybind11::arg("type"), pybind11::arg("number"), pybind11::arg("value"), pybind11::call_guard<pybind11::gil_scoped_release>()) .def("set_digital_io", pybind11::overload_cast<IO, size_t, bool>(&Device::setDigitalIO), pybind11::arg("type"), pybind11::arg("number"), pybind11::arg("value"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_polling_message_limit", &Device::setPollingMessageLimit) .def("set_polling_message_limit", &Device::setPollingMessageLimit)
.def("set_rtc", &Device::setRTC, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("set_rtc", &Device::setRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("reboot", &Device::reboot, pybind11::arg("safe") = false, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("start_script", &Device::startScript, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("start_script", &Device::startScript, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("stop_script", &Device::stopScript, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("stop_script", &Device::stopScript, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("supports_tc10", &Device::supportsTC10) .def("supports_tc10", &Device::supportsTC10)
.def("supports_reboot", &Device::supportsReboot)
.def("supports_live_data", &Device::supportsLiveData) .def("supports_live_data", &Device::supportsLiveData)
.def("subscribe_live_data", &Device::subscribeLiveData, pybind11::arg("message"), pybind11::call_guard<pybind11::gil_scoped_release>()) .def("subscribe_live_data", &Device::subscribeLiveData, pybind11::arg("message"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("unsubscribe_live_data", &Device::unsubscribeLiveData, pybind11::arg("handle"), pybind11::call_guard<pybind11::gil_scoped_release>()) .def("unsubscribe_live_data", &Device::unsubscribeLiveData, pybind11::arg("handle"), pybind11::call_guard<pybind11::gil_scoped_release>())
@@ -40,6 +40,16 @@ 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_<RADGPTPProfile>(settings, "GPTPProfile")
.value("Standard", RADGPTPProfile::RAD_GPTP_PROFILE_STANDARD)
.value("Automotive", RADGPTPProfile::RAD_GPTP_PROFILE_AUTOMOTIVE);
pybind11::enum_<RADGPTPRole>(settings, "GPTPRole")
.value("Disabled", RADGPTPRole::RAD_GPTP_ROLE_DISABLED)
.value("Passive", RADGPTPRole::RAD_GPTP_ROLE_PASSIVE)
.value("Master", RADGPTPRole::RAD_GPTP_ROLE_MASTER)
.value("Slave", RADGPTPRole::RAD_GPTP_ROLE_SLAVE);
pybind11::enum_<MiscIOAnalogVoltage>(settings, "MiscIOAnalogVoltage") pybind11::enum_<MiscIOAnalogVoltage>(settings, "MiscIOAnalogVoltage")
.value("V0", MiscIOAnalogVoltage::V0) .value("V0", MiscIOAnalogVoltage::V0)
.value("V1", MiscIOAnalogVoltage::V1) .value("V1", MiscIOAnalogVoltage::V1)
@@ -48,6 +58,10 @@ void init_idevicesettings(pybind11::module_& m) {
.value("V4", MiscIOAnalogVoltage::V4) .value("V4", MiscIOAnalogVoltage::V4)
.value("V5", MiscIOAnalogVoltage::V5); .value("V5", MiscIOAnalogVoltage::V5);
pybind11::enum_<LinuxConfigurationPort>(settings, "LinuxConfigurationPort")
.value("USB", LinuxConfigurationPort::USB)
.value("ETH01", LinuxConfigurationPort::ETH01);
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>())
@@ -119,7 +133,28 @@ void init_idevicesettings(pybind11::module_& m) {
.def("set_misc_io_analog_output_enabled", &IDeviceSettings::setMiscIOAnalogOutputEnabled, 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>()) .def("set_misc_io_analog_output", &IDeviceSettings::setMiscIOAnalogOutput, pybind11::call_guard<pybind11::gil_scoped_release>())
// Performance blast
.def("is_perf_test_enabled", &IDeviceSettings::isPerfTestEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_perf_test_enable", &IDeviceSettings::setPerfTestEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
// gPTP methods
.def("get_gptp_profile", &IDeviceSettings::getGPTPProfile, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_gptp_profile", &IDeviceSettings::setGPTPProfile, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_gptp_role", &IDeviceSettings::getGPTPRole, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_gptp_role", &IDeviceSettings::setGPTPRole, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_gptp_enabled_port", &IDeviceSettings::getGPTPEnabledPort, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_gptp_enabled_port", &IDeviceSettings::setGPTPEnabledPort, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("is_gptp_clock_syntonization_enabled", &IDeviceSettings::isGPTPClockSyntonizationEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_gptp_clock_syntonization_enabled", &IDeviceSettings::setGPTPClockSyntonizationEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
// Linux operating-system settings (Fire3 family devices)
.def("get_linux_boot_enabled", &IDeviceSettings::getLinuxBootEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_linux_boot_enabled", &IDeviceSettings::setLinuxBootEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_external_wifi_antenna_enabled", &IDeviceSettings::getExternalWifiAntennaEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_external_wifi_antenna_enabled", &IDeviceSettings::setExternalWifiAntennaEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_linux_configuration_port", &IDeviceSettings::getLinuxConfigurationPort, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_linux_configuration_port", &IDeviceSettings::setLinuxConfigurationPort, 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);
+2
View File
@@ -20,6 +20,7 @@ void init_linmessage(pybind11::module_&);
void init_tc10statusmessage(pybind11::module_&); void init_tc10statusmessage(pybind11::module_&);
void init_gptpstatusmessage(pybind11::module_&); void init_gptpstatusmessage(pybind11::module_&);
void init_allmacaddressesmessage(pybind11::module_&); void init_allmacaddressesmessage(pybind11::module_&);
void init_apperrormessage(pybind11::module_&);
void init_mdiomessage(pybind11::module_&); void init_mdiomessage(pybind11::module_&);
void init_spimessage(pybind11::module_&); void init_spimessage(pybind11::module_&);
void init_ethernetstatusmessage(pybind11::module_&); void init_ethernetstatusmessage(pybind11::module_&);
@@ -61,6 +62,7 @@ PYBIND11_MODULE(icsneopy, m) {
init_tc10statusmessage(m); init_tc10statusmessage(m);
init_gptpstatusmessage(m); init_gptpstatusmessage(m);
init_allmacaddressesmessage(m); init_allmacaddressesmessage(m);
init_apperrormessage(m);
init_mdiomessage(m); init_mdiomessage(m);
init_ethernetstatusmessage(m); init_ethernetstatusmessage(m);
init_macsecconfig(m); init_macsecconfig(m);
+9
View File
@@ -3735,6 +3735,15 @@ bool Device::requestTC10Sleep(Network::NetID network) {
return typed->response == ExtendedResponse::OK; return typed->response == ExtendedResponse::OK;
} }
bool Device::reboot(bool safe) {
if(!supportsReboot()) {
report(APIEvent::Type::NotSupported, APIEvent::Severity::Error);
return false;
}
// The device reboots in response to this command, so no reply is expected.
return com->sendCommand(ExtendedCommand::Reboot, { uint8_t(safe ? 1 : 0) });
}
std::optional<TC10StatusMessage> Device::getTC10Status(Network::NetID network) { std::optional<TC10StatusMessage> Device::getTC10Status(Network::NetID network) {
if(!supportsTC10()) { if(!supportsTC10()) {
report(APIEvent::Type::NotSupported, APIEvent::Severity::Error); report(APIEvent::Type::NotSupported, APIEvent::Severity::Error);
+147 -1
View File
@@ -959,4 +959,150 @@ bool IDeviceSettings::setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage vol
(void)voltage; (void)voltage;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error); report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
return false; return false;
} }
std::optional<RADGPTPProfile> IDeviceSettings::getGPTPProfile() const {
const auto* gptp = getGPTPSettings();
if(!gptp) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
return static_cast<RADGPTPProfile>(gptp->profile);
}
bool IDeviceSettings::setGPTPProfile(RADGPTPProfile profile) {
auto* gptp = getMutableGPTPSettings();
if(!gptp) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
gptp->profile = static_cast<uint8_t>(profile);
return true;
}
std::optional<RADGPTPRole> IDeviceSettings::getGPTPRole() const {
const auto* gptp = getGPTPSettings();
if(!gptp) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
return static_cast<RADGPTPRole>(gptp->gptpPortRole);
}
bool IDeviceSettings::setGPTPRole(RADGPTPRole role) {
auto* gptp = getMutableGPTPSettings();
if(!gptp) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
gptp->gptpPortRole = static_cast<uint8_t>(role);
return true;
}
std::optional<uint8_t> IDeviceSettings::getGPTPEnabledPort() const {
const auto* gptp = getGPTPSettings();
if(!gptp) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
return gptp->gptpEnabledPort;
}
bool IDeviceSettings::setGPTPEnabledPort(uint8_t port) {
auto* gptp = getMutableGPTPSettings();
if(!gptp) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
gptp->gptpEnabledPort = port;
return true;
}
std::optional<bool> IDeviceSettings::isGPTPClockSyntonizationEnabled() const {
const auto* gptp = getGPTPSettings();
if(!gptp) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
return gptp->enableClockSyntonization != 0;
}
bool IDeviceSettings::setGPTPClockSyntonizationEnabled(bool enable) {
auto* gptp = getMutableGPTPSettings();
if(!gptp) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
gptp->enableClockSyntonization = enable ? 1 : 0;
return true;
}
std::optional<bool> IDeviceSettings::getLinuxBootEnabled() {
const auto* os = getLinuxSettings();
if(os == nullptr) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
return os->allowBoot != 0;
}
bool IDeviceSettings::setLinuxBootEnabled(bool enabled) {
auto os = getMutableLinuxSettings();
if(!os) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
return false;
}
(*os)->allowBoot = enabled ? 1 : 0;
return true;
}
std::optional<bool> IDeviceSettings::getExternalWifiAntennaEnabled() {
const auto* os = getLinuxSettings();
if(os == nullptr) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
return os->useExternalWifiAntenna != 0;
}
bool IDeviceSettings::setExternalWifiAntennaEnabled(bool enabled) {
auto os = getMutableLinuxSettings();
if(!os) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
return false;
}
(*os)->useExternalWifiAntenna = enabled ? 1 : 0;
return true;
}
std::optional<LinuxConfigurationPort> IDeviceSettings::getLinuxConfigurationPort() {
const auto* os = getLinuxSettings();
if(os == nullptr) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
switch(static_cast<LinuxConfigurationPort>(os->ethConfigurationPort)) {
case LinuxConfigurationPort::ETH01:
return LinuxConfigurationPort::ETH01;
case LinuxConfigurationPort::USB:
default: // Any other value means the configuration interface is over USB
return LinuxConfigurationPort::USB;
}
}
bool IDeviceSettings::setLinuxConfigurationPort(LinuxConfigurationPort port) {
switch(port) {
case LinuxConfigurationPort::USB:
case LinuxConfigurationPort::ETH01:
break;
default:
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
auto os = getMutableLinuxSettings();
if(!os) {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
return false;
}
(*os)->ethConfigurationPort = static_cast<uint8_t>(port);
return true;
}
+10
View File
@@ -14,6 +14,7 @@ option(LIBICSNEO_BUILD_C2_ETHERNET_TRANSMIT_EXAMPLE "Build the C2 ethernet trans
option(LIBICSNEO_BUILD_C2_ETHERNET_RECEIVE_EXAMPLE "Build the C2 ethernet receive example." ON) option(LIBICSNEO_BUILD_C2_ETHERNET_RECEIVE_EXAMPLE "Build the C2 ethernet receive example." ON)
option(LIBICSNEO_BUILD_C2_T1S_LOOPBACK_EXAMPLE "Build the C2 RAD-Comet3 T1S loopback example." ON) option(LIBICSNEO_BUILD_C2_T1S_LOOPBACK_EXAMPLE "Build the C2 RAD-Comet3 T1S loopback example." ON)
option(LIBICSNEO_BUILD_C2_TC10_EXAMPLE "Build the C2 TC10 example." ON) option(LIBICSNEO_BUILD_C2_TC10_EXAMPLE "Build the C2 TC10 example." ON)
option(LIBICSNEO_BUILD_C2_GPTP_EXAMPLE "Build the C2 gPTP settings example." ON)
option(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE "Build the simple C++ example." ON) option(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE "Build the simple C++ example." ON)
option(LIBICSNEO_BUILD_CPP_DEVICE_INFO_EXAMPLE "Build the C++ device info example." ON) option(LIBICSNEO_BUILD_CPP_DEVICE_INFO_EXAMPLE "Build the C++ device info example." ON)
option(LIBICSNEO_BUILD_CPP_INTERACTIVE_EXAMPLE "Build the command-line interactive C++ example." ON) option(LIBICSNEO_BUILD_CPP_INTERACTIVE_EXAMPLE "Build the command-line interactive C++ example." ON)
@@ -31,6 +32,7 @@ option(LIBICSNEO_BUILD_CPP_MUTEX_EXAMPLE "Build the NetworkMutex example." ON)
option(LIBICSNEO_BUILD_CPP_ANALOG_OUT_EXAMPLE "Build the analog output example." ON) option(LIBICSNEO_BUILD_CPP_ANALOG_OUT_EXAMPLE "Build the analog output example." ON)
option(LIBICSNEO_BUILD_CPP_DISKFORMAT_EXAMPLE "Build the disk format example." ON) option(LIBICSNEO_BUILD_CPP_DISKFORMAT_EXAMPLE "Build the disk format example." ON)
option(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE "Build the T1S example." ON) option(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE "Build the T1S example." ON)
option(LIBICSNEO_BUILD_CPP_GPTP_EXAMPLE "Build the C++ gPTP settings example." ON)
add_compile_options(${LIBICSNEO_COMPILER_WARNINGS}) add_compile_options(${LIBICSNEO_COMPILER_WARNINGS})
@@ -98,6 +100,10 @@ if(LIBICSNEO_BUILD_C2_TC10_EXAMPLE)
add_subdirectory(c2/tc10) add_subdirectory(c2/tc10)
endif() endif()
if(LIBICSNEO_BUILD_C2_GPTP_EXAMPLE)
add_subdirectory(c2/gptp)
endif()
if(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE) if(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE)
add_subdirectory(cpp/simple) add_subdirectory(cpp/simple)
endif() endif()
@@ -165,3 +171,7 @@ endif()
if(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE) if(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE)
add_subdirectory(cpp/t1s) add_subdirectory(cpp/t1s)
endif() endif()
if(LIBICSNEO_BUILD_CPP_GPTP_EXAMPLE)
add_subdirectory(cpp/gptp)
endif()
+6
View File
@@ -0,0 +1,6 @@
add_executable(libicsneoc2-gptp-example src/main.c)
target_link_libraries(libicsneoc2-gptp-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-gptp-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
+330
View File
@@ -0,0 +1,330 @@
/*
* gPTP settings configurator example.
*
* Lists connected devices and their gPTP support, then lets the user
* configure the gPTP profile, role, port, and clock syntonization on any
* device that supports it. If --serial is omitted, the first available
* gPTP-capable device is used.
*/
#include <icsneo/icsneoc2.h>
#include <icsneo/icsneoc2settings.h>
#include <icsneo/icsneoc2messages.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
const char* serial;
bool list;
} args_t;
/* Maps an icsneoc2_netid_t to its gPTP port index (0 = not a gPTP port). */
static uint8_t netid_to_gptp_port(icsneoc2_netid_t netid) {
switch(netid) {
case icsneoc2_netid_ae_01: return 1;
case icsneoc2_netid_ae_02: return 2;
case icsneoc2_netid_ae_03: return 3;
case icsneoc2_netid_ae_04: return 4;
case icsneoc2_netid_ae_05: return 5;
case icsneoc2_netid_ae_06: return 6;
case icsneoc2_netid_ae_07: return 7;
case icsneoc2_netid_ae_08: return 8;
case icsneoc2_netid_ae_09: return 9;
case icsneoc2_netid_ae_10: return 10;
case icsneoc2_netid_ae_11: return 11;
case icsneoc2_netid_ae_12: return 12;
case icsneoc2_netid_ethernet_01: return 13;
case icsneoc2_netid_ethernet_02: return 14;
case icsneoc2_netid_ethernet_03: return 15;
case icsneoc2_netid_ae_13: return 16;
case icsneoc2_netid_ae_14: return 17;
case icsneoc2_netid_ae_15: return 18;
case icsneoc2_netid_ae_16: return 19;
default: return 0;
}
}
static const char* gptp_profile_str(icsneoc2_gptp_profile_t p) {
switch(p) {
case icsneoc2_gptp_profile_standard: return "Standard";
case icsneoc2_gptp_profile_automotive: return "Automotive";
default: return "Unknown";
}
}
static const char* gptp_role_str(icsneoc2_gptp_role_t r) {
switch(r) {
case icsneoc2_gptp_role_disabled: return "Disabled";
case icsneoc2_gptp_role_passive: return "Passive";
case icsneoc2_gptp_role_master: return "Master";
case icsneoc2_gptp_role_slave: return "Slave";
default: return "Unknown";
}
}
static int print_error_code(const char* message, icsneoc2_error_t error) {
char error_str[64] = {0};
size_t error_str_len = sizeof(error_str);
icsneoc2_error_t res = icsneoc2_error_code_get(error, error_str, &error_str_len);
if(res != icsneoc2_error_success) {
fprintf(stderr, "%s: failed to get string for error code %u\n", message, error);
return (int)res;
}
fprintf(stderr, "%s: \"%s\" (%u)\n", message, error_str, error);
return (int)error;
}
static void print_usage(const char* prog) {
printf("Usage:\n");
printf(" %s --list\n", prog);
printf(" %s [--serial SERIAL]\n", prog);
printf("\n");
printf(" --list List connected devices and their gPTP support.\n");
printf(" --serial SERIAL Serial number of the device to configure.\n");
printf(" -h, --help Show this message.\n");
}
static int parse_args(int argc, char** argv, args_t* out) {
memset(out, 0, sizeof(*out));
for(int i = 1; i < argc; ++i) {
const char* a = argv[i];
if(strcmp(a, "-h") == 0 || strcmp(a, "--help") == 0) {
print_usage(argv[0]);
exit(0);
} else if(strcmp(a, "--list") == 0) {
out->list = true;
} else if(strcmp(a, "--serial") == 0) {
if(i + 1 >= argc) {
fprintf(stderr, "error: --serial requires a value\n");
return 1;
}
out->serial = argv[++i];
} else {
fprintf(stderr, "error: unknown argument '%s'\n", a);
print_usage(argv[0]);
return 1;
}
}
return 0;
}
static icsneoc2_device_info_t* find_device(icsneoc2_device_info_t* list, const char* serial) {
for(icsneoc2_device_info_t* cur = list; cur != NULL; cur = icsneoc2_device_info_next(cur)) {
if(serial == NULL)
return cur;
char dev_serial[64] = {0};
size_t dev_serial_len = sizeof(dev_serial);
if(icsneoc2_device_info_serial_get(cur, dev_serial, &dev_serial_len) != icsneoc2_error_success)
continue;
if(strcmp(dev_serial, serial) == 0)
return cur;
}
return NULL;
}
/*
* Print a list of available Ethernet/AE networks with their gPTP port indices.
* Returns the number of ports printed.
*/
static size_t print_gptp_ports(icsneoc2_device_t* device) {
icsneoc2_netid_t nets[128] = {0};
size_t count = sizeof(nets) / sizeof(nets[0]);
if(icsneoc2_device_supported_tx_networks_get(device, nets, &count) != icsneoc2_error_success)
return 0;
size_t printed = 0;
for(size_t i = 0; i < count; ++i) {
uint8_t port = netid_to_gptp_port(nets[i]);
if(port == 0)
continue;
char name[64] = {0};
size_t name_len = sizeof(name);
icsneoc2_netid_name_get(nets[i], name, &name_len);
printf(" [%u] %s\n", (unsigned)port, name);
++printed;
}
return printed;
}
static int list_devices(icsneoc2_device_info_t* list) {
size_t index = 0;
for(icsneoc2_device_info_t* cur = list; cur != NULL; cur = icsneoc2_device_info_next(cur)) {
char serial[64] = {0};
size_t serial_len = sizeof(serial);
char description[256] = {0};
size_t description_len = sizeof(description);
icsneoc2_device_info_serial_get(cur, serial, &serial_len);
icsneoc2_device_info_description_get(cur, description, &description_len);
printf("[%zu] %s (%s)\n", index++, description, serial);
icsneoc2_device_t* device = NULL;
if(icsneoc2_device_create(cur, &device) != icsneoc2_error_success)
continue;
icsneoc2_open_options_t opts = icsneoc2_open_options_default;
opts &= ~ICSNEOC2_OPEN_OPTIONS_SYNC_RTC;
opts &= ~ICSNEOC2_OPEN_OPTIONS_GO_ONLINE;
if(icsneoc2_device_open(device, opts) != icsneoc2_error_success) {
icsneoc2_device_free(device);
continue;
}
bool supported = false;
icsneoc2_device_supports_gptp(device, &supported);
printf(" gPTP supported: %s\n", supported ? "yes" : "no");
if(supported) {
printf(" gPTP ports:\n");
print_gptp_ports(device);
}
icsneoc2_device_close(device);
icsneoc2_device_free(device);
}
return 0;
}
static void print_current_settings(icsneoc2_device_t* device) {
icsneoc2_gptp_profile_t profile = icsneoc2_gptp_profile_standard;
icsneoc2_gptp_role_t role = icsneoc2_gptp_role_disabled;
uint8_t port = 0;
bool clock_syntonization = false;
printf("\nCurrent gPTP settings:\n");
if(icsneoc2_settings_gptp_profile_get(device, &profile) == icsneoc2_error_success)
printf(" Profile: %s\n", gptp_profile_str(profile));
if(icsneoc2_settings_gptp_role_get(device, &role) == icsneoc2_error_success)
printf(" Role: %s\n", gptp_role_str(role));
if(icsneoc2_settings_gptp_enabled_port_get(device, &port) == icsneoc2_error_success)
printf(" Enabled port: %u%s\n", (unsigned)port, port == 0 ? " (disabled)" : "");
if(icsneoc2_settings_gptp_clock_syntonization_enabled_get(device, &clock_syntonization) == icsneoc2_error_success)
printf(" Clock syntonization: %s\n", clock_syntonization ? "enabled" : "disabled");
}
static long prompt_long(const char* prompt, long default_val, long min, long max) {
char buf[32] = {0};
printf("%s [%ld]: ", prompt, default_val);
fflush(stdout);
if(fgets(buf, sizeof(buf), stdin) == NULL || buf[0] == '\n')
return default_val;
char* end = NULL;
long val = strtol(buf, &end, 10);
if(end == buf || val < min || val > max) {
printf("Invalid input, using %ld.\n", default_val);
return default_val;
}
return val;
}
static int configure_device(icsneoc2_device_t* device) {
icsneoc2_error_t res;
res = icsneoc2_settings_refresh(device);
if(res != icsneoc2_error_success)
return print_error_code("Failed to refresh settings", res);
print_current_settings(device);
printf("\nAvailable gPTP ports (0 = disabled):\n");
printf(" [0] Disabled\n");
print_gptp_ports(device);
printf("\nConfigure gPTP:\n");
long profile = prompt_long(" Profile (0=Standard, 1=Automotive)", 1, 0, 1);
res = icsneoc2_settings_gptp_profile_set(device, (icsneoc2_gptp_profile_t)profile);
if(res != icsneoc2_error_success)
return print_error_code("Failed to set profile", res);
long role = prompt_long(" Role (0=Disabled, 1=Passive, 2=Master, 3=Slave)", 3, 0, 3);
res = icsneoc2_settings_gptp_role_set(device, (icsneoc2_gptp_role_t)role);
if(res != icsneoc2_error_success)
return print_error_code("Failed to set role", res);
long port = prompt_long(" Enabled port index", 0, 0, 19);
res = icsneoc2_settings_gptp_enabled_port_set(device, (uint8_t)port);
if(res != icsneoc2_error_success)
return print_error_code("Failed to set enabled port", res);
long syntonization = prompt_long(" Clock syntonization (0=disabled, 1=enabled)", 0, 0, 1);
res = icsneoc2_settings_gptp_clock_syntonization_enabled_set(device, syntonization != 0);
if(res != icsneoc2_error_success)
return print_error_code("Failed to set clock syntonization", res);
printf("\nNote: icsneoc2_settings_apply() persists settings on the device.\n");
res = icsneoc2_settings_apply(device);
if(res != icsneoc2_error_success)
return print_error_code("Failed to apply settings", res);
printf("\nUpdated gPTP settings:\n");
print_current_settings(device);
return 0;
}
int main(int argc, char** argv) {
args_t args;
if(parse_args(argc, argv, &args) != 0)
return 1;
icsneoc2_device_info_t* found_devices = NULL;
icsneoc2_error_t res = icsneoc2_device_enumerate(0, &found_devices);
if(res != icsneoc2_error_success)
return print_error_code("Failed to enumerate devices", res);
if(found_devices == NULL) {
fprintf(stderr, "error: no devices found\n");
return 1;
}
if(args.list) {
int rc = list_devices(found_devices);
icsneoc2_enumeration_free(found_devices);
return rc;
}
icsneoc2_device_info_t* info = find_device(found_devices, args.serial);
if(info == NULL) {
fprintf(stderr, "error: unable to find device %s\n", args.serial ? args.serial : "(any)");
icsneoc2_enumeration_free(found_devices);
return 1;
}
char description[256] = {0};
size_t description_len = sizeof(description);
icsneoc2_device_info_description_get(info, description, &description_len);
icsneoc2_device_t* device = NULL;
res = icsneoc2_device_create(info, &device);
if(res != icsneoc2_error_success) {
icsneoc2_enumeration_free(found_devices);
return print_error_code("Failed to create device", res);
}
printf("Opening %s\n", description);
res = icsneoc2_device_open(device, icsneoc2_open_options_default);
if(res != icsneoc2_error_success) {
icsneoc2_device_free(device);
icsneoc2_enumeration_free(found_devices);
return print_error_code("Failed to open device", res);
}
bool supported = false;
icsneoc2_device_supports_gptp(device, &supported);
if(!supported) {
fprintf(stderr, "error: device does not support gPTP (%s)\n", description);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
icsneoc2_enumeration_free(found_devices);
return 1;
}
int rc = configure_device(device);
printf("Closing %s\n", description);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
icsneoc2_enumeration_free(found_devices);
return rc;
}
+2
View File
@@ -0,0 +1,2 @@
add_executable(libicsneocpp-gptp-settings src/GPTPSettingsExample.cpp)
target_link_libraries(libicsneocpp-gptp-settings icsneocpp)
@@ -0,0 +1,179 @@
#include <iostream>
#include <iomanip>
#include <vector>
#include <optional>
#include <string>
#include <limits>
#include "icsneo/icsneocpp.h"
/* Maps a Network::NetID to its gPTP port index (0 = not a gPTP port). */
static uint8_t netidToGPTPPort(icsneo::Network::NetID netid) {
using N = icsneo::Network::NetID;
switch(netid) {
case N::AE_01: return 1;
case N::AE_02: return 2;
case N::AE_03: return 3;
case N::AE_04: return 4;
case N::AE_05: return 5;
case N::AE_06: return 6;
case N::AE_07: return 7;
case N::AE_08: return 8;
case N::AE_09: return 9;
case N::AE_10: return 10;
case N::AE_11: return 11;
case N::AE_12: return 12;
case N::ETHERNET_01: return 13;
case N::ETHERNET_02: return 14;
case N::ETHERNET_03: return 15;
case N::AE_13: return 16;
case N::AE_14: return 17;
case N::AE_15: return 18;
case N::AE_16: return 19;
default: return 0;
}
}
static std::string gptpProfileStr(RADGPTPProfile p) {
switch(p) {
case RAD_GPTP_PROFILE_STANDARD: return "Standard";
case RAD_GPTP_PROFILE_AUTOMOTIVE: return "Automotive";
default: return "Unknown";
}
}
static std::string gptpRoleStr(RADGPTPRole r) {
switch(r) {
case RAD_GPTP_ROLE_DISABLED: return "Disabled";
case RAD_GPTP_ROLE_PASSIVE: return "Passive";
case RAD_GPTP_ROLE_MASTER: return "Master";
case RAD_GPTP_ROLE_SLAVE: return "Slave";
default: return "Unknown";
}
}
template<typename T>
static std::string optStr(const std::optional<T>& opt) {
if(!opt.has_value()) return "N/A";
if constexpr(std::is_same_v<T, bool>)
return opt.value() ? "enabled" : "disabled";
else
return std::to_string(static_cast<int>(opt.value()));
}
static long promptLong(const std::string& prompt, long defaultVal, long min, long max) {
std::cout << prompt << " [" << defaultVal << "]: " << std::flush;
std::string input;
std::getline(std::cin, input);
if(input.empty())
return defaultVal;
try {
long val = std::stol(input);
if(val >= min && val <= max)
return val;
} catch(...) {}
std::cout << "Invalid input, using " << defaultVal << ".\n";
return defaultVal;
}
static void printGPTPPorts(const std::shared_ptr<icsneo::Device>& device) {
for(const auto& net : device->getSupportedTXNetworks()) {
uint8_t port = netidToGPTPPort(net.getNetID());
if(port == 0) continue;
std::cout << " [" << (int)port << "] " << net << "\n";
}
}
static void printCurrentSettings(const std::shared_ptr<icsneo::Device>& device) {
std::cout << "\nCurrent gPTP settings:\n";
auto profile = device->settings->getGPTPProfile();
auto role = device->settings->getGPTPRole();
auto port = device->settings->getGPTPEnabledPort();
auto synton = device->settings->isGPTPClockSyntonizationEnabled();
if(profile.has_value())
std::cout << " Profile: " << gptpProfileStr(profile.value()) << "\n";
if(role.has_value())
std::cout << " Role: " << gptpRoleStr(role.value()) << "\n";
if(port.has_value())
std::cout << " Enabled port: " << (int)port.value() << (port.value() == 0 ? " (disabled)" : "") << "\n";
if(synton.has_value())
std::cout << " Clock syntonization: " << optStr(synton) << "\n";
}
int main() {
std::cout << "Finding devices... " << std::flush;
auto devices = icsneo::FindAllDevices();
std::cout << devices.size() << " found\n";
if(devices.empty()) {
auto err = icsneo::GetLastError();
if(err.getType() != icsneo::APIEvent::Type::NoErrorFound)
std::cout << err << "\n";
return 1;
}
std::vector<std::shared_ptr<icsneo::Device>> gptp_devices;
for(auto& d : devices) {
if(d->supportsGPTP())
gptp_devices.push_back(d);
}
if(gptp_devices.empty()) {
std::cout << "No gPTP-capable devices found.\n";
return 1;
}
std::cout << "\nAvailable gPTP-capable devices:\n";
for(size_t i = 0; i < gptp_devices.size(); ++i)
std::cout << " [" << (i + 1) << "] " << gptp_devices[i]->describe() << "\n";
long choice = promptLong("Select device", 1, 1, (long)gptp_devices.size());
auto device = gptp_devices[choice - 1];
std::cout << "\nOpening " << device->describe() << "... " << std::flush;
if(!device->open()) {
std::cout << "failed\n" << icsneo::GetLastError() << "\n";
return 1;
}
std::cout << "OK\n";
if(!device->settings->refresh()) {
std::cout << "Failed to refresh settings\n";
device->close();
return 1;
}
printCurrentSettings(device);
std::cout << "\nAvailable gPTP ports (0 = disabled):\n";
std::cout << " [0] Disabled\n";
printGPTPPorts(device);
std::cout << "\nConfigure gPTP:\n";
long profile = promptLong(" Profile (0=Standard, 1=Automotive)", 1, 0, 1);
device->settings->setGPTPProfile(static_cast<RADGPTPProfile>(profile));
long role = promptLong(" Role (0=Disabled, 1=Passive, 2=Master, 3=Slave)", 3, 0, 3);
device->settings->setGPTPRole(static_cast<RADGPTPRole>(role));
long port = promptLong(" Enabled port index", 0, 0, 19);
device->settings->setGPTPEnabledPort(static_cast<uint8_t>(port));
long syntonization = promptLong(" Clock syntonization (0=disabled, 1=enabled)", 0, 0, 1);
device->settings->setGPTPClockSyntonizationEnabled(syntonization != 0);
long permanent = promptLong("\nSave to EEPROM? (0=temporary, 1=permanent)", 0, 0, 1);
if(!device->settings->apply(permanent == 0)) {
std::cout << "Failed to apply settings\n" << icsneo::GetLastError() << "\n";
device->close();
return 1;
}
printCurrentSettings(device);
std::cout << "\nClosing " << device->describe() << "\n";
device->close();
return 0;
}
+51
View File
@@ -0,0 +1,51 @@
import icsneopy
import time
#
# App errors are responses from the device indicating internal runtime errors
# NOTE: To trigger the app error in this example, disable the DW CAN 01 network on the device
# (e.g. with ICS Device Manager)
#
def apperror():
devices = icsneopy.find_all_devices()
if len(devices) == 0:
print("no devices found")
return False
device = devices[0]
print(f"selected {device}")
def on_apperror(message):
if message.get_app_error_type() != icsneopy.AppErrorType.NetworkNotEnabled:
print("unexpected app error type")
return
print(message.get_app_error_string())
filter = icsneopy.MessageFilter(icsneopy.Message.Type.AppError)
callback = icsneopy.MessageCallback(on_apperror, filter)
device.add_message_callback(callback)
if not device.open():
print("unable to open device")
return False
if not device.go_online():
print("unable to go online")
return False
frame = icsneopy.CANMessage()
frame.network = icsneopy.Network(icsneopy.Network.NetID.DWCAN_01)
frame.arbid = 0x22
frame.data = (0xAA, 0xBB, 0xCC)
if not device.transmit(frame):
print("failed to transmit frame")
return False
time.sleep(2) # wait for error to come back
return True
if __name__ == "__main__":
apperror()
+151
View File
@@ -0,0 +1,151 @@
import icsneopy
GPTP_PORT_MAP = {
icsneopy.Network.NetID.AE_01: (1, "AE 01"),
icsneopy.Network.NetID.AE_02: (2, "AE 02"),
icsneopy.Network.NetID.AE_03: (3, "AE 03"),
icsneopy.Network.NetID.AE_04: (4, "AE 04"),
icsneopy.Network.NetID.AE_05: (5, "AE 05"),
icsneopy.Network.NetID.AE_06: (6, "AE 06"),
icsneopy.Network.NetID.AE_07: (7, "AE 07"),
icsneopy.Network.NetID.AE_08: (8, "AE 08"),
icsneopy.Network.NetID.AE_09: (9, "AE 09"),
icsneopy.Network.NetID.AE_10: (10, "AE 10"),
icsneopy.Network.NetID.AE_11: (11, "AE 11"),
icsneopy.Network.NetID.AE_12: (12, "AE 12"),
icsneopy.Network.NetID.ETHERNET_01: (13, "Ethernet 01"),
icsneopy.Network.NetID.ETHERNET_02: (14, "Ethernet 02"),
icsneopy.Network.NetID.ETHERNET_03: (15, "Ethernet 03"),
icsneopy.Network.NetID.AE_13: (16, "AE 13"),
icsneopy.Network.NetID.AE_14: (17, "AE 14"),
icsneopy.Network.NetID.AE_15: (18, "AE 15"),
icsneopy.Network.NetID.AE_16: (19, "AE 16"),
}
PROFILE_NAMES = {
icsneopy.Settings.GTPPProfile.Standard: "Standard",
icsneopy.Settings.GTPPProfile.Automotive: "Automotive",
}
ROLE_NAMES = {
icsneopy.Settings.GTPPRole.Disabled: "Disabled",
icsneopy.Settings.GTPPRole.Passive: "Passive",
icsneopy.Settings.GTPPRole.Master: "Master",
icsneopy.Settings.GTPPRole.Slave: "Slave",
}
def prompt_int(prompt, default, lo, hi):
try:
raw = input(f"{prompt} [{default}]: ").strip()
if not raw:
return default
val = int(raw)
if lo <= val <= hi:
return val
except (ValueError, EOFError):
pass
print(f"Invalid input, using {default}.")
return default
def gptp_ports(device):
ports = []
for net in device.get_supported_tx_networks():
entry = GPTP_PORT_MAP.get(net.get_net_id())
if entry:
ports.append(entry)
return sorted(ports)
def print_settings(device):
s = device.settings
profile = s.get_gptp_profile()
role = s.get_gptp_role()
port = s.get_gptp_enabled_port()
synton = s.is_gptp_clock_syntonization_enabled()
print("\nCurrent gPTP settings:")
if profile is not None:
print(f" Profile: {PROFILE_NAMES.get(profile, profile)}")
if role is not None:
print(f" Role: {ROLE_NAMES.get(role, role)}")
if port is not None:
suffix = " (disabled)" if port == 0 else ""
print(f" Enabled port: {port}{suffix}")
if synton is not None:
print(f" Clock syntonization: {'enabled' if synton else 'disabled'}")
def configure(device):
if not device.settings.refresh():
print("error: failed to refresh settings")
return False
print_settings(device)
ports = gptp_ports(device)
print("\nAvailable gPTP ports (0 = disabled):")
print(" [0] Disabled")
for idx, name in ports:
print(f" [{idx}] {name}")
print("\nConfigure gPTP:")
profile = prompt_int(" Profile (0=Standard, 1=Automotive)", 1, 0, 1)
role = prompt_int(" Role (0=Disabled, 1=Passive, 2=Master, 3=Slave)", 3, 0, 3)
port = prompt_int(" Enabled port index", 0, 0, 19)
synton = prompt_int(" Clock syntonization (0=disabled, 1=enabled)", 0, 0, 1)
permanent = prompt_int("\nSave to EEPROM? (0=temporary, 1=permanent)", 0, 0, 1)
s = device.settings
profile_enum = list(PROFILE_NAMES.keys())[profile]
role_enum = list(ROLE_NAMES.keys())[role]
s.set_gptp_profile(profile_enum)
s.set_gptp_role(role_enum)
s.set_gptp_enabled_port(port)
s.set_gptp_clock_syntonization_enabled(bool(synton))
if not s.apply(not permanent):
print("error: failed to apply settings")
return False
print_settings(device)
return True
def main():
devices = icsneopy.find_all_devices()
if not devices:
print("error: no devices found")
return 1
gptp_devices = [d for d in devices if d.settings.get_gptp_profile() is not None]
if not gptp_devices:
print("error: no gPTP-capable devices found")
return 1
print("Available gPTP-capable devices:")
for i, d in enumerate(gptp_devices, 1):
print(f" [{i}] {d}")
choice = prompt_int("Select device", 1, 1, len(gptp_devices))
device = gptp_devices[choice - 1]
print(f"\nOpening {device}... ", end="", flush=True)
if not device.open():
print("failed")
return 1
print("OK")
try:
ok = configure(device)
finally:
print(f"\nClosing {device}")
device.close()
return 0 if ok else 1
if __name__ == "__main__":
raise SystemExit(main())
+7
View File
@@ -862,10 +862,17 @@ public:
virtual bool supportsGPTP() const { return false; } virtual bool supportsGPTP() const { return false; }
virtual bool supportsReboot() const { return false; }
bool requestTC10Wake(Network::NetID network); bool requestTC10Wake(Network::NetID network);
bool requestTC10Sleep(Network::NetID network); bool requestTC10Sleep(Network::NetID network);
// Reboot the device. When safe is true the device boots the Linux rescue image and does not
// load coremini ("safe boot"); otherwise it reboots normally. The device reboots in response,
// so no reply is expected. Only supported on devices where supportsReboot() is true.
bool reboot(bool safe = false);
std::optional<TC10StatusMessage> getTC10Status(Network::NetID network); std::optional<TC10StatusMessage> getTC10Status(Network::NetID network);
std::optional<GPTPStatus> getGPTPStatus(std::chrono::milliseconds timeout = std::chrono::milliseconds(100)); std::optional<GPTPStatus> getGPTPStatus(std::chrono::milliseconds timeout = std::chrono::milliseconds(100));
+61
View File
@@ -613,6 +613,18 @@ enum : uint8_t
RESISTOR_OFF RESISTOR_OFF
}; };
enum RADGPTPProfile : icsneoc2_gptp_profile_t {
RAD_GPTP_PROFILE_STANDARD = icsneoc2_gptp_profile_standard,
RAD_GPTP_PROFILE_AUTOMOTIVE = icsneoc2_gptp_profile_automotive,
};
enum RADGPTPRole : icsneoc2_gptp_role_t {
RAD_GPTP_ROLE_DISABLED = icsneoc2_gptp_role_disabled,
RAD_GPTP_ROLE_PASSIVE = icsneoc2_gptp_role_passive,
RAD_GPTP_ROLE_MASTER = icsneoc2_gptp_role_master,
RAD_GPTP_ROLE_SLAVE = icsneoc2_gptp_role_slave,
};
/* Mode in LIN_SETTINGS */ /* Mode in LIN_SETTINGS */
enum LINMode enum LINMode
{ {
@@ -761,6 +773,13 @@ enum class MiscIOAnalogVoltage : uint8_t
V5 = icsneoc2_misc_io_analog_voltage_v5 V5 = icsneoc2_misc_io_analog_voltage_v5
}; };
// Selects which Ethernet port(s) are reserved for the Linux configuration interface.
enum class LinuxConfigurationPort : icsneoc2_linux_configuration_port_t
{
USB = icsneoc2_linux_configuration_port_usb, // Linux configuration interface accessed over USB (default)
ETH01 = icsneoc2_linux_configuration_port_eth01 // ETH 01 reserved for Linux configuration
};
class IDeviceSettings { class IDeviceSettings {
public: public:
using TerminationGroup = std::vector<Network>; using TerminationGroup = std::vector<Network>;
@@ -1265,9 +1284,45 @@ public:
return false; return false;
} }
virtual std::optional<bool> isPerfTestEnabled() const {
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
virtual bool setPerfTestEnable(bool enable) {
(void)enable;
return false;
}
virtual bool setMiscIOAnalogOutputEnabled(uint8_t pin, bool enabled); virtual bool setMiscIOAnalogOutputEnabled(uint8_t pin, bool enabled);
virtual bool setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage voltage); virtual bool setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage voltage);
// gPTP methods
std::optional<RADGPTPProfile> getGPTPProfile() const;
bool setGPTPProfile(RADGPTPProfile profile);
std::optional<RADGPTPRole> getGPTPRole() const;
bool setGPTPRole(RADGPTPRole role);
std::optional<uint8_t> getGPTPEnabledPort() const;
bool setGPTPEnabledPort(uint8_t port);
std::optional<bool> isGPTPClockSyntonizationEnabled() const;
bool setGPTPClockSyntonizationEnabled(bool enable);
virtual const RAD_GPTP_SETTINGS* getGPTPSettings() const { return nullptr; }
virtual RAD_GPTP_SETTINGS* getMutableGPTPSettings() { return nullptr; }
/* Linux operating-system settings (Fire3 family devices) */
// Whether the device is allowed to boot its Linux operating system.
std::optional<bool> getLinuxBootEnabled();
bool setLinuxBootEnabled(bool enabled);
// Whether the external WiFi antenna is used (true) instead of the internal antenna (false).
std::optional<bool> getExternalWifiAntennaEnabled();
bool setExternalWifiAntennaEnabled(bool enabled);
// Which Ethernet port(s) are reserved for the Linux configuration interface.
std::optional<LinuxConfigurationPort> getLinuxConfigurationPort();
bool setLinuxConfigurationPort(LinuxConfigurationPort port);
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()); }
@@ -1300,6 +1355,12 @@ protected:
IDeviceSettings(warn_t createInoperableSettings, std::shared_ptr<Communication> com) IDeviceSettings(warn_t createInoperableSettings, std::shared_ptr<Communication> com)
: disabled(true), readonly(true), report(com->report), structSize(0) { (void)createInoperableSettings; } : disabled(true), readonly(true), report(com->report), structSize(0) { (void)createInoperableSettings; }
// Devices that embed a Fire3LinuxSettings block in their settings structure override these to
// expose it; all other devices report not-available (nullptr / nullopt) and the Linux accessors
// report not-available in turn.
virtual const Fire3LinuxSettings* getLinuxSettings() const { return nullptr; }
virtual std::optional<Fire3LinuxSettings*> getMutableLinuxSettings() { return std::nullopt; }
virtual ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const { return nullptr; } virtual ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const { return nullptr; }
virtual ICSNEO_UNALIGNED(uint64_t*) getMutableTerminationEnables() { virtual ICSNEO_UNALIGNED(uint64_t*) getMutableTerminationEnables() {
if(disabled || readonly) if(disabled || readonly)
@@ -81,6 +81,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<etherbadge_settings_t>(); auto cfg = getStructurePointer<etherbadge_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -92,6 +93,7 @@ public:
return nullptr; return nullptr;
} }
} }
const LIN_SETTINGS* getLINSettingsFor(Network net) const override { const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
auto cfg = getStructurePointer<etherbadge_settings_t>(); auto cfg = getStructurePointer<etherbadge_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -103,6 +105,23 @@ public:
return nullptr; return nullptr;
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<etherbadge_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<etherbadge_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
}; };
} }
@@ -34,6 +34,8 @@ public:
return supportedNetworks; return supportedNetworks;
} }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override { ProductID getProductID() const override {
return ProductID::Connect; return ProductID::Connect;
} }
@@ -89,6 +89,16 @@ static_assert(sizeof(neoviconnect_settings_t) == 628, "NeoVIConnect settings siz
class NeoVIConnectSettings : public IDeviceSettings { class NeoVIConnectSettings : public IDeviceSettings {
public: public:
NeoVIConnectSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neoviconnect_settings_t)) {} NeoVIConnectSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neoviconnect_settings_t)) {}
const Fire3LinuxSettings* getLinuxSettings() const override {
auto cfg = getStructurePointer<neoviconnect_settings_t>();
return cfg ? &cfg->os_settings : nullptr;
}
std::optional<Fire3LinuxSettings*> getMutableLinuxSettings() override {
auto cfg = getMutableStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return &cfg->os_settings;
}
const CAN_SETTINGS* getCANSettingsFor(Network net) const override { const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neoviconnect_settings_t>(); auto cfg = getStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -114,6 +124,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neoviconnect_settings_t>(); auto cfg = getStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -139,6 +150,7 @@ public:
return nullptr; return nullptr;
} }
} }
const LIN_SETTINGS* getLINSettingsFor(Network net) const override { const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neoviconnect_settings_t>(); auto cfg = getStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -152,6 +164,32 @@ public:
return nullptr; return nullptr;
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<neoviconnect_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<neoviconnect_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -121,6 +121,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override { return getCANSettingsFor(net); } const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override { return getCANSettingsFor(net); }
const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override { const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire_settings_t>(); auto cfg = getStructurePointer<neovifire_settings_t>();
@@ -133,6 +134,7 @@ public:
return nullptr; return nullptr;
} }
} }
const LIN_SETTINGS* getLINSettingsFor(Network net) const override { const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire_settings_t>(); auto cfg = getStructurePointer<neovifire_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -150,6 +152,23 @@ public:
return nullptr; return nullptr;
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<neovifire_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<neovifire_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
}; };
} }
@@ -155,6 +155,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire2_settings_t>(); auto cfg = getStructurePointer<neovifire2_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -180,6 +181,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override { return getCANSettingsFor(net); } const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override { return getCANSettingsFor(net); }
const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override { const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire2_settings_t>(); auto cfg = getStructurePointer<neovifire2_settings_t>();
@@ -234,6 +236,23 @@ public:
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<neovifire2_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<neovifire2_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
protected: protected:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override { ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovifire2_settings_t>(); auto cfg = getStructurePointer<neovifire2_settings_t>();
@@ -53,6 +53,8 @@ public:
} }
size_t getEthernetActivationLineCount() const override { return 2; } size_t getEthernetActivationLineCount() const override { return 2; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override { ProductID getProductID() const override {
return ProductID::neoVIFIRE3; return ProductID::neoVIFIRE3;
} }
@@ -167,6 +167,16 @@ static_assert(sizeof(neovifire3_settings_t) == 1722, "NeoVIFire3 settings size m
class NeoVIFIRE3Settings : public IDeviceSettings { class NeoVIFIRE3Settings : public IDeviceSettings {
public: public:
NeoVIFIRE3Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovifire3_settings_t)) {} NeoVIFIRE3Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovifire3_settings_t)) {}
const Fire3LinuxSettings* getLinuxSettings() const override {
auto cfg = getStructurePointer<neovifire3_settings_t>();
return cfg ? &cfg->os_settings : nullptr;
}
std::optional<Fire3LinuxSettings*> getMutableLinuxSettings() override {
auto cfg = getMutableStructurePointer<neovifire3_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return &cfg->os_settings;
}
const CAN_SETTINGS* getCANSettingsFor(Network net) const override { const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3_settings_t>(); auto cfg = getStructurePointer<neovifire3_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -208,6 +218,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3_settings_t>(); auto cfg = getStructurePointer<neovifire3_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -397,6 +408,23 @@ public:
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<neovifire3_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<neovifire3_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
protected: protected:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override { ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovifire3_settings_t>(); auto cfg = getStructurePointer<neovifire3_settings_t>();
@@ -404,6 +432,15 @@ protected:
return nullptr; return nullptr;
return &cfg->termination_enables; return &cfg->termination_enables;
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<neovifire3_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<neovifire3_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -55,6 +55,8 @@ public:
return supportedNetworks; return supportedNetworks;
} }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override { ProductID getProductID() const override {
return ProductID::neoVIFIRE3; return ProductID::neoVIFIRE3;
} }
@@ -150,6 +150,16 @@ static_assert(sizeof(neovifire3flexray_settings_t) == 1372, "NeoVIFire3Flexray s
class NeoVIFIRE3FlexRaySettings : public IDeviceSettings { class NeoVIFIRE3FlexRaySettings : public IDeviceSettings {
public: public:
NeoVIFIRE3FlexRaySettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovifire3flexray_settings_t)) {} NeoVIFIRE3FlexRaySettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovifire3flexray_settings_t)) {}
const Fire3LinuxSettings* getLinuxSettings() const override {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
return cfg ? &cfg->os_settings : nullptr;
}
std::optional<Fire3LinuxSettings*> getMutableLinuxSettings() override {
auto cfg = getMutableStructurePointer<neovifire3flexray_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return &cfg->os_settings;
}
const CAN_SETTINGS* getCANSettingsFor(Network net) const override { const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>(); auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -175,6 +185,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>(); auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -236,6 +247,23 @@ public:
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<neovifire3flexray_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
protected: protected:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override { ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>(); auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
@@ -243,6 +271,15 @@ protected:
return nullptr; return nullptr;
return &cfg->termination_enables; return &cfg->termination_enables;
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<neovifire3flexray_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -61,6 +61,8 @@ public:
bool supportsTC10() const override { return true; } bool supportsTC10() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override { ProductID getProductID() const override {
return ProductID::neoVIFIRE3; return ProductID::neoVIFIRE3;
} }
@@ -159,6 +159,16 @@ static_assert(sizeof(neovifire3t1slin_settings_t) == 1594, "NeoVIFire3T1SLIN set
class NeoVIFIRE3T1SLINSettings : public IDeviceSettings { class NeoVIFIRE3T1SLINSettings : public IDeviceSettings {
public: public:
NeoVIFIRE3T1SLINSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovifire3t1slin_settings_t)) {} NeoVIFIRE3T1SLINSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovifire3t1slin_settings_t)) {}
const Fire3LinuxSettings* getLinuxSettings() const override {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
return cfg ? &cfg->os_settings : nullptr;
}
std::optional<Fire3LinuxSettings*> getMutableLinuxSettings() override {
auto cfg = getMutableStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return &cfg->os_settings;
}
const CAN_SETTINGS* getCANSettingsFor(Network net) const override { const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>(); auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -184,6 +194,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>(); auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -466,6 +477,23 @@ public:
return true; return true;
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
private: private:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const { const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>(); auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
@@ -554,6 +582,15 @@ protected:
return nullptr; return nullptr;
return &cfg->termination_enables; return &cfg->termination_enables;
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<neovifire3t1slin_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -39,6 +39,8 @@ public:
bool supportsGPTP() const override { return true; } bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override { ProductID getProductID() const override {
return ProductID::neoVIFIRE3; return ProductID::neoVIFIRE3;
} }
@@ -112,6 +112,16 @@ static_assert(sizeof(neovired2_settings_t) == 918, "NeoVIRED2 settings size mism
class NeoVIRED2Settings : public IDeviceSettings { class NeoVIRED2Settings : public IDeviceSettings {
public: public:
NeoVIRED2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovired2_settings_t)) {} NeoVIRED2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovired2_settings_t)) {}
const Fire3LinuxSettings* getLinuxSettings() const override {
auto cfg = getStructurePointer<neovired2_settings_t>();
return cfg ? &cfg->os_settings : nullptr;
}
std::optional<Fire3LinuxSettings*> getMutableLinuxSettings() override {
auto cfg = getMutableStructurePointer<neovired2_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return &cfg->os_settings;
}
const CAN_SETTINGS* getCANSettingsFor(Network net) const override { const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovired2_settings_t>(); auto cfg = getStructurePointer<neovired2_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -137,6 +147,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovired2_settings_t>(); auto cfg = getStructurePointer<neovired2_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -295,6 +306,23 @@ public:
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<neovired2_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<neovired2_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
protected: protected:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override { ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovired2_settings_t>(); auto cfg = getStructurePointer<neovired2_settings_t>();
@@ -302,6 +330,15 @@ protected:
return nullptr; return nullptr;
return &cfg->termination_enables; return &cfg->termination_enables;
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<neovired2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<neovired2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -114,6 +114,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<rada2b_settings_t>(); auto cfg = getStructurePointer<rada2b_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -241,6 +242,32 @@ public:
} }
static constexpr uint8_t a2bSettingsFlag16bit = 0x01; static constexpr uint8_t a2bSettingsFlag16bit = 0x01;
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<rada2b_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<rada2b_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<rada2b_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<rada2b_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -103,6 +103,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radcomet2_settings_t>(); auto cfg = getStructurePointer<radcomet2_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -244,6 +245,23 @@ public:
return true; return true;
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radcomet2_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radcomet2_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
private: private:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const { const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radcomet2_settings_t>(); auto cfg = getStructurePointer<radcomet2_settings_t>();
@@ -272,6 +290,15 @@ private:
return nullptr; return nullptr;
} }
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radcomet2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radcomet2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -100,6 +100,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radcomet3_settings_t>(); auto cfg = getStructurePointer<radcomet3_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -638,6 +639,23 @@ public:
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radcomet3_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radcomet3_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
private: private:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const { const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radcomet3_settings_t>(); auto cfg = getStructurePointer<radcomet3_settings_t>();
@@ -710,6 +728,15 @@ private:
return nullptr; return nullptr;
} }
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radcomet3_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radcomet3_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -100,6 +100,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radepsilon_settings_t>(); auto cfg = getStructurePointer<radepsilon_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -269,6 +270,23 @@ public:
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radepsilon_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radepsilon_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
private: private:
enum class EpsilonPhyMode : uint8_t { enum class EpsilonPhyMode : uint8_t {
Auto = 0, Auto = 0,
@@ -135,6 +135,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radgalaxy_settings_t>(); auto cfg = getStructurePointer<radgalaxy_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -160,6 +161,7 @@ public:
return nullptr; return nullptr;
} }
} }
const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override { const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radgalaxy_settings_t>(); auto cfg = getStructurePointer<radgalaxy_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -271,6 +273,32 @@ public:
return true; return true;
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radgalaxy_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radgalaxy_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radgalaxy_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radgalaxy_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -151,6 +151,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radgalaxy2_settings_t>(); auto cfg = getStructurePointer<radgalaxy2_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -259,6 +260,32 @@ public:
return GetNetworkEnabled(bitfields, 2, networkID); return GetNetworkEnabled(bitfields, 2, networkID);
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radgalaxy2_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radgalaxy2_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radgalaxy2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radgalaxy2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -129,6 +129,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radgigastar_settings_t>(); auto cfg = getStructurePointer<radgigastar_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -178,6 +179,23 @@ public:
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radgigastar_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radgigastar_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
protected: protected:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override { ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<radgigastar_settings_t>(); auto cfg = getStructurePointer<radgigastar_settings_t>();
@@ -185,6 +203,15 @@ protected:
return nullptr; return nullptr;
return &cfg->termination_enables; return &cfg->termination_enables;
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radgigastar_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radgigastar_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
typedef struct { typedef struct {
@@ -217,7 +217,7 @@ public:
protected: protected:
RADGigastar2(neodevice_t neodevice, const driver_factory_t &makeDriver) : Device(neodevice) RADGigastar2(neodevice_t neodevice, const driver_factory_t &makeDriver) : Device(neodevice)
{ {
initialize<RADGigastar2Settings>(makeDriver); initialize<RADGigastar2Settings, Disk::ExtExtractorDiskReadDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
} }
void setupPacketizer(Packetizer &packetizer) override void setupPacketizer(Packetizer &packetizer) override
@@ -176,6 +176,7 @@ namespace icsneo
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS *getCANFDSettingsFor(Network net) const override const CANFD_SETTINGS *getCANFDSettingsFor(Network net) const override
{ {
auto cfg = getStructurePointer<radgigastar2_settings_t>(); auto cfg = getStructurePointer<radgigastar2_settings_t>();
@@ -537,6 +538,23 @@ namespace icsneo
return true; return true;
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radgigastar2_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radgigastar2_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
private: private:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const { const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radgigastar2_settings_t>(); auto cfg = getStructurePointer<radgigastar2_settings_t>();
@@ -627,6 +645,14 @@ namespace icsneo
return nullptr; return nullptr;
return &cfg->termination_enables; return &cfg->termination_enables;
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radgigastar2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radgigastar2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
typedef struct typedef struct
@@ -105,6 +105,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radjupiter_settings_t>(); auto cfg = getStructurePointer<radjupiter_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -118,6 +119,7 @@ public:
return nullptr; return nullptr;
} }
} }
const LIN_SETTINGS* getLINSettingsFor(Network net) const override { const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radjupiter_settings_t>(); auto cfg = getStructurePointer<radjupiter_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -129,6 +131,23 @@ public:
return nullptr; return nullptr;
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radjupiter_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radjupiter_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
}; };
} }
@@ -43,6 +43,15 @@ static_assert(sizeof(radmoon2_settings_t) == 170, "RADMoon2 settings size mismat
class RADMoon2Settings : public IDeviceSettings { class RADMoon2Settings : public IDeviceSettings {
public: public:
RADMoon2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radmoon2_settings_t)) {} RADMoon2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radmoon2_settings_t)) {}
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radmoon2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radmoon2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -154,6 +154,23 @@ public:
return true; return true;
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
private: private:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const { const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radmoont1s_settings_t>(); auto cfg = getStructurePointer<radmoont1s_settings_t>();
@@ -363,6 +380,15 @@ private:
cfg->t1sExt.multi_id[index] = id; cfg->t1sExt.multi_id[index] = id;
return true; return true;
} }
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radmoont1s_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -90,6 +90,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radpluto_settings_t>(); auto cfg = getStructurePointer<radpluto_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -115,6 +116,23 @@ public:
return nullptr; return nullptr;
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radpluto_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radpluto_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
}; };
} }
@@ -35,6 +35,21 @@ public:
ProductID getProductID() const override { ProductID getProductID() const override {
return ProductID::RADStar2; return ProductID::RADStar2;
} }
const std::vector<ChipInfo>& getChipInfo() const override {
static std::vector<ChipInfo> chips = {
{ChipID::RADStar2_ZYNQ, true, "ZCHIP", "RADStar2_SW_bin", 0, FirmwareType::Zip}
};
return chips;
}
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADStar2_ZYNQ, BootloaderCommunication::RAD, false)
.add<EnterApplicationPhase>(ChipID::RADStar2_ZYNQ)
.add<WaitPhase>(std::chrono::milliseconds(3000));
}
protected: protected:
RADStar2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { RADStar2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<RADStar2Settings>(makeDriver); initialize<RADStar2Settings>(makeDriver);
@@ -91,6 +91,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radstar2_settings_t>(); auto cfg = getStructurePointer<radstar2_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -116,6 +117,32 @@ public:
return nullptr; return nullptr;
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<radstar2_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<radstar2_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
auto cfg = getStructurePointer<radstar2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
RAD_GPTP_SETTINGS* getMutableGPTPSettings() override {
auto cfg = getMutableStructurePointer<radstar2_settings_t>();
return cfg ? &cfg->gPTP : nullptr;
}
}; };
} }
@@ -51,6 +51,23 @@ public:
return nullptr; return nullptr;
} }
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<valuecan3_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<valuecan3_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
}; };
} }
@@ -62,6 +62,7 @@ public:
return nullptr; return nullptr;
} }
} }
const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override { const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<vividcan_settings_t>(); auto cfg = getStructurePointer<vividcan_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -73,6 +74,7 @@ public:
return nullptr; return nullptr;
} }
} }
const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override { const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<vividcan_settings_t>(); auto cfg = getStructurePointer<vividcan_settings_t>();
if(cfg == nullptr) if(cfg == nullptr)
@@ -115,6 +117,23 @@ public:
return success; return success;
} }
std::optional<bool> isPerfTestEnabled() const override {
auto cfg = getStructurePointer<vividcan_settings_t>();
if(cfg == nullptr)
return std::nullopt;
return std::make_optional<bool>(cfg->perf_en != 0);
}
bool setPerfTestEnable(bool enable) override {
auto cfg = getMutableStructurePointer<vividcan_settings_t>();
if(cfg == nullptr)
return false;
cfg->perf_en = !!enable;
return true;
}
protected: protected:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override { ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
// Check the structure pointer even though we're not using it so // Check the structure pointer even though we're not using it so
+44
View File
@@ -581,6 +581,50 @@ icsneoc2_error_t icsneoc2_device_tc10_sleep_request(const icsneoc2_device_t* dev
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise. * @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/ */
icsneoc2_error_t icsneoc2_device_tc10_status_get(const icsneoc2_device_t* device, icsneoc2_netid_t netid, icsneoc2_tc10_sleep_status_t* sleep_status, icsneoc2_tc10_wake_status_t* wake_status); icsneoc2_error_t icsneoc2_device_tc10_status_get(const icsneoc2_device_t* device, icsneoc2_netid_t netid, icsneoc2_tc10_sleep_status_t* sleep_status, icsneoc2_tc10_wake_status_t* wake_status);
/**
* Check if the device supports gPTP.
*
* @param[in] device The device to check against.
* @param[out] supported Pointer to a bool to copy the value into.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_device_supports_gptp(const icsneoc2_device_t* device, bool* supported);
/**
* Get the current gPTP status from the device.
*
* @param[in] device The device to query.
* @param[in] timeout_ms Timeout in milliseconds to wait for the device response.
* @param[out] status Pointer to an icsneoc2_gptp_status_t to copy the status into.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_invalid_type otherwise.
*/
icsneoc2_error_t icsneoc2_device_gptp_status_get(const icsneoc2_device_t* device, uint32_t timeout_ms, icsneoc2_gptp_status_t* status);
/**
* Check if the device supports rebooting.
*
* @param[in] device The device to check against.
* @param[out] supported Pointer to a bool to copy the value into.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_device_supports_reboot(const icsneoc2_device_t* device, bool* supported);
/**
* Reboot the device. When safe is true the device boots the Linux rescue image and does not load
* coremini ("safe boot"); otherwise it reboots normally. The device reboots in response, so no reply
* is expected. Only supported on devices where icsneoc2_device_supports_reboot() reports true.
*
* @param[in] device The device to reboot.
* @param[in] safe true to reboot into safe boot mode, false to reboot normally.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_transmit_message_failed otherwise.
*/
icsneoc2_error_t icsneoc2_device_reboot(const icsneoc2_device_t* device, bool safe);
/** /**
* Get the current state of a digital I/O pin. * Get the current state of a digital I/O pin.
* *
+140
View File
@@ -656,6 +656,66 @@ icsneoc2_error_t icsneoc2_settings_misc_io_analog_output_enabled_set(icsneoc2_de
*/ */
icsneoc2_error_t icsneoc2_settings_misc_io_analog_output_set(icsneoc2_device_t* device, uint8_t pin, icsneoc2_misc_io_analog_voltage_t value); icsneoc2_error_t icsneoc2_settings_misc_io_analog_output_set(icsneoc2_device_t* device, uint8_t pin, icsneoc2_misc_io_analog_voltage_t value);
/**
* Get whether the device is allowed to boot its Linux operating system (Fire3 family devices).
*
* @param[in] device The device to query.
* @param[out] value Pointer to a bool to copy the value into.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_get_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_linux_boot_enabled_get(icsneoc2_device_t* device, bool* value);
/**
* Set whether the device is allowed to boot its Linux operating system (Fire3 family devices).
*
* @param[in] device The device to configure.
* @param[in] value true to allow Linux to boot, false to prevent it.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_linux_boot_enabled_set(icsneoc2_device_t* device, bool value);
/**
* Get whether the external WiFi antenna is used instead of the internal antenna (Fire3 family devices).
*
* @param[in] device The device to query.
* @param[out] value Pointer to a bool to copy the value into (true for external, false for internal).
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_get_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_external_wifi_antenna_enabled_get(icsneoc2_device_t* device, bool* value);
/**
* Set whether the external WiFi antenna is used instead of the internal antenna (Fire3 family devices).
*
* @param[in] device The device to configure.
* @param[in] value true to use the external antenna, false to use the internal antenna.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_external_wifi_antenna_enabled_set(icsneoc2_device_t* device, bool value);
/**
* Get which Ethernet port(s) are reserved for the Linux configuration interface (Fire3 family devices).
*
* @param[in] device The device to query.
* @param[out] value Pointer to a icsneoc2_linux_configuration_port_t to copy the value into.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_get_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_linux_configuration_port_get(icsneoc2_device_t* device, icsneoc2_linux_configuration_port_t* value);
/**
* Set which Ethernet port(s) are reserved for the Linux configuration interface (Fire3 family devices).
*
* @param[in] device The device to configure.
* @param[in] value The configuration port selection to set.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_linux_configuration_port_set(icsneoc2_device_t* device, icsneoc2_linux_configuration_port_t value);
/** /**
* Check if settings are disabled. * Check if settings are disabled.
* *
@@ -676,6 +736,86 @@ icsneoc2_error_t icsneoc2_settings_disabled_get(icsneoc2_device_t* device, bool*
*/ */
icsneoc2_error_t icsneoc2_settings_readonly_get(icsneoc2_device_t* device, bool* value); icsneoc2_error_t icsneoc2_settings_readonly_get(icsneoc2_device_t* device, bool* value);
/**
* Get the gPTP profile.
*
* @param[in] device The device to check.
* @param[out] value Pointer to store the gPTP profile.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_settings_gptp_profile_get(icsneoc2_device_t* device, icsneoc2_gptp_profile_t* value);
/**
* Set the gPTP profile.
*
* @param[in] device The device to configure.
* @param[in] value The gPTP profile to set.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_gptp_profile_set(icsneoc2_device_t* device, icsneoc2_gptp_profile_t value);
/**
* Get the gPTP port role.
*
* @param[in] device The device to check.
* @param[out] value Pointer to store the gPTP port role.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_settings_gptp_role_get(icsneoc2_device_t* device, icsneoc2_gptp_role_t* value);
/**
* Set the gPTP port role.
*
* @param[in] device The device to configure.
* @param[in] value The gPTP port role to set.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_gptp_role_set(icsneoc2_device_t* device, icsneoc2_gptp_role_t value);
/**
* Get the gPTP enabled port index. A value of 0 indicates gPTP is disabled.
*
* @param[in] device The device to check.
* @param[out] value Pointer to store the enabled port index.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_settings_gptp_enabled_port_get(icsneoc2_device_t* device, uint8_t* value);
/**
* Set the gPTP enabled port index. Set to 0 to disable gPTP.
*
* @param[in] device The device to configure.
* @param[in] value The port index to enable gPTP on, or 0 to disable.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_gptp_enabled_port_set(icsneoc2_device_t* device, uint8_t value);
/**
* Check if gPTP clock syntonization is enabled.
*
* @param[in] device The device to check.
* @param[out] value Pointer to store the clock syntonization enable state.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_settings_gptp_clock_syntonization_enabled_get(icsneoc2_device_t* device, bool* value);
/**
* Enable or disable gPTP clock syntonization.
*
* @param[in] device The device to configure.
* @param[in] value The clock syntonization enable state to set.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise.
*/
icsneoc2_error_t icsneoc2_settings_gptp_clock_syntonization_enabled_set(icsneoc2_device_t* device, bool value);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
+45
View File
@@ -352,6 +352,51 @@ typedef enum _icsneoc2_misc_io_analog_voltage_t {
typedef uint8_t icsneoc2_misc_io_analog_voltage_t; typedef uint8_t icsneoc2_misc_io_analog_voltage_t;
typedef enum _icsneoc2_gptp_profile_t {
icsneoc2_gptp_profile_standard = 0, // IEEE 802.1AS standard profile
icsneoc2_gptp_profile_automotive = 1, // Automotive gPTP profile
// Must be last entry. Don't use as a gPTP profile.
icsneoc2_gptp_profile_maxsize
} _icsneoc2_gptp_profile_t;
typedef uint8_t icsneoc2_gptp_profile_t;
typedef enum _icsneoc2_gptp_role_t {
icsneoc2_gptp_role_disabled = 0, // gPTP disabled on this port
icsneoc2_gptp_role_passive = 1, // Passive role
icsneoc2_gptp_role_master = 2, // Master role
icsneoc2_gptp_role_slave = 3, // Slave role
// Must be last entry. Don't use as a gPTP role.
icsneoc2_gptp_role_maxsize
} _icsneoc2_gptp_role_t;
typedef uint8_t icsneoc2_gptp_role_t;
typedef struct icsneoc2_gptp_status_t {
uint64_t current_time_seconds; // Current PTP time (seconds portion)
uint32_t current_time_nanoseconds; // Current PTP time (nanoseconds portion)
int64_t ms_offset_ns; // Master-slave clock offset in nanoseconds
uint8_t is_sync; // Non-zero if the clock is synchronized
uint8_t link_status; // Non-zero if the link is up
int64_t link_delay_ns; // One-way propagation delay in nanoseconds
uint8_t selected_role; // Negotiated port role (see icsneoc2_gptp_role_t)
uint8_t as_capable; // Non-zero if the port is AS-capable (802.1AS)
uint8_t is_syntonized; // Non-zero if frequency is locked to grandmaster
uint8_t short_format; // Non-zero if firmware returned a partial response
} icsneoc2_gptp_status_t;
typedef enum _icsneoc2_linux_configuration_port_t {
icsneoc2_linux_configuration_port_usb = 0, // Linux configuration interface accessed over USB (default)
icsneoc2_linux_configuration_port_eth01 = 1, // ETH 01 reserved for the Linux configuration interface
// Must be last entry. Don't use as a configuration port.
icsneoc2_linux_configuration_port_maxsize
} _icsneoc2_linux_configuration_port_t;
typedef uint32_t icsneoc2_linux_configuration_port_t;
typedef struct icsneoc2_disk_details_t icsneoc2_disk_details_t; typedef struct icsneoc2_disk_details_t icsneoc2_disk_details_t;
typedef enum _icsneoc2_disk_layout_t { typedef enum _icsneoc2_disk_layout_t {
+9 -1
View File
@@ -137,6 +137,9 @@ public:
if (::poll(&pfd, 1, static_cast<int>(timeout.count())) == -1) { if (::poll(&pfd, 1, static_cast<int>(timeout.count())) == -1) {
return false; return false;
} }
if (pfd.revents & (POLLHUP | POLLERR)) {
return false;
}
in = pfd.revents & POLLIN; in = pfd.revents & POLLIN;
return true; return true;
#endif #endif
@@ -155,7 +158,12 @@ public:
} }
bool send(const void* buffer, size_t size) { bool send(const void* buffer, size_t size) {
auto sent = ::send(mFD, (const char*)buffer, (int)size, 0); #ifdef _WIN32
int flags = 0;
#else
int flags = MSG_NOSIGNAL;
#endif
auto sent = ::send(mFD, (const char*)buffer, (int)size, flags);
if(sent == -1) { if(sent == -1) {
return false; return false;
} }
+3 -2
View File
@@ -108,8 +108,9 @@ void CDCACM::Find(std::vector<FoundDevice>& found) {
releasers.emplace_back(parent); releasers.emplace_back(parent);
current = parent; current = parent;
// On old macOSes, IOUSBDevice is the type of the class we want // On old macOSes, IOUSBDevice is the type of the class we want
// On newer macOSes, IOUSBDevice may further be subclassed as IOUSBHostDevice // On macOS 12+, IOUSBHostDevice is the main USB device class (separate hierarchy from IOUSBDevice)
if(IOObjectConformsTo(parent, kIOUSBDeviceClassName)) { if(IOObjectConformsTo(parent, kIOUSBDeviceClassName) ||
IOObjectConformsTo(parent, "IOUSBHostDevice")) {
usb = parent; usb = parent;
break; break;
} }
+4
View File
@@ -113,6 +113,10 @@ bool Servd::open() {
return false; return false;
} }
const auto tokens = split(response); const auto tokens = split(response);
if(tokens.size() == 1 && tokens[0] == "0") {
EventManager::GetInstance().add(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
return false;
}
if(tokens.size() != 2) { if(tokens.size() != 2) {
EventManager::GetInstance().add(APIEvent::Type::ServdInvalidResponseError, APIEvent::Severity::Error); EventManager::GetInstance().add(APIEvent::Type::ServdInvalidResponseError, APIEvent::Severity::Error);
return false; return false;
+50
View File
@@ -139,6 +139,7 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
icsneoc2_eth_phy_link_mode_t placeholderEthPhyLinkMode = 0; icsneoc2_eth_phy_link_mode_t placeholderEthPhyLinkMode = 0;
icsneoc2_eth_phy_link_mode_t* placeholderEthPhyLinkModePtr = nullptr; icsneoc2_eth_phy_link_mode_t* placeholderEthPhyLinkModePtr = nullptr;
icsneoc2_misc_io_analog_voltage_t placeholderMiscIoAnalogVoltage = 0; icsneoc2_misc_io_analog_voltage_t placeholderMiscIoAnalogVoltage = 0;
icsneoc2_linux_configuration_port_t placeholderLinuxConfigPort = 0;
// All of these don't have a device parameter // All of these don't have a device parameter
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_enumerate(0, NULL)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_enumerate(0, NULL));
@@ -227,6 +228,8 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_tc10_status_get(NULL, icsneoc2_netid_dwcan_01, &sleep_s, &wake_s)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_tc10_status_get(NULL, icsneoc2_netid_dwcan_01, &sleep_s, &wake_s));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_tc10_status_get(NULL, icsneoc2_netid_dwcan_01, NULL, NULL)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_tc10_status_get(NULL, icsneoc2_netid_dwcan_01, NULL, NULL));
} }
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_supports_reboot(NULL, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_reboot(NULL, false));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_netid_network_type_get(icsneoc2_netid_dwcan_01, NULL)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_netid_network_type_get(icsneoc2_netid_dwcan_01, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_timestamp_resolution_get(NULL, &placeholderInteger32)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_timestamp_resolution_get(NULL, &placeholderInteger32));
@@ -296,9 +299,31 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_t1s_multi_id_set(NULL, 0, 0, placeholderInteger8)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_t1s_multi_id_set(NULL, 0, 0, placeholderInteger8));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_misc_io_analog_output_enabled_set(NULL, 0, placeholderInteger8)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_misc_io_analog_output_enabled_set(NULL, 0, placeholderInteger8));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_misc_io_analog_output_set(NULL, 0, placeholderMiscIoAnalogVoltage)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_misc_io_analog_output_set(NULL, 0, placeholderMiscIoAnalogVoltage));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_linux_boot_enabled_get(NULL, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_linux_boot_enabled_set(NULL, false));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_external_wifi_antenna_enabled_get(NULL, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_external_wifi_antenna_enabled_set(NULL, false));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_linux_configuration_port_get(NULL, &placeholderLinuxConfigPort));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_linux_configuration_port_set(NULL, placeholderLinuxConfigPort));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_disabled_get(NULL, &placeholderBool)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_disabled_get(NULL, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_readonly_get(NULL, &placeholderBool)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_readonly_get(NULL, &placeholderBool));
// gPTP settings NULL parameter checks
icsneoc2_gptp_profile_t placeholderGptpProfile = 0;
icsneoc2_gptp_role_t placeholderGptpRole = 0;
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_profile_get(NULL, &placeholderGptpProfile));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_profile_get(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_profile_set(NULL, placeholderGptpProfile));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_role_get(NULL, &placeholderGptpRole));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_role_get(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_role_set(NULL, placeholderGptpRole));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_enabled_port_get(NULL, &placeholderInteger8));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_enabled_port_get(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_enabled_port_set(NULL, 0));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_clock_syntonization_enabled_get(NULL, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_clock_syntonization_enabled_get(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_gptp_clock_syntonization_enabled_set(NULL, false));
// Disk formatting functions // Disk formatting functions
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_disk_count_get(NULL, &placeholderSizeT)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_disk_count_get(NULL, &placeholderSizeT));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_supports_disk_formatting(NULL, &placeholderBool)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_supports_disk_formatting(NULL, &placeholderBool));
@@ -1763,4 +1788,29 @@ TEST(icsneoc2, test_icsneoc2_eth_invalid_type)
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_free(can_msg)); ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_free(can_msg));
} }
TEST(icsneoc2, test_gptp_enum_values)
{
ASSERT_EQ(icsneoc2_gptp_profile_standard, 0);
ASSERT_EQ(icsneoc2_gptp_profile_automotive, 1);
ASSERT_EQ(sizeof(icsneoc2_gptp_profile_t), sizeof(uint8_t));
ASSERT_EQ(icsneoc2_gptp_role_disabled, 0);
ASSERT_EQ(icsneoc2_gptp_role_passive, 1);
ASSERT_EQ(icsneoc2_gptp_role_master, 2);
ASSERT_EQ(icsneoc2_gptp_role_slave, 3);
ASSERT_EQ(sizeof(icsneoc2_gptp_role_t), sizeof(uint8_t));
}
TEST(icsneoc2, test_gptp_enum_alignment)
{
ASSERT_EQ(RADGPTPProfile::RAD_GPTP_PROFILE_STANDARD, icsneoc2_gptp_profile_standard);
ASSERT_EQ(RADGPTPProfile::RAD_GPTP_PROFILE_AUTOMOTIVE, icsneoc2_gptp_profile_automotive);
ASSERT_EQ(sizeof(RADGPTPProfile), sizeof(icsneoc2_gptp_profile_t));
ASSERT_EQ(RADGPTPRole::RAD_GPTP_ROLE_DISABLED, icsneoc2_gptp_role_disabled);
ASSERT_EQ(RADGPTPRole::RAD_GPTP_ROLE_PASSIVE, icsneoc2_gptp_role_passive);
ASSERT_EQ(RADGPTPRole::RAD_GPTP_ROLE_MASTER, icsneoc2_gptp_role_master);
ASSERT_EQ(RADGPTPRole::RAD_GPTP_ROLE_SLAVE, icsneoc2_gptp_role_slave);
ASSERT_EQ(sizeof(RADGPTPRole), sizeof(icsneoc2_gptp_role_t));
}