37 Commits
Author SHA1 Message Date
Gowtham NanjukuttyandGitHub f95d65817e Merge 0c9f1c5f3e into 0dd8dbfb64 2026-07-13 13:36:44 +00:00
Thomas StoddardandKyle Schwarz 0dd8dbfb64 Communication: Command: Add Main51 errors 2026-07-07 21:47:52 -04:00
David RebbeandKyle Schwarz d708f8081a C2: Add termination group support 2026-07-07 21:25:23 -04:00
David RebbeandKyle Schwarz 743246e813 Legacy: Update icsnVC40.h to Vehicle Spy 3.26.3.9 2026-07-07 20:51:37 -04:00
Max BrombachandKyle Schwarz 4ed29b4a5e Device: Add Failed enum value to Device::OpenStatusType enum 2026-06-29 16:13:39 -04:00
Jonathan SchwartzandKyle Schwarz 55d69246b0 Device: FIRE3: Add EnterBootloader phase 2026-06-29 12:19:02 -04:00
David RebbeandKyle Schwarz 19232def41 C2: Add icsneoc2_device_force_disk_config_update 2026-06-29 09:55:18 -04:00
David RebbeandKyle Schwarz 9d91524dc0 C2: Add EthernetStatusMessage 2026-06-29 09:08:51 -04:00
David RebbeandKyle Schwarz d86e3164af C2: Add AppError support 2026-06-26 17:32:43 -04:00
David RebbeandKyle Schwarz 3d99898598 FIRE3: Fix termination groups 2026-06-25 16:59:09 -04:00
David RebbeandKyle Schwarz 4b9cf1a37f Device: RAD: Add reboot support 2026-06-25 14:06:43 -04:00
David RebbeandKyle Schwarz 40d83f3b7c C2: Add device_product_name_get() 2026-06-24 16:58:28 -04:00
David RebbeandKyle Schwarz 60918c4b6d C2: Add PerfTest setting 2026-06-24 15:16:51 -04:00
Bryant JonesandKyle Schwarz 749552e443 Device: Fix coremini loading
For:
- RADA2B
- RADComet2
- RADComet3
- RADGalaxy2
- RADMoonT1S
- RADStar2
2026-06-24 13:28:12 -04:00
David RebbeandKyle Schwarz 8af6d5f2a8 FIRE3: Add reboot support 2026-06-19 17:58:49 -04:00
David RebbeandKyle Schwarz 54fb89b675 Settings: Add Linux options 2026-06-19 17:12:42 -04:00
Thomas StoddardandKyle Schwarz 299766403f Settings: Add GPTP 2026-06-18 22:23:13 -04:00
Max Brombach 2d0b0c63ed Device: RAD-Star 2: Add bootloader pipeline and chip info 2026-06-18 15:30:21 +00:00
Bryant JonesandKyle Schwarz 30606be7a8 Settings: Add PerfTest 2026-06-18 11:12:13 -04:00
Kyle Schwarz 4dd97f734a Servd: Disable signal on send failure 2026-06-18 10:21:35 -04:00
Bryant JonesandKyle Schwarz 44d0e3de64 Gigastar2: Fix loading coremini 2026-06-10 18:08:02 -04:00
Kyle Schwarz 023f5aa089 Bindings: Python: Add AppError 2026-06-10 16:59:43 -04:00
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 SchwartzandKyle Schwarz 99792a0ee1 Communication: Increase max packet length 2026-06-02 11:10:16 -04:00
Max BrombachandKyle Schwarz d42c51d772 EventManager: Fix Event Manager being accessed after static destruction 2026-05-22 15:56:02 -04:00
Thomas StoddardandKyle Schwarz 3ab06199c3 Device: Add ExtendedCommand::GetAllMACAddresses 2026-05-22 11:40:44 -04:00
Gowtham Nanjukutty (XC-CP/ECC2.3) 0c9f1c5f3e darwin: fix CDCACM device detection on macOS 12+
On macOS 12 and later, Apple replaced IOUSBDevice with IOUSBHostDevice
in the USB host stack. When walking the IORegistry parent chain to find
the USB device providing a serial port, the existing code only checked
IOObjectConformsTo(parent, kIOUSBDeviceClassName). On macOS 12+, this
check fails because the USB device node conforms to IOUSBHostDevice
instead.

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

Verified on macOS 26 (Tahoe, arm64) with a ValueCAN 4-2 (V2D805).
2026-05-22 09:12:58 -04:00
Max BrombachandKyle Schwarz 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 RebbeandKyle Schwarz 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 StoddardandKyle Schwarz 0ecb360195 RADComet1: Deprecate and replace with RADComet2 2026-05-14 20:20:46 -04:00
David RebbeandKyle Schwarz b3bb033ecb C2: Add Supported Device Types" 2026-05-14 19:08:11 -04:00
David RebbeandKyle Schwarz c3762bbf22 C2: Add ChipVersions
Also fixes some formatting issues.
2026-05-14 13:39:39 -04:00
Thomas StoddardandKyle Schwarz e926e10dc5 RADGigastar2: Add to MACsecConfig 2026-05-14 11:29:54 -04:00
136 changed files with 7360 additions and 2162 deletions
+7 -3
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:
+40 -1
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
-1
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
+296 -18
View File
@@ -12,8 +12,10 @@
#include <map>
#include <algorithm>
#include <optional>
#include <chrono>
#include <sstream>
#include <fstream>
#include <cstring>
using namespace icsneo;
@@ -69,6 +71,7 @@ icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* valu
"Close failed", // icsneoc2_error_close_failed
"Reconnect failed", // icsneoc2_error_reconnect_failed
"Invalid data", // icsneoc2_error_invalid_data
"Force disk config update failed", // icsneoc2_error_force_disk_config_update_failed
};
static_assert(std::size(error_strings) == icsneoc2_error_maxsize,
"error_strings is out of sync with _icsneoc2_error_t enum - update both together");
@@ -84,6 +87,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;
@@ -214,7 +272,9 @@ static icsneoc2_error_t open_device_with_options(std::shared_ptr<Device> dev, ic
if(!dev) {
return icsneoc2_error_invalid_device;
}
if(!dev->enableMessagePolling(std::make_optional<MessageFilter>())) {
MessageFilter filter;
filter.includeInternalInAny = true;
if(!dev->enableMessagePolling(std::make_optional(filter))) {
return icsneoc2_error_enable_message_polling_failed;
}
if(!dev->isOpen() && !dev->open()) {
@@ -251,12 +311,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 +339,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 +362,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 +402,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;
@@ -382,6 +442,16 @@ icsneoc2_error_t icsneoc2_device_serial_get(const icsneoc2_device_t* device, cha
return safe_str_copy(value, value_length, dev->getSerial()) ? icsneoc2_error_success : icsneoc2_error_string_copy_failed;
}
icsneoc2_error_t icsneoc2_device_product_name_get(const icsneoc2_device_t* device, char* value, size_t* value_length) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
auto dev = device->device;
// Copy the string into value
return safe_str_copy(value, value_length, dev->getProductName()) ? icsneoc2_error_success : icsneoc2_error_string_copy_failed;
}
icsneoc2_error_t icsneoc2_device_pcb_serial_get(const icsneoc2_device_t* device, uint8_t* value, size_t* value_length) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
@@ -403,27 +473,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 +792,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) {
@@ -916,6 +1098,21 @@ icsneoc2_error_t icsneoc2_device_format_disk(const icsneoc2_device_t* device, ic
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_force_disk_config_update(const icsneoc2_device_t* device, icsneoc2_disk_details_t* disk_details) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!disk_details || !disk_details->details) {
return icsneoc2_error_invalid_parameters;
}
if(!device->device->forceDiskConfigUpdate(*disk_details->details)) {
return icsneoc2_error_force_disk_config_update_failed;
}
return icsneoc2_error_success;
}
static icsneoc2_error_t get_supported_networks(const icsneoc2_device_t* device, const std::vector<Network>& nets, icsneoc2_netid_t* networks, size_t* count) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
@@ -1208,3 +1405,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;
}
+21
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,22 @@ 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_termination_group_t {
std::vector<icsneoc2_netid_t> netids;
icsneoc2_termination_group_t* next;
} icsneoc2_termination_group_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.
*
+94 -1
View File
@@ -7,8 +7,10 @@
#include "icsneo/communication/message/message.h"
#include "icsneo/communication/message/canmessage.h"
#include "icsneo/communication/message/canerrormessage.h"
#include "icsneo/communication/message/apperrormessage.h"
#include "icsneo/communication/message/linmessage.h"
#include "icsneo/communication/message/ethernetmessage.h"
#include "icsneo/communication/message/ethernetstatusmessage.h"
#include "icsneo/communication/packet/canpacket.h"
icsneoc2_error_t icsneoc2_message_is_valid(icsneoc2_message_t* message, bool* is_valid) {
@@ -126,6 +128,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;
@@ -294,6 +318,44 @@ icsneoc2_error_t icsneoc2_message_can_error_props_get(
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_is_app_error(icsneoc2_message_t* message, bool* is_app_error) {
if(!message || !is_app_error) {
return icsneoc2_error_invalid_parameters;
}
*is_app_error = std::dynamic_pointer_cast<AppErrorMessage>(message->message) != nullptr;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_app_error_props_get(icsneoc2_message_t* message,
icsneoc2_app_error_type_t* error_type, icsneoc2_netid_t* error_netid) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
auto app_err = std::dynamic_pointer_cast<AppErrorMessage>(message->message);
if(!app_err) {
return icsneoc2_error_invalid_type;
}
if(error_type) {
*error_type = static_cast<icsneoc2_app_error_type_t>(app_err->getAppErrorType());
}
if(error_netid) {
*error_netid = static_cast<icsneoc2_netid_t>(app_err->errorNetID);
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_app_error_string_get(icsneoc2_message_t* message,
char* value, size_t* value_length) {
if(!message || !value_length) {
return icsneoc2_error_invalid_parameters;
}
auto app_err = std::dynamic_pointer_cast<AppErrorMessage>(message->message);
if(!app_err) {
return icsneoc2_error_invalid_type;
}
return safe_str_copy(value, value_length, app_err->getAppErrorString()) ? icsneoc2_error_success : icsneoc2_error_string_copy_failed;
}
icsneoc2_error_t icsneoc2_message_is_lin(icsneoc2_message_t* message, bool* is_lin) {
if(!message || !is_lin) {
return icsneoc2_error_invalid_parameters;
@@ -609,9 +671,40 @@ icsneoc2_error_t icsneoc2_message_eth_t1s_props_get(icsneoc2_message_t* message,
}
icsneoc2_error_t icsneoc2_message_is_ethernet(icsneoc2_message_t* message, bool* is_ethernet) {
if(!message) {
if(!message || !is_ethernet) {
return icsneoc2_error_invalid_parameters;
}
*is_ethernet = std::dynamic_pointer_cast<EthernetMessage>(message->message) != nullptr;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_is_ethernet_status(icsneoc2_message_t* message, bool* is_ethernet_status) {
if(!message || !is_ethernet_status) {
return icsneoc2_error_invalid_parameters;
}
*is_ethernet_status = std::dynamic_pointer_cast<EthernetStatusMessage>(message->message) != nullptr;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_eth_status_props_get(icsneoc2_message_t* message, bool* link_state, bool* duplex, icsneoc2_link_speed_t* link_speed, icsneoc2_link_mode_t* link_mode) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
auto msg = std::dynamic_pointer_cast<EthernetStatusMessage>(message->message);
if(!msg) {
return icsneoc2_error_invalid_type;
}
if(link_state) {
*link_state = msg->state;
}
if(duplex) {
*duplex = msg->duplex;
}
if(link_speed) {
*link_speed = static_cast<icsneoc2_link_speed_t>(msg->speed);
}
if(link_mode) {
*link_mode = static_cast<icsneoc2_link_mode_t>(msg->mode);
}
return icsneoc2_error_success;
}
+300
View File
@@ -179,6 +179,82 @@ icsneoc2_error_t icsneoc2_settings_termination_set(icsneoc2_device_t* device, ic
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_termination_groups_enumerate(icsneoc2_device_t* device, icsneoc2_termination_group_t** groups, size_t* count) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!groups) {
return icsneoc2_error_invalid_parameters;
}
auto termination_groups = device->device->settings->getTerminationGroups();
icsneoc2_termination_group_t* head = nullptr;
icsneoc2_termination_group_t* tail = nullptr;
for(const auto& group : termination_groups) {
auto* node = new (std::nothrow) icsneoc2_termination_group_t;
if(!node) {
icsneoc2_settings_termination_groups_free(head);
return icsneoc2_error_out_of_memory;
}
node->netids.reserve(group.size());
for(const auto& network : group) {
node->netids.push_back(static_cast<icsneoc2_netid_t>(network.getNetID()));
}
node->next = nullptr;
if(!head) {
head = node;
} else {
tail->next = node;
}
tail = node;
}
*groups = head;
if(count) {
*count = termination_groups.size();
}
return icsneoc2_error_success;
}
icsneoc2_termination_group_t* icsneoc2_termination_group_next(const icsneoc2_termination_group_t* group) {
if(!group) {
return nullptr;
}
return group->next;
}
icsneoc2_error_t icsneoc2_termination_group_networks_get(const icsneoc2_termination_group_t* group, icsneoc2_netid_t* networks, size_t* count) {
if(!group || !count) {
return icsneoc2_error_invalid_parameters;
}
if(!networks) {
*count = group->netids.size();
return icsneoc2_error_success;
}
size_t to_copy = std::min<size_t>(*count, group->netids.size());
for(size_t i = 0; i < to_copy; i++) {
networks[i] = group->netids[i];
}
*count = to_copy;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_termination_groups_free(icsneoc2_termination_group_t* groups) {
if(!groups) {
return icsneoc2_error_invalid_parameters;
}
while(groups) {
auto* next = groups->next;
delete groups;
groups = next;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_commander_resistor_enabled(icsneoc2_device_t* device, icsneoc2_netid_t netid, bool* enabled) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
@@ -867,6 +943,120 @@ 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_perf_test_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->isPerfTestEnabled(); result.has_value()) {
*value = result.value();
return icsneoc2_error_success;
} else {
*value = false;
return icsneoc2_error_get_settings_failure;
}
}
icsneoc2_error_t icsneoc2_settings_perf_test_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->setPerfTestEnable(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 +1082,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;
}
+10 -8
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";
+2 -2
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() {
@@ -5,6 +5,13 @@
#include <windows.h>
#include "icsneo/icsnVC40.h"
// Vehicle Spy 3.26.3.9 removed these legacy settings structure definitions from
// icsnVC40.h. The corresponding functions only ever treat them as opaque
// buffers, so forward declarations keep the existing API/ABI intact.
typedef struct _SFireSettings SFireSettings;
typedef struct _SVCAN3Settings SVCAN3Settings;
typedef struct _SVCANRFSettings SVCANRFSettings;
bool LoadDLLAPI(HINSTANCE &hAPIDLL);
+9 -9
View File
@@ -1035,10 +1035,10 @@ int LegacyDLLExport icsneoGetDeviceSettingsType(void* hObject, EPlasmaIonVnetCha
case NEODEVICE_ION:
*pDeviceSettingsType = DeviceFire2SettingsType; //defaults to FIRE2 vnets with libicsneo - no firevnets!
break;
case NEODEVICE_VCAN3:
*pDeviceSettingsType = DeviceVCAN3SettingsType;
case NEODEVICE_VCAN3_DEPRECATED:
*pDeviceSettingsType = DeviceVCAN3SettingsTypeDeprecated;
break;
case NEODEVICE_FIRE:
case NEODEVICE_FIRE_DEPRECATED:
*pDeviceSettingsType = DeviceFireSettingsType;
break;
case NEODEVICE_FIRE2:
@@ -1061,17 +1061,17 @@ int LegacyDLLExport icsneoGetDeviceSettingsType(void* hObject, EPlasmaIonVnetCha
case NEODEVICE_VIVIDCAN:
*pDeviceSettingsType = DeviceVividCANSettingsType;
break;
case NEODEVICE_ECU_AVB:
*pDeviceSettingsType = DeviceECU_AVBSettingsType;
case NEODEVICE_ECU_AVB_DEPRECATED:
*pDeviceSettingsType = DeviceECU_AVBSettingsTypeDeprecated;
break;
case NEODEVICE_RADSUPERMOON:
*pDeviceSettingsType = DeviceRADSuperMoonSettingsType;
case NEODEVICE_RADSUPERMOON_DEPRECATED:
*pDeviceSettingsType = DeviceRADSuperMoonSettingsTypeDeprecated;
break;
case NEODEVICE_RADMOON2:
*pDeviceSettingsType = DeviceRADMoon2SettingsType;
break;
case NEODEVICE_RADGIGALOG:
*pDeviceSettingsType = DeviceRADGigalogSettingsType;
case NEODEVICE_RADGIGALOG_DEPRECATED:
*pDeviceSettingsType = DeviceRADGigalogSettingsTypeDeprecated;
break;
case NEODEVICE_RADMOON3:
*pDeviceSettingsType = DeviceRADMoon3SettingsType;
+2
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
@@ -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
@@ -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
@@ -7,7 +7,7 @@
namespace icsneo {
void init_ethernetstatusmessage(pybind11::module_& m) {
pybind11::classh<EthernetStatusMessage, Message> ethernetStatusMessage(m, "EthernetStatusMessage");
pybind11::classh<EthernetStatusMessage, RawMessage> ethernetStatusMessage(m, "EthernetStatusMessage");
pybind11::enum_<EthernetStatusMessage::LinkSpeed>(ethernetStatusMessage, "LinkSpeed")
.value("LinkSpeedAuto", EthernetStatusMessage::LinkSpeed::LinkSpeedAuto)
+1 -1
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)
+3 -1
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>())
@@ -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)
@@ -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);
+4
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);
+4
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;
@@ -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;
}
@@ -37,7 +37,7 @@ struct Packet {
};
#pragma pack(pop)
std::shared_ptr<Message> EthernetStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
std::shared_ptr<RawMessage> EthernetStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
if(bytestream.size() < sizeof(Packet)) {
return nullptr;
}
@@ -76,5 +76,5 @@ std::shared_ptr<Message> EthernetStatusMessage::DecodeToMessage(const std::vecto
break;
default: return nullptr;
}
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state, speed, packet->duplex, mode);
}
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state != 0, speed, packet->duplex != 0, mode);
}
+1 -1
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;
+1
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;
+52 -19
View File
@@ -737,15 +737,17 @@ bool Device::uploadCoremini(std::istream& stream, Disk::MemoryType memType) {
return false;
}
auto connected = isLogicalDiskConnected();
if(!connected) {
return false; // Already added an API error
}
if(!(*connected)) {
report(APIEvent::Type::DiskNotConnected, APIEvent::Severity::Error);
return false;
if (memType == Disk::MemoryType::SD) {
auto connected = isLogicalDiskConnected();
if(!connected) {
return false; // Already added an API error
}
if(!(*connected)) {
report(APIEvent::Type::DiskNotConnected, APIEvent::Severity::Error);
return false;
}
}
if(!stopScript()) {
@@ -756,7 +758,6 @@ bool Device::uploadCoremini(std::istream& stream, Disk::MemoryType memType) {
return false;
}
if(!eraseScriptMemory(memType, static_cast<uint64_t>(bin.size()))) {
return false;
}
@@ -846,10 +847,12 @@ std::optional<CoreminiHeader> Device::readCoreminiHeader(Disk::MemoryType memTyp
return std::nullopt;
}
auto connected = isLogicalDiskConnected();
if(!connected) {
return std::nullopt; // Already added an API error
if (memType == Disk::MemoryType::SD) {
auto connected = isLogicalDiskConnected();
if(!connected) {
return std::nullopt; // Already added an API error
}
}
#pragma pack(push, 2)
@@ -2263,13 +2266,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 +3738,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);
+2 -6
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_
+147 -1
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;
}
+40
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
===========
@@ -66,6 +74,14 @@ Ethernet Receive
.. literalinclude:: ../../examples/c2/ethernet_receive/src/main.c
:language: c
Ethernet Status
===============
:download:`Download example <../../examples/c2/ethernet_status/src/main.c>`
.. literalinclude:: ../../examples/c2/ethernet_status/src/main.c
:language: c
T1S Loopback
============
@@ -82,3 +98,27 @@ TC10
.. literalinclude:: ../../examples/c2/tc10/src/main.c
:language: c
gPTP
====
:download:`Download example <../../examples/c2/gptp/src/main.c>`
.. literalinclude:: ../../examples/c2/gptp/src/main.c
:language: c
PerfTest
========
:download:`Download example <../../examples/c2/perf_test/src/main.c>`
.. literalinclude:: ../../examples/c2/perf_test/src/main.c
:language: c
Termination Groups
==================
:download:`Download example <../../examples/c2/termination/src/main.c>`
.. literalinclude:: ../../examples/c2/termination/src/main.c
:language: c
+40
View File
@@ -2,17 +2,24 @@ 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_TERMINATION_EXAMPLE "Build the C2 termination groups 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_ETHERNET_STATUS_EXAMPLE "Build the C2 ethernet status 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_C2_PERF_TEST_EXAMPLE "Build the C2 PerfTest setting 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 +35,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 +55,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 +75,14 @@ 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_TERMINATION_EXAMPLE)
add_subdirectory(c2/termination)
endif()
if(LIBICSNEO_BUILD_C2_LIN_EXAMPLE)
add_subdirectory(c2/lin)
endif()
@@ -79,6 +99,10 @@ if(LIBICSNEO_BUILD_C2_ETHERNET_RECEIVE_EXAMPLE)
add_subdirectory(c2/ethernet_receive)
endif()
if(LIBICSNEO_BUILD_C2_ETHERNET_STATUS_EXAMPLE)
add_subdirectory(c2/ethernet_status)
endif()
if(LIBICSNEO_BUILD_C2_T1S_LOOPBACK_EXAMPLE)
add_subdirectory(c2/t1s_loopback)
endif()
@@ -87,10 +111,22 @@ 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_C2_PERF_TEST_EXAMPLE)
add_subdirectory(c2/perf_test)
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 +186,7 @@ endif()
if(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE)
add_subdirectory(cpp/t1s)
endif()
if(LIBICSNEO_BUILD_CPP_GPTP_EXAMPLE)
add_subdirectory(cpp/gptp)
endif()
+5 -5
View File
@@ -58,7 +58,7 @@ int main() {
msg1.Protocol = SPY_PROTOCOL_LIN;
msg1.StatusBitField = 0;
msg1.StatusBitField2 = 0;
lNetworkID = NETID_LIN_02;
lNetworkID = NETID_LIN2;
msg1.Header[0] = 0x11; //protected ID
msg1.Header[1] = 0xaa;
msg1.Header[2] = 0xbb;
@@ -80,7 +80,7 @@ int main() {
icsSpyMessageJ1850 msg2 = {0};
msg2.Protocol = SPY_PROTOCOL_LIN;
msg2.StatusBitField = SPY_STATUS_INIT_MESSAGE;
lNetworkID = NETID_LIN_01;
lNetworkID = NETID_LIN;
msg2.Header[0] = 0x11; //protected ID
msg2.NumberBytesData = 0;
msg2.NumberBytesHeader = 1;
@@ -96,7 +96,7 @@ int main() {
msg3.Protocol = SPY_PROTOCOL_LIN;
msg3.StatusBitField = SPY_STATUS_INIT_MESSAGE;
msg3.StatusBitField2 = 0;
lNetworkID = NETID_LIN_01;
lNetworkID = NETID_LIN;
msg3.Header[0] = 0xe2; //protected ID
msg3.Header[1] = 0x44;
msg3.Header[2] = 0x33;
@@ -131,10 +131,10 @@ int main() {
const icsSpyMessageJ1850* linMsg = (icsSpyMessageJ1850*)&rxMsg[idx];
size_t frameLen = (linMsg->NumberBytesHeader + linMsg->NumberBytesData);
size_t dataLen = (frameLen > 2) ? (frameLen - 2) : 0;
if(linMsg->NetworkID == NETID_LIN_01) {
if(linMsg->NetworkID == NETID_LIN) {
printf("LIN 1 | ID: 0x%02x [%zu] ", linMsg->Header[0], dataLen);
}
else if (linMsg->NetworkID == NETID_LIN_02) {
else if (linMsg->NetworkID == NETID_LIN2) {
printf("LIN 2 | ID: 0x%02x [%zu] ", linMsg->Header[0], dataLen);
}
+6
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()
+59
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;
}
+22 -10
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 */
+79
View File
@@ -109,6 +109,85 @@ int main() {
}
}
/* Choose operation */
printf("\n\tChoose operation:\n");
printf("\t [f] Format the disk(s)\n");
printf("\t [u] Update the disk configuration without formatting\n");
printf("\t [q] Quit\n");
printf("\tSelection [f/u/q]: ");
char choice[8] = {0};
if(scanf("%7s", choice) != 1) {
choice[0] = 'q';
}
if(choice[0] == 'u' || choice[0] == 'U') {
/* Force a disk config update (e.g. changing the disk layout) without formatting.
* Unlike a format, this preserves the existing data on the disk(s). */
printf("\n\tChoose disk layout:\n");
printf("\t [s] Spanned\n");
printf("\t [r] RAID0\n");
printf("\tSelection [s/r] (current: %s): ", layout == icsneoc2_disk_layout_raid0 ? "RAID0" : "Spanned");
char layout_choice[8] = {0};
if(scanf("%7s", layout_choice) != 1) {
layout_choice[0] = '\0';
}
if(layout_choice[0] == 'r' || layout_choice[0] == 'R') {
icsneoc2_disk_details_layout_set(details, icsneoc2_disk_layout_raid0);
} else if(layout_choice[0] == 's' || layout_choice[0] == 'S') {
icsneoc2_disk_details_layout_set(details, icsneoc2_disk_layout_spanned);
} else {
printf("\tKeeping current layout.\n");
}
/* Enable/disable individual disks in the configuration. A disk's enabled
* state is carried by the FORMATTED flag; only present disks can be enabled. */
for(size_t i = 0; i < detail_count; i++) {
icsneoc2_disk_format_flags_t flags = 0;
icsneoc2_disk_details_flags_get(details, i, &flags);
if(!(flags & ICSNEOC2_DISK_FORMAT_FLAGS_PRESENT)) {
continue; /* Can't enable a disk that isn't present */
}
printf("\tEnable disk [%zu]? [y/N] (currently %s): ", i,
(flags & ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED) ? "enabled" : "disabled");
char disk_choice[8] = {0};
if(scanf("%7s", disk_choice) != 1) {
disk_choice[0] = '\0';
}
if(disk_choice[0] == 'y' || disk_choice[0] == 'Y') {
flags |= ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED;
} else {
flags &= ~(icsneoc2_disk_format_flags_t)ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED;
}
icsneoc2_disk_details_flags_set(details, i, flags);
}
icsneoc2_disk_layout_t new_layout = 0;
icsneoc2_disk_details_layout_get(details, &new_layout);
printf("\n\tForcing disk config update on %s to %s layout (no data will be erased)...\n",
description, new_layout == icsneoc2_disk_layout_raid0 ? "RAID0" : "Spanned");
res = icsneoc2_device_force_disk_config_update(device, details);
if(res != icsneoc2_error_success) {
print_error_code("\tForce disk config update failed", res);
icsneoc2_disk_details_free(details);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return -1;
}
printf("\tDisk config update complete!\n");
icsneoc2_disk_details_free(details);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 0;
}
if(choice[0] != 'f' && choice[0] != 'F') {
printf("\tAborted.\n");
icsneoc2_disk_details_free(details);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 0;
}
/* Build format config: mark present disks for formatting */
bool any_present = false;
for(size_t i = 0; i < detail_count; i++) {
+6
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};
@@ -0,0 +1,6 @@
add_executable(libicsneoc2-ethernet-status-example src/main.c)
target_link_libraries(libicsneoc2-ethernet-status-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-ethernet-status-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
+228
View File
@@ -0,0 +1,228 @@
#include <icsneo/icsneoc2.h>
#include <icsneo/icsneoc2messages.h>
#include <stdio.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
void sleep_ms(uint32_t ms) {
#ifdef _WIN32
Sleep(ms);
#else
usleep(ms * 1000);
#endif
}
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 with error code %u\n", message, error, res);
return (int)res;
}
printf("%s: \"%s\" (%u)\n", message, error_str, error);
return (int)error;
}
void print_events(void) {
icsneoc2_event_t* events[256] = {0};
size_t events_count = 256;
for(size_t i = 0; i < events_count; ++i) {
icsneoc2_error_t res = icsneoc2_event_get(&events[i], NULL);
if(res != icsneoc2_error_success) {
(void)print_error_code("\tFailed to get events", res);
return;
}
if(events[i] == NULL) {
events_count = i;
break;
}
}
for(size_t i = 0; i < events_count; i++) {
char description[255] = {0};
size_t description_length = sizeof(description);
icsneoc2_error_t res = icsneoc2_event_description_get(events[i], description, &description_length);
if(res != icsneoc2_error_success) {
(void)print_error_code("\tFailed to get event description", res);
continue;
}
printf("\tEvent %zu: %s\n", i, description);
}
for(size_t i = 0; i < events_count; i++) {
icsneoc2_event_free(events[i]);
}
if(events_count > 0) {
printf("\tReceived %zu events\n", events_count);
}
}
const char* link_speed_name(icsneoc2_link_speed_t speed) {
switch(speed) {
case icsneoc2_link_speed_auto:
return "Auto";
case icsneoc2_link_speed_10mbps:
return "10 Mbps";
case icsneoc2_link_speed_100mbps:
return "100 Mbps";
case icsneoc2_link_speed_1000mbps:
return "1000 Mbps";
case icsneoc2_link_speed_2500mbps:
return "2500 Mbps";
case icsneoc2_link_speed_5000mbps:
return "5000 Mbps";
case icsneoc2_link_speed_10000mbps:
return "10000 Mbps";
default:
return "Unknown";
}
}
const char* link_mode_name(icsneoc2_link_mode_t mode) {
switch(mode) {
case icsneoc2_link_mode_auto:
return "Auto";
case icsneoc2_link_mode_master:
return "Master";
case icsneoc2_link_mode_slave:
return "Slave";
case icsneoc2_link_mode_invalid:
return "Invalid";
case icsneoc2_link_mode_none:
return "None";
default:
return "Unknown";
}
}
int print_ethernet_status_message(icsneoc2_message_t* message, size_t index) {
icsneoc2_netid_t netid = 0;
char netid_name[128] = {0};
size_t netid_name_length = sizeof(netid_name);
bool link_state = false;
bool duplex = false;
icsneoc2_link_speed_t link_speed = icsneoc2_link_speed_auto;
icsneoc2_link_mode_t link_mode = icsneoc2_link_mode_auto;
icsneoc2_error_t res = icsneoc2_message_netid_get(message, &netid);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get Ethernet status netid", res);
}
res = icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get Ethernet status netid name", res);
}
res = icsneoc2_message_eth_status_props_get(message, &link_state, &duplex, &link_speed, &link_mode);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get Ethernet status properties", res);
}
printf("\t%zu) Ethernet status on %s (0x%x)\n", index, netid_name, netid);
printf("\t Link: %s\n", link_state ? "Up" : "Down");
printf("\t Duplex: %s\n", duplex ? "Full" : "Half");
printf("\t Speed: %s (%u)\n", link_speed_name(link_speed), link_speed);
printf("\t Mode: %s (%u)\n", link_mode_name(link_mode), link_mode);
return icsneoc2_error_success;
}
int main(void) {
printf("Opening first available device offline...\n");
icsneoc2_device_t* device = NULL;
icsneoc2_open_options_t options = icsneoc2_open_options_default & ~ICSNEOC2_OPEN_OPTIONS_GO_ONLINE;
icsneoc2_error_t res = icsneoc2_device_open_first(0, options, &device);
if(res != icsneoc2_error_success) {
return print_error_code("Failed to open first device", res);
}
char description[255] = {0};
size_t description_length = sizeof(description);
res = icsneoc2_device_description_get(device, description, &description_length);
if(res != icsneoc2_error_success) {
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return print_error_code("Failed to get device description", res);
}
printf("Opened device: %s\n", description);
printf("Going online to trigger Ethernet status broadcast...\n");
res = icsneoc2_device_go_online(device, true);
if(res != icsneoc2_error_success) {
print_events();
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return print_error_code("Failed to go online", res);
}
const int listen_seconds = 6;
time_t start_time = time(NULL);
size_t status_count = 0;
size_t total_count = 0;
printf("Listening for Ethernet status messages for %d seconds...\n", listen_seconds);
while(time(NULL) - start_time < listen_seconds) {
icsneoc2_message_t* message = NULL;
res = icsneoc2_device_message_get(device, &message, 100);
if(res != icsneoc2_error_success) {
print_events();
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return print_error_code("Failed to get message", res);
}
if(message == NULL) {
sleep_ms(10);
continue;
}
total_count++;
bool is_ethernet_status = false;
res = icsneoc2_message_is_ethernet_status(message, &is_ethernet_status);
if(res != icsneoc2_error_success) {
icsneoc2_message_free(message);
print_events();
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return print_error_code("Failed to check for Ethernet status message", res);
}
if(is_ethernet_status) {
res = print_ethernet_status_message(message, status_count);
if(res != icsneoc2_error_success) {
icsneoc2_message_free(message);
print_events();
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return (int)res;
}
status_count++;
}
icsneoc2_message_free(message);
}
printf("Received %zu Ethernet status messages out of %zu total messages.\n", status_count, total_count);
if(status_count == 0) {
printf("No Ethernet status messages were seen. These messages are broadcast when the device goes online and may depend on device Ethernet support.\n");
}
print_events();
printf("Closing device...\n");
res = icsneoc2_device_close(device);
if(res != icsneoc2_error_success) {
icsneoc2_device_free(device);
return print_error_code("Failed to close device", res);
}
icsneoc2_device_free(device);
return 0;
}
+6
View File
@@ -0,0 +1,6 @@
add_executable(libicsneoc2-gptp-example src/main.c)
target_link_libraries(libicsneoc2-gptp-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-gptp-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
+330
View File
@@ -0,0 +1,330 @@
/*
* gPTP settings configurator example.
*
* Lists connected devices and their gPTP support, then lets the user
* configure the gPTP profile, role, port, and clock syntonization on any
* device that supports it. If --serial is omitted, the first available
* gPTP-capable device is used.
*/
#include <icsneo/icsneoc2.h>
#include <icsneo/icsneoc2settings.h>
#include <icsneo/icsneoc2messages.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
const char* serial;
bool list;
} args_t;
/* Maps an icsneoc2_netid_t to its gPTP port index (0 = not a gPTP port). */
static uint8_t netid_to_gptp_port(icsneoc2_netid_t netid) {
switch(netid) {
case icsneoc2_netid_ae_01: return 1;
case icsneoc2_netid_ae_02: return 2;
case icsneoc2_netid_ae_03: return 3;
case icsneoc2_netid_ae_04: return 4;
case icsneoc2_netid_ae_05: return 5;
case icsneoc2_netid_ae_06: return 6;
case icsneoc2_netid_ae_07: return 7;
case icsneoc2_netid_ae_08: return 8;
case icsneoc2_netid_ae_09: return 9;
case icsneoc2_netid_ae_10: return 10;
case icsneoc2_netid_ae_11: return 11;
case icsneoc2_netid_ae_12: return 12;
case icsneoc2_netid_ethernet_01: return 13;
case icsneoc2_netid_ethernet_02: return 14;
case icsneoc2_netid_ethernet_03: return 15;
case icsneoc2_netid_ae_13: return 16;
case icsneoc2_netid_ae_14: return 17;
case icsneoc2_netid_ae_15: return 18;
case icsneoc2_netid_ae_16: return 19;
default: return 0;
}
}
static const char* gptp_profile_str(icsneoc2_gptp_profile_t p) {
switch(p) {
case icsneoc2_gptp_profile_standard: return "Standard";
case icsneoc2_gptp_profile_automotive: return "Automotive";
default: return "Unknown";
}
}
static const char* gptp_role_str(icsneoc2_gptp_role_t r) {
switch(r) {
case icsneoc2_gptp_role_disabled: return "Disabled";
case icsneoc2_gptp_role_passive: return "Passive";
case icsneoc2_gptp_role_master: return "Master";
case icsneoc2_gptp_role_slave: return "Slave";
default: return "Unknown";
}
}
static int print_error_code(const char* message, icsneoc2_error_t error) {
char error_str[64] = {0};
size_t error_str_len = sizeof(error_str);
icsneoc2_error_t res = icsneoc2_error_code_get(error, error_str, &error_str_len);
if(res != icsneoc2_error_success) {
fprintf(stderr, "%s: failed to get string for error code %u\n", message, error);
return (int)res;
}
fprintf(stderr, "%s: \"%s\" (%u)\n", message, error_str, error);
return (int)error;
}
static void print_usage(const char* prog) {
printf("Usage:\n");
printf(" %s --list\n", prog);
printf(" %s [--serial SERIAL]\n", prog);
printf("\n");
printf(" --list List connected devices and their gPTP support.\n");
printf(" --serial SERIAL Serial number of the device to configure.\n");
printf(" -h, --help Show this message.\n");
}
static int parse_args(int argc, char** argv, args_t* out) {
memset(out, 0, sizeof(*out));
for(int i = 1; i < argc; ++i) {
const char* a = argv[i];
if(strcmp(a, "-h") == 0 || strcmp(a, "--help") == 0) {
print_usage(argv[0]);
exit(0);
} else if(strcmp(a, "--list") == 0) {
out->list = true;
} else if(strcmp(a, "--serial") == 0) {
if(i + 1 >= argc) {
fprintf(stderr, "error: --serial requires a value\n");
return 1;
}
out->serial = argv[++i];
} else {
fprintf(stderr, "error: unknown argument '%s'\n", a);
print_usage(argv[0]);
return 1;
}
}
return 0;
}
static icsneoc2_device_info_t* find_device(icsneoc2_device_info_t* list, const char* serial) {
for(icsneoc2_device_info_t* cur = list; cur != NULL; cur = icsneoc2_device_info_next(cur)) {
if(serial == NULL)
return cur;
char dev_serial[64] = {0};
size_t dev_serial_len = sizeof(dev_serial);
if(icsneoc2_device_info_serial_get(cur, dev_serial, &dev_serial_len) != icsneoc2_error_success)
continue;
if(strcmp(dev_serial, serial) == 0)
return cur;
}
return NULL;
}
/*
* Print a list of available Ethernet/AE networks with their gPTP port indices.
* Returns the number of ports printed.
*/
static size_t print_gptp_ports(icsneoc2_device_t* device) {
icsneoc2_netid_t nets[128] = {0};
size_t count = sizeof(nets) / sizeof(nets[0]);
if(icsneoc2_device_supported_tx_networks_get(device, nets, &count) != icsneoc2_error_success)
return 0;
size_t printed = 0;
for(size_t i = 0; i < count; ++i) {
uint8_t port = netid_to_gptp_port(nets[i]);
if(port == 0)
continue;
char name[64] = {0};
size_t name_len = sizeof(name);
icsneoc2_netid_name_get(nets[i], name, &name_len);
printf(" [%u] %s\n", (unsigned)port, name);
++printed;
}
return printed;
}
static int list_devices(icsneoc2_device_info_t* list) {
size_t index = 0;
for(icsneoc2_device_info_t* cur = list; cur != NULL; cur = icsneoc2_device_info_next(cur)) {
char serial[64] = {0};
size_t serial_len = sizeof(serial);
char description[256] = {0};
size_t description_len = sizeof(description);
icsneoc2_device_info_serial_get(cur, serial, &serial_len);
icsneoc2_device_info_description_get(cur, description, &description_len);
printf("[%zu] %s (%s)\n", index++, description, serial);
icsneoc2_device_t* device = NULL;
if(icsneoc2_device_create(cur, &device) != icsneoc2_error_success)
continue;
icsneoc2_open_options_t opts = icsneoc2_open_options_default;
opts &= ~ICSNEOC2_OPEN_OPTIONS_SYNC_RTC;
opts &= ~ICSNEOC2_OPEN_OPTIONS_GO_ONLINE;
if(icsneoc2_device_open(device, opts) != icsneoc2_error_success) {
icsneoc2_device_free(device);
continue;
}
bool supported = false;
icsneoc2_device_supports_gptp(device, &supported);
printf(" gPTP supported: %s\n", supported ? "yes" : "no");
if(supported) {
printf(" gPTP ports:\n");
print_gptp_ports(device);
}
icsneoc2_device_close(device);
icsneoc2_device_free(device);
}
return 0;
}
static void print_current_settings(icsneoc2_device_t* device) {
icsneoc2_gptp_profile_t profile = icsneoc2_gptp_profile_standard;
icsneoc2_gptp_role_t role = icsneoc2_gptp_role_disabled;
uint8_t port = 0;
bool clock_syntonization = false;
printf("\nCurrent gPTP settings:\n");
if(icsneoc2_settings_gptp_profile_get(device, &profile) == icsneoc2_error_success)
printf(" Profile: %s\n", gptp_profile_str(profile));
if(icsneoc2_settings_gptp_role_get(device, &role) == icsneoc2_error_success)
printf(" Role: %s\n", gptp_role_str(role));
if(icsneoc2_settings_gptp_enabled_port_get(device, &port) == icsneoc2_error_success)
printf(" Enabled port: %u%s\n", (unsigned)port, port == 0 ? " (disabled)" : "");
if(icsneoc2_settings_gptp_clock_syntonization_enabled_get(device, &clock_syntonization) == icsneoc2_error_success)
printf(" Clock syntonization: %s\n", clock_syntonization ? "enabled" : "disabled");
}
static long prompt_long(const char* prompt, long default_val, long min, long max) {
char buf[32] = {0};
printf("%s [%ld]: ", prompt, default_val);
fflush(stdout);
if(fgets(buf, sizeof(buf), stdin) == NULL || buf[0] == '\n')
return default_val;
char* end = NULL;
long val = strtol(buf, &end, 10);
if(end == buf || val < min || val > max) {
printf("Invalid input, using %ld.\n", default_val);
return default_val;
}
return val;
}
static int configure_device(icsneoc2_device_t* device) {
icsneoc2_error_t res;
res = icsneoc2_settings_refresh(device);
if(res != icsneoc2_error_success)
return print_error_code("Failed to refresh settings", res);
print_current_settings(device);
printf("\nAvailable gPTP ports (0 = disabled):\n");
printf(" [0] Disabled\n");
print_gptp_ports(device);
printf("\nConfigure gPTP:\n");
long profile = prompt_long(" Profile (0=Standard, 1=Automotive)", 1, 0, 1);
res = icsneoc2_settings_gptp_profile_set(device, (icsneoc2_gptp_profile_t)profile);
if(res != icsneoc2_error_success)
return print_error_code("Failed to set profile", res);
long role = prompt_long(" Role (0=Disabled, 1=Passive, 2=Master, 3=Slave)", 3, 0, 3);
res = icsneoc2_settings_gptp_role_set(device, (icsneoc2_gptp_role_t)role);
if(res != icsneoc2_error_success)
return print_error_code("Failed to set role", res);
long port = prompt_long(" Enabled port index", 0, 0, 19);
res = icsneoc2_settings_gptp_enabled_port_set(device, (uint8_t)port);
if(res != icsneoc2_error_success)
return print_error_code("Failed to set enabled port", res);
long syntonization = prompt_long(" Clock syntonization (0=disabled, 1=enabled)", 0, 0, 1);
res = icsneoc2_settings_gptp_clock_syntonization_enabled_set(device, syntonization != 0);
if(res != icsneoc2_error_success)
return print_error_code("Failed to set clock syntonization", res);
printf("\nNote: icsneoc2_settings_apply() persists settings on the device.\n");
res = icsneoc2_settings_apply(device);
if(res != icsneoc2_error_success)
return print_error_code("Failed to apply settings", res);
printf("\nUpdated gPTP settings:\n");
print_current_settings(device);
return 0;
}
int main(int argc, char** argv) {
args_t args;
if(parse_args(argc, argv, &args) != 0)
return 1;
icsneoc2_device_info_t* found_devices = NULL;
icsneoc2_error_t res = icsneoc2_device_enumerate(0, &found_devices);
if(res != icsneoc2_error_success)
return print_error_code("Failed to enumerate devices", res);
if(found_devices == NULL) {
fprintf(stderr, "error: no devices found\n");
return 1;
}
if(args.list) {
int rc = list_devices(found_devices);
icsneoc2_enumeration_free(found_devices);
return rc;
}
icsneoc2_device_info_t* info = find_device(found_devices, args.serial);
if(info == NULL) {
fprintf(stderr, "error: unable to find device %s\n", args.serial ? args.serial : "(any)");
icsneoc2_enumeration_free(found_devices);
return 1;
}
char description[256] = {0};
size_t description_len = sizeof(description);
icsneoc2_device_info_description_get(info, description, &description_len);
icsneoc2_device_t* device = NULL;
res = icsneoc2_device_create(info, &device);
if(res != icsneoc2_error_success) {
icsneoc2_enumeration_free(found_devices);
return print_error_code("Failed to create device", res);
}
printf("Opening %s\n", description);
res = icsneoc2_device_open(device, icsneoc2_open_options_default);
if(res != icsneoc2_error_success) {
icsneoc2_device_free(device);
icsneoc2_enumeration_free(found_devices);
return print_error_code("Failed to open device", res);
}
bool supported = false;
icsneoc2_device_supports_gptp(device, &supported);
if(!supported) {
fprintf(stderr, "error: device does not support gPTP (%s)\n", description);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
icsneoc2_enumeration_free(found_devices);
return 1;
}
int rc = configure_device(device);
printf("Closing %s\n", description);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
icsneoc2_enumeration_free(found_devices);
return rc;
}
+3
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]);
+6
View File
@@ -0,0 +1,6 @@
add_executable(libicsneoc2-perf_test-example src/main.c)
target_link_libraries(libicsneoc2-perf_test-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-perf_test-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
+137
View File
@@ -0,0 +1,137 @@
/*
* PerfTest setting example.
*
* Opens the first available device, enables the device-global PerfTest mode
* via icsneoc2_settings_perf_test_enabled_set(), reads messages for a few
* seconds while PerfTest is active, then disables PerfTest again. Each step
* reads the value back with icsneoc2_settings_perf_test_enabled_get() to
* confirm the change took effect.
*/
#include <icsneo/icsneoc2.h>
#include <icsneo/icsneoc2settings.h>
#include <icsneo/icsneoc2messages.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.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) {
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;
}
/* Sets PerfTest, applies it to the device, then reads it back to confirm. */
static icsneoc2_error_t set_and_verify_perf_test(icsneoc2_device_t* device, bool enable) {
icsneoc2_error_t res = icsneoc2_settings_perf_test_enabled_set(device, enable);
if(res != icsneoc2_error_success)
return res;
res = icsneoc2_settings_apply(device);
if(res != icsneoc2_error_success)
return res;
/* Re-read settings from the device so the read-back reflects what was
* actually persisted, not just the local settings buffer. */
res = icsneoc2_settings_refresh(device);
if(res != icsneoc2_error_success)
return res;
bool value = !enable;
res = icsneoc2_settings_perf_test_enabled_get(device, &value);
if(res != icsneoc2_error_success)
return res;
printf("\tPerfTest now reads back as: %s\n", value ? "enabled" : "disabled");
if(value != enable) {
fprintf(stderr, "\tERROR: expected PerfTest %s but device reports %s\n",
enable ? "enabled" : "disabled", value ? "enabled" : "disabled");
return icsneoc2_error_get_settings_failure;
}
return icsneoc2_error_success;
}
/* Continuously drains and counts messages for the given wall-clock duration. */
static icsneoc2_error_t read_messages_for(icsneoc2_device_t* device, unsigned seconds) {
size_t total = 0;
printf("\tReading messages for %u seconds...\n", seconds);
time_t start = time(NULL);
while((time_t)(time(NULL) - start) < (time_t)seconds) {
/* Short timeout so an idle bus still lets us re-check the clock,
* while a flooding bus is drained as fast as messages arrive. */
icsneoc2_message_t* message = NULL;
icsneoc2_error_t res = icsneoc2_device_message_get(device, &message, 50);
if(res != icsneoc2_error_success)
return res;
if(message == NULL)
continue;
++total;
icsneoc2_message_free(message);
}
printf("\tReceived %zu messages in %u seconds.\n", total, seconds);
return icsneoc2_error_success;
}
int main(void) {
printf("Opening first available device...\n");
icsneoc2_device_t* device = NULL;
icsneoc2_error_t res = icsneoc2_device_open_first(0, icsneoc2_open_options_default, &device);
if(res != icsneoc2_error_success)
return print_error_code("\tFailed to open first device", res);
char description[255] = {0};
size_t description_length = sizeof(description);
res = icsneoc2_device_description_get(device, description, &description_length);
if(res != icsneoc2_error_success) {
icsneoc2_device_free(device);
return print_error_code("\tFailed to get device description", res);
}
printf("\tOpened device: %s\n", description);
/* Pull the current settings down from the device before reading/modifying them. */
res = icsneoc2_settings_refresh(device);
if(res != icsneoc2_error_success)
goto cleanup;
bool initial = false;
res = icsneoc2_settings_perf_test_enabled_get(device, &initial);
if(res != icsneoc2_error_success) {
print_error_code("\tFailed to read initial PerfTest state (device may not support it)", res);
goto cleanup;
}
printf("\tInitial PerfTest state: %s\n", initial ? "enabled" : "disabled");
printf("Enabling PerfTest...\n");
res = set_and_verify_perf_test(device, true);
if(res != icsneoc2_error_success) {
print_error_code("\tFailed to enable PerfTest", res);
goto cleanup;
}
res = read_messages_for(device, 3);
if(res != icsneoc2_error_success) {
print_error_code("\tFailed while reading messages", res);
goto cleanup;
}
printf("Disabling PerfTest...\n");
res = set_and_verify_perf_test(device, false);
if(res != icsneoc2_error_success) {
print_error_code("\tFailed to disable PerfTest", res);
goto cleanup;
}
printf("PerfTest enable/read/disable cycle completed successfully.\n");
cleanup:
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return (int)res;
}
+14 -2
View File
@@ -176,6 +176,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
// Print the type and bus type of each message
size_t tx_count = 0;
size_t can_error_count = 0;
size_t internal_count = 0;
icsneoc2_error_t res = icsneoc2_error_success;
for(size_t i = 0; i < messages_count; i++) {
icsneoc2_message_t* message = messages[i];
@@ -216,13 +217,21 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
continue;
}
// This example only cares about bus traffic, so skip internal
// device/status messages.
icsneoc2_network_type_t internal_check = icsneoc2_network_type_invalid;
res = icsneoc2_message_network_type_get(message, &internal_check);
if(res == icsneoc2_error_success && internal_check == icsneoc2_network_type_internal) {
internal_count++;
continue;
}
bool is_frame = false;
res = icsneoc2_message_is_frame(message, &is_frame);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to check if message is a frame", res);
}
if(!is_frame) {
printf("Ignoring non-frame message at index %zu\n", i);
continue;
}
icsneoc2_network_type_t network_type;
@@ -244,6 +253,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 +266,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 +287,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" : "",
@@ -293,7 +305,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
printf(" ]\n");
}
}
printf("\tReceived %zu messages total, %zu were TX messages, %zu were CAN errors\n", messages_count, tx_count, can_error_count);
printf("\tReceived %zu messages total, %zu were TX messages, %zu were CAN errors, %zu internal (skipped)\n", messages_count, tx_count, can_error_count, internal_count);
return icsneoc2_error_success;
}
+36 -2
View File
@@ -359,6 +359,8 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
// Print the type and bus type of each message
size_t tx_count = 0;
size_t can_error_count = 0;
size_t app_error_count = 0;
size_t internal_count = 0;
for(size_t i = 0; i < messages_count; i++) {
icsneoc2_message_t* message = messages[i];
@@ -392,13 +394,42 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
continue;
}
// Check for application error messages
bool is_app_error = false;
res = icsneoc2_message_is_app_error(message, &is_app_error);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to check if message is an app error", res);
}
if(is_app_error) {
icsneoc2_app_error_type_t error_type = icsneoc2_app_error_type_no_error;
icsneoc2_netid_t error_netid = 0;
char description[256] = {0};
size_t description_length = sizeof(description);
res = icsneoc2_message_app_error_props_get(message, &error_type, &error_netid);
res += icsneoc2_message_app_error_string_get(message, description, &description_length);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get app error properties", res);
}
printf("\t%zd) App Error (type %u) on netid 0x%x: %s\n", i, error_type, error_netid, description);
app_error_count++;
continue;
}
// This example only cares about bus traffic, so skip internal
// device/status messages.
icsneoc2_network_type_t internal_check = icsneoc2_network_type_invalid;
res = icsneoc2_message_network_type_get(message, &internal_check);
if(res == icsneoc2_error_success && internal_check == icsneoc2_network_type_internal) {
internal_count++;
continue;
}
bool is_frame = false;
res = icsneoc2_message_is_frame(message, &is_frame);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to check if message is a frame", res);
}
if(!is_frame) {
printf("Ignoring non-frame message at index %zu\n", i);
continue;
}
icsneoc2_network_type_t network_type;
@@ -426,6 +457,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 +468,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 +485,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" : "",
@@ -469,7 +503,7 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
printf(" ]\n");
}
}
printf("\tReceived %zu messages total, %zu were TX messages, %zu were CAN errors\n", messages_count, tx_count, can_error_count);
printf("\tReceived %zu messages total, %zu were TX messages, %zu were CAN errors, %zu were app errors, %zu internal (skipped)\n", messages_count, tx_count, can_error_count, app_error_count, internal_count);
return icsneoc2_error_success;
}
@@ -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()
+55
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;
}
+5 -1
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;
}
}
+6
View File
@@ -0,0 +1,6 @@
add_executable(libicsneoc2-termination-example src/main.c)
target_link_libraries(libicsneoc2-termination-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-termination-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
+91
View File
@@ -0,0 +1,91 @@
#include <icsneo/icsneoc2.h>
#include <icsneo/icsneoc2messages.h>
#include <icsneo/icsneoc2settings.h>
#include <stdio.h>
#include <stdlib.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_termination_group_t* groups = NULL;
res = icsneoc2_settings_termination_groups_enumerate(device, &groups, &count);
if(res != icsneoc2_error_success) {
print_error_code("Failed to enumerate termination groups", res);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 1;
}
if(count == 0) {
printf("This device does not support software switchable termination.\n");
} else {
printf("Found %zu termination group(s) (only one network per group may be terminated at a time):\n", count);
}
size_t group_index = 0;
for(icsneoc2_termination_group_t* group = groups; group; group = icsneoc2_termination_group_next(group), group_index++) {
// First call with a NULL buffer to learn how many networks are in this group.
size_t network_count = 0;
icsneoc2_termination_group_networks_get(group, NULL, &network_count);
icsneoc2_netid_t* netids = (icsneoc2_netid_t*)malloc(network_count * sizeof(icsneoc2_netid_t));
if(!netids) {
print_error_code("Out of memory", icsneoc2_error_out_of_memory);
break;
}
// Second call to fill the buffer.
res = icsneoc2_termination_group_networks_get(group, netids, &network_count);
if(res != icsneoc2_error_success) {
print_error_code("Failed to get termination group networks", res);
free(netids);
continue;
}
printf(" Group %zu:", group_index);
for(size_t i = 0; i < network_count; i++) {
char name[64] = {0};
size_t name_length = sizeof(name);
if(icsneoc2_netid_name_get(netids[i], name, &name_length) == icsneoc2_error_success) {
printf(" %s", name);
} else {
printf(" %u", netids[i]);
}
if(i + 1 < network_count) {
printf(",");
}
}
printf("\n");
free(netids);
}
icsneoc2_settings_termination_groups_free(groups);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 0;
}
+2
View File
@@ -0,0 +1,2 @@
add_executable(libicsneocpp-device-info-example src/DeviceInfoExample.cpp)
target_link_libraries(libicsneocpp-device-info-example icsneocpp)
@@ -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;
}
+2
View File
@@ -0,0 +1,2 @@
add_executable(libicsneocpp-gptp-settings src/GPTPSettingsExample.cpp)
target_link_libraries(libicsneocpp-gptp-settings icsneocpp)
@@ -0,0 +1,179 @@
#include <iostream>
#include <iomanip>
#include <vector>
#include <optional>
#include <string>
#include <limits>
#include "icsneo/icsneocpp.h"
/* Maps a Network::NetID to its gPTP port index (0 = not a gPTP port). */
static uint8_t netidToGPTPPort(icsneo::Network::NetID netid) {
using N = icsneo::Network::NetID;
switch(netid) {
case N::AE_01: return 1;
case N::AE_02: return 2;
case N::AE_03: return 3;
case N::AE_04: return 4;
case N::AE_05: return 5;
case N::AE_06: return 6;
case N::AE_07: return 7;
case N::AE_08: return 8;
case N::AE_09: return 9;
case N::AE_10: return 10;
case N::AE_11: return 11;
case N::AE_12: return 12;
case N::ETHERNET_01: return 13;
case N::ETHERNET_02: return 14;
case N::ETHERNET_03: return 15;
case N::AE_13: return 16;
case N::AE_14: return 17;
case N::AE_15: return 18;
case N::AE_16: return 19;
default: return 0;
}
}
static std::string gptpProfileStr(RADGPTPProfile p) {
switch(p) {
case RAD_GPTP_PROFILE_STANDARD: return "Standard";
case RAD_GPTP_PROFILE_AUTOMOTIVE: return "Automotive";
default: return "Unknown";
}
}
static std::string gptpRoleStr(RADGPTPRole r) {
switch(r) {
case RAD_GPTP_ROLE_DISABLED: return "Disabled";
case RAD_GPTP_ROLE_PASSIVE: return "Passive";
case RAD_GPTP_ROLE_MASTER: return "Master";
case RAD_GPTP_ROLE_SLAVE: return "Slave";
default: return "Unknown";
}
}
template<typename T>
static std::string optStr(const std::optional<T>& opt) {
if(!opt.has_value()) return "N/A";
if constexpr(std::is_same_v<T, bool>)
return opt.value() ? "enabled" : "disabled";
else
return std::to_string(static_cast<int>(opt.value()));
}
static long promptLong(const std::string& prompt, long defaultVal, long min, long max) {
std::cout << prompt << " [" << defaultVal << "]: " << std::flush;
std::string input;
std::getline(std::cin, input);
if(input.empty())
return defaultVal;
try {
long val = std::stol(input);
if(val >= min && val <= max)
return val;
} catch(...) {}
std::cout << "Invalid input, using " << defaultVal << ".\n";
return defaultVal;
}
static void printGPTPPorts(const std::shared_ptr<icsneo::Device>& device) {
for(const auto& net : device->getSupportedTXNetworks()) {
uint8_t port = netidToGPTPPort(net.getNetID());
if(port == 0) continue;
std::cout << " [" << (int)port << "] " << net << "\n";
}
}
static void printCurrentSettings(const std::shared_ptr<icsneo::Device>& device) {
std::cout << "\nCurrent gPTP settings:\n";
auto profile = device->settings->getGPTPProfile();
auto role = device->settings->getGPTPRole();
auto port = device->settings->getGPTPEnabledPort();
auto synton = device->settings->isGPTPClockSyntonizationEnabled();
if(profile.has_value())
std::cout << " Profile: " << gptpProfileStr(profile.value()) << "\n";
if(role.has_value())
std::cout << " Role: " << gptpRoleStr(role.value()) << "\n";
if(port.has_value())
std::cout << " Enabled port: " << (int)port.value() << (port.value() == 0 ? " (disabled)" : "") << "\n";
if(synton.has_value())
std::cout << " Clock syntonization: " << optStr(synton) << "\n";
}
int main() {
std::cout << "Finding devices... " << std::flush;
auto devices = icsneo::FindAllDevices();
std::cout << devices.size() << " found\n";
if(devices.empty()) {
auto err = icsneo::GetLastError();
if(err.getType() != icsneo::APIEvent::Type::NoErrorFound)
std::cout << err << "\n";
return 1;
}
std::vector<std::shared_ptr<icsneo::Device>> gptp_devices;
for(auto& d : devices) {
if(d->supportsGPTP())
gptp_devices.push_back(d);
}
if(gptp_devices.empty()) {
std::cout << "No gPTP-capable devices found.\n";
return 1;
}
std::cout << "\nAvailable gPTP-capable devices:\n";
for(size_t i = 0; i < gptp_devices.size(); ++i)
std::cout << " [" << (i + 1) << "] " << gptp_devices[i]->describe() << "\n";
long choice = promptLong("Select device", 1, 1, (long)gptp_devices.size());
auto device = gptp_devices[choice - 1];
std::cout << "\nOpening " << device->describe() << "... " << std::flush;
if(!device->open()) {
std::cout << "failed\n" << icsneo::GetLastError() << "\n";
return 1;
}
std::cout << "OK\n";
if(!device->settings->refresh()) {
std::cout << "Failed to refresh settings\n";
device->close();
return 1;
}
printCurrentSettings(device);
std::cout << "\nAvailable gPTP ports (0 = disabled):\n";
std::cout << " [0] Disabled\n";
printGPTPPorts(device);
std::cout << "\nConfigure gPTP:\n";
long profile = promptLong(" Profile (0=Standard, 1=Automotive)", 1, 0, 1);
device->settings->setGPTPProfile(static_cast<RADGPTPProfile>(profile));
long role = promptLong(" Role (0=Disabled, 1=Passive, 2=Master, 3=Slave)", 3, 0, 3);
device->settings->setGPTPRole(static_cast<RADGPTPRole>(role));
long port = promptLong(" Enabled port index", 0, 0, 19);
device->settings->setGPTPEnabledPort(static_cast<uint8_t>(port));
long syntonization = promptLong(" Clock syntonization (0=disabled, 1=enabled)", 0, 0, 1);
device->settings->setGPTPClockSyntonizationEnabled(syntonization != 0);
long permanent = promptLong("\nSave to EEPROM? (0=temporary, 1=permanent)", 0, 0, 1);
if(!device->settings->apply(permanent == 0)) {
std::cout << "Failed to apply settings\n" << icsneo::GetLastError() << "\n";
device->close();
return 1;
}
printCurrentSettings(device);
std::cout << "\nClosing " << device->describe() << "\n";
device->close();
return 0;
}
+51
View File
@@ -0,0 +1,51 @@
import icsneopy
import time
#
# App errors are responses from the device indicating internal runtime errors
# NOTE: To trigger the app error in this example, disable the DW CAN 01 network on the device
# (e.g. with ICS Device Manager)
#
def apperror():
devices = icsneopy.find_all_devices()
if len(devices) == 0:
print("no devices found")
return False
device = devices[0]
print(f"selected {device}")
def on_apperror(message):
if message.get_app_error_type() != icsneopy.AppErrorType.NetworkNotEnabled:
print("unexpected app error type")
return
print(message.get_app_error_string())
filter = icsneopy.MessageFilter(icsneopy.Message.Type.AppError)
callback = icsneopy.MessageCallback(on_apperror, filter)
device.add_message_callback(callback)
if not device.open():
print("unable to open device")
return False
if not device.go_online():
print("unable to go online")
return False
frame = icsneopy.CANMessage()
frame.network = icsneopy.Network(icsneopy.Network.NetID.DWCAN_01)
frame.arbid = 0x22
frame.data = (0xAA, 0xBB, 0xCC)
if not device.transmit(frame):
print("failed to transmit frame")
return False
time.sleep(2) # wait for error to come back
return True
if __name__ == "__main__":
apperror()
+151
View File
@@ -0,0 +1,151 @@
import icsneopy
GPTP_PORT_MAP = {
icsneopy.Network.NetID.AE_01: (1, "AE 01"),
icsneopy.Network.NetID.AE_02: (2, "AE 02"),
icsneopy.Network.NetID.AE_03: (3, "AE 03"),
icsneopy.Network.NetID.AE_04: (4, "AE 04"),
icsneopy.Network.NetID.AE_05: (5, "AE 05"),
icsneopy.Network.NetID.AE_06: (6, "AE 06"),
icsneopy.Network.NetID.AE_07: (7, "AE 07"),
icsneopy.Network.NetID.AE_08: (8, "AE 08"),
icsneopy.Network.NetID.AE_09: (9, "AE 09"),
icsneopy.Network.NetID.AE_10: (10, "AE 10"),
icsneopy.Network.NetID.AE_11: (11, "AE 11"),
icsneopy.Network.NetID.AE_12: (12, "AE 12"),
icsneopy.Network.NetID.ETHERNET_01: (13, "Ethernet 01"),
icsneopy.Network.NetID.ETHERNET_02: (14, "Ethernet 02"),
icsneopy.Network.NetID.ETHERNET_03: (15, "Ethernet 03"),
icsneopy.Network.NetID.AE_13: (16, "AE 13"),
icsneopy.Network.NetID.AE_14: (17, "AE 14"),
icsneopy.Network.NetID.AE_15: (18, "AE 15"),
icsneopy.Network.NetID.AE_16: (19, "AE 16"),
}
PROFILE_NAMES = {
icsneopy.Settings.GTPPProfile.Standard: "Standard",
icsneopy.Settings.GTPPProfile.Automotive: "Automotive",
}
ROLE_NAMES = {
icsneopy.Settings.GTPPRole.Disabled: "Disabled",
icsneopy.Settings.GTPPRole.Passive: "Passive",
icsneopy.Settings.GTPPRole.Master: "Master",
icsneopy.Settings.GTPPRole.Slave: "Slave",
}
def prompt_int(prompt, default, lo, hi):
try:
raw = input(f"{prompt} [{default}]: ").strip()
if not raw:
return default
val = int(raw)
if lo <= val <= hi:
return val
except (ValueError, EOFError):
pass
print(f"Invalid input, using {default}.")
return default
def gptp_ports(device):
ports = []
for net in device.get_supported_tx_networks():
entry = GPTP_PORT_MAP.get(net.get_net_id())
if entry:
ports.append(entry)
return sorted(ports)
def print_settings(device):
s = device.settings
profile = s.get_gptp_profile()
role = s.get_gptp_role()
port = s.get_gptp_enabled_port()
synton = s.is_gptp_clock_syntonization_enabled()
print("\nCurrent gPTP settings:")
if profile is not None:
print(f" Profile: {PROFILE_NAMES.get(profile, profile)}")
if role is not None:
print(f" Role: {ROLE_NAMES.get(role, role)}")
if port is not None:
suffix = " (disabled)" if port == 0 else ""
print(f" Enabled port: {port}{suffix}")
if synton is not None:
print(f" Clock syntonization: {'enabled' if synton else 'disabled'}")
def configure(device):
if not device.settings.refresh():
print("error: failed to refresh settings")
return False
print_settings(device)
ports = gptp_ports(device)
print("\nAvailable gPTP ports (0 = disabled):")
print(" [0] Disabled")
for idx, name in ports:
print(f" [{idx}] {name}")
print("\nConfigure gPTP:")
profile = prompt_int(" Profile (0=Standard, 1=Automotive)", 1, 0, 1)
role = prompt_int(" Role (0=Disabled, 1=Passive, 2=Master, 3=Slave)", 3, 0, 3)
port = prompt_int(" Enabled port index", 0, 0, 19)
synton = prompt_int(" Clock syntonization (0=disabled, 1=enabled)", 0, 0, 1)
permanent = prompt_int("\nSave to EEPROM? (0=temporary, 1=permanent)", 0, 0, 1)
s = device.settings
profile_enum = list(PROFILE_NAMES.keys())[profile]
role_enum = list(ROLE_NAMES.keys())[role]
s.set_gptp_profile(profile_enum)
s.set_gptp_role(role_enum)
s.set_gptp_enabled_port(port)
s.set_gptp_clock_syntonization_enabled(bool(synton))
if not s.apply(not permanent):
print("error: failed to apply settings")
return False
print_settings(device)
return True
def main():
devices = icsneopy.find_all_devices()
if not devices:
print("error: no devices found")
return 1
gptp_devices = [d for d in devices if d.settings.get_gptp_profile() is not None]
if not gptp_devices:
print("error: no gPTP-capable devices found")
return 1
print("Available gPTP-capable devices:")
for i, d in enumerate(gptp_devices, 1):
print(f" [{i}] {d}")
choice = prompt_int("Select device", 1, 1, len(gptp_devices))
device = gptp_devices[choice - 1]
print(f"\nOpening {device}... ", end="", flush=True)
if not device.open():
print("failed")
return 1
print("OK")
try:
ok = configure(device)
finally:
print(f"\nClosing {device}")
device.close()
return 0 if ok else 1
if __name__ == "__main__":
raise SystemExit(main())
+12 -5
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);
};
+1 -1
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));
}
+249
View File
@@ -0,0 +1,249 @@
// --------------------------------------------------------------------------
// COPYRIGHT INTREPID CONTROL SYSTEMS, INC. (c) 1994-20xx
// Confidential and proprietary. This document and its contents are the
// property of Intrepid Control Systems, Inc. It is not to be copied,
// distributed, or otherwise disclosed or used without the prior written
// consent of Intrepid Control Systems Inc.
// All rights reserved.
// --------------------------------------------------------------------------
// SPY Status Bit Definitions
// Generated automatically - DO NOT MODIFY
// Modify cicsSpyStatusBits_config.yml and run cicsSpyStatusBits_gen.py
// Generated on: 2025-07-14 14:31:40
#ifndef CICSSPYSTATUSBITS_H_
#define CICSSPYSTATUSBITS_H_ 1
// WARNING: The following bit conflicts were detected:
// spystatus value 0x10000000: // VSI value 'SPY_STATUS_VSI_IFR_CRC_BIT' conflicts with common value 'SPY_STATUS_PDU'
// spystatus value 0x10000000: // A2B value 'SPY_STATUS_A2B_CONTROL' conflicts with common value 'SPY_STATUS_PDU'
// spystatus value 0x08: // A2B value 'SPY_STATUS_A2B_SCF_VALID_WAITING' conflicts with common value 'SPY_STATUS_REMOTE_FRAME'
// spystatus value 0x40000000: // A2B value 'SPY_STATUS_A2B_UPSTREAM' conflicts with common value 'SPY_STATUS_HIGH_SPEED'
// spystatus value 0x10000000: // FLEXRAY value 'SPY_STATUS_FLEXRAY_PDU' conflicts with common value 'SPY_STATUS_PDU'
// spystatus value 0x40000000: // FLEXRAY value 'SPY_STATUS_FLEXRAY_PDU_UPDATE_BIT_SET' conflicts with common value 'SPY_STATUS_HIGH_SPEED'
// spystatus value 0x08: // FLEXRAY value 'SPY_STATUS_FLEXRAY_PDU_NO_UPDATE_BIT' conflicts with common value 'SPY_STATUS_REMOTE_FRAME'
// Glyph definitions
// '|' - byte divider
// '.' - nibble divider
// '-' - unused bit
// 'o' - common bit
// 'x' - protocol specific bit
// '!' - conflict bit
// SPYSTATUS bit definitions
// SPYSTATUS - Common bits
// |oo-o.oooo|oooo.oooo|oooo.oo-o|oo-o.oooo|
#define SPY_STATUS_GLOBAL_ERR 0x01 // Global error flag
#define SPY_STATUS_TX_MSG 0x02 // Transmitted message
#define SPY_STATUS_XTD_FRAME 0x04 // Extended frame
#define SPY_STATUS_REMOTE_FRAME 0x08 // Remote frame
#define SPY_STATUS_CRC_ERROR 0x10 // CRC error
#define SPY_STATUS_INCOMPLETE_FRAME 0x40 // Incomplete frame
#define SPY_STATUS_LOST_ARBITRATION 0x80 // Lost arbitration
#define SPY_STATUS_UNDEFINED_ERROR 0x0100 // Undefined error
#define SPY_STATUS_BUS_RECOVERED 0x0400 // Bus recovered
#define SPY_STATUS_BUS_SHORTED_PLUS 0x0800 // Bus shorted to plus
#define SPY_STATUS_BUS_SHORTED_GND 0x1000 // Bus shorted to ground
#define SPY_STATUS_CHECKSUM_ERROR 0x2000 // Checksum error
#define SPY_STATUS_BAD_MESSAGE_BIT_TIME_ERROR 0x4000 // Bad message bit time error
#define SPY_STATUS_TX_NOMATCH 0x8000 // TX no match
#define SPY_STATUS_COMM_IN_OVERFLOW 0x010000 // Communication input overflow
#define SPY_STATUS_EXPECTED_LEN_MISMATCH 0x020000 // Expected length mismatch
#define SPY_STATUS_MSG_NO_MATCH 0x040000 // Message no match
#define SPY_STATUS_BREAK 0x080000 // Break detected
#define SPY_STATUS_AVSI_REC_OVERFLOW 0x100000 // AVSI record overflow
#define SPY_STATUS_TEST_TRIGGER 0x200000 // Test trigger
#define SPY_STATUS_AUDIO_COMMENT 0x400000 // Audio comment
#define SPY_STATUS_GPS_DATA 0x800000 // GPS data
#define SPY_STATUS_ANALOG_DIGITAL_INPUT 0x01000000 // Analog digital input
#define SPY_STATUS_TEXT_COMMENT 0x02000000 // Text comment
#define SPY_STATUS_NETWORK_MESSAGE_TYPE 0x04000000 // Network message type
#define SPY_STATUS_VSI_TX_UNDERRUN 0x08000000 // VSI TX underrun
#define SPY_STATUS_PDU 0x10000000 // PDU message
#define SPY_STATUS_HIGH_SPEED 0x40000000 // High speed
#define SPY_STATUS_EXTENDED 0x80000000 // Extended - if this bit is set than decode StatusBitField3 in AckBytes
// SPYSTATUS - A2B protocol bits
// |o!x!.oooo|oooo.oooo|oooo.oo-o|oo-o.!ooo|
#define SPY_STATUS_A2B_SCF_VALID_WAITING 0x08 // A2B SCF valid waiting
#define SPY_STATUS_A2B_CONTROL 0x10000000 // A2B control message
#define SPY_STATUS_A2B_MONITOR 0x20000000 // A2B monitor message
#define SPY_STATUS_A2B_UPSTREAM 0x40000000 // A2B upstream message
// SPYSTATUS - CAN protocol bits
// |ooxo.oooo|oooo.oooo|oooo.ooxo|ooxo.oooo|
#define SPY_STATUS_CAN_ERROR_PASSIVE 0x20 // CAN error passive state
#define SPY_STATUS_CAN_BUS_OFF 0x0200 // CAN bus off state
#define SPY_STATUS_CANFD 0x20000000 // CAN FD frame
// SPYSTATUS - ETHERNET protocol bits
// |oo-o.oooo|oooo.oooo|oooo.oo-o|ooxo.oooo|
#define SPY_STATUS_HEADERCRC_ERROR 0x20 // Header CRC error
// SPYSTATUS - FLEXRAY protocol bits
// |o!-!.oooo|oooo.oooo|oooo.oo-o|oo-o.!ooo|
#define SPY_STATUS_FLEXRAY_PDU_NO_UPDATE_BIT 0x08 // FlexRay PDU no update bit
#define SPY_STATUS_FLEXRAY_PDU 0x10000000 // FlexRay PDU (alias for SPY_STATUS_PDU)
#define SPY_STATUS_FLEXRAY_PDU_UPDATE_BIT_SET 0x40000000 // FlexRay PDU update bit set
// SPYSTATUS - LIN protocol bits
// |ooxo.oooo|oooo.oooo|oooo.oo-o|oo-o.oooo|
#define SPY_STATUS_LIN_MASTER 0x20000000 // LIN master message
// SPYSTATUS - VSI protocol bits
// |oox!.oooo|oooo.oooo|oooo.oo-o|oo-o.oooo|
#define SPY_STATUS_VSI_IFR_CRC_BIT 0x10000000 // VSI IFR CRC bit
#define SPY_STATUS_INIT_MESSAGE 0x20000000 // Initialization message
// SPYSTATUS2 bit definitions
// SPYSTATUS2 - Common bits
// |----.----|---o.--oo|----.----|----.oooo|
#define SPY_STATUS2_HAS_VALUE 0x01
#define SPY_STATUS2_VALUE_IS_BOOLEAN 0x02
#define SPY_STATUS2_HIGH_VOLTAGE 0x04
#define SPY_STATUS2_LONG_MESSAGE 0x08
#define SPY_STATUS2_GLOBAL_CHANGE 0x010000
#define SPY_STATUS2_ERROR_FRAME 0x020000
#define SPY_STATUS2_END_OF_LONG_MESSAGE 0x100000
// SPYSTATUS2 - CAN protocol bits
// |----.----|-xxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_CAN_ISO15765_LOGICAL_FRAME 0x200000
#define SPY_STATUS2_CAN_HAVE_LINK_DATA 0x400000
// SPYSTATUS2 - ETHERNET protocol bits
// |xxxx.xxxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_ETHERNET_CRC_ERROR 0x200000
#define SPY_STATUS2_ETHERNET_FRAME_TOO_SHORT 0x400000
#define SPY_STATUS2_ETHERNET_FCS_AVAILABLE 0x800000 // This frame contains FCS (4 bytes) obtained from ICS Ethernet hardware (ex. RAD-STAR)
#define SPY_STATUS2_ETHERNET_NO_PADDING 0x01000000
#define SPY_STATUS2_ETHERNET_PREEMPTION_ENABLED 0x02000000
#define SPY_STATUS2_ETHERNET_UPDATE_CHECKSUMS 0x04000000
#define SPY_STATUS2_ETHERNET_MANUALFCS_ENABLED 0x08000000
#define SPY_STATUS2_ETHERNET_FCS_VERIFIED 0x10000000
#define SPY_STATUS2_ETHERNET_T1S_SYMBOL 0x20000000
#define SPY_STATUS2_ETHERNET_T1S_BURST 0x40000000
#define SPY_STATUS2_ETHERNET_T1S_ETHERNET 0x80000000
// SPYSTATUS2 - FLEXRAY protocol bits
// |----.-xxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_FLEXRAY_TX_AB 0x200000
#define SPY_STATUS2_FLEXRAY_TX_AB_NO_A 0x400000
#define SPY_STATUS2_FLEXRAY_TX_AB_NO_B 0x800000
#define SPY_STATUS2_FLEXRAY_TX_AB_NO_MATCH 0x01000000
#define SPY_STATUS2_FLEXRAY_NO_CRC 0x02000000
#define SPY_STATUS2_FLEXRAY_NO_HEADERCRC 0x04000000 //
// SPYSTATUS2 - I2C protocol bits
// |----.----|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_I2C_ERR_TIMEOUT 0x200000
#define SPY_STATUS2_I2C_ERR_NACK 0x400000
#define SPY_STATUS2_I2C_DIR_READ 0x800000
// SPYSTATUS2 - ISO protocol bits
// |-xxx.x---|---o.--oo|----.----|----.oooo|
#define SPY_STATUS2_ISO_FRAME_ERROR 0x08000000 // ISO frame error
#define SPY_STATUS2_ISO_OVERFLOW_ERROR 0x10000000 // ISO overflow error
#define SPY_STATUS2_ISO_PARITY_ERROR 0x20000000 // ISO parity error
#define SPY_STATUS2_ISO_RX_TIMEOUT_ERROR 0x40000000 // ISO specific timeout error
// SPYSTATUS2 - LIN protocol bits
// |xxxx.xxxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_LIN_ERR_RX_BREAK_NOT_0 0x200000 // LIN RX break not 0 error
#define SPY_STATUS2_LIN_ERR_RX_BREAK_TOO_SHORT 0x400000 // LIN RX break too short error
#define SPY_STATUS2_LIN_ERR_RX_SYNC_NOT_55 0x800000 // LIN RX sync not 0x55 error
#define SPY_STATUS2_LIN_ERR_RX_DATA_GREATER_8 0x01000000 // LIN RX data greater than 8 bytes error
#define SPY_STATUS2_LIN_ERR_TX_RX_MISMATCH 0x02000000 // LIN TX/RX mismatch error
#define SPY_STATUS2_LIN_ERR_MSG_ID_PARITY 0x04000000 // LIN message ID parity error
#define SPY_STATUS2_LIN_SYNC_FRAME_ERROR 0x08000000 // LIN sync frame error
#define SPY_STATUS2_LIN_ID_FRAME_ERROR 0x10000000 // LIN ID frame error
#define SPY_STATUS2_LIN_SLAVE_BYTE_ERROR 0x20000000 // LIN slave byte error
#define SPY_STATUS2_LIN_RX_TIMEOUT_ERROR 0x40000000 // RX timeout error
#define SPY_STATUS2_LIN_NO_SLAVE_DATA 0x80000000 // LIN no slave data
// SPYSTATUS2 - MDIO protocol bits
// |-xxx.xxxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_MDIO_ERR_TIMEOUT 0x200000
#define SPY_STATUS2_MDIO_JOB_CANCELLED 0x400000
#define SPY_STATUS2_MDIO_INVALID_BUS 0x800000
#define SPY_STATUS2_MDIO_INVALID_PHYADDR 0x01000000
#define SPY_STATUS2_MDIO_INVALID_REGADDR 0x02000000
#define SPY_STATUS2_MDIO_UNSUPPORTED_CLAUSE 0x04000000
#define SPY_STATUS2_MDIO_UNSUPPORTED_OPCODE 0x08000000
#define SPY_STATUS2_MDIO_OVERFLOW 0x10000000
#define SPY_STATUS2_MDIO_CLAUSE45 0x20000000
#define SPY_STATUS2_MDIO_READ 0x40000000
// SPYSTATUS2 - MOST protocol bits
// |xxxx.xxxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_MOST_PACKET_DATA 0x200000
#define SPY_STATUS2_MOST_STATUS 0x400000 // reflects changes in light/lock/MPR/SBC/etc...
#define SPY_STATUS2_MOST_LOW_LEVEL 0x800000 // MOST low level message, allocs, deallocs, remote requests...*/
#define SPY_STATUS2_MOST_CONTROL_DATA 0x01000000
#define SPY_STATUS2_MOST_MHP_USER_DATA 0x02000000 // MOST HIGH User Data Frame
#define SPY_STATUS2_MOST_MHP_CONTROL_DATA 0x04000000 // MOST HIGH Control Data
#define SPY_STATUS2_MOST_I2S_DUMP 0x08000000
#define SPY_STATUS2_MOST_TOO_SHORT 0x10000000
#define SPY_STATUS2_MOST_MOST50 0x20000000 // absence of MOST50 and MOST150 implies it's MOST25
#define SPY_STATUS2_MOST_MOST150 0x40000000
#define SPY_STATUS2_MOST_CHANGED_PAR 0x80000000 // first byte in ack reflects what changed.
// SPYSTATUS2 - WBMS protocol bits
// |----.----|--xo.--oo|----.----|----.oooo|
#define SPY_STATUS2_WBMS_API_IS_CALLBACK 0x200000
// SPYSTATUS3 bit definitions
// SPYSTATUS3 - CAN protocol bits
// |----.----|-xxx.xxxx|-xxx.xxxx|----.-xxx|
#define SPY_STATUS3_CAN_ERR_PASSIVE 0x01 // CAN error passive state: typically when error counter is > 127
#define SPY_STATUS3_CAN_BUS_OFF 0x02 // CAN bus off state
#define SPY_STATUS3_CAN_ERR_WARNING 0x04 // CAN error warning: typically when error counter is > 96
#define SPY_STATUS3_CAN_DATAERR_STUFF_ERROR 0x0100 // CAN stuff error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_FORM_ERROR 0x0200 // CAN form error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_ACK_ERROR 0x0400 // CAN ack error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_BIT1_ERROR 0x0800 // CAN bit1 error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_BIT0_ERROR 0x1000 // CAN bit0 error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_CRC_ERROR 0x2000 // CAN CRC error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_NOCHANGE 0x4000 // CAN data error occurred before and no change yet
#define SPY_STATUS3_CAN_GENERR_STUFF_ERROR 0x010000 // CAN stuff error at the general frame level
#define SPY_STATUS3_CAN_GENERR_FORM_ERROR 0x020000 // CAN form error at the general frame level
#define SPY_STATUS3_CAN_GENERR_ACK_ERROR 0x040000 // CAN ack error at the general frame level
#define SPY_STATUS3_CAN_GENERR_BIT1_ERROR 0x080000 // CAN bit1 error at the general frame level
#define SPY_STATUS3_CAN_GENERR_BIT0_ERROR 0x100000 // CAN bit0 error at the general frame level
#define SPY_STATUS3_CAN_GENERR_CRC_ERROR 0x200000 // CAN CRC error at the general frame level
#define SPY_STATUS3_CAN_GENERR_NOCHANGE 0x400000 // CAN frame Error occurred before and no change yet
// SPYSTATUS3 - CANFD protocol bits
// |----.----|----.----|----.----|---x.xxxx|
#define SPY_STATUS3_CANFD_ESI 0x01 // CAN FD Error State Indicator (ESI) reflects the error state of the transmitting node
#define SPY_STATUS3_CANFD_IDE 0x02 // CAN FD Identifier Extension (IDE) indicates if standard or extended IDs are in use
#define SPY_STATUS3_CANFD_RTR 0x04
#define SPY_STATUS3_CANFD_FDF 0x08 // CAN FD Format (FDF) flag -- distinguishes classic CAN from CANFD
#define SPY_STATUS3_CANFD_BRS 0x10 // CANFD Baud Rate Select (BRS) flag, indicates if the data portion transmits at a higher bitrate
// SPYSTATUS3 - ETHERNET protocol bits
// |----.----|----.----|----.----|----.--xx|
#define SPY_STATUS3_ETHERNET_TX_COLLISION 0x01
#define SPY_STATUS3_ETHERNET_T1S_WAKE 0x02
// SPYSTATUS3 - LIN protocol bits
// |----.----|----.----|----.----|----.-xxx|
#define SPY_STATUS3_LIN_JUST_BREAK_SYNC 0x01
#define SPY_STATUS3_LIN_SLAVE_DATA_TOO_SHORT 0x02
#define SPY_STATUS3_LIN_ONLY_UPDATE_SLAVE_TABLE_ONCE 0x04
// SPYSTATUS4 bit definitions
// SPYSTATUS4 - ETHERNET protocol bits
// |----.----|----.----|----.----|----.--xx|
#define SPY_STATUS4_ETH_CRC_ERROR 0x01 // Ethernet CRC error
#define SPY_STATUS4_ETH_FRAME_TOO_LONG 0x02 // Ethernet frame too long
#endif // CICSSPYSTATUSBITS_H_
+17
View File
@@ -6,6 +6,22 @@
namespace icsneo {
enum class Command : uint8_t {
// Device-originated Main51 event/error notifications (device -> host)
Main51RxBufferOverflow = 0x01,
Main51StartCmd = 0x02,
Main51TxFifoOverflow = 0x03,
Main51BulkInNoData = 0x04,
Main51SetModeComplete = 0x05,
Main51ReadEeprom = 0x06,
// 0x07, 0x08, 0x09 reserved for host->device commands below
Main51CmdDone = 0x0A,
Main51ErrStatus = 0x0B,
Main51ReadSectorBuff = 0x0C,
Main51WriteSectorBuff = 0x0D,
Main51MmcProcessDone = 0x0E,
Main51ReInitDone = 0x0F,
// Host-originated commands (host -> device)
EnableNetworkCommunication = 0x07,
EnableNetworkCommunicationEx = 0x08,
KeepAlive = 0x09,
@@ -64,6 +80,7 @@ enum class ExtendedCommand : uint16_t {
RequestTC10Wake = 0x003D,
RequestTC10Sleep = 0x003E,
GetTC10Status = 0x003F,
GetAllMACAddresses = 0x0040,
ProtobufAPI = 0x0041,
TransmitMessage = 0x0042,
};
@@ -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_
@@ -4,6 +4,7 @@
#ifdef __cplusplus
#include "icsneo/communication/message/message.h"
#include "icsneo/icsneoc2types.h"
#include <unordered_set>
#include <memory>
#include "icsneo/api/eventmanager.h"
@@ -11,57 +12,57 @@
namespace icsneo {
enum class AppErrorType : uint16_t {
AppErrorRxMessagesFull = 0,
AppErrorTxMessagesFull = 1,
AppErrorTxReportMessagesFull = 2,
AppErrorBadCommWithDspIC = 3,
AppErrorDriverOverflow = 4,
AppErrorPCBuffOverflow = 5,
AppErrorPCChksumError = 6,
AppErrorPCMissedByte = 7,
AppErrorPCOverrunError = 8,
AppErrorSettingFailure = 9,
AppErrorTooManySelectedNetworks = 10,
AppErrorNetworkNotEnabled = 11,
AppErrorRtcNotCorrect = 12,
AppErrorLoadedDefaultSettings = 13,
AppErrorFeatureNotUnlocked = 14,
AppErrorFeatureRtcCmdDropped = 15,
AppErrorTxMessagesFlushed = 16,
AppErrorTxMessagesHalfFull = 17,
AppErrorNetworkNotValid = 18,
AppErrorTxInterfaceNotImplemented = 19,
AppErrorTxMessagesCommEnableIsOff = 20,
AppErrorRxFilterMatchCountExceeded = 21,
AppErrorEthPreemptionNotEnabled = 22,
AppErrorTxNotSupportedInMode = 23,
AppErrorJumboFramesNotSupported = 24,
AppErrorEthernetIpFragment = 25,
AppErrorTxMessagesUnderrun = 26,
AppErrorDeviceFanFailure = 27,
AppErrorDeviceOvertemperature = 28,
AppErrorTxMessageIndexOutOfRange = 29,
AppErrorUndersizedFrameDropped = 30,
AppErrorOversizedFrameDropped = 31,
AppErrorWatchdogEvent = 32,
AppErrorSystemClockFailure = 33,
AppErrorSystemClockRecovered = 34,
AppErrorSystemPeripheralReset = 35,
AppErrorSystemCommunicationFailure = 36,
AppErrorTxMessagesUnsupportedSourceOrPacketId = 37,
AppErrorWbmsManagerConnectFailed = 38,
AppErrorWbmsManagerConnectBadState = 39,
AppErrorWbmsManagerConnectTimeout = 40,
AppErrorFailedToInitializeLoggerDisk = 41,
AppErrorInvalidSetting = 42,
AppErrorSystemFailureRequestedReset = 43,
AppErrorPortKeyMistmatch = 45,
AppErrorBusFailure = 46,
AppErrorTapOverflow = 47,
AppErrorEthTxNoLink = 48,
AppErrorErrorBufferOverflow = 254,
AppNoError = 255
enum class AppErrorType : icsneoc2_app_error_type_t {
AppErrorRxMessagesFull = icsneoc2_app_error_type_rx_messages_full,
AppErrorTxMessagesFull = icsneoc2_app_error_type_tx_messages_full,
AppErrorTxReportMessagesFull = icsneoc2_app_error_type_tx_report_messages_full,
AppErrorBadCommWithDspIC = icsneoc2_app_error_type_bad_comm_with_dsp_ic,
AppErrorDriverOverflow = icsneoc2_app_error_type_driver_overflow,
AppErrorPCBuffOverflow = icsneoc2_app_error_type_pc_buff_overflow,
AppErrorPCChksumError = icsneoc2_app_error_type_pc_chksum_error,
AppErrorPCMissedByte = icsneoc2_app_error_type_pc_missed_byte,
AppErrorPCOverrunError = icsneoc2_app_error_type_pc_overrun_error,
AppErrorSettingFailure = icsneoc2_app_error_type_setting_failure,
AppErrorTooManySelectedNetworks = icsneoc2_app_error_type_too_many_selected_networks,
AppErrorNetworkNotEnabled = icsneoc2_app_error_type_network_not_enabled,
AppErrorRtcNotCorrect = icsneoc2_app_error_type_rtc_not_correct,
AppErrorLoadedDefaultSettings = icsneoc2_app_error_type_loaded_default_settings,
AppErrorFeatureNotUnlocked = icsneoc2_app_error_type_feature_not_unlocked,
AppErrorFeatureRtcCmdDropped = icsneoc2_app_error_type_feature_rtc_cmd_dropped,
AppErrorTxMessagesFlushed = icsneoc2_app_error_type_tx_messages_flushed,
AppErrorTxMessagesHalfFull = icsneoc2_app_error_type_tx_messages_half_full,
AppErrorNetworkNotValid = icsneoc2_app_error_type_network_not_valid,
AppErrorTxInterfaceNotImplemented = icsneoc2_app_error_type_tx_interface_not_implemented,
AppErrorTxMessagesCommEnableIsOff = icsneoc2_app_error_type_tx_messages_comm_enable_is_off,
AppErrorRxFilterMatchCountExceeded = icsneoc2_app_error_type_rx_filter_match_count_exceeded,
AppErrorEthPreemptionNotEnabled = icsneoc2_app_error_type_eth_preemption_not_enabled,
AppErrorTxNotSupportedInMode = icsneoc2_app_error_type_tx_not_supported_in_mode,
AppErrorJumboFramesNotSupported = icsneoc2_app_error_type_jumbo_frames_not_supported,
AppErrorEthernetIpFragment = icsneoc2_app_error_type_ethernet_ip_fragment,
AppErrorTxMessagesUnderrun = icsneoc2_app_error_type_tx_messages_underrun,
AppErrorDeviceFanFailure = icsneoc2_app_error_type_device_fan_failure,
AppErrorDeviceOvertemperature = icsneoc2_app_error_type_device_overtemperature,
AppErrorTxMessageIndexOutOfRange = icsneoc2_app_error_type_tx_message_index_out_of_range,
AppErrorUndersizedFrameDropped = icsneoc2_app_error_type_undersized_frame_dropped,
AppErrorOversizedFrameDropped = icsneoc2_app_error_type_oversized_frame_dropped,
AppErrorWatchdogEvent = icsneoc2_app_error_type_watchdog_event,
AppErrorSystemClockFailure = icsneoc2_app_error_type_system_clock_failure,
AppErrorSystemClockRecovered = icsneoc2_app_error_type_system_clock_recovered,
AppErrorSystemPeripheralReset = icsneoc2_app_error_type_system_peripheral_reset,
AppErrorSystemCommunicationFailure = icsneoc2_app_error_type_system_communication_failure,
AppErrorTxMessagesUnsupportedSourceOrPacketId = icsneoc2_app_error_type_tx_messages_unsupported_source_or_packet_id,
AppErrorWbmsManagerConnectFailed = icsneoc2_app_error_type_wbms_manager_connect_failed,
AppErrorWbmsManagerConnectBadState = icsneoc2_app_error_type_wbms_manager_connect_bad_state,
AppErrorWbmsManagerConnectTimeout = icsneoc2_app_error_type_wbms_manager_connect_timeout,
AppErrorFailedToInitializeLoggerDisk = icsneoc2_app_error_type_failed_to_initialize_logger_disk,
AppErrorInvalidSetting = icsneoc2_app_error_type_invalid_setting,
AppErrorSystemFailureRequestedReset = icsneoc2_app_error_type_system_failure_requested_reset,
AppErrorPortKeyMistmatch = icsneoc2_app_error_type_port_key_mistmatch,
AppErrorBusFailure = icsneoc2_app_error_type_bus_failure,
AppErrorTapOverflow = icsneoc2_app_error_type_tap_overflow,
AppErrorEthTxNoLink = icsneoc2_app_error_type_eth_tx_no_link,
AppErrorErrorBufferOverflow = icsneoc2_app_error_type_error_buffer_overflow,
AppNoError = icsneoc2_app_error_type_no_error
};
class AppErrorMessage : public RawMessage {
@@ -4,37 +4,41 @@
#ifdef __cplusplus
#include "icsneo/communication/message/message.h"
#include "icsneo/icsneoc2types.h"
#include <memory>
namespace icsneo {
class EthernetStatusMessage : public Message {
class EthernetStatusMessage : public RawMessage {
public:
enum class LinkSpeed {
LinkSpeedAuto,
LinkSpeed10,
LinkSpeed100,
LinkSpeed1000,
LinkSpeed2500,
LinkSpeed5000,
LinkSpeed10000,
enum class LinkSpeed: icsneoc2_link_speed_t {
LinkSpeedAuto = icsneoc2_link_speed_auto,
LinkSpeed10 = icsneoc2_link_speed_10mbps,
LinkSpeed100 = icsneoc2_link_speed_100mbps,
LinkSpeed1000 = icsneoc2_link_speed_1000mbps,
LinkSpeed2500 = icsneoc2_link_speed_2500mbps,
LinkSpeed5000 = icsneoc2_link_speed_5000mbps,
LinkSpeed10000 = icsneoc2_link_speed_10000mbps,
};
enum class LinkMode {
LinkModeAuto,
LinkModeMaster,
LinkModeSlave,
LinkModeInvalid,
LinkModeNone,
enum class LinkMode: icsneoc2_link_mode_t {
LinkModeAuto = icsneoc2_link_mode_auto,
LinkModeMaster = icsneoc2_link_mode_master,
LinkModeSlave = icsneoc2_link_mode_slave,
LinkModeInvalid = icsneoc2_link_mode_invalid,
LinkModeNone = icsneoc2_link_mode_none,
};
EthernetStatusMessage(Network net, bool state, LinkSpeed speed, bool duplex, LinkMode mode) : Message(Type::EthernetStatus),
network(net), state(state), speed(speed), duplex(duplex), mode(mode) {}
Network network;
EthernetStatusMessage(Network net, bool state, LinkSpeed speed, bool duplex, LinkMode mode) : RawMessage(Type::EthernetStatus, net),
state(state), speed(speed), duplex(duplex), mode(mode) {}
// Link State: False = Link Down, True = Link Up
bool state;
LinkSpeed speed;
// Duplex: False = Half, True = Full
bool duplex;
LinkMode mode;
static std::shared_ptr<Message> DecodeToMessage(const std::vector<uint8_t>& bytestream);
static std::shared_ptr<RawMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
};
}; // namespace icsneo
@@ -47,6 +47,7 @@ public:
LogData = 0x8015,
NetworkMutex = 0x8016,
ClientId = 0x8017,
AllMACAddresses = 0x8018,
};
Message(Type t) : type(t) {}
+132 -130
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
};
}
+25 -6
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;
@@ -230,9 +231,18 @@ public:
enum class OpenStatusType {
QuestionContinueSkipCancel,
QuestionContinueCancel,
Progress
Progress,
Failed
};
/**
* @brief Alias of callback function for progress of a bootloader pipeline task
*
* The progress value passed into the callback function indicates the following:
* 1) If the value is std::nullopt, this implies the status message is for an asynchronous task or a task in which the current progress is unknown.
* 2) If the value is between 0 and 1 (i.e., 0 <= progress <= 1), this implies the actual progress of the current task as a percentage.
* 3) Values not between 0 and 1 (i.e., progress < 0 or progress > 1) are undefined.
*/
using OpenStatusHandler = std::function<Device::OpenDirective(OpenStatusType type, const std::string& status, std::optional<double> progress)>;
bool open(OpenFlags flags = {}, OpenStatusHandler handler =
@@ -858,13 +868,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 +946,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 +1015,8 @@ protected:
bool supportsNetworkMutex = false;
virtual bool supportsGetAllMACAddresses() const { return true; }
private:
neodevice_t data;
std::shared_ptr<ResetStatusMessage> latestResetStatus;
+4 -4
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)
+61
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)
@@ -62,6 +62,9 @@ protected:
return true;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}
@@ -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;
}
};
}
@@ -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);
@@ -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);
@@ -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;
}
@@ -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;
}
};
}
@@ -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);
@@ -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;
}
};
}
@@ -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>();
@@ -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;
}
@@ -67,6 +71,7 @@ public:
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false)
.add<FlashPhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true)
.add<FlashPhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false)
@@ -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)
@@ -251,18 +262,29 @@ public:
}
virtual std::vector<TerminationGroup> getTerminationGroups() const override {
// FIRE3 has two physical termination banks: DW CAN 01-08 and DW CAN 09-16.
// Termination within a bank is actually independent (any number may be
// enabled at once).
return {
{
Network(Network::NetID::DWCAN_01),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_07)
Network(Network::NetID::DWCAN_06),
Network(Network::NetID::DWCAN_07),
Network(Network::NetID::DWCAN_08)
},
{
Network(Network::NetID::DWCAN_08),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_06)
Network(Network::NetID::DWCAN_09),
Network(Network::NetID::DWCAN_10),
Network(Network::NetID::DWCAN_11),
Network(Network::NetID::DWCAN_12),
Network(Network::NetID::DWCAN_13),
Network(Network::NetID::DWCAN_14),
Network(Network::NetID::DWCAN_15),
Network(Network::NetID::DWCAN_16)
}
};
}
@@ -397,6 +419,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 +443,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;
}
};
}
@@ -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;
}
@@ -70,6 +74,7 @@ public:
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false)
.add<FlashPhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true)
.add<FlashPhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false)
@@ -109,7 +114,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 {
@@ -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)
@@ -202,18 +213,28 @@ public:
}
virtual std::vector<TerminationGroup> getTerminationGroups() const override {
// FIRE3 FlexRay has two physical termination banks: DW CAN 01-08 and
// DW CAN 09-15 (DW CAN 16 is used by FlexRay). Termination within a bank is
// actually independent (any number may be enabled at once).
return {
{
Network(Network::NetID::DWCAN_01),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_07)
Network(Network::NetID::DWCAN_06),
Network(Network::NetID::DWCAN_07),
Network(Network::NetID::DWCAN_08)
},
{
Network(Network::NetID::DWCAN_08),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_06)
Network(Network::NetID::DWCAN_09),
Network(Network::NetID::DWCAN_10),
Network(Network::NetID::DWCAN_11),
Network(Network::NetID::DWCAN_12),
Network(Network::NetID::DWCAN_13),
Network(Network::NetID::DWCAN_14),
Network(Network::NetID::DWCAN_15)
}
};
}
@@ -236,6 +257,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 +281,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;
}
};
}
@@ -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;
}
@@ -75,6 +79,7 @@ public:
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false)
.add<FlashPhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true)
.add<FlashPhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false)
@@ -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)
@@ -211,18 +222,19 @@ public:
}
virtual std::vector<TerminationGroup> getTerminationGroups() const override {
// FIRE3 T1S-LIN has a single physical termination bank: DW CAN 01-08.
// Termination within the bank is actually independent (any number may be
// enabled at once).
return {
{
Network(Network::NetID::DWCAN_01),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_07)
},
{
Network(Network::NetID::DWCAN_08),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_06)
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_06),
Network(Network::NetID::DWCAN_07),
Network(Network::NetID::DWCAN_08)
}
};
}
@@ -466,6 +478,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 +583,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;
}
};
}
@@ -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;
}
@@ -52,6 +56,7 @@ public:
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false)
.add<FlashPhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true)
.add<FlashPhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false)
@@ -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)
@@ -164,18 +175,19 @@ public:
}
virtual std::vector<TerminationGroup> getTerminationGroups() const override {
// RED2 has a single physical termination bank: DW CAN 01-08. Termination
// within the bank is actually independent (any number may be enabled at
// once).
return {
{
Network(Network::NetID::DWCAN_01),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_07)
},
{
Network(Network::NetID::DWCAN_08),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_06)
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_06),
Network(Network::NetID::DWCAN_07),
Network(Network::NetID::DWCAN_08)
}
};
}
@@ -295,6 +307,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 +331,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;
}
};
}
@@ -92,6 +92,10 @@ protected:
}
bool supportsWiVI() const override { return true; }
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}
+2 -4
View File
@@ -42,6 +42,8 @@ public:
size_t getEthernetActivationLineCount() const override { return 1; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADA2B;
}
@@ -96,10 +98,6 @@ protected:
return 15*1024*1024;
}
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
return 0;
}
};
}
@@ -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;
}
};
}
@@ -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
@@ -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
@@ -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,53 @@ 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; }
bool supportsReboot() 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, Disk::NeoMemoryDiskDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
}
void setupPacketizer(Packetizer& packetizer) override {
Device::setupPacketizer(packetizer);
@@ -61,13 +82,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 +96,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 +108,4 @@ protected:
#endif // __cplusplus
#endif
#endif
@@ -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;
}
};
}
@@ -54,6 +54,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADComet3;
}
@@ -76,7 +78,7 @@ public:
protected:
RADComet3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<RADComet3Settings>(makeDriver);
initialize<RADComet3Settings, Disk::NeoMemoryDiskDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
}
void setupPacketizer(Packetizer& packetizer) override {
@@ -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;
}
};
}
@@ -79,6 +79,10 @@ protected:
size_t getDiskCount() const override {
return 1;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}
@@ -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,
@@ -85,6 +85,10 @@ protected:
size_t getDiskCount() const override {
return 1;
}
bool supportsGetAllMACAddresses() const override {
return false;
}
};
}; // namespace icsneo
@@ -63,6 +63,7 @@ public:
size_t getEthernetActivationLineCount() const override { return 1; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADGalaxy;
@@ -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;
}
};
}
@@ -71,6 +71,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADGalaxy2;
}
@@ -131,7 +133,7 @@ protected:
}
std::optional<MemoryAddress> getCoreminiStartAddressFlash() const override {
return 512*4;
return 92*1024*1024;
}
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {

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