Compare commits

...

22 Commits

Author SHA1 Message Date
David Rebbe 8af6d5f2a8 FIRE3: Add reboot support 2026-06-19 17:58:49 -04:00
David Rebbe 54fb89b675 Settings: Add Linux options 2026-06-19 17:12:42 -04:00
Thomas Stoddard 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 Jones 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 Jones 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
Kyle Schwarz bb711ae7e2 Event: Store device as weak pointer 2026-06-02 17:19:23 -04:00
Kyle Schwarz 476b5ff35c FIRE3: Add MDIO_01 network 2026-06-02 13:19:56 -04:00
Jonathan Schwartz 99792a0ee1 Communication: Increase max packet length 2026-06-02 11:10:16 -04:00
Max Brombach d42c51d772 EventManager: Fix Event Manager being accessed after static destruction 2026-05-22 15:56:02 -04:00
Thomas Stoddard 3ab06199c3 Device: Add ExtendedCommand::GetAllMACAddresses 2026-05-22 11:40:44 -04:00
Max Brombach 49e578a657 Device: RAD-Comet and RAD-Comet 2: Replace all references to RAD-Comet with RAD-Comet2 2026-05-19 13:17:12 -04:00
Kyle Schwarz 0bf279c7b9 Build: Add WORKING_DIRECTORY to git commands 2026-05-15 14:55:17 -04:00
Kyle Schwarz 9de0cf688c Build: Parse CMake version from git 2026-05-14 23:16:20 -04:00
David Rebbe eded388b83 C2: Add message timestamp support 2026-05-14 22:16:41 -04:00
Kyle Schwarz 00b7b4a6de CI: Set ICSPB_BOOTSTRAP_DIR 2026-05-14 21:29:24 -04:00
Thomas Stoddard 0ecb360195 RADComet1: Deprecate and replace with RADComet2 2026-05-14 20:20:46 -04:00
David Rebbe b3bb033ecb C2: Add Supported Device Types" 2026-05-14 19:08:11 -04:00
David Rebbe c3762bbf22 C2: Add ChipVersions
Also fixes some formatting issues.
2026-05-14 13:39:39 -04:00
Thomas Stoddard e926e10dc5 RADGigastar2: Add to MACsecConfig 2026-05-14 11:29:54 -04:00
110 changed files with 3926 additions and 333 deletions

View File

@ -303,7 +303,8 @@ build python/linux/amd64:
CIBW_BEFORE_ALL: sh ci/bootstrap-cibuildwheel.sh && sh ci/bootstrap-libpcap.sh
CIBW_BUILD: "*manylinux*" # no musl
CIBW_ARCHS: x86_64
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install
CIBW_ENVIRONMENT: PCAP_ROOT=/project/libpcap/install
SKBUILD_CMAKE_DEFINE: ICSPB_BOOTSTRAP_DIR=/project/icspb
script:
- sh ci/build-wheel-posix.sh
artifacts:
@ -318,7 +319,8 @@ build python/linux/arm64:
CIBW_BEFORE_ALL: sh ci/bootstrap-cibuildwheel.sh && sh ci/bootstrap-libpcap.sh
CIBW_BUILD: "*manylinux*" # no musl
CIBW_ARCHS: aarch64
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install
CIBW_ENVIRONMENT: PCAP_ROOT=/project/libpcap/install
SKBUILD_CMAKE_DEFINE: ICSPB_BOOTSTRAP_DIR=/project/icspb
script:
- sh ci/build-wheel-posix.sh
artifacts:
@ -332,7 +334,8 @@ build python/macos:
variables:
CIBW_BEFORE_ALL: sh ci/bootstrap-libpcap.sh
CIBW_ARCHS: arm64
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=$CI_PROJECT_DIR/libpcap/install
CIBW_ENVIRONMENT: PCAP_ROOT=$CI_PROJECT_DIR/libpcap/install
SKBUILD_CMAKE_DEFINE: ICSPB_BOOTSTRAP_DIR=$CI_PROJECT_DIR/icspb
MACOSX_DEPLOYMENT_TARGET: 10.14
script:
- sh ci/build-wheel-posix.sh
@ -347,6 +350,7 @@ build python/windows:
variables:
CIBW_ARCHS: AMD64
CIBW_ENVIRONMENT: CMAKE_GENERATOR=Ninja
SKBUILD_CMAKE_DEFINE: ICSPB_BOOTSTRAP_DIR=$CI_PROJECT_DIR/icspb
script:
- cmd /c ci\build-wheel-windows.bat
artifacts:

View File

@ -1,5 +1,43 @@
cmake_minimum_required(VERSION 3.16)
project(libicsneo VERSION 1.0.0)
function(git_tag_version VERSION_RESULT)
set(${VERSION_RESULT} "0.0.0.0" PARENT_SCOPE)
find_package(Git)
if(NOT Git_FOUND)
return()
endif()
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE LAST_TAG
RESULT_VARIABLE RESULT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT RESULT EQUAL 0)
return()
endif()
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-list ${LAST_TAG}..HEAD --count
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE COMMIT_COUNT_SINCE_TAG
RESULT_VARIABLE RESULT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT RESULT EQUAL 0)
return()
endif()
set(${VERSION_RESULT} "${LAST_TAG}.${COMMIT_COUNT_SINCE_TAG}" PARENT_SCOPE)
endfunction()
git_tag_version(LIBICSNEO_VERSION)
if(LIBICSNEO_VERSION STREQUAL "0.0.0.0")
message(WARNING "Unable to parse version from git history")
endif()
project(libicsneo VERSION ${LIBICSNEO_VERSION})
cmake_policy(SET CMP0074 NEW)
if(POLICY CMP0135)
@ -192,6 +230,7 @@ set(SRC_FILES
communication/message/logdatamessage.cpp
communication/message/tc10statusmessage.cpp
communication/message/gptpstatusmessage.cpp
communication/message/allmacaddressesmessage.cpp
communication/message/ethernetstatusmessage.cpp
communication/message/networkmutexmessage.cpp
communication/message/clientidmessage.cpp

View File

@ -45,7 +45,6 @@ Instructions for installing each API can be found in its respective documentatio
- RAD-Pluto
- RAD-Star 2
- RAD-SuperMoon
- RADComet
- ValueCAN 3
- ValueCAN 4

View File

@ -12,8 +12,10 @@
#include <map>
#include <algorithm>
#include <optional>
#include <chrono>
#include <sstream>
#include <fstream>
#include <cstring>
using namespace icsneo;
@ -84,6 +86,61 @@ icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* valu
return safe_str_copy(value, value_length, error_strings[error_code]) ? icsneoc2_error_success : icsneoc2_error_string_copy_failed;
}
icsneoc2_error_t icsneoc2_supported_devices_enumerate(icsneoc2_supported_device_t** supported_devices) {
if(!supported_devices) {
return icsneoc2_error_invalid_parameters;
}
auto device_types = DeviceFinder::GetSupportedDevices();
icsneoc2_supported_device_t* head = nullptr;
icsneoc2_supported_device_t* tail = nullptr;
for(auto& device_type : device_types) {
auto* node = new (std::nothrow) icsneoc2_supported_device_t;
if(!node) {
return icsneoc2_error_out_of_memory;
}
node->device_type = device_type;
node->next = nullptr;
if(!head) {
head = node;
} else {
tail->next = node;
}
tail = node;
}
*supported_devices = head;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_supported_devices_free(icsneoc2_supported_device_t* supported_devices) {
if(!supported_devices) {
return icsneoc2_error_invalid_parameters;
}
while(supported_devices) {
auto* next = supported_devices->next;
delete supported_devices;
supported_devices = next;
}
return icsneoc2_error_success;
}
icsneoc2_supported_device_t* icsneoc2_supported_devices_next(const icsneoc2_supported_device_t* supported_device) {
if(!supported_device) {
return nullptr;
}
return supported_device->next;
}
icsneoc2_error_t icsneoc2_supported_device_get(const icsneoc2_supported_device_t* supported_device, icsneoc2_devicetype_t* device_type) {
if(!supported_device || !device_type) {
return icsneoc2_error_invalid_parameters;
}
*device_type = static_cast<icsneoc2_devicetype_t>(supported_device->device_type);
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_type_name_get(icsneoc2_devicetype_t device_type, char* value, size_t* value_length) {
if(!value || !value_length) {
return icsneoc2_error_invalid_parameters;
@ -251,12 +308,12 @@ icsneoc2_error_t icsneoc2_device_open_serial(const char* serial, icsneoc2_open_o
std::string_view target(serial);
for(auto* cur = devs; cur; cur = cur->next) {
if(cur->device && cur->device->getSerial() == target) {
if (res = icsneoc2_device_create(cur, device); res != icsneoc2_error_success) {
if(res = icsneoc2_device_create(cur, device); res != icsneoc2_error_success) {
icsneoc2_enumeration_free(devs);
return res;
}
res = open_device_with_options((*device)->device, options);
if (res != icsneoc2_error_success) {
if(res != icsneoc2_error_success) {
icsneoc2_device_free(*device);
*device = nullptr;
}
@ -279,12 +336,12 @@ icsneoc2_error_t icsneoc2_device_open_first(icsneoc2_devicetype_t device_type, i
}
for(auto* cur = devs; cur; cur = cur->next) {
if(cur->device && !cur->device->isOpen()) {
if (res = icsneoc2_device_create(cur, device); res != icsneoc2_error_success) {
if(res = icsneoc2_device_create(cur, device); res != icsneoc2_error_success) {
icsneoc2_enumeration_free(devs);
return res;
}
res = open_device_with_options((*device)->device, options);
if (res != icsneoc2_error_success) {
if(res != icsneoc2_error_success) {
icsneoc2_device_free(*device);
*device = nullptr;
}
@ -302,7 +359,7 @@ icsneoc2_error_t icsneoc2_device_reconnect(icsneoc2_device_t* device, icsneoc2_o
return res;
}
// If the device is currently open, close it first before trying to reconnect
if (device->device->isOpen()) {
if(device->device->isOpen()) {
res = icsneoc2_device_close(device);
if(res != icsneoc2_error_success) {
return res;
@ -342,7 +399,7 @@ icsneoc2_error_t icsneoc2_device_free(icsneoc2_device_t* device) {
if(res != icsneoc2_error_success) {
return res;
}
if (device->device->isOpen()) {
if(device->device->isOpen()) {
res = icsneoc2_device_close(device);
if(res != icsneoc2_error_success) {
return res;
@ -403,27 +460,78 @@ icsneoc2_error_t icsneoc2_device_pcb_serial_get(const icsneoc2_device_t* device,
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_mac_address_get(const icsneoc2_device_t* device, uint8_t* value, size_t* value_length) {
icsneoc2_error_t icsneoc2_device_mac_addresses_enumerate(const icsneoc2_device_t* device, icsneoc2_mac_addr_entry_t** mac_entries) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!value_length) {
if(!mac_entries) {
return icsneoc2_error_invalid_parameters;
}
auto macAddress = device->device->getMACAddress();
if(!macAddress.has_value()) {
const auto result = device->device->getMACAddresses();
if(result.empty()) {
return icsneoc2_error_invalid_type;
}
const auto& data = *macAddress;
if(value) {
size_t copyLen = std::min(*value_length, data.size());
std::copy(data.begin(), data.begin() + copyLen, value);
icsneoc2_mac_addr_entry_t* head = nullptr;
icsneoc2_mac_addr_entry_t* tail = nullptr;
for(auto addr_pair : result) {
auto* node = new (std::nothrow) icsneoc2_mac_addr_entry_t;
if(!node) {
icsneoc2_mac_addresses_free(head);
return icsneoc2_error_out_of_memory;
}
node->network_id = static_cast<uint16_t>(addr_pair.first);
std::copy(addr_pair.second.begin(), addr_pair.second.end(), node->address);
node->next = nullptr;
if(!head) {
head = node;
} else {
tail->next = node;
}
tail = node;
}
*value_length = data.size();
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_mac_network_id_get(const icsneoc2_mac_addr_entry_t* mac_address, _icsneoc2_netid_t* network_id) {
if(!mac_address || !network_id) {
return icsneoc2_error_invalid_parameters;
}
*network_id = static_cast<_icsneoc2_netid_t>(mac_address->network_id);
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_mac_address_get(const icsneoc2_mac_addr_entry_t* mac_address, uint8_t* value, size_t* value_length) {
if(!mac_address || !value || !value_length) {
return icsneoc2_error_invalid_parameters;
}
if(value) {
size_t copyLen = std::min(*value_length, static_cast<size_t>(ICSNEO_MAC_ADDRESS_LEN));
std::copy(mac_address->address, mac_address->address + copyLen, value);
}
*value_length = static_cast<size_t>(ICSNEO_MAC_ADDRESS_LEN);
return icsneoc2_error_success;
}
icsneoc2_mac_addr_entry_t* icsneoc2_mac_addresses_next(const icsneoc2_mac_addr_entry_t* mac_address) {
if(!mac_address) {
return nullptr;
}
return mac_address->next;
}
icsneoc2_error_t icsneoc2_mac_addresses_free(icsneoc2_mac_addr_entry_t* mac_address) {
if(!mac_address) {
return icsneoc2_error_invalid_parameters;
}
while(mac_address) {
auto* next = mac_address->next;
delete mac_address;
mac_address = next;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_go_online(const icsneoc2_device_t* device, bool go_online) {
auto res = icsneoc2_device_is_valid(device);
@ -671,15 +779,76 @@ icsneoc2_error_t icsneoc2_device_tc10_status_get(const icsneoc2_device_t* device
if(!cpp_status.has_value()) {
return icsneoc2_error_invalid_type;
}
if (sleep_status) {
if(sleep_status) {
*sleep_status = static_cast<icsneoc2_tc10_sleep_status_t>(cpp_status->sleepStatus);
}
if (wake_status) {
if(wake_status) {
*wake_status = static_cast<icsneoc2_tc10_wake_status_t>(cpp_status->wakeStatus);
}
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) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
@ -1208,3 +1377,84 @@ icsneoc2_error_t icsneoc2_script_status_max_coremini_size_kb_get(const icsneoc2_
*value = script_status->status->maxCoreminiSizeKB;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_chip_versions_enumerate(const icsneoc2_device_t* device, icsneoc2_chip_versions_t** chip_versions, bool refresh, size_t* count) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!chip_versions) {
return icsneoc2_error_invalid_parameters;
}
auto version_reports = device->device->getChipVersions(refresh);
if(count) {
*count = version_reports.size();
}
icsneoc2_chip_versions_t* head = nullptr;
icsneoc2_chip_versions_t* tail = nullptr;
for(auto& version_report : version_reports) {
auto* node = new (std::nothrow) icsneoc2_chip_versions_t;
if(!node) {
icsneoc2_chip_versions_free(head);
return icsneoc2_error_out_of_memory;
}
node->version_report = version_report;
node->next = nullptr;
if(!head) {
head = node;
} else {
tail->next = node;
}
tail = node;
}
*chip_versions = head;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_chip_versions_free(icsneoc2_chip_versions_t* chip_versions) {
if(!chip_versions) {
return icsneoc2_error_invalid_parameters;
}
while(chip_versions) {
auto* next = chip_versions->next;
delete chip_versions;
chip_versions = next;
}
return icsneoc2_error_success;
}
icsneoc2_chip_versions_t* icsneoc2_chip_versions_next(const icsneoc2_chip_versions_t* chip_versions) {
if(!chip_versions) {
return nullptr;
}
return chip_versions->next;
}
icsneoc2_error_t icsneoc2_chip_versions_props_get(const icsneoc2_chip_versions_t* chip_versions, char* name, size_t* name_length, uint8_t* major, uint8_t* minor, uint8_t* maintenance, uint8_t* build) {
if(!chip_versions) {
return icsneoc2_error_invalid_parameters;
}
auto& report = chip_versions->version_report;
if(name && name_length) {
if(!safe_str_copy(name,name_length, report.name)) {
return icsneoc2_error_string_copy_failed;
}
}
if(major) {
*major = report.major;
}
if(minor) {
*minor = report.minor;
}
if(maintenance) {
*maintenance = report.maintenance;
}
if(build) {
*build = report.build;
}
return icsneoc2_error_success;
}

View File

@ -13,6 +13,11 @@
using namespace icsneo;
typedef struct icsneoc2_supported_device_t {
DeviceType device_type;
icsneoc2_supported_device_t* next;
} icsneoc2_supported_device_t;
typedef struct icsneoc2_message_t {
std::shared_ptr<Message> message;
} icsneoc2_message_t;
@ -38,6 +43,17 @@ typedef struct icsneoc2_script_status_t {
std::shared_ptr<ScriptStatusMessage> status;
} icsneoc2_script_status_t;
typedef struct icsneoc2_chip_versions_t {
VersionReport version_report;
icsneoc2_chip_versions_t* next;
} icsneoc2_chip_versions_t;
typedef struct icsneoc2_mac_addr_entry_t {
uint16_t network_id;
uint8_t address[ICSNEO_MAC_ADDRESS_LEN];
icsneoc2_mac_addr_entry_t* next;
} icsneoc2_mac_addr_entry_t;
/**
* Safely copies a std::string to a char array.
*

View File

@ -126,6 +126,28 @@ icsneoc2_error_t icsneoc2_message_data_get(icsneoc2_message_t* message, uint8_t*
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_timestamp_set(icsneoc2_message_t* message, uint64_t timestamp) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
if(!message->message) {
return icsneoc2_error_invalid_message;
}
message->message->timestamp = timestamp;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_timestamp_get(icsneoc2_message_t* message, uint64_t* timestamp) {
if(!message || !timestamp) {
return icsneoc2_error_invalid_parameters;
}
if(!message->message) {
return icsneoc2_error_invalid_message;
}
*timestamp = message->message->timestamp;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_can_create(icsneoc2_message_t** message) {
if(!message) {
return icsneoc2_error_invalid_parameters;

View File

@ -867,6 +867,90 @@ icsneoc2_error_t icsneoc2_settings_misc_io_analog_output_set(icsneoc2_device_t*
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) {
if(!value) {
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;
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;
}

View File

@ -4,10 +4,10 @@
using namespace icsneo;
APIEvent::APIEvent(Type type, APIEvent::Severity severity, const Device* device) : eventStruct({}) {
this->device = device;
if(device) {
serial = device->getSerial();
APIEvent::APIEvent(Type type, APIEvent::Severity severity, std::weak_ptr<Device> device) : eventStruct({}), device(device) {
auto shared = device.lock();
if(shared) {
serial = shared->getSerial();
eventStruct.serial[serial.copy(eventStruct.serial, sizeof(eventStruct.serial))] = '\0';
}
@ -27,9 +27,10 @@ void APIEvent::downgradeFromError() noexcept {
}
bool APIEvent::isForDevice(std::string filterSerial) const noexcept {
if(!device || filterSerial.length() == 0)
auto shared = device.lock();
if(!shared || filterSerial.length() == 0)
return false;
return device->getSerial() == filterSerial;
return shared->getSerial() == filterSerial;
}
// API Errors
@ -467,8 +468,9 @@ const char* APIEvent::DescriptionForType(Type type) {
std::string APIEvent::describe() const noexcept {
std::stringstream ss;
if(device)
ss << *device; // Makes use of device.describe()
auto shared = device.lock();
if(shared)
ss << *shared; // Makes use of device.describe()
else
ss << "API";

View File

@ -7,8 +7,8 @@
using namespace icsneo;
EventManager& EventManager::GetInstance() {
static EventManager inst;
return inst;
static EventManager* inst = new EventManager();
return *inst;
}
void EventManager::downgradeErrorsOnCurrentThread() {

View File

@ -31,6 +31,8 @@ pybind11_add_module(icsneopy
icsneopy/communication/message/tc10statusmessage.cpp
icsneopy/communication/message/mdiomessage.cpp
icsneopy/communication/message/gptpstatusmessage.cpp
icsneopy/communication/message/allmacaddressesmessage.cpp
icsneopy/communication/message/apperrormessage.cpp
icsneopy/communication/message/ethernetstatusmessage.cpp
icsneopy/communication/message/spimessage.cpp
icsneopy/communication/message/scriptstatusmessage.cpp

View File

@ -0,0 +1,13 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "icsneo/communication/message/allmacaddressesmessage.h"
namespace icsneo {
void init_allmacaddressesmessage(pybind11::module_& m) {
pybind11::classh<AllMACAddressesMessage, Message>(m, "AllMACAddressesMessage")
.def_readonly("addresses", &AllMACAddressesMessage::addresses);
}
} // namespace icsneo

View File

@ -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

View File

@ -120,7 +120,7 @@ void init_chipid(pybind11::module_& m) {
.value("VEM_01_8DW_ZCHIP", ChipID::VEM_01_8DW_ZCHIP)
.value("RADGalaxy_FFG_Zynq", ChipID::RADGalaxy_FFG_Zynq)
.value("RADMoon3_MCHIP", ChipID::RADMoon3_MCHIP)
.value("RADComet_ZYNQ", ChipID::RADComet_ZYNQ)
.value("RADComet2_ZYNQ", ChipID::RADComet2_ZYNQ)
.value("VEM_02_FR_ZCHIP", ChipID::VEM_02_FR_ZCHIP)
.value("RADA2B_REVB_ZCHIP", ChipID::RADA2B_REVB_ZCHIP)
.value("RADGigastar_FFG_ZYNQ", ChipID::RADGigastar_FFG_ZYNQ)

View File

@ -33,7 +33,7 @@ void init_device(pybind11::module_& m) {
.def("get_serial_number", &Device::getSerialNumber)
.def("get_serial", &Device::getSerial)
.def("get_pcb_serial", &Device::getPCBSerial, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_mac_address", &Device::getMACAddress, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_mac_addresses", &Device::getMACAddresses, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_supported_rx_networks", &Device::getSupportedRXNetworks, pybind11::return_value_policy::reference)
.def("get_supported_tx_networks", &Device::getSupportedTXNetworks, pybind11::return_value_policy::reference)
.def("get_tc10_status", &Device::getTC10Status, pybind11::call_guard<pybind11::gil_scoped_release>())
@ -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_polling_message_limit", &Device::setPollingMessageLimit)
.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("stop_script", &Device::stopScript, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("supports_tc10", &Device::supportsTC10)
.def("supports_reboot", &Device::supportsReboot)
.def("supports_live_data", &Device::supportsLiveData)
.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>())

View File

@ -38,7 +38,7 @@ void init_devicetype(pybind11::module_& m) {
.value("RADGalaxy2", DeviceType::Enum::RADGalaxy2)
.value("RADMoon3", DeviceType::Enum::RADMoon3)
.value("RADGemini", DeviceType::Enum::RADGemini)
.value("RADComet", DeviceType::Enum::RADComet)
.value("RADComet2", DeviceType::Enum::RADComet2)
.value("FIRE3_FlexRay", DeviceType::Enum::FIRE3_FlexRay)
.value("FIRE3_T1S_LIN", DeviceType::Enum::FIRE3_T1S_LIN)
.value("FIRE3_T1S_SENT", DeviceType::Enum::FIRE3_T1S_SENT)

View File

@ -40,6 +40,16 @@ void init_idevicesettings(pybind11::module_& m) {
.value("Normal", LINMode::NORMAL_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")
.value("V0", MiscIOAnalogVoltage::V0)
.value("V1", MiscIOAnalogVoltage::V1)
@ -48,6 +58,10 @@ void init_idevicesettings(pybind11::module_& m) {
.value("V4", MiscIOAnalogVoltage::V4)
.value("V5", MiscIOAnalogVoltage::V5);
pybind11::enum_<LinuxConfigurationPort>(settings, "LinuxConfigurationPort")
.value("USB", LinuxConfigurationPort::USB)
.value("ETH01", LinuxConfigurationPort::ETH01);
pybind11::classh<IDeviceSettings>(m, "IDeviceSettings")
.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>())
@ -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", &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
.def_readonly("disabled", &IDeviceSettings::disabled)
.def_readonly("readonly", &IDeviceSettings::readonly);

View File

@ -19,6 +19,8 @@ void init_ethernetmessage(pybind11::module_&);
void init_linmessage(pybind11::module_&);
void init_tc10statusmessage(pybind11::module_&);
void init_gptpstatusmessage(pybind11::module_&);
void init_allmacaddressesmessage(pybind11::module_&);
void init_apperrormessage(pybind11::module_&);
void init_mdiomessage(pybind11::module_&);
void init_spimessage(pybind11::module_&);
void init_ethernetstatusmessage(pybind11::module_&);
@ -59,6 +61,8 @@ PYBIND11_MODULE(icsneopy, m) {
init_linmessage(m);
init_tc10statusmessage(m);
init_gptpstatusmessage(m);
init_allmacaddressesmessage(m);
init_apperrormessage(m);
init_mdiomessage(m);
init_ethernetstatusmessage(m);
init_macsecconfig(m);

View File

@ -21,6 +21,7 @@
#include "icsneo/communication/message/hardwareinfo.h"
#include "icsneo/communication/message/tc10statusmessage.h"
#include "icsneo/communication/message/gptpstatusmessage.h"
#include "icsneo/communication/message/allmacaddressesmessage.h"
#include "icsneo/communication/message/apperrormessage.h"
#include "icsneo/communication/message/ethernetstatusmessage.h"
#include "icsneo/communication/message/networkmutexmessage.h"
@ -343,6 +344,9 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
case ExtendedCommand::GetTC10Status:
result = TC10StatusMessage::DecodeToMessage(packet->data);
return true;
case ExtendedCommand::GetAllMACAddresses:
result = AllMACAddressesMessage::DecodeToMessage(packet->data);
return true;
case ExtendedCommand::GetGPTPStatus: {
result = GPTPStatus::DecodeToMessage(packet->data, report);
return true;

View File

@ -0,0 +1,51 @@
#include "icsneo/communication/message/allmacaddressesmessage.h"
#include "icsneo/communication/command.h"
#include "icsneo/communication/network.h"
#include <cstring>
using namespace icsneo;
#pragma pack(push, 2)
struct ResponseHeader {
ExtendedCommand command;
uint16_t length;
uint16_t count;
};
struct MacAddrEntryPacket {
uint16_t networkId;
uint8_t address[MACAddressLength];
};
#pragma pack(pop)
std::shared_ptr<AllMACAddressesMessage> AllMACAddressesMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
if(bytestream.size() < sizeof(ResponseHeader))
return nullptr;
const auto* hdr = reinterpret_cast<const ResponseHeader*>(bytestream.data());
if(hdr->command != ExtendedCommand::GetAllMACAddresses)
return nullptr;
if(hdr->count > MaxMACAddressCount)
return nullptr;
const size_t required = sizeof(ResponseHeader) + hdr->count * sizeof(MacAddrEntryPacket);
if(bytestream.size() < required)
return nullptr;
auto msg = std::make_shared<AllMACAddressesMessage>();
const auto* entries = reinterpret_cast<const MacAddrEntryPacket*>(bytestream.data() + sizeof(ResponseHeader));
for(uint16_t i = 0; i < hdr->count; ++i) {
// The firmware sends CoreMini network IDs — convert to NetID for consistent use in libicsneo
Network::NetID netId = Network::GetNetIDFromCoreMiniNetwork(static_cast<Network::CoreMini>(entries[i].networkId));
auto addr = entries[i].address;
MACAddress arrAddr;
std::copy(addr, addr + MACAddressLength, arrAddr.begin());
msg->addresses.emplace(std::make_pair(netId, arrAddr));
}
return msg;
}

View File

@ -80,7 +80,7 @@ bool Packetizer::input(RingBuffer& bytes) {
* end of the payload. The short packet length, for reference, only encompasses the length of the actual
* payload, and not the header or checksum.
*/
if(packetLength < 6 || packetLength > 4000) {
if(packetLength < 6 || packetLength > std::numeric_limits<uint16_t>::max()) {
bytes.pop_front();
EventManager::GetInstance().add(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
state = ReadState::SearchForHeader;

View File

@ -230,6 +230,7 @@ MACsecConfig::MACsecConfig(const DeviceType& deviceType) : type(deviceType) {
case icsneo::DeviceType::Enum::RADMoon2:
case icsneo::DeviceType::Enum::RADMoon3:
case icsneo::DeviceType::Enum::RADEpsilon:
case icsneo::DeviceType::Enum::RADGigastar2:
maxSecY = 2;
maxRule = 2;
maxSa = 4;

View File

@ -2263,13 +2263,34 @@ std::optional<std::vector<uint8_t>> Device::getPCBSerial() {
return std::vector<uint8_t>(serialMsg->pcbSerial, serialMsg->pcbSerial + sizeof(serialMsg->pcbSerial));
}
std::optional<std::vector<uint8_t>> Device::getMACAddress() {
auto serialMsg = com->getSerialNumberSync();
if(!serialMsg || !serialMsg->hasMacAddress) {
return std::nullopt;
std::unordered_map<Network::NetID, MACAddress> Device::getMACAddresses() {
if(supportsGetAllMACAddresses()) {
if(!isOpen()) {
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
return {};
}
auto msg = com->waitForMessageSync(
[this](){ return com->sendCommand(ExtendedCommand::GetAllMACAddresses, {}); },
std::make_shared<MessageFilter>(Message::Type::AllMACAddresses),
std::chrono::milliseconds(100)
);
if(msg) {
const auto typed = std::dynamic_pointer_cast<AllMACAddressesMessage>(msg);
if(typed)
return typed->addresses;
}
}
return std::vector<uint8_t>(serialMsg->macAddress, serialMsg->macAddress + sizeof(serialMsg->macAddress));
auto serialMsg = com->getSerialNumberSync();
if(!serialMsg || !serialMsg->hasMacAddress)
return {};
std::unordered_map<Network::NetID, MACAddress> addresses;
auto addr = serialMsg->macAddress;
MACAddress arrAddr;
std::copy(addr, addr + MACAddressLength, arrAddr.begin());
addresses.emplace(std::make_pair(Network::NetID::ETHERNET_01, arrAddr));
return addresses;
}
std::optional<std::set<SupportedFeature>> Device::getSupportedFeatures() {
@ -3714,6 +3735,15 @@ bool Device::requestTC10Sleep(Network::NetID network) {
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) {
if(!supportsTC10()) {
report(APIEvent::Type::NotSupported, APIEvent::Severity::Error);

View File

@ -165,10 +165,6 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
makeIfSerialMatches<RADA2B>(dev, newFoundDevices);
#endif
#ifdef __RADCOMET_H_
makeIfSerialRangeMatches<RADComet>(dev, newFoundDevices);
#endif
#ifdef __RADCOMET2_H_
makeIfSerialRangeMatches<RADComet2>(dev, newFoundDevices);
#endif
@ -340,8 +336,8 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
RADA2B::DEVICE_TYPE,
#endif
#ifdef __RADCOMET_H_
RADComet::DEVICE_TYPE,
#ifdef __RADCOMET2_H_
RADComet2::DEVICE_TYPE,
#endif
#ifdef __RADCOMET3_H_

View File

@ -959,4 +959,150 @@ bool IDeviceSettings::setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage vol
(void)voltage;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error);
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;
}

View File

@ -10,6 +10,14 @@ Simple
.. literalinclude:: ../../examples/c2/simple/src/main.c
:language: c
Supported Devices
=================
:download:`Download example <../../examples/c2/supported_devices/src/main.c>`
.. literalinclude:: ../../examples/c2/supported_devices/src/main.c
:language: c
Disk Format
===========

View File

@ -2,17 +2,21 @@ option(LIBICSNEO_BUILD_C_INTERACTIVE_EXAMPLE "Build the command-line interactive
option(LIBICSNEO_BUILD_C_SIMPLE_EXAMPLE "Build the command-line simple C example." ON)
option(LIBICSNEO_BUILD_C_LEGACY_EXAMPLE "Build the command-line simple C example." ON)
option(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE "Build the simple C2 example." ON)
option(LIBICSNEO_BUILD_C2_SUPPORTED_DEVICES_EXAMPLE "Build the C2 supported devices example." ON)
option(LIBICSNEO_BUILD_C2_READ_MESSAGES_EXAMPLE "Build the C2 read messages example." ON)
option(LIBICSNEO_BUILD_C2_DISKFORMAT_EXAMPLE "Build the C2 disk format example." ON)
option(LIBICSNEO_BUILD_C2_RECONNECT_EXAMPLE "Build the C2 reconnect example." ON)
option(LIBICSNEO_BUILD_C2_DEVICE_INFO_EXAMPLE "Build the C2 device info example." ON)
option(LIBICSNEO_BUILD_C2_CHIP_VERSIONS_EXAMPLE "Build the C2 chip versions example." ON)
option(LIBICSNEO_BUILD_C2_LIN_EXAMPLE "Build the C2 LIN example." ON)
option(LIBICSNEO_BUILD_C2_LIN_TRANSMIT_EXAMPLE "Build the C2 LIN transmit example." ON)
option(LIBICSNEO_BUILD_C2_ETHERNET_TRANSMIT_EXAMPLE "Build the C2 ethernet transmit 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_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_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_A2B_EXAMPLE "Build the A2B example." ON)
option(LIBICSNEO_BUILD_CPP_LIN_EXAMPLE "Build the LIN example." ON)
@ -28,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_DISKFORMAT_EXAMPLE "Build the disk format 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})
@ -47,6 +52,10 @@ if(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE)
add_subdirectory(c2/simple)
endif()
if(LIBICSNEO_BUILD_C2_SUPPORTED_DEVICES_EXAMPLE)
add_subdirectory(c2/supported_devices)
endif()
if(LIBICSNEO_BUILD_C2_READ_MESSAGES_EXAMPLE)
add_subdirectory(c2/read_messages)
endif()
@ -63,6 +72,10 @@ if(LIBICSNEO_BUILD_C2_DEVICE_INFO_EXAMPLE)
add_subdirectory(c2/device_info)
endif()
if(LIBICSNEO_BUILD_C2_CHIP_VERSIONS_EXAMPLE)
add_subdirectory(c2/chip_versions)
endif()
if(LIBICSNEO_BUILD_C2_LIN_EXAMPLE)
add_subdirectory(c2/lin)
endif()
@ -87,10 +100,18 @@ if(LIBICSNEO_BUILD_C2_TC10_EXAMPLE)
add_subdirectory(c2/tc10)
endif()
if(LIBICSNEO_BUILD_C2_GPTP_EXAMPLE)
add_subdirectory(c2/gptp)
endif()
if(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE)
add_subdirectory(cpp/simple)
endif()
if(LIBICSNEO_BUILD_CPP_DEVICE_INFO_EXAMPLE)
add_subdirectory(cpp/device_info)
endif()
if(LIBICSNEO_BUILD_CPP_INTERACTIVE_EXAMPLE)
add_subdirectory(cpp/interactive)
endif()
@ -150,3 +171,7 @@ endif()
if(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE)
add_subdirectory(cpp/t1s)
endif()
if(LIBICSNEO_BUILD_CPP_GPTP_EXAMPLE)
add_subdirectory(cpp/gptp)
endif()

View File

@ -0,0 +1,6 @@
add_executable(libicsneoc2-chip-versions-example src/main.c)
target_link_libraries(libicsneoc2-chip-versions-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-chip-versions-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()

View File

@ -0,0 +1,59 @@
#include <icsneo/icsneoc2.h>
#include <stdio.h>
#include <inttypes.h>
int print_error_code(const char* message, icsneoc2_error_t error) {
char error_str[64];
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) {
printf("%s: Failed to get string for error code %u with error code %u\n", message, error, res);
return (int)res;
}
printf("%s: \"%s\" (%u)\n", message, error_str, error);
return (int)error;
}
int main() {
icsneoc2_error_t res;
icsneoc2_device_t* device = NULL;
res = icsneoc2_device_open_first(0, icsneoc2_open_options_default, &device);
if(res != icsneoc2_error_success) {
return print_error_code("Failed to open first device", res);
}
char description[128] = {0};
size_t description_length = sizeof(description);
icsneoc2_device_description_get(device, description, &description_length);
printf("Opened device: %s\n\n", description);
size_t count = 0;
icsneoc2_chip_versions_t* chip_versions = NULL;
res = icsneoc2_device_chip_versions_enumerate(device, &chip_versions, true, &count);
if(res != icsneoc2_error_success) {
print_error_code("Failed to enumerate chip versions", res);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 1;
}
printf("Found %zu chip version(s):\n", count);
for(icsneoc2_chip_versions_t* cur = chip_versions; cur; cur = icsneoc2_chip_versions_next(cur)) {
char name[64] = {0};
size_t name_length = sizeof(name);
uint8_t major = 0, minor = 0, maintenance = 0, build = 0;
res = icsneoc2_chip_versions_props_get(cur, name, &name_length, &major, &minor, &maintenance, &build);
if(res != icsneoc2_error_success) {
print_error_code("Failed to get chip version properties", res);
continue;
}
printf(" %s: %u.%u.%u.%u\n", name, major, minor, maintenance, build);
}
icsneoc2_chip_versions_free(chip_versions);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 0;
}

View File

@ -102,19 +102,31 @@ int main() {
print_error_code("Failed to get PCB serial (device may not support it)", res);
}
/* ===== MAC Address ===== */
uint8_t mac[6] = {0};
size_t mac_len = sizeof(mac);
res = icsneoc2_device_mac_address_get(device, mac, &mac_len);
/* ===== MAC Addresses ===== */
icsneoc2_mac_addr_entry_t* macs = NULL;
res = icsneoc2_device_mac_addresses_enumerate(device, &macs);
if(res == icsneoc2_error_success) {
printf("MAC: ");
for(size_t i = 0; i < mac_len; i++) {
if(i > 0) printf(":");
printf("%02X", mac[i]);
uint16_t mac_count = 0;
for(icsneoc2_mac_addr_entry_t* cur = macs; cur; cur = icsneoc2_mac_addresses_next(cur)) {
mac_count++;
}
printf("\n");
printf("MACs: %u entr%s\n", mac_count, mac_count == 1 ? "y" : "ies");
for(icsneoc2_mac_addr_entry_t* cur = macs; cur; cur = icsneoc2_mac_addresses_next(cur)) {
_icsneoc2_netid_t network_id;
icsneoc2_mac_network_id_get(cur, &network_id);
printf(" Network %-5u ", (unsigned)network_id);
uint8_t address[6];
size_t address_size = 6;
icsneoc2_mac_address_get(cur, address, &address_size);
for(int j = 0; j < 6; j++) {
if(j > 0) printf(":");
printf("%02X", (unsigned)address[j]);
}
printf("\n");
}
icsneoc2_mac_addresses_free(macs);
} else {
print_error_code("Failed to get MAC address (device may not support it)", res);
print_error_code("Failed to get MAC addresses (device may not support it)", res);
}
/* Cleanup */

View File

@ -68,6 +68,7 @@ void print_mac(const char* label, const uint8_t* mac) {
int process_ethernet_message(icsneoc2_message_t* message, size_t index) {
icsneoc2_netid_t netid = 0;
uint64_t timestamp = 0;
char netid_name[128] = {0};
size_t netid_name_length = 128;
@ -79,6 +80,10 @@ int process_ethernet_message(icsneoc2_message_t* message, size_t index) {
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get netid name", res);
}
res = icsneoc2_message_timestamp_get(message, &timestamp);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get timestamp", res);
}
/* Get data length first */
size_t data_length = 0;
@ -88,6 +93,7 @@ int process_ethernet_message(icsneoc2_message_t* message, size_t index) {
}
printf("\t%zu) Ethernet Frame on %s (0x%x) - %zu bytes\n", index, netid_name, netid, data_length);
printf("\t Timestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
/* Get MAC addresses and EtherType if we have enough data */
uint8_t dst_mac[6] = {0};

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()

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;
}

View File

@ -86,6 +86,8 @@ void process_lin_messages(icsneoc2_message_t** messages, size_t count) {
icsneoc2_netid_t netid = 0;
icsneoc2_message_netid_get(messages[i], &netid);
uint64_t timestamp = 0;
icsneoc2_message_timestamp_get(messages[i], &timestamp);
char netid_name[128] = {0};
size_t netid_name_length = 128;
icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
@ -98,6 +100,7 @@ void process_lin_messages(icsneoc2_message_t** messages, size_t count) {
icsneoc2_message_lin_err_flags_get(messages[i], &err_flags);
printf("\t%s RX | ID: 0x%02x | Protected ID: 0x%02x\n", netid_name, id, protected_id);
printf("\tTimestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
printf("\tData: [");
for(size_t x = 0; x < data_length; x++) {
printf(" 0x%02x", data[x]);

View File

@ -244,6 +244,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
printf("\t%zd) network type: %s (%u)\n", i, network_type_name, network_type);
if(network_type == icsneoc2_network_type_can) {
uint64_t timestamp = 0;
uint64_t arbid = 0;
int32_t dlc = 0;
icsneoc2_netid_t netid = 0;
@ -256,6 +257,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
bool is_tx = false;
icsneoc2_error_t result = icsneoc2_message_netid_get(message, &netid);
result += icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
result += icsneoc2_message_timestamp_get(message, &timestamp);
result += icsneoc2_message_can_props_get(message, &arbid, &can_flags);
result += icsneoc2_message_data_get(message, data, &data_length);
result += icsneoc2_message_is_transmit(message, &is_tx);
@ -276,6 +278,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
dlc = (int32_t)data_length;
printf("\t %s%s\n", is_tx ? "TX" : "RX", is_error ? " [Error]" : "");
printf("\t Timestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
printf("\t NetID: %s (0x%x)\tArbID: 0x%llx\tDLC: %u\tLen: %zu\n", netid_name, netid, (unsigned long long)arbid, dlc, data_length);
printf("\t Flags:%s%s%s%s%s%s%s%s\n",
is_remote ? " RTR" : "",

View File

@ -426,6 +426,7 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
printf("\t%zd) network type: %s (%u)\n", i, network_type_name, network_type);
if(network_type == icsneoc2_network_type_can) {
uint64_t timestamp = 0;
uint64_t arbid = 0;
int32_t dlc = 0;
icsneoc2_netid_t netid = 0;
@ -436,6 +437,7 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
size_t netid_name_length = 128;
icsneoc2_error_t result = icsneoc2_message_netid_get(message, &netid);
result += icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
result += icsneoc2_message_timestamp_get(message, &timestamp);
result += icsneoc2_message_can_props_get(message, &arbid, &can_flags);
result += icsneoc2_message_data_get(message, data, &data_length);
if(result != icsneoc2_error_success) {
@ -452,6 +454,7 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
bool tx_error = (can_flags & ICSNEOC2_MESSAGE_CAN_FLAGS_TX_ERROR) != 0;
dlc = (int32_t)data_length;
printf("\t Timestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
printf("\t NetID: %s (0x%x)\tArbID: 0x%llx\tDLC: %u\tLen: %zu\n", netid_name, netid, (unsigned long long)arbid, dlc, data_length);
printf("\t Flags:%s%s%s%s%s%s%s%s\n",
is_remote ? " RTR" : "",

View File

@ -0,0 +1,6 @@
add_executable(libicsneoc2-supported-devices-example src/main.c)
target_link_libraries(libicsneoc2-supported-devices-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-supported-devices-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()

View File

@ -0,0 +1,55 @@
#include <icsneo/icsneoc2.h>
#include <stdio.h>
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) {
printf("%s: failed to get string for error code %u\n", message, error);
return (int)res;
}
printf("%s: %s (%u)\n", message, error_str, error);
return (int)error;
}
int main(void) {
icsneoc2_supported_device_t* supported_devices = NULL;
icsneoc2_error_t res = icsneoc2_supported_devices_enumerate(&supported_devices);
if(res != icsneoc2_error_success) {
return print_error_code("Failed to enumerate supported devices", res);
}
if(!supported_devices) {
printf("No supported devices found.\n");
return 0;
}
printf("Supported devices:\n");
for(icsneoc2_supported_device_t* cur = supported_devices; cur != NULL; cur = icsneoc2_supported_devices_next(cur)) {
icsneoc2_devicetype_t device_type = 0;
res = icsneoc2_supported_device_get(cur, &device_type);
if(res != icsneoc2_error_success) {
icsneoc2_supported_devices_free(supported_devices);
return print_error_code("Failed to get supported device type", res);
}
char name[128] = {0};
size_t name_len = sizeof(name);
res = icsneoc2_device_type_name_get(device_type, name, &name_len);
if(res != icsneoc2_error_success) {
icsneoc2_supported_devices_free(supported_devices);
return print_error_code("Failed to get supported device type name", res);
}
printf(" %s (%u)\n", name, (unsigned int)device_type);
}
res = icsneoc2_supported_devices_free(supported_devices);
if(res != icsneoc2_error_success) {
return print_error_code("Failed to free supported device list", res);
}
return 0;
}

View File

@ -468,6 +468,7 @@ static int message_matches_loopback_frame(icsneoc2_message_t* message, const uin
static int print_ethernet_message(icsneoc2_message_t* message, const char* direction_label) {
icsneoc2_netid_t netid = 0;
uint64_t timestamp = 0;
char netid_name[64] = {0};
uint8_t dst_mac[6] = {0};
uint8_t src_mac[6] = {0};
@ -483,11 +484,14 @@ static int print_ethernet_message(icsneoc2_message_t* message, const char* direc
res = icsneoc2_message_netid_get(message, &netid);
if(res != icsneoc2_error_success) return print_error_code("Failed to get message netid", res);
if(get_netid_name(netid, netid_name, sizeof(netid_name)) != 0) return 1;
res = icsneoc2_message_timestamp_get(message, &timestamp);
if(res != icsneoc2_error_success) return print_error_code("Failed to get message timestamp", res);
res = icsneoc2_message_data_get(message, data, &data_length);
if(res != icsneoc2_error_success) return print_error_code("Failed to get Ethernet data", res);
printf("%s on %s: %zu bytes\n", direction_label, netid_name, data_length);
printf(" Timestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
res = icsneoc2_message_eth_mac_get(message, dst_mac, src_mac);
if(res == icsneoc2_error_success) {
@ -640,4 +644,4 @@ static int poll_for_loopback_messages(icsneoc2_device_t* device,
printf("Loopback complete: TX echo on %s and RX frame on %s were both observed.\n", tx_name, rx_name);
return 0;
}
}

View File

@ -0,0 +1,2 @@
add_executable(libicsneocpp-device-info-example src/DeviceInfoExample.cpp)
target_link_libraries(libicsneocpp-device-info-example icsneocpp)

View File

@ -0,0 +1,80 @@
#include <iostream>
#include <iomanip>
#include <sstream>
#include "icsneo/icsneocpp.h"
static std::string formatMAC(const std::array<uint8_t, icsneo::MACAddressLength> addr) {
std::ostringstream oss;
for(size_t i = 0; i < icsneo::MACAddressLength; i++) {
if(i > 0) {
oss << ':';
}
oss << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast<unsigned>(addr[i]);
}
return oss.str();
}
int main() {
// ===== Device Selection =====
std::cout << "Searching for devices...\n";
auto devices = icsneo::FindAllDevices();
if(devices.empty()) {
std::cout << "No devices found.\n";
return 1;
}
for(size_t i = 0; i < devices.size(); i++) {
std::cout << " [" << (i + 1) << "] " << devices[i]->describe() << "\n";
}
int choice;
std::cout << "Select device (1-" << devices.size() << "): ";
if(!(std::cin >> choice) || choice < 1 || choice > (int)devices.size()) {
std::cout << "Invalid selection.\n";
return 1;
}
auto& device = devices[choice - 1];
std::cout << "\nOpening " << device->describe() << "... ";
if(!device->open()) {
std::cout << "FAIL\n" << icsneo::GetLastError() << "\n";
return 1;
}
std::cout << "OK\n\n";
// ===== Serial Number =====
std::cout << "Serial: " << device->getSerial() << "\n";
// ===== PCB Serial Number =====
auto pcbSerial = device->getPCBSerial();
if(pcbSerial.has_value()) {
std::cout << "PCB Serial: ";
for(auto b : *pcbSerial)
std::cout << (char)b;
std::cout << "\n";
} else {
std::cout << "PCB Serial: Not supported\n";
}
auto macs = device->getMACAddresses();
if(!macs.empty()) {
std::cout << "MACs: " << macs.size()
<< (macs.size() == 1 ? " entry" : " entries") << "\n";
for(auto macPair : macs) {
std::cout << " " << std::left << std::setw(20)
<< icsneo::Network::GetNetIDString(static_cast<icsneo::Network::NetID>(macPair.first))
<< " " << formatMAC(macPair.second) << "\n";
}
} else {
std::cout << "MACs: Not supported\n";
}
// ===== Cleanup =====
std::cout << "\nClosing device... ";
std::cout << (device->close() ? "OK" : "FAIL") << "\n";
return 0;
}

View File

@ -0,0 +1,2 @@
add_executable(libicsneocpp-gptp-settings src/GPTPSettingsExample.cpp)
target_link_libraries(libicsneocpp-gptp-settings icsneocpp)

View File

@ -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;
}

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()

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())

View File

@ -19,6 +19,7 @@ typedef struct {
#include <chrono>
#include <string>
#include <ostream>
#include <memory>
namespace icsneo {
@ -185,19 +186,25 @@ public:
Error = 0x30
};
APIEvent() : eventStruct({}), serial(), timepoint(), device(nullptr) {}
APIEvent(APIEvent::Type event, APIEvent::Severity severity, const Device* device = nullptr);
APIEvent() : eventStruct({}), serial(), timepoint() {}
APIEvent(APIEvent::Type event, APIEvent::Severity severity, std::weak_ptr<Device> device = {});
const neoevent_t* getNeoEvent() const noexcept { return &eventStruct; }
Type getType() const noexcept { return Type(eventStruct.eventNumber); }
Severity getSeverity() const noexcept { return Severity(eventStruct.severity); }
std::string getDescription() const noexcept { return std::string(eventStruct.description); }
const Device* getDevice() const noexcept { return device; } // Will return nullptr if this is an API-wide event
const Device* getDevice() const noexcept { // Will return nullptr if this is an API-wide event
auto shared = device.lock();
return (shared) ? shared.get() : nullptr;
}
EventTimePoint getTimestamp() const noexcept { return timepoint; }
void downgradeFromError() noexcept;
bool isForDevice(const Device* forDevice) const noexcept { return forDevice == device; }
bool isForDevice(const Device* forDevice) const noexcept {
auto shared = device.lock();
return shared && (shared.get() == forDevice);
}
bool isForDevice(std::string serial) const noexcept;
// As opposed to getDescription, this will also add text such as "neoVI FIRE 2 CY2468 Error: " to fully describe the problem
@ -213,7 +220,7 @@ private:
neoevent_t eventStruct;
std::string serial;
EventTimePoint timepoint;
const Device* device;
std::weak_ptr<Device> device;
void init(APIEvent::Type event, APIEvent::Severity);
};

View File

@ -56,7 +56,7 @@ public:
APIEvent getLastError();
void add(APIEvent event);
void add(APIEvent::Type type, APIEvent::Severity severity, const Device* forDevice = nullptr) {
void add(APIEvent::Type type, APIEvent::Severity severity, std::weak_ptr<Device> forDevice = {}) {
add(APIEvent(type, severity, forDevice));
}

View File

@ -64,6 +64,7 @@ enum class ExtendedCommand : uint16_t {
RequestTC10Wake = 0x003D,
RequestTC10Sleep = 0x003E,
GetTC10Status = 0x003F,
GetAllMACAddresses = 0x0040,
ProtobufAPI = 0x0041,
TransmitMessage = 0x0042,
};

View File

@ -0,0 +1,35 @@
#ifndef __ALLMACADDRESSESMESSAGE_H_
#define __ALLMACADDRESSESMESSAGE_H_
#define ICSNEO_MAC_ADDRESS_LEN 6
#define ICSNEO_MAX_MAC_COUNT 32
#ifdef __cplusplus
#include "icsneo/communication/message/message.h"
#include <memory>
#include <vector>
#include <unordered_map>
#include <array>
namespace icsneo {
static constexpr uint16_t MaxMACAddressCount = ICSNEO_MAX_MAC_COUNT;
static constexpr uint8_t MACAddressLength = ICSNEO_MAC_ADDRESS_LEN;
using MACAddress = std::array<uint8_t, MACAddressLength>;
class AllMACAddressesMessage : public Message {
public:
static std::shared_ptr<AllMACAddressesMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
AllMACAddressesMessage() : Message(Type::AllMACAddresses) {}
std::unordered_map<Network::NetID, MACAddress> addresses;
};
} // namespace icsneo
#endif // __cplusplus
#endif // __ALLMACADDRESSESMESSAGE_H_

View File

@ -47,6 +47,7 @@ public:
LogData = 0x8015,
NetworkMutex = 0x8016,
ClientId = 0x8017,
AllMACAddresses = 0x8018,
};
Message(Type t) : type(t) {}

View File

@ -1,142 +1,144 @@
#ifndef __CHIP_ID_H_
#define __CHIP_ID_H_
#include "icsneo/icsneoc2types.h"
#ifdef __cplusplus
#include <cstdint>
namespace icsneo {
enum class ChipID : uint8_t {
neoVIFIRE_MCHIP = 0,
neoVIFIRE_LCHIP = 1,
neoVIFIRE_UCHIP = 2,
neoVIFIRE_JCHIP = 3,
ValueCAN3_MCHIP = 4,
neoVIECU_MPIC = 6,
neoVIIEVB_MPIC = 7,
neoVIPENDANT_MPIC = 8,
neoVIFIRE_VNET_MCHIP = 9,
neoVIFIRE_VNET_LCHIP = 10,
neoVIPLASMA_Core = 11,
neoVIPLASMA_HID = 12,
neoVIANALOG_MPIC = 13,
neoVIPLASMA_ANALOG_Core = 14,
neoVIPLASMA_FlexRay_Core = 15,
neoVIPLASMA_Core_1_12 = 16,
neoVIFIRE_Slave_VNET_MCHIP = 17,
neoVIFIRE_Slave_VNET_LCHIP = 18,
neoVIION_Core = 19,
neoVIION_HID = 20,
neoVIION_Core_Loader = 21,
neoVIION_HID_Loader = 22,
neoVIION_FPGA_BIT = 23,
neoVIFIRE_VNET_EP_MCHIP = 24,
neoVIFIRE_VNET_EP_LCHIP = 25,
neoVIAnalogOut_MCHIP = 26,
neoVIMOST25_MCHIP = 27,
neoVIMOST50_MCHIP = 28,
neoVIMOST150_MCHIP = 29,
ValueCAN4_4_MCHIP = 30,
ValueCAN4_4_SCHIP = 31,
cmProbe_ZYNQ = 33,
EEVB_STM32 = 34,
neoVIFIRE_Slave_VNET_EP_MCHIP = 35,
neoVIFIRE_Slave_VNET_EP_LCHIP = 36,
RADStar_MCHIP = 37,
ValueCANrf_MCHIP = 38,
neoVIFIRE2_MCHIP = 39,
neoVIFIRE2_CCHIP = 40,
neoVIFIRE2_Core = 41,
neoVIFIRE2_BLECHIP = 42,
neoVIFIRE2_ZYNQ = 43, // FIRE2 MVNET Z - Zynq
neoVIFIRE2_SECURITYCHIP = 44,
RADGalaxy_ZYNQ = 45,
neoVIFIRE2_VNET_MCHIP = 46,
neoVIFIRE2_Slave_VNET_A_MCHIP = 47,
neoVIFIRE2_Slave_VNET_A_CCHIP = 48,
neoVIFIRE2_VNET_CCHIP = 49,
neoVIFIRE2_VNET_Core = 50,
RADStar2_ZYNQ = 51,
VividCAN_MCHIP = 52,
neoOBD2SIM_MCHIP = 53,
neoVIFIRE2_VNETZ_MCHIP = 54,
neoVIFIRE2_VNETZ_ZYNQ = 55,
neoVIFIRE2_Slave_VNETZ_A_MCHIP = 56,
neoVIFIRE2_Slave_VNETZ_A_ZYNQ = 57,
VividCAN_EXT_FLASH = 58,
VividCAN_NRF52 = 59,
cmProbe_ZYNQ_Unused = 60, // Double defined
neoOBD2PRO_MCHIP = 61,
ValueCAN4_1_MCHIP = 62,
ValueCAN4_2_MCHIP = 63,
ValueCAN4_4_2EL_Core = 64,
neoOBD2PRO_SCHIP = 65,
ValueCAN4_2EL_MCHIP = 67,
neoECUAVBTSN_MCHIP = 68,
neoOBD2PRO_Core = 69,
RADSupermoon_ZYNQ = 70,
RADMoon2_ZYNQ = 71,
VividCANPRO_MCHIP = 72,
VividCANPRO_EXT_FLASH = 73,
RADPluto_MCHIP = 74,
RADMars_ZYNQ = 75,
neoECU12_MCHIP = 76,
RADIOCANHUB_MCHIP = 77,
FlexRay_VNETZ_ZCHIP = 78,
neoOBD2_LCBADGE_MCHIP = 79,
neoOBD2_LCBADGE_SCHIP = 80,
RADMoonDuo_MCHIP = 81,
neoVIFIRE3_ZCHIP = 82,
FlexRay_VNETZ_FCHIP = 83,
RADJupiter_MCHIP = 84,
ValueCAN4Industrial_MCHIP = 85,
EtherBADGE_MCHIP = 86,
RADMars_3_ZYNQ = 87,
RADGigastar_USBZ_ZYNQ = 88,
RADGigastar_ZYNQ = 89,
RAD4G_MCHIP = 90,
neoVIFIRE3_SCHIP = 91,
RADEpsilon_MCHIP = 92,
RADA2B_ZCHIP = 93,
neoOBD2Dev_MCHIP = 94,
neoOBD2Dev_SCHIP = 95,
neoOBD2SIMDoIP_MCHIP = 96,
SFPModule_88q2112_MCHIP = 97,
RADEpsilonT_MCHIP = 98,
RADEpsilonExpress_MCHIP = 99,
RADProxima_MCHIP = 100,
NewDevice57_ZCHIP = 101,
RAD_GALAXY_2_ZMPCHIP_ID = 102,
NewDevice59_MCHIP = 103,
RADMoon2_Z7010_ZYNQ = 104,
neoVIFIRE2_Core_SG4 = 105,
RADBMS_MCHIP = 106,
RADMoon2_ZL_MCHIP = 107,
RADGigastar_USBZ_Z7010_ZYNQ = 108,
neoVIFIRE3_LINUX = 109,
RADGigastar_USBZ_Z7007S_ZYNQ = 110,
VEM_01_8DW_ZCHIP = 111,
RADGalaxy_FFG_Zynq = 112,
RADMoon3_MCHIP = 113,
RADComet_ZYNQ = 114,
VEM_02_FR_ZCHIP = 115,
RADA2B_REVB_ZCHIP = 116,
RADGigastar_FFG_ZYNQ = 117,
VEM_02_FR_FCHIP = 118,
Connect_ZCHIP = 121,
SFPModule_88q2221_MCHIP = 122,
RADGALAXY2_SYSMON_CHIP = 123,
SFPModule_88q3244_MCHIP = 124,
RADCOMET3_ZCHIP = 125,
Connect_LINUX = 126,
SFPModule_lan8670_MCHIP = 127,
VEM_04_T1S_LIN_ZCHIP = 129,
RADMOONT1S_ZCHIP = 130,
RADGigastar2_ZYNQ = 131,
SFPModule_ent11100_MCHIP = 132,
RADGemini_MCHIP = 135,
Invalid = 255
enum class ChipID : icsneoc2_chip_id_t {
neoVIFIRE_MCHIP = icsneoc2_chip_id_neovifire_mchip,
neoVIFIRE_LCHIP = icsneoc2_chip_id_neovifire_lchip,
neoVIFIRE_UCHIP = icsneoc2_chip_id_neovifire_uchip,
neoVIFIRE_JCHIP = icsneoc2_chip_id_neovifire_jchip,
ValueCAN3_MCHIP = icsneoc2_chip_id_valuecan3_mchip,
neoVIECU_MPIC = icsneoc2_chip_id_neoviecu_mpic,
neoVIIEVB_MPIC = icsneoc2_chip_id_neoviievb_mpic,
neoVIPENDANT_MPIC = icsneoc2_chip_id_neovipendant_mpic,
neoVIFIRE_VNET_MCHIP = icsneoc2_chip_id_neovifire_vnet_mchip,
neoVIFIRE_VNET_LCHIP = icsneoc2_chip_id_neovifire_vnet_lchip,
neoVIPLASMA_Core = icsneoc2_chip_id_neoviplasma_core,
neoVIPLASMA_HID = icsneoc2_chip_id_neoviplasma_hid,
neoVIANALOG_MPIC = icsneoc2_chip_id_neovianalog_mpic,
neoVIPLASMA_ANALOG_Core = icsneoc2_chip_id_neoviplasma_analog_core,
neoVIPLASMA_FlexRay_Core = icsneoc2_chip_id_neoviplasma_flexray_core,
neoVIPLASMA_Core_1_12 = icsneoc2_chip_id_neoviplasma_core_1_12,
neoVIFIRE_Slave_VNET_MCHIP = icsneoc2_chip_id_neovifire_slave_vnet_mchip,
neoVIFIRE_Slave_VNET_LCHIP = icsneoc2_chip_id_neovifire_slave_vnet_lchip,
neoVIION_Core = icsneoc2_chip_id_neoviion_core,
neoVIION_HID = icsneoc2_chip_id_neoviion_hid,
neoVIION_Core_Loader = icsneoc2_chip_id_neoviion_core_loader,
neoVIION_HID_Loader = icsneoc2_chip_id_neoviion_hid_loader,
neoVIION_FPGA_BIT = icsneoc2_chip_id_neoviion_fpga_bit,
neoVIFIRE_VNET_EP_MCHIP = icsneoc2_chip_id_neovifire_vnet_ep_mchip,
neoVIFIRE_VNET_EP_LCHIP = icsneoc2_chip_id_neovifire_vnet_ep_lchip,
neoVIAnalogOut_MCHIP = icsneoc2_chip_id_neovianalogout_mchip,
neoVIMOST25_MCHIP = icsneoc2_chip_id_neovimost25_mchip,
neoVIMOST50_MCHIP = icsneoc2_chip_id_neovimost50_mchip,
neoVIMOST150_MCHIP = icsneoc2_chip_id_neovimost150_mchip,
ValueCAN4_4_MCHIP = icsneoc2_chip_id_valuecan4_4_mchip,
ValueCAN4_4_SCHIP = icsneoc2_chip_id_valuecan4_4_schip,
cmProbe_ZYNQ = icsneoc2_chip_id_cmprobe_zynq,
EEVB_STM32 = icsneoc2_chip_id_eevb_stm32,
neoVIFIRE_Slave_VNET_EP_MCHIP = icsneoc2_chip_id_neovifire_slave_vnet_ep_mchip,
neoVIFIRE_Slave_VNET_EP_LCHIP = icsneoc2_chip_id_neovifire_slave_vnet_ep_lchip,
RADStar_MCHIP = icsneoc2_chip_id_radstar_mchip,
ValueCANrf_MCHIP = icsneoc2_chip_id_valuecanrf_mchip,
neoVIFIRE2_MCHIP = icsneoc2_chip_id_neovifire2_mchip,
neoVIFIRE2_CCHIP = icsneoc2_chip_id_neovifire2_cchip,
neoVIFIRE2_Core = icsneoc2_chip_id_neovifire2_core,
neoVIFIRE2_BLECHIP = icsneoc2_chip_id_neovifire2_blechip,
neoVIFIRE2_ZYNQ = icsneoc2_chip_id_neovifire2_zynq, // FIRE2 MVNET Z - Zynq
neoVIFIRE2_SECURITYCHIP = icsneoc2_chip_id_neovifire2_securitychip,
RADGalaxy_ZYNQ = icsneoc2_chip_id_radgalaxy_zynq,
neoVIFIRE2_VNET_MCHIP = icsneoc2_chip_id_neovifire2_vnet_mchip,
neoVIFIRE2_Slave_VNET_A_MCHIP = icsneoc2_chip_id_neovifire2_slave_vnet_a_mchip,
neoVIFIRE2_Slave_VNET_A_CCHIP = icsneoc2_chip_id_neovifire2_slave_vnet_a_cchip,
neoVIFIRE2_VNET_CCHIP = icsneoc2_chip_id_neovifire2_vnet_cchip,
neoVIFIRE2_VNET_Core = icsneoc2_chip_id_neovifire2_vnet_core,
RADStar2_ZYNQ = icsneoc2_chip_id_radstar2_zynq,
VividCAN_MCHIP = icsneoc2_chip_id_vividcan_mchip,
neoOBD2SIM_MCHIP = icsneoc2_chip_id_neoobd2sim_mchip,
neoVIFIRE2_VNETZ_MCHIP = icsneoc2_chip_id_neovifire2_vnetz_mchip,
neoVIFIRE2_VNETZ_ZYNQ = icsneoc2_chip_id_neovifire2_vnetz_zynq,
neoVIFIRE2_Slave_VNETZ_A_MCHIP = icsneoc2_chip_id_neovifire2_slave_vnetz_a_mchip,
neoVIFIRE2_Slave_VNETZ_A_ZYNQ = icsneoc2_chip_id_neovifire2_slave_vnetz_a_zynq,
VividCAN_EXT_FLASH = icsneoc2_chip_id_vividcan_ext_flash,
VividCAN_NRF52 = icsneoc2_chip_id_vividcan_nrf52,
cmProbe_ZYNQ_Unused = icsneoc2_chip_id_cmprobe_zynq_unused, // Double defined
neoOBD2PRO_MCHIP = icsneoc2_chip_id_neoobd2pro_mchip,
ValueCAN4_1_MCHIP = icsneoc2_chip_id_valuecan4_1_mchip,
ValueCAN4_2_MCHIP = icsneoc2_chip_id_valuecan4_2_mchip,
ValueCAN4_4_2EL_Core = icsneoc2_chip_id_valuecan4_4_2el_core,
neoOBD2PRO_SCHIP = icsneoc2_chip_id_neoobd2pro_schip,
ValueCAN4_2EL_MCHIP = icsneoc2_chip_id_valuecan4_2el_mchip,
neoECUAVBTSN_MCHIP = icsneoc2_chip_id_neoecuavbtsn_mchip,
neoOBD2PRO_Core = icsneoc2_chip_id_neoobd2pro_core,
RADSupermoon_ZYNQ = icsneoc2_chip_id_radsupermoon_zynq,
RADMoon2_ZYNQ = icsneoc2_chip_id_radmoon2_zynq,
VividCANPRO_MCHIP = icsneoc2_chip_id_vividcanpro_mchip,
VividCANPRO_EXT_FLASH = icsneoc2_chip_id_vividcanpro_ext_flash,
RADPluto_MCHIP = icsneoc2_chip_id_radpluto_mchip,
RADMars_ZYNQ = icsneoc2_chip_id_radmars_zynq,
neoECU12_MCHIP = icsneoc2_chip_id_neoecu12_mchip,
RADIOCANHUB_MCHIP = icsneoc2_chip_id_radiocanhub_mchip,
FlexRay_VNETZ_ZCHIP = icsneoc2_chip_id_flexray_vnetz_zchip,
neoOBD2_LCBADGE_MCHIP = icsneoc2_chip_id_neoobd2_lcbadge_mchip,
neoOBD2_LCBADGE_SCHIP = icsneoc2_chip_id_neoobd2_lcbadge_schip,
RADMoonDuo_MCHIP = icsneoc2_chip_id_radmoonduo_mchip,
neoVIFIRE3_ZCHIP = icsneoc2_chip_id_neovifire3_zchip,
FlexRay_VNETZ_FCHIP = icsneoc2_chip_id_flexray_vnetz_fchip,
RADJupiter_MCHIP = icsneoc2_chip_id_radjupiter_mchip,
ValueCAN4Industrial_MCHIP = icsneoc2_chip_id_valuecan4industrial_mchip,
EtherBADGE_MCHIP = icsneoc2_chip_id_etherbadge_mchip,
RADMars_3_ZYNQ = icsneoc2_chip_id_radmars_3_zynq,
RADGigastar_USBZ_ZYNQ = icsneoc2_chip_id_radgigastar_usbz_zynq,
RADGigastar_ZYNQ = icsneoc2_chip_id_radgigastar_zynq,
RAD4G_MCHIP = icsneoc2_chip_id_rad4g_mchip,
neoVIFIRE3_SCHIP = icsneoc2_chip_id_neovifire3_schip,
RADEpsilon_MCHIP = icsneoc2_chip_id_radepsilon_mchip,
RADA2B_ZCHIP = icsneoc2_chip_id_rada2b_zchip,
neoOBD2Dev_MCHIP = icsneoc2_chip_id_neoobd2dev_mchip,
neoOBD2Dev_SCHIP = icsneoc2_chip_id_neoobd2dev_schip,
neoOBD2SIMDoIP_MCHIP = icsneoc2_chip_id_neoobd2simdoip_mchip,
SFPModule_88q2112_MCHIP = icsneoc2_chip_id_sfpmodule_88q2112_mchip,
RADEpsilonT_MCHIP = icsneoc2_chip_id_radepsilont_mchip,
RADEpsilonExpress_MCHIP = icsneoc2_chip_id_radepsilonexpress_mchip,
RADProxima_MCHIP = icsneoc2_chip_id_radproxima_mchip,
NewDevice57_ZCHIP = icsneoc2_chip_id_newdevice57_zchip,
RAD_GALAXY_2_ZMPCHIP_ID = icsneoc2_chip_id_rad_galaxy_2_zmpchip_id,
NewDevice59_MCHIP = icsneoc2_chip_id_newdevice59_mchip,
RADMoon2_Z7010_ZYNQ = icsneoc2_chip_id_radmoon2_z7010_zynq,
neoVIFIRE2_Core_SG4 = icsneoc2_chip_id_neovifire2_core_sg4,
RADBMS_MCHIP = icsneoc2_chip_id_radbms_mchip,
RADMoon2_ZL_MCHIP = icsneoc2_chip_id_radmoon2_zl_mchip,
RADGigastar_USBZ_Z7010_ZYNQ = icsneoc2_chip_id_radgigastar_usbz_z7010_zynq,
neoVIFIRE3_LINUX = icsneoc2_chip_id_neovifire3_linux,
RADGigastar_USBZ_Z7007S_ZYNQ = icsneoc2_chip_id_radgigastar_usbz_z7007s_zynq,
VEM_01_8DW_ZCHIP = icsneoc2_chip_id_vem_01_8dw_zchip,
RADGalaxy_FFG_Zynq = icsneoc2_chip_id_radgalaxy_ffg_zynq,
RADMoon3_MCHIP = icsneoc2_chip_id_radmoon3_mchip,
RADComet2_ZYNQ = icsneoc2_chip_id_radcomet2_zynq,
VEM_02_FR_ZCHIP = icsneoc2_chip_id_vem_02_fr_zchip,
RADA2B_REVB_ZCHIP = icsneoc2_chip_id_rada2b_revb_zchip,
RADGigastar_FFG_ZYNQ = icsneoc2_chip_id_radgigastar_ffg_zynq,
VEM_02_FR_FCHIP = icsneoc2_chip_id_vem_02_fr_fchip,
Connect_ZCHIP = icsneoc2_chip_id_connect_zchip,
SFPModule_88q2221_MCHIP = icsneoc2_chip_id_sfpmodule_88q2221_mchip,
RADGALAXY2_SYSMON_CHIP = icsneoc2_chip_id_radgalaxy2_sysmon_chip,
SFPModule_88q3244_MCHIP = icsneoc2_chip_id_sfpmodule_88q3244_mchip,
RADCOMET3_ZCHIP = icsneoc2_chip_id_radcomet3_zchip,
Connect_LINUX = icsneoc2_chip_id_connect_linux,
SFPModule_lan8670_MCHIP = icsneoc2_chip_id_sfpmodule_lan8670_mchip,
VEM_04_T1S_LIN_ZCHIP = icsneoc2_chip_id_vem_04_t1s_lin_zchip,
RADMOONT1S_ZCHIP = icsneoc2_chip_id_radmoont1s_zchip,
RADGigastar2_ZYNQ = icsneoc2_chip_id_radgigastar2_zynq,
SFPModule_ent11100_MCHIP = icsneoc2_chip_id_sfpmodule_ent11100_mchip,
RADGemini_MCHIP = icsneoc2_chip_id_radgemini_mchip,
Invalid = icsneoc2_chip_id_invalid
};
}

View File

@ -59,6 +59,7 @@
#include "icsneo/communication/message/versionmessage.h"
#include "icsneo/communication/message/gptpstatusmessage.h"
#include "icsneo/communication/message/networkmutexmessage.h"
#include "icsneo/communication/message/allmacaddressesmessage.h"
#define ICSNEO_FINDABLE_DEVICE_BASE(className, type) \
static constexpr DeviceType::Enum DEVICE_TYPE = type; \
@ -86,7 +87,7 @@ class DeviceExtension;
typedef uint64_t MemoryAddress;
class Device {
class Device : public std::enable_shared_from_this<Device> {
public:
virtual ~Device();
@ -133,7 +134,7 @@ public:
SFPModule_88q2112 = 41,
RADGalaxy2 = 47,
RADMoon3 = 49,
RADComet = 50,
RADComet2 = 50,
Connect = 51,
SFPModule_88q2221m = 52,
SFPModule_88q4364 = 53,
@ -183,7 +184,7 @@ public:
std::string getSerial() const { return data.serial; }
uint32_t getSerialNumber() const { return Device::SerialStringToNum(getSerial()); }
std::optional<std::vector<uint8_t>> getPCBSerial();
std::optional<std::vector<uint8_t>> getMACAddress();
std::unordered_map<Network::NetID, MACAddress> getMACAddresses();
const neodevice_t& getNeoDevice() const { return data; }
virtual std::string getProductName() const { return getType().getGenericProductName(); }
std::string describe() const;
@ -858,13 +859,20 @@ public:
}
virtual bool supportsTC10() const { return false; }
virtual bool supportsGPTP() const { return false; }
virtual bool supportsReboot() const { return false; }
bool requestTC10Wake(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<GPTPStatus> getGPTPStatus(std::chrono::milliseconds timeout = std::chrono::milliseconds(100));
@ -929,7 +937,7 @@ protected:
virtual device_eventhandler_t makeEventHandler() {
return [this](APIEvent::Type type, APIEvent::Severity severity) {
EventManager::GetInstance().add(type, severity, this);
EventManager::GetInstance().add(type, severity, weak_from_this());
};
}
@ -998,6 +1006,8 @@ protected:
bool supportsNetworkMutex = false;
virtual bool supportsGetAllMACAddresses() const { return true; }
private:
neodevice_t data;
std::shared_ptr<ResetStatusMessage> latestResetStatus;

View File

@ -53,7 +53,7 @@ public:
RADEpsilonXL = icsneoc2_devicetype_rad_epsilon_xl,
RADGalaxy2 = icsneoc2_devicetype_rad_galaxy2,
RADMoon3 = icsneoc2_devicetype_rad_moon3,
RADComet = icsneoc2_devicetype_rad_comet,
RADComet2 = icsneoc2_devicetype_rad_comet2,
FIRE3_FlexRay = icsneoc2_devicetype_fire3_flexray,
Connect = icsneoc2_devicetype_connect,
RADComet3 = icsneoc2_devicetype_rad_comet3,
@ -154,8 +154,8 @@ public:
return "RAD-Moon 3";
case RADGemini:
return "RAD-Gemini";
case RADComet:
return "RAD-Comet";
case RADComet2:
return "RAD-Comet 2";
case RED:
return "neoVI RED";
case ECU:
@ -269,7 +269,7 @@ private:
#define ICSNEO_DEVICETYPE_RADEPSILONXL ((devicetype_t)icsneoc2_devicetype_rad_epsilon_xl)
#define ICSNEO_DEVICETYPE_RADGALAXY2 ((devicetype_t)icsneoc2_devicetype_rad_galaxy2)
#define ICSNEO_DEVICETYPE_RADMoon3 ((devicetype_t)icsneoc2_devicetype_rad_moon3)
#define ICSNEO_DEVICETYPE_RADCOMET ((devicetype_t)icsneoc2_devicetype_rad_comet)
#define ICSNEO_DEVICETYPE_RADCOMET2 ((devicetype_t)icsneoc2_devicetype_rad_comet2)
#define ICSNEO_DEVICETYPE_FIRE3FLEXRAY ((devicetype_t)icsneoc2_devicetype_fire3_flexray)
#define ICSNEO_DEVICETYPE_CONNECT ((devicetype_t)icsneoc2_devicetype_connect)
#define ICSNEO_DEVICETYPE_RADCOMET3 ((devicetype_t)icsneoc2_devicetype_rad_comet3)

View File

@ -613,6 +613,18 @@ enum : uint8_t
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 */
enum LINMode
{
@ -761,6 +773,13 @@ enum class MiscIOAnalogVoltage : uint8_t
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 {
public:
using TerminationGroup = std::vector<Network>;
@ -1265,9 +1284,45 @@ public:
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 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(); }
void* getMutableRawStructurePointer() { return settings.data(); }
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)
: 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(uint64_t*) getMutableTerminationEnables() {
if(disabled || readonly)

View File

@ -62,6 +62,9 @@ protected:
return true;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}

View File

@ -81,6 +81,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<etherbadge_settings_t>();
if(cfg == nullptr)
@ -92,6 +93,7 @@ public:
return nullptr;
}
}
const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
auto cfg = getStructurePointer<etherbadge_settings_t>();
if(cfg == nullptr)
@ -103,6 +105,23 @@ public:
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;
}
};
}

View File

@ -26,6 +26,11 @@ public:
return ProductID::neoOBD2Pro;
}
protected:
bool supportsGetAllMACAddresses() const override {
return false;
}
private:
NeoOBD2PRO(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize(makeDriver);

View File

@ -25,6 +25,12 @@ public:
ProductID getProductID() const override {
return ProductID::neoOBD2Sim;
}
protected:
bool supportsGetAllMACAddresses() const override {
return false;
}
private:
NeoOBD2SIM(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize(makeDriver);

View File

@ -34,6 +34,8 @@ public:
return supportedNetworks;
}
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::Connect;
}
@ -93,7 +95,6 @@ protected:
}
bool supportsGPTP() const override { return true; }
size_t getDiskCount() const override {
return 2;
}

View File

@ -89,6 +89,16 @@ static_assert(sizeof(neoviconnect_settings_t) == 628, "NeoVIConnect settings siz
class NeoVIConnectSettings : public IDeviceSettings {
public:
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 {
auto cfg = getStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr)
@ -114,6 +124,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr)
@ -139,6 +150,7 @@ public:
return nullptr;
}
}
const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neoviconnect_settings_t>();
if(cfg == nullptr)
@ -152,6 +164,32 @@ public:
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;
}
};
}

View File

@ -60,6 +60,12 @@ public:
ProductID getProductID() const override {
return ProductID::neoVIFIRE;
}
protected:
bool supportsGetAllMACAddresses() const override {
return false;
}
private:
NeoVIFIRE(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<NeoVIFIRESettings>(makeDriver);

View File

@ -121,6 +121,7 @@ public:
return nullptr;
}
}
const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override { return getCANSettingsFor(net); }
const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire_settings_t>();
@ -133,6 +134,7 @@ public:
return nullptr;
}
}
const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire_settings_t>();
if(cfg == nullptr)
@ -150,6 +152,23 @@ public:
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;
}
};
}

View File

@ -155,6 +155,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire2_settings_t>();
if(cfg == nullptr)
@ -180,6 +181,7 @@ public:
return nullptr;
}
}
const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override { return getCANSettingsFor(net); }
const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override {
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:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovifire2_settings_t>();

View File

@ -46,11 +46,15 @@ public:
Network::NetID::LIN_06,
Network::NetID::LIN_07,
Network::NetID::LIN_08,
Network::NetID::MDIO_01,
};
return supportedNetworks;
}
size_t getEthernetActivationLineCount() const override { return 2; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::neoVIFIRE3;
}

View File

@ -167,6 +167,16 @@ static_assert(sizeof(neovifire3_settings_t) == 1722, "NeoVIFire3 settings size m
class NeoVIFIRE3Settings : public IDeviceSettings {
public:
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 {
auto cfg = getStructurePointer<neovifire3_settings_t>();
if(cfg == nullptr)
@ -208,6 +218,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3_settings_t>();
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:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovifire3_settings_t>();
@ -404,6 +432,15 @@ protected:
return nullptr;
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;
}
};
}

View File

@ -49,10 +49,14 @@ public:
Network::NetID::FLEXRAY_02,
Network::NetID::FLEXRAY_02A,
Network::NetID::FLEXRAY_02B,
Network::NetID::MDIO_01,
};
return supportedNetworks;
}
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::neoVIFIRE3;
}
@ -109,7 +113,7 @@ protected:
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
bool supportsWiVI() const override { return true; }
bool supportsLiveData() const override { return true; }
std::optional<MemoryAddress> getCoreminiStartAddressFlash() const override {

View File

@ -150,6 +150,16 @@ static_assert(sizeof(neovifire3flexray_settings_t) == 1372, "NeoVIFire3Flexray s
class NeoVIFIRE3FlexRaySettings : public IDeviceSettings {
public:
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 {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
if(cfg == nullptr)
@ -175,6 +185,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
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:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
@ -243,6 +271,15 @@ protected:
return nullptr;
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;
}
};
}

View File

@ -53,12 +53,16 @@ public:
Network::NetID::AE_06,
Network::NetID::AE_07,
Network::NetID::AE_08,
Network::NetID::MDIO_01,
};
return supportedNetworks;
}
bool supportsTC10() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::neoVIFIRE3;
}

View File

@ -159,6 +159,16 @@ static_assert(sizeof(neovifire3t1slin_settings_t) == 1594, "NeoVIFire3T1SLIN set
class NeoVIFIRE3T1SLINSettings : public IDeviceSettings {
public:
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 {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr)
@ -184,6 +194,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr)
@ -466,6 +477,23 @@ public:
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:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
@ -554,6 +582,15 @@ protected:
return nullptr;
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;
}
};
}

View File

@ -30,13 +30,17 @@ public:
Network::NetID::ETHERNET_02,
Network::NetID::LIN_01,
Network::NetID::LIN_02
Network::NetID::LIN_02,
Network::NetID::MDIO_01,
};
return supportedNetworks;
}
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::neoVIFIRE3;
}

View File

@ -112,6 +112,16 @@ static_assert(sizeof(neovired2_settings_t) == 918, "NeoVIRED2 settings size mism
class NeoVIRED2Settings : public IDeviceSettings {
public:
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 {
auto cfg = getStructurePointer<neovired2_settings_t>();
if(cfg == nullptr)
@ -137,6 +147,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<neovired2_settings_t>();
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:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovired2_settings_t>();
@ -302,6 +330,15 @@ protected:
return nullptr;
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;
}
};
}

View File

@ -92,6 +92,10 @@ protected:
}
bool supportsWiVI() const override { return true; }
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}

View File

@ -114,6 +114,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<rada2b_settings_t>();
if(cfg == nullptr)
@ -241,6 +242,32 @@ public:
}
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;
}
};
}

View File

@ -1,34 +0,0 @@
#ifndef __RADCOMET_H_
#define __RADCOMET_H_
#ifdef __cplusplus
#include "icsneo/device/tree/radcomet/radcometbase.h"
#include "icsneo/device/tree/radcomet/radcometsettings.h"
namespace icsneo {
class RADComet : public RADCometBase {
public:
// Serial numbers start with RC
// USB PID is 0x1207, standard driver is DXX
// Ethernet MAC allocation is 0x1D, standard driver is Raw
ICSNEO_FINDABLE_DEVICE_BY_SERIAL_RANGE(RADComet, DeviceType::RADComet, "RC0000", "RC0299");
std::string getProductName() const override {
return "RAD-Comet";
}
protected:
RADComet(neodevice_t neodevice, const driver_factory_t& makeDriver) : RADCometBase(neodevice) {
initialize<RADCometSettings>(makeDriver);
}
};
}
#endif // __cplusplus
#endif

View File

@ -1,45 +0,0 @@
#ifndef __RADCOMET2_H_
#define __RADCOMET2_H_
#ifdef __cplusplus
#include "icsneo/device/tree/radcomet/radcometbase.h"
#include "icsneo/device/tree/radcomet/radcometsettings.h"
namespace icsneo {
class RADComet2 : public RADCometBase {
public:
// Serial numbers start with RC, Comet2 starts at RC0300
// USB PID is 0x1207, standard driver is DXX
// Ethernet MAC allocation is 0x1D, standard driver is Raw
ICSNEO_FINDABLE_DEVICE_BY_SERIAL_RANGE(RADComet2, DeviceType::RADComet, "RC0300", "RCZZZZ");
std::string getProductName() const override {
return "RAD-Comet 2";
}
const std::vector<Network>& GetSupportedNetworks() override {
static std::vector<Network> supportedNetworks = RADCometBase::GetSupportedNetworks();
supportedNetworks.push_back(Network::NetID::AE_03);
supportedNetworks.push_back(Network::NetID::MDIO_04);
supportedNetworks.push_back(Network::NetID::LIN_01);
supportedNetworks.push_back(Network::NetID::ISO9141_01);
return supportedNetworks;
}
bool supportsTC10() const override { return true; }
protected:
RADComet2(neodevice_t neodevice, const driver_factory_t& makeDriver) : RADCometBase(neodevice) {
initialize<RADCometSettings>(makeDriver);
}
};
}
#endif // __cplusplus
#endif

View File

@ -1,16 +1,23 @@
#ifndef __RADCOMETBASE_H_
#define __RADCOMETBASE_H_
#ifndef __RADCOMET2_H_
#define __RADCOMET2_H_
#ifdef __cplusplus
#include "icsneo/device/device.h"
#include "icsneo/device/devicetype.h"
#include "icsneo/device/tree/radcomet2/radcomet2settings.h"
namespace icsneo {
class RADCometBase : public Device {
class RADComet2 : public Device {
public:
virtual const std::vector<Network>& GetSupportedNetworks() {
// Serial numbers start with RC
// USB PID is 0x1207, standard driver is DXX
// Ethernet MAC allocation is 0x1D, standard driver is Raw
ICSNEO_FINDABLE_DEVICE_BY_SERIAL_RANGE(RADComet2, DeviceType::RADComet2, "RC0300", "RCZZZZ");
static const std::vector<Network>& GetSupportedNetworks() {
static std::vector<Network> supportedNetworks = {
Network::NetID::DWCAN_01,
Network::NetID::DWCAN_02,
@ -19,39 +26,51 @@ public:
Network::NetID::AE_01,
Network::NetID::AE_02,
Network::NetID::AE_03,
Network::NetID::MDIO_01,
Network::NetID::MDIO_02,
Network::NetID::MDIO_03,
Network::NetID::MDIO_04,
Network::NetID::LIN_01,
Network::NetID::ISO9141_01,
};
return supportedNetworks;
}
std::string getProductName() const override {
return "RAD-Comet 2";
}
bool getEthPhyRegControlSupported() const override { return true; }
bool supportsTC10() const override { return true; }
bool supportsGPTP() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADComet;
return ProductID::RADComet2;
}
const std::vector<ChipInfo>& getChipInfo() const override {
static std::vector<ChipInfo> chips = {
{ChipID::RADComet_ZYNQ, true, "ZCHIP", "RADComet_SW_bin", 0, FirmwareType::Zip},
{ChipID::RADComet2_ZYNQ, true, "ZCHIP", "RADComet_SW_bin", 0, FirmwareType::Zip},
};
return chips;
}
BootloaderPipeline getBootloader() override {
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::RADComet_ZYNQ, BootloaderCommunication::RAD)
.add<EnterApplicationPhase>(ChipID::RADComet_ZYNQ)
.add<FlashPhase>(ChipID::RADComet2_ZYNQ, BootloaderCommunication::RAD)
.add<EnterApplicationPhase>(ChipID::RADComet2_ZYNQ)
.add<WaitPhase>(std::chrono::milliseconds(3000))
.add<ReconnectPhase>();
}
protected:
using Device::Device;
RADComet2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<RADComet2Settings>(makeDriver);
}
void setupPacketizer(Packetizer& packetizer) override {
Device::setupPacketizer(packetizer);
@ -61,13 +80,13 @@ protected:
void setupEncoder(Encoder& encoder) override {
Device::setupEncoder(encoder);
encoder.supportCANFD = true;
encoder.supportCANFD = true;
encoder.supportEthPhy = true;
}
void setupDecoder(Decoder& decoder) override {
Device::setupDecoder(decoder);
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
decoder.timestampResolution = 10;
}
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
@ -75,7 +94,6 @@ protected:
rxNetworks.emplace_back(netid);
}
// The supported TX networks are the same as the supported RX networks for this device
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
std::optional<MemoryAddress> getCoreminiStartAddressFlash() const override {
@ -88,4 +106,4 @@ protected:
#endif // __cplusplus
#endif
#endif

View File

@ -1,5 +1,5 @@
#ifndef __RADCOMETSETTINGS_H_
#define __RADCOMETSETTINGS_H_
#ifndef __RADCOMET2SETTINGS_H_
#define __RADCOMET2SETTINGS_H_
#include <stdint.h>
#include "icsneo/device/idevicesettings.h"
@ -74,7 +74,7 @@ typedef struct {
// 10T1S Extended settings
ETHERNET10T1S_SETTINGS_EXT t1s1Ext;
ETHERNET10T1S_SETTINGS_EXT t1s2Ext;
} radcomet_settings_t;
} radcomet2_settings_t;
#pragma pack(pop)
#ifdef _MSC_VER
@ -83,15 +83,15 @@ typedef struct {
#ifdef __cplusplus
static_assert(sizeof(radcomet_settings_t) == 498, "RADComet settings size mismatch");
static_assert(sizeof(radcomet2_settings_t) == 498, "RADComet2 settings size mismatch");
#include <iostream>
class RADCometSettings : public IDeviceSettings {
class RADComet2Settings : public IDeviceSettings {
public:
RADCometSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radcomet_settings_t)) {}
RADComet2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radcomet2_settings_t)) {}
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radcomet_settings_t>();
auto cfg = getStructurePointer<radcomet2_settings_t>();
if(cfg == nullptr)
return nullptr;
switch(net.getNetID()) {
@ -103,8 +103,9 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radcomet_settings_t>();
auto cfg = getStructurePointer<radcomet2_settings_t>();
if(cfg == nullptr)
return nullptr;
switch(net.getNetID()) {
@ -244,9 +245,26 @@ public:
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:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radcomet_settings_t>();
auto cfg = getStructurePointer<radcomet2_settings_t>();
if(cfg == nullptr)
return nullptr;
@ -260,7 +278,7 @@ private:
}
ETHERNET10T1S_SETTINGS* getMutableT1SSettingsFor(Network net) {
auto cfg = getMutableStructurePointer<radcomet_settings_t>();
auto cfg = getMutableStructurePointer<radcomet2_settings_t>();
if(cfg == nullptr)
return nullptr;
@ -272,6 +290,15 @@ private:
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;
}
};
}

View File

@ -100,6 +100,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radcomet3_settings_t>();
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:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radcomet3_settings_t>();
@ -710,6 +728,15 @@ private:
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;
}
};
}

View File

@ -79,6 +79,10 @@ protected:
size_t getDiskCount() const override {
return 1;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}

View File

@ -100,6 +100,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radepsilon_settings_t>();
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:
enum class EpsilonPhyMode : uint8_t {
Auto = 0,

View File

@ -85,6 +85,10 @@ protected:
size_t getDiskCount() const override {
return 1;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}; // namespace icsneo

View File

@ -135,6 +135,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radgalaxy_settings_t>();
if(cfg == nullptr)
@ -160,6 +161,7 @@ public:
return nullptr;
}
}
const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radgalaxy_settings_t>();
if(cfg == nullptr)
@ -271,6 +273,32 @@ public:
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;
}
};
}

View File

@ -151,6 +151,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radgalaxy2_settings_t>();
if(cfg == nullptr)
@ -259,6 +260,32 @@ public:
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;
}
};
}

View File

@ -129,6 +129,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radgigastar_settings_t>();
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:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<radgigastar_settings_t>();
@ -185,6 +203,15 @@ protected:
return nullptr;
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 {

View File

@ -217,7 +217,7 @@ public:
protected:
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

View File

@ -176,6 +176,7 @@ namespace icsneo
return nullptr;
}
}
const CANFD_SETTINGS *getCANFDSettingsFor(Network net) const override
{
auto cfg = getStructurePointer<radgigastar2_settings_t>();
@ -537,6 +538,23 @@ namespace icsneo
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:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radgigastar2_settings_t>();
@ -627,6 +645,14 @@ namespace icsneo
return nullptr;
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

View File

@ -80,6 +80,10 @@ protected:
bool supportsEraseMemory() const override {
return true;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}

View File

@ -105,6 +105,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radjupiter_settings_t>();
if(cfg == nullptr)
@ -118,6 +119,7 @@ public:
return nullptr;
}
}
const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radjupiter_settings_t>();
if(cfg == nullptr)
@ -129,6 +131,23 @@ public:
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;
}
};
}

View File

@ -43,6 +43,15 @@ static_assert(sizeof(radmoon2_settings_t) == 170, "RADMoon2 settings size mismat
class RADMoon2Settings : public IDeviceSettings {
public:
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;
}
};
}

View File

@ -60,6 +60,10 @@ protected:
bool supportsEraseMemory() const override {
return true;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}

View File

@ -154,6 +154,23 @@ public:
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:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radmoont1s_settings_t>();
@ -363,6 +380,15 @@ private:
cfg->t1sExt.multi_id[index] = id;
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;
}
};
}

View File

@ -90,6 +90,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radpluto_settings_t>();
if(cfg == nullptr)
@ -115,6 +116,23 @@ public:
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;
}
};
}

View File

@ -35,6 +35,21 @@ public:
ProductID getProductID() const override {
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:
RADStar2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<RADStar2Settings>(makeDriver);
@ -71,6 +86,10 @@ protected:
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
return 0;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}

View File

@ -91,6 +91,7 @@ public:
return nullptr;
}
}
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
auto cfg = getStructurePointer<radstar2_settings_t>();
if(cfg == nullptr)
@ -116,6 +117,32 @@ public:
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;
}
};
}

View File

@ -25,6 +25,11 @@ public:
ProductID getProductID() const override {
return ProductID::ValueCAN3;
}
protected:
bool supportsGetAllMACAddresses() const override {
return false;
}
private:
ValueCAN3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<ValueCAN3Settings>(makeDriver);

View File

@ -51,6 +51,23 @@ public:
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;
}
};
}

View File

@ -28,6 +28,10 @@ protected:
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
return 0;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}

View File

@ -68,6 +68,10 @@ protected:
bool supportsEraseMemory() const override {
return true;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}

View File

@ -62,6 +62,7 @@ public:
return nullptr;
}
}
const CAN_SETTINGS* getLSFTCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<vividcan_settings_t>();
if(cfg == nullptr)
@ -73,6 +74,7 @@ public:
return nullptr;
}
}
const SWCAN_SETTINGS* getSWCANSettingsFor(Network net) const override {
auto cfg = getStructurePointer<vividcan_settings_t>();
if(cfg == nullptr)
@ -115,6 +117,23 @@ public:
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:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
// Check the structure pointer even though we're not using it so

View File

@ -223,7 +223,7 @@ typedef unsigned __int64 uint64_t;
#define NEODEVICE_RAD_GALAXY_2 (0x00000021)
#define NEODEVICE_RAD_BMS (0x00000022)
#define NEODEVICE_RADMOON3 (0x00000023)
#define NEODEVICE_RADCOMET (0x00000024)
#define NEODEVICE_RADCOMET2 (0x00000024)
#define NEODEVICE_FIRE3_FLEXRAY (0x00000025)
#define NEODEVICE_RED2_OEM (0x00000026)
#define NEODEVICE_RADCOMET3 (0x00000027)

View File

@ -19,6 +19,8 @@ typedef struct icsneoc2_message_t icsneoc2_message_t;
typedef struct icsneoc2_event_t icsneoc2_event_t;
typedef struct icsneoc2_supported_device_t icsneoc2_supported_device_t;
typedef enum _icsneoc2_error_t {
icsneoc2_error_success, // Function was successful
icsneoc2_error_invalid_parameters, // Invalid parameters, typically because of a NULL reference.
@ -65,6 +67,44 @@ static const icsneoc2_open_options_t icsneoc2_open_options_default =
*/
icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* value, size_t* value_length);
/**
* Enumerate supported device types.
*
* @param[out] supported_devices Pointer to receive the head of the supported device types linked list. Must be freed with icsneoc2_supported_devices_free().
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_supported_devices_enumerate(icsneoc2_supported_device_t** supported_devices);
/**
* Free a supported device types list returned by icsneoc2_supported_devices_enumerate().
*
* @param[in] supported_devices The head of the supported device types linked list to free.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_supported_devices_free(icsneoc2_supported_device_t* supported_devices);
/**
* Advance to the next supported device type in a list.
*
* @param[in] supported_device The current supported device type node.
*
* @return The next supported device type node, or NULL at the end of the list.
*/
icsneoc2_supported_device_t* icsneoc2_supported_devices_next(const icsneoc2_supported_device_t* supported_device);
/**
* Get the device type from a supported device node.
*
* @param[in] supported_device The supported device node.
* @param[out] device_type Pointer to receive the device type.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_supported_device_get(const icsneoc2_supported_device_t* supported_device, icsneoc2_devicetype_t* device_type);
/**
* Get the device type string for a icsneoc2_devicetype_t.
*
@ -303,15 +343,52 @@ icsneoc2_error_t icsneoc2_device_serial_get(const icsneoc2_device_t* device, cha
icsneoc2_error_t icsneoc2_device_pcb_serial_get(const icsneoc2_device_t* device, uint8_t* value, size_t* value_length);
/**
* Get the MAC address of a device.
* Enumerate MAC addresses from a device.
*
* @param[in] device The device to get the MAC address of.
* @param[out] value Pointer to a buffer to copy the MAC address into. If NULL, only value_length is written.
* @param[in,out] value_length Size of the value buffer in bytes. Modified with the length of the MAC address.
* @param[in] device The device to query.
* @param[out] mac_entries Pointer to receive the head of the MAC addresses linked list.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_type if the device does not have a MAC address.
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters on failure.
*/
icsneoc2_error_t icsneoc2_device_mac_address_get(const icsneoc2_device_t* device, uint8_t* value, size_t* value_length);
icsneoc2_error_t icsneoc2_device_mac_addresses_enumerate(const icsneoc2_device_t* device, icsneoc2_mac_addr_entry_t** mac_entries);
/**
* Get the network ID of a MAC address.
*
* @param[in] mac_address The MAC address object to get the network ID of.
* @param[out] network_id Pointer to an icsneoc2_netid_t to copy the network ID into.
*
* @return icsneoc2_error_t icsneoc2_error success if successful, icsneoc2_error_invalid_parameters on failure.
*/
icsneoc2_error_t icsneoc2_mac_network_id_get(const icsneoc2_mac_addr_entry_t* mac_address, _icsneoc2_netid_t* network_id);
/**
* Get the MAC Address bytes of a MAC address.
*
* @param[in] mac_address The MAC address object to get the MAC address bytes of.
* @param[out] value Pointer to a buffer to copy the MAC address into. If NULL, only value_length is written.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters on failure.
*/
icsneoc2_error_t icsneoc2_mac_address_get(const icsneoc2_mac_addr_entry_t* mac_address, uint8_t* value, size_t* value_length);
/**
* Advance to the next MAC address in an enumeration list.
*
* @param[in] mac_address The current MAC address node.
*
* @return icsneoc2_mac_addr_entry_t The next MAC address node.
*/
icsneoc2_mac_addr_entry_t* icsneoc2_mac_addresses_next(const icsneoc2_mac_addr_entry_t* mac_address);
/**
* Free all MAC addresses in enumeration handle returned by icsneoc2_device_mac_addresses_enumerate().
*
* @param[in] mac_address The head of the MAC address enumeration to free. May be NULL.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_mac_addresses_free(icsneoc2_mac_addr_entry_t* mac_address);
/**
* Set the online state of a device.
@ -504,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.
*/
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.
*
@ -993,6 +1114,50 @@ icsneoc2_error_t icsneoc2_script_status_diagnostic_error_code_count_get(const ic
*/
icsneoc2_error_t icsneoc2_script_status_max_coremini_size_kb_get(const icsneoc2_script_status_t* script_status, uint16_t* value);
/**
* Get the list of chip versions on the device.
*
* @param[in] device The device to query.
* @param[out] chip_versions Receives a newly allocated chip versions handle. The caller owns this handle and must free it with icsneoc2_chip_versions_free() when done.
* @param[in] refresh Whether to refresh the chip versions from the device.
* @param[out] count Receives the number of chip versions. May be NULL if not needed.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_device_chip_versions_enumerate(const icsneoc2_device_t* device, icsneoc2_chip_versions_t** chip_versions, bool refresh, size_t* count);
/**
* Free a chip versions handle returned by icsneoc2_device_chip_versions_enumerate().
*
* @param[in] chip_versions The chip versions handle to free. May be NULL.
*/
icsneoc2_error_t icsneoc2_chip_versions_free(icsneoc2_chip_versions_t* chip_versions);
/**
* Advance to the next chip version in an enumeration list.
*
* @param[in] chip_versions The current chip versions handle.
*
* @return The next chip version handle, or NULL at the end of the list.
*/
icsneoc2_chip_versions_t* icsneoc2_chip_versions_next(const icsneoc2_chip_versions_t* chip_versions);
/**
* Get the properties of a chip version.
*
* @param[in] chip_versions The chip versions handle to query.
* @param[out] name Pointer to a buffer to copy the null-terminated chip name into. May be NULL if the name is not needed.
* @param[in,out] name_length On input, the size of the name buffer. On output, the length of the chip name. May be NULL if the name is not needed.
* @param[out] major Pointer to receive the major version number. May be NULL.
* @param[out] minor Pointer to receive the minor version number. May be NULL.
* @param[out] maintenance Pointer to receive the maintenance version number. May be NULL.
* @param[out] build Pointer to receive the build version number. May be NULL.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_string_copy_failed otherwise.
*/
icsneoc2_error_t icsneoc2_chip_versions_props_get(const icsneoc2_chip_versions_t* chip_versions, char* name, size_t* name_length, uint8_t* major, uint8_t* minor, uint8_t* maintenance, uint8_t* build);
#ifdef __cplusplus
}
#endif

Some files were not shown because too many files have changed in this diff Show More