mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-09-20 16:08:37 +02:00
Compare commits
20
Commits
2158a9781b
..
1.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07e4eca14a | ||
|
|
936566170f | ||
|
|
3aaacb6cc8 | ||
|
|
1dda9f5412 | ||
|
|
78c2e3ff89 | ||
|
|
afedd4bb1f | ||
|
|
9b01e488da | ||
|
|
77a886bbe0 | ||
|
|
aff547b738 | ||
|
|
7a5c8c2879 | ||
|
|
0dd8dbfb64 | ||
|
|
d708f8081a | ||
|
|
743246e813 | ||
|
|
4ed29b4a5e | ||
|
|
55d69246b0 | ||
|
|
19232def41 | ||
|
|
9d91524dc0 | ||
|
|
d86e3164af | ||
|
|
3d99898598 | ||
|
|
4b9cf1a37f |
@@ -35,30 +35,6 @@ unit_test windows/x64:
|
||||
- libicsneo-win-x64
|
||||
timeout: 5m
|
||||
|
||||
build windows/x86:
|
||||
stage: build
|
||||
script:
|
||||
- cmd /C ci\build-windows32.bat
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
|
||||
unit_test windows/x86:
|
||||
stage: unit_test
|
||||
script:
|
||||
- build\libicsneo-unit-tests.exe
|
||||
dependencies:
|
||||
- build windows/x86
|
||||
needs:
|
||||
- build windows/x86
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
timeout: 5m
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Ubuntu
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
+5
-1
@@ -82,7 +82,7 @@ if(MSVC)
|
||||
add_definitions(-D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING)
|
||||
add_definitions(-D_ITERATOR_DEBUG_LEVEL=0)
|
||||
else() #if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(LIBICSNEO_COMPILER_WARNINGS -Wall -Wno-switch -Wno-unknown-pragmas)
|
||||
set(LIBICSNEO_COMPILER_WARNINGS -Wall -Wno-unknown-pragmas)
|
||||
endif()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
@@ -235,6 +235,9 @@ set(SRC_FILES
|
||||
communication/message/networkmutexmessage.cpp
|
||||
communication/message/clientidmessage.cpp
|
||||
communication/message/transmitmessage.cpp
|
||||
communication/message/spiportkeymessage.cpp
|
||||
communication/message/genericapidatamessage.cpp
|
||||
communication/message/genericapistatusmessage.cpp
|
||||
communication/packet/flexraypacket.cpp
|
||||
communication/packet/canpacket.cpp
|
||||
communication/packet/a2bpacket.cpp
|
||||
@@ -345,6 +348,7 @@ add_library(icsneocpp
|
||||
api/icsneocpp/icsneocpp.cpp
|
||||
api/icsneocpp/event.cpp
|
||||
api/icsneocpp/eventmanager.cpp
|
||||
api/icsneocpp/heartbeat.cpp
|
||||
api/icsneocpp/version.cpp
|
||||
${SRC_FILES}
|
||||
)
|
||||
|
||||
@@ -45,6 +45,7 @@ Instructions for installing each API can be found in its respective documentatio
|
||||
- RAD-Pluto
|
||||
- RAD-Star 2
|
||||
- RAD-SuperMoon
|
||||
- RAD-wBMS
|
||||
- ValueCAN 3
|
||||
- ValueCAN 4
|
||||
|
||||
|
||||
+39
-12
@@ -5,6 +5,7 @@
|
||||
#include "icsneo/device/devicefinder.h"
|
||||
#include "icsneo/icsneocpp.h"
|
||||
#include "icsneo/communication/io.h"
|
||||
#include "icsneo/communication/network.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -71,6 +72,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");
|
||||
@@ -271,7 +273,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()) {
|
||||
@@ -462,11 +466,13 @@ icsneoc2_error_t icsneoc2_device_pcb_serial_get(const icsneoc2_device_t* device,
|
||||
return icsneoc2_error_invalid_type;
|
||||
}
|
||||
const auto& data = *pcbSerial;
|
||||
if(value) {
|
||||
size_t copyLen = std::min(*value_length, data.size());
|
||||
std::copy(data.begin(), data.begin() + copyLen, value);
|
||||
if(!value) {
|
||||
*value_length = data.size();
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
*value_length = data.size();
|
||||
size_t copyLen = std::min(*value_length, data.size());
|
||||
std::copy(data.begin(), data.begin() + copyLen, value);
|
||||
*value_length = copyLen;
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
|
||||
@@ -500,26 +506,32 @@ icsneoc2_error_t icsneoc2_device_mac_addresses_enumerate(const icsneoc2_device_t
|
||||
}
|
||||
tail = node;
|
||||
}
|
||||
*mac_entries = head;
|
||||
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) {
|
||||
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);
|
||||
const auto netid = static_cast<Network::NetID>(mac_address->network_id);
|
||||
*network_id = Network::GetCoreMiniNetworkFromNetID(netid).has_value()
|
||||
? mac_address->network_id
|
||||
: static_cast<icsneoc2_netid_t>(icsneoc2_netid_invalid);
|
||||
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) {
|
||||
if(!mac_address || !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);
|
||||
if(!value) {
|
||||
*value_length = static_cast<size_t>(ICSNEO_MAC_ADDRESS_LEN);
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
*value_length = static_cast<size_t>(ICSNEO_MAC_ADDRESS_LEN);
|
||||
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 = copyLen;
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
|
||||
@@ -1095,6 +1107,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) {
|
||||
|
||||
@@ -48,6 +48,11 @@ typedef struct icsneoc2_chip_versions_t {
|
||||
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];
|
||||
|
||||
@@ -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) {
|
||||
@@ -316,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;
|
||||
@@ -631,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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -462,6 +462,8 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||
return TOO_MANY_EVENTS;
|
||||
case Type::Unknown:
|
||||
return UNKNOWN;
|
||||
case Type::Any:
|
||||
break;
|
||||
}
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "icsneo/api/heartbeat.h"
|
||||
#include "icsneo/api/lifetime.h"
|
||||
#include "icsneo/device/device.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
Heartbeat::Heartbeat(Device& device) :
|
||||
device(device), mode(device.isOnline() ? Mode::Passive : Mode::Active), thread(&Heartbeat::run, this) {
|
||||
}
|
||||
|
||||
Heartbeat::~Heartbeat() {
|
||||
{
|
||||
std::lock_guard lk(mutex);
|
||||
stop = true;
|
||||
}
|
||||
cv.notify_one();
|
||||
thread.join();
|
||||
}
|
||||
|
||||
void Heartbeat::run() {
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
|
||||
auto filter = std::make_shared<MessageFilter>();
|
||||
filter->includeInternalInAny = true;
|
||||
bool status = false;
|
||||
auto cbHandle = device.com->addMessageCallback(std::make_shared<MessageCallback>(filter, [&](std::shared_ptr<Message> msg) {
|
||||
// TODO: remove DeviceStatus after 2027-08-17, as ResetStatus should be widely supported
|
||||
const bool isHeartbeat =
|
||||
(msg->type == Message::Type::ResetStatus) ||
|
||||
(msg->type == Message::Type::RawMessage && std::static_pointer_cast<RawMessage>(msg)->network == Network::NetID::DeviceStatus);
|
||||
if(!isHeartbeat)
|
||||
return;
|
||||
{
|
||||
std::lock_guard lk(mutex);
|
||||
status = true;
|
||||
}
|
||||
cv.notify_one();
|
||||
}));
|
||||
Lifetime cbLifetime([&] {
|
||||
device.com->removeMessageCallback(cbHandle);
|
||||
});
|
||||
while(true) {
|
||||
std::unique_lock lk(mutex);
|
||||
if(mode == Mode::Active) {
|
||||
if(cv.wait_for(lk, std::chrono::milliseconds(100), [&] { return stop; })) {
|
||||
break;
|
||||
}
|
||||
device.com->sendCommand(Command::RequestStatusUpdate);
|
||||
}
|
||||
if(!cv.wait_for(lk, std::chrono::seconds(2), [&] { return status || stop; })) {
|
||||
// we disconnect instead of close because it indicates to the user that a cleanup is still required (our thread join)
|
||||
device.report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
device.com->driver->setIsDisconnected(true);
|
||||
break;
|
||||
}
|
||||
if(stop)
|
||||
break;
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -1088,6 +1088,8 @@ int LegacyDLLExport icsneoGetDeviceSettingsType(void* hObject, EPlasmaIonVnetCha
|
||||
case NEODEVICE_FIRE3_FLEXRAY:
|
||||
*pDeviceSettingsType = DeviceFire3FlexraySettingsType;
|
||||
break;
|
||||
case NEODEVICE_RAD_BMS:
|
||||
*pDeviceSettingsType = DeviceRADBMSSettingsType;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -36,6 +36,7 @@ void init_devicetype(pybind11::module_& m) {
|
||||
.value("RADEpsilon", DeviceType::Enum::RADEpsilon)
|
||||
.value("RADEpsilonXL", DeviceType::Enum::RADEpsilonXL)
|
||||
.value("RADGalaxy2", DeviceType::Enum::RADGalaxy2)
|
||||
.value("RADwBMS", DeviceType::Enum::RADwBMS)
|
||||
.value("RADMoon3", DeviceType::Enum::RADMoon3)
|
||||
.value("RADGemini", DeviceType::Enum::RADGemini)
|
||||
.value("RADComet2", DeviceType::Enum::RADComet2)
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DLIBICSNEO_BUILD_EXAMPLES=ON \
|
||||
-DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_ENABLE_TCP=OFF || exit 1
|
||||
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DLIBICSNEO_BUILD_EXAMPLES=ON -DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_ENABLE_TCP=OFF || exit 1
|
||||
|
||||
cmake --build build || exit 1
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
mkdir build >nul 2>&1
|
||||
|
||||
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DLIBICSNEO_BUILD_UNIT_TESTS=ON ^
|
||||
-DLIBICSNEO_ENABLE_TCP=ON || exit /b 1
|
||||
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DLIBICSNEO_BUILD_UNIT_TESTS=ON-DLIBICSNEO_ENABLE_TCP=ON || exit /b 1
|
||||
|
||||
cmake --build build || exit /b 1
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
#include "icsneo/communication/message/networkmutexmessage.h"
|
||||
#include "icsneo/communication/message/clientidmessage.h"
|
||||
#include "icsneo/communication/message/spiportkeymessage.h"
|
||||
#include "icsneo/communication/message/genericapidatamessage.h"
|
||||
#include "icsneo/communication/message/genericapistatusmessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
@@ -341,6 +344,15 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
case ExtendedCommand::LiveData:
|
||||
result = HardwareLiveDataPacket::DecodeToMessage(packet->data, report);
|
||||
return true;
|
||||
case ExtendedCommand::ExecuteSPIPortKeyOperation:
|
||||
result = SPIPortKeyMessage::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
case ExtendedCommand::ReadGenericAPIData:
|
||||
result = GenericAPIDataMessage::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
case ExtendedCommand::ReadGenericAPIStatus:
|
||||
result = GenericAPIStatusMessage::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
case ExtendedCommand::GetTC10Status:
|
||||
result = TC10StatusMessage::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
@@ -563,6 +575,9 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// For the moment other types of messages will automatically be decoded as raw messages
|
||||
|
||||
@@ -234,7 +234,9 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
result = packetizer.packetWrap(result, false);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false; // The message was not a properly formed Message
|
||||
}
|
||||
|
||||
// Early returns may mean we don't reach this far, check the type you're concerned with
|
||||
|
||||
@@ -163,6 +163,8 @@ void A2BMessage::setChannelSample(Direction dir, uint8_t channel, size_t frame,
|
||||
case PCMType::L24:
|
||||
sampleToSet = sampleToSet << 8;
|
||||
break;
|
||||
case PCMType::L32:
|
||||
break;
|
||||
}
|
||||
|
||||
if(channelSize16) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph
|
||||
|
||||
bool EthPhyMessage::appendPhyMessage(std::shared_ptr<PhyMessage> message)
|
||||
{
|
||||
if(message != nullptr)
|
||||
if(message)
|
||||
{
|
||||
messages.push_back(message);
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "icsneo/communication/message/genericapidatamessage.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
std::shared_ptr<GenericAPIDataMessage> GenericAPIDataMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() < sizeof(ExtendedResponseMessage::ResponseHeader))
|
||||
return nullptr;
|
||||
|
||||
const auto* hdr = reinterpret_cast<const ExtendedResponseMessage::ResponseHeader*>(bytestream.data());
|
||||
|
||||
if(hdr->command != ExtendedCommand::ReadGenericAPIData)
|
||||
return nullptr;
|
||||
|
||||
const size_t required = sizeof(ExtendedResponseMessage::ResponseHeader) + sizeof(GenericAPIDataHeader);
|
||||
if(bytestream.size() < required)
|
||||
return nullptr;
|
||||
|
||||
auto msg = std::make_shared<GenericAPIDataMessage>();
|
||||
|
||||
const auto* packet = reinterpret_cast<const GenericAPIDataPacket*>(bytestream.data() + sizeof(ExtendedResponseMessage::ResponseHeader));
|
||||
|
||||
msg->functionId = packet->header.functionId;
|
||||
msg->buffer.resize(packet->header.bufferLength);
|
||||
std::copy(packet->buffer, packet->buffer + packet->header.bufferLength, msg->buffer.data());
|
||||
return msg;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "icsneo/communication/message/genericapistatusmessage.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
std::shared_ptr<GenericAPIStatusMessage> GenericAPIStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() < sizeof(ExtendedResponseMessage::ResponseHeader))
|
||||
return nullptr;
|
||||
|
||||
const auto* hdr = reinterpret_cast<const ExtendedResponseMessage::ResponseHeader*>(bytestream.data());
|
||||
|
||||
if(hdr->command != ExtendedCommand::ReadGenericAPIStatus)
|
||||
return nullptr;
|
||||
|
||||
const size_t required = sizeof(ExtendedResponseMessage::ResponseHeader) + sizeof(GenericAPIStatusResponsePacket);
|
||||
if(bytestream.size() < required)
|
||||
return nullptr;
|
||||
|
||||
auto msg = std::make_shared<GenericAPIStatusMessage>();
|
||||
|
||||
const auto* packet = reinterpret_cast<const GenericAPIStatusResponsePacket*>(bytestream.data() + sizeof(ExtendedResponseMessage::ResponseHeader));
|
||||
|
||||
msg->functionId = packet->functionId;
|
||||
msg->finishedProcessing = static_cast<bool>(packet->finishedProcessing);
|
||||
msg->functionError = packet->functionError;
|
||||
msg->callbackError = packet->callbackError;
|
||||
return msg;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "icsneo/communication/message/spiportkeymessage.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/communication/network.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
std::shared_ptr<SPIPortKeyMessage> SPIPortKeyMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() < sizeof(ExtendedResponseMessage::ResponseHeader))
|
||||
return nullptr;
|
||||
|
||||
const auto* hdr = reinterpret_cast<const ExtendedResponseMessage::ResponseHeader*>(bytestream.data());
|
||||
|
||||
if(hdr->command != ExtendedCommand::ExecuteSPIPortKeyOperation)
|
||||
return nullptr;
|
||||
|
||||
const size_t required = sizeof(ExtendedResponseMessage::ResponseHeader) + sizeof(SPIPortKeyPacket);
|
||||
if(bytestream.size() < required)
|
||||
return nullptr;
|
||||
|
||||
auto msg = std::make_shared<SPIPortKeyMessage>();
|
||||
|
||||
const auto* packet = reinterpret_cast<const SPIPortKeyPacket*>(bytestream.data() + sizeof(ExtendedResponseMessage::ResponseHeader));
|
||||
msg->isKeyLoaded = packet->isKeyLoaded;
|
||||
|
||||
return msg;
|
||||
}
|
||||
@@ -142,6 +142,8 @@ void MultiChannelCommunication::hidReadTask() {
|
||||
dispatchMessage(msg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(currentQueue == nullptr) {
|
||||
|
||||
+54
-114
@@ -92,10 +92,6 @@ Device::~Device() {
|
||||
disableMessagePolling();
|
||||
if(isOpen())
|
||||
close();
|
||||
if(heartbeatThread.joinable()) {
|
||||
stopHeartbeatThread = true;
|
||||
heartbeatThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Device::getTimestampResolution() const {
|
||||
@@ -288,6 +284,8 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
return false;
|
||||
}
|
||||
|
||||
startHeartbeat();
|
||||
|
||||
APIEvent::Type attemptErr = attemptToBeginCommunication();
|
||||
if(attemptErr != APIEvent::Type::NoErrorFound) {
|
||||
// We could not communicate with the device, let's see if an extension can
|
||||
@@ -334,79 +332,6 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
EventManager::GetInstance().cancelErrorDowngradingOnCurrentThread();
|
||||
}
|
||||
|
||||
MessageFilter filter;
|
||||
filter.includeInternalInAny = true;
|
||||
internalHandlerCallbackID = com->addMessageCallback(std::make_shared<MessageCallback>(filter, [this](std::shared_ptr<Message> message) {
|
||||
handleInternalMessage(message);
|
||||
}));
|
||||
|
||||
// Clear the previous heartbeat thread, in case open() was called on this instance more than once
|
||||
if(heartbeatThread.joinable())
|
||||
heartbeatThread.join();
|
||||
|
||||
stopHeartbeatThread = false;
|
||||
|
||||
heartbeatThread = std::thread([this]() {
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
|
||||
MessageFilter filter;
|
||||
filter.includeInternalInAny = true;
|
||||
|
||||
std::condition_variable heartbeatCV;
|
||||
std::mutex receivedMessageMutex;
|
||||
bool receivedMessage = false;
|
||||
auto messageReceivedCallbackID = com->addMessageCallback(std::make_shared<MessageCallback>(filter, [&](std::shared_ptr<Message>) {
|
||||
{
|
||||
std::scoped_lock<std::mutex> lk(receivedMessageMutex);
|
||||
receivedMessage = true;
|
||||
}
|
||||
heartbeatCV.notify_all();
|
||||
}));
|
||||
|
||||
// Give the device time to get situated
|
||||
auto i = 150;
|
||||
while(!stopHeartbeatThread && i != 0) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
i--;
|
||||
}
|
||||
|
||||
while(!stopHeartbeatThread) {
|
||||
std::unique_lock<std::mutex> recvLk(receivedMessageMutex);
|
||||
// Wait for 110ms for a possible heartbeat
|
||||
if(heartbeatCV.wait_for(recvLk, std::chrono::milliseconds(110), [&]() { return receivedMessage; })) {
|
||||
receivedMessage = false;
|
||||
} else if(!stopHeartbeatThread) { // Add this condition here in case the thread was stopped while waiting for the last message
|
||||
|
||||
// Some communication, such as the bootloader and extractor interfaces, must
|
||||
// redirect the input stream from the device as it will no longer be in the
|
||||
// packet format we expect here. As a result, status updates will not reach
|
||||
// us here and suppressDisconnects() must be used. We don't want to request
|
||||
// a status and then redirect the stream, as we'll then be polluting an
|
||||
// otherwise quiet stream. This lock makes sure suppressDisconnects() will
|
||||
// block until we've either gotten our status update or disconnected from
|
||||
// the device.
|
||||
std::unique_lock<std::mutex> lk(heartbeatMutex);
|
||||
if(heartbeatSuppressed()) continue;
|
||||
|
||||
// No heartbeat received, request a status
|
||||
com->sendCommand(Command::RequestStatusUpdate);
|
||||
|
||||
// Check if we got a message, and if not, if settings are being applied
|
||||
if(heartbeatCV.wait_for(recvLk, std::chrono::milliseconds(3500), [&](){ return receivedMessage; })) {
|
||||
receivedMessage = false;
|
||||
} else {
|
||||
if(!stopHeartbeatThread) {
|
||||
close();
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
com->removeMessageCallback(messageReceivedCallbackID);
|
||||
});
|
||||
|
||||
if(supportsLiveData())
|
||||
clearAllLiveData();
|
||||
|
||||
@@ -503,7 +428,7 @@ bool Device::close() {
|
||||
return false;
|
||||
}
|
||||
|
||||
stopHeartbeatThread = true;
|
||||
stopHeartbeat();
|
||||
|
||||
if (isMessagePollingEnabled()) {
|
||||
disableMessagePolling();
|
||||
@@ -534,31 +459,15 @@ bool Device::goOnline() {
|
||||
if(!enableNetworkCommunication(true, onlineTimeoutMs))
|
||||
return false;
|
||||
|
||||
auto startTime = std::chrono::system_clock::now();
|
||||
|
||||
ledState = LEDState::Online;
|
||||
|
||||
updateLEDState();
|
||||
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::Reset_Status);
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
// Wait until communication is enabled or 5 seconds, whichever comes first
|
||||
while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds(5)) {
|
||||
if(latestResetStatus && latestResetStatus->comEnabled)
|
||||
break;
|
||||
|
||||
bool failOut = false;
|
||||
com->waitForMessageSync([this, &failOut]() {
|
||||
if(!com->sendCommand(Command::RequestStatusUpdate)) {
|
||||
failOut = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, filter, std::chrono::milliseconds(100));
|
||||
if(failOut)
|
||||
return false;
|
||||
}
|
||||
// (re)start the keeponline
|
||||
keeponline = std::make_unique<Periodic>([this] {
|
||||
static std::vector<uint8_t> timeoutBytes = std::vector<uint8_t>((uint8_t*)&onlineTimeoutMs, (uint8_t*)&onlineTimeoutMs + sizeof(onlineTimeoutMs));
|
||||
return com->sendCommand(Command::KeepAlive, timeoutBytes);
|
||||
}, std::chrono::milliseconds(onlineTimeoutMs / 4));
|
||||
|
||||
if(supportsNetworkMutex) {
|
||||
assignedClientId = com->getClientIDSync();
|
||||
@@ -575,41 +484,46 @@ bool Device::goOnline() {
|
||||
case NetworkMutexEvent::Acquired:
|
||||
lockedNetworks.emplace(*netMutexMsg->networks.begin());
|
||||
break;
|
||||
case NetworkMutexEvent::Expired:
|
||||
case NetworkMutexEvent::Preempted:
|
||||
case NetworkMutexEvent::Released: {
|
||||
auto it = lockedNetworks.find(*netMutexMsg->networks.begin());
|
||||
if (it != lockedNetworks.end())
|
||||
lockedNetworks.erase(it);
|
||||
break;
|
||||
}
|
||||
case NetworkMutexEvent::Queued:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// (re)start the keeponline
|
||||
keeponline = std::make_unique<Periodic>([this] {
|
||||
static std::vector<uint8_t> timeoutBytes = std::vector<uint8_t>((uint8_t*)&onlineTimeoutMs, (uint8_t*)&onlineTimeoutMs + sizeof(onlineTimeoutMs));
|
||||
return com->sendCommand(Command::KeepAlive, timeoutBytes);
|
||||
}, std::chrono::milliseconds(onlineTimeoutMs / 4));
|
||||
|
||||
online = true;
|
||||
|
||||
// restart the heartbeat in online mode
|
||||
restartHeartbeat();
|
||||
|
||||
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onGoOnline(); return true; });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Device::goOffline() {
|
||||
online = false;
|
||||
|
||||
keeponline.reset();
|
||||
|
||||
// restart the heartbeat in offline mode
|
||||
restartHeartbeat();
|
||||
|
||||
if(networkMutexCallbackHandle)
|
||||
removeMessageCallback(*networkMutexCallbackHandle);
|
||||
|
||||
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onGoOffline(); return true; });
|
||||
|
||||
if(isDisconnected()) {
|
||||
online = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -625,8 +539,6 @@ bool Device::goOffline() {
|
||||
|
||||
updateLEDState();
|
||||
|
||||
online = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1988,11 +1900,9 @@ void Device::stopScriptStatusThreadIfNecessary(std::unique_lock<std::mutex> lk)
|
||||
}
|
||||
|
||||
Lifetime Device::suppressDisconnects() {
|
||||
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
||||
heartbeatSuppressedByUser++;
|
||||
stopHeartbeat();
|
||||
return Lifetime([this] {
|
||||
std::lock_guard<std::mutex> lk2(heartbeatMutex);
|
||||
heartbeatSuppressedByUser--;
|
||||
startHeartbeat();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2128,6 +2038,18 @@ std::optional<EthPhyMessage> Device::sendEthPhyMsg(const EthPhyMessage& message,
|
||||
return std::make_optional<EthPhyMessage>(*retMsg);
|
||||
}
|
||||
|
||||
bool Device::sendSPIPortKeyOperation(uint8_t portIndex, SPIPortKeyMessage::Operation op, std::array<uint8_t, 16> key) {
|
||||
std::vector<uint8_t> args(sizeof(SPIPortKeyMessage::SPIPortKeyPacket));
|
||||
auto& params = *reinterpret_cast<SPIPortKeyMessage::SPIPortKeyPacket*>(args.data());
|
||||
params.op = op;
|
||||
params.portIndex = portIndex;
|
||||
std::copy(key.begin(), key.end(), params.key);
|
||||
if(!com->sendCommand(ExtendedCommand::ExecuteSPIPortKeyOperation, args)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> Device::SetRootDirectoryEntryFlags(uint8_t mask, uint8_t values, uint32_t collectionEntryByteAddress)
|
||||
{
|
||||
if(!supportsWiVI())
|
||||
@@ -3297,11 +3219,12 @@ bool Device::findVSAOffsetFromTimepoint(ICSClock::time_point point, uint64_t& vs
|
||||
std::shared_ptr<VSA> midRecord;
|
||||
auto midRecordStatus = parser.getRecordFromBytes(buffer.data(), Disk::SectorSize, midRecord);
|
||||
switch(midRecordStatus) {
|
||||
case VSAParser::RecordParseStatus::NotARecordStart:
|
||||
case VSAParser::RecordParseStatus::NotARecordStart: {
|
||||
// This part of the buffer does not contain records
|
||||
rightIndex = midIndex - 1;
|
||||
continue;
|
||||
case VSAParser::RecordParseStatus::ConsecutiveExtended:
|
||||
}
|
||||
case VSAParser::RecordParseStatus::ConsecutiveExtended: {
|
||||
// We dropped in the middle of an extended message record
|
||||
auto extendedRecord = std::dynamic_pointer_cast<VSAExtendedMessage>(midRecord);
|
||||
uint64_t pos = readPos;
|
||||
@@ -3316,6 +3239,9 @@ bool Device::findVSAOffsetFromTimepoint(ICSClock::time_point point, uint64_t& vs
|
||||
midIndex = (pos - firstOffset) / Disk::SectorSize;
|
||||
midRecord = extendedRecord;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(midIndex <= leftIndex) {
|
||||
// Extended records cause problems with binary search
|
||||
@@ -4156,3 +4082,17 @@ bool Device::unlockAllNetworks()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Device::startHeartbeat() {
|
||||
if(!heartbeat)
|
||||
heartbeat = std::make_unique<Heartbeat>(*this);
|
||||
}
|
||||
|
||||
void Device::stopHeartbeat() {
|
||||
heartbeat.reset();
|
||||
}
|
||||
|
||||
void Device::restartHeartbeat() {
|
||||
stopHeartbeat();
|
||||
startHeartbeat();
|
||||
}
|
||||
|
||||
@@ -241,6 +241,10 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
makeIfSerialMatches<RADSupermoon>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADWBMS_H_
|
||||
makeIfSerialMatches<RADwBMS>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN3_H_
|
||||
makeIfSerialRangeMatches<ValueCAN3>(dev, newFoundDevices);
|
||||
#endif
|
||||
@@ -404,6 +408,10 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
RADSupermoon::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADWBMS_H_
|
||||
RADwBMS::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN3_H_
|
||||
ValueCAN3::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
+24
-17
@@ -1,9 +1,16 @@
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/idevicesettings.h"
|
||||
#include "icsneo/communication/message/filter/main51messagefilter.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
IDeviceSettings::IDeviceSettings(Device* device, size_t size)
|
||||
: device(device), report(device->report), structSize(size) {}
|
||||
|
||||
IDeviceSettings::IDeviceSettings(warn_t createInoperableSettings, Device* device)
|
||||
: disabled(true), readonly(true), report(device->report), structSize(0) { (void)createInoperableSettings; }
|
||||
|
||||
std::optional<uint16_t> IDeviceSettings::CalculateGSChecksum(const std::vector<uint8_t>& settings) {
|
||||
const uint16_t* p = reinterpret_cast<const uint16_t*>(settings.data());
|
||||
size_t words = settings.size();
|
||||
@@ -166,7 +173,7 @@ bool IDeviceSettings::refresh() {
|
||||
}
|
||||
|
||||
std::vector<uint8_t> rxSettings;
|
||||
bool ret = com->getSettingsSync(rxSettings);
|
||||
bool ret = device->com->getSettingsSync(rxSettings);
|
||||
if(!ret) {
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
@@ -231,10 +238,10 @@ bool IDeviceSettings::apply(bool temporary) {
|
||||
memcpy(bytestream.data() + 7, getMutableRawStructurePointer(), settings.size());
|
||||
|
||||
// Pause I/O with the device while the settings are applied
|
||||
applyingSettings = true;
|
||||
device->stopHeartbeat();
|
||||
|
||||
std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
|
||||
return com->sendCommand(Command::SetSettings, bytestream);
|
||||
std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(device->com->waitForMessageSync([this, &bytestream]() {
|
||||
return device->com->sendCommand(Command::SetSettings, bytestream);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(5000)));
|
||||
|
||||
if(!msg || msg->data[0] != 1) { // We did not receive a response
|
||||
@@ -259,8 +266,8 @@ bool IDeviceSettings::apply(bool temporary) {
|
||||
bytestream[6] = (uint8_t)(*gsChecksum >> 8);
|
||||
memcpy(bytestream.data() + 7, getMutableRawStructurePointer(), settings.size());
|
||||
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
|
||||
return com->sendCommand(Command::SetSettings, bytestream);
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(device->com->waitForMessageSync([this, &bytestream]() {
|
||||
return device->com->sendCommand(Command::SetSettings, bytestream);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(5000)));
|
||||
if(!msg || msg->data[0] != 1) {
|
||||
// Attempt to get the settings from the device so we're up to date if possible
|
||||
@@ -272,12 +279,12 @@ bool IDeviceSettings::apply(bool temporary) {
|
||||
}
|
||||
|
||||
if(!temporary) {
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() {
|
||||
return com->sendCommand(Command::SaveSettings);
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(device->com->waitForMessageSync([this]() {
|
||||
return device->com->sendCommand(Command::SaveSettings);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SaveSettings), std::chrono::milliseconds(5000)));
|
||||
}
|
||||
|
||||
applyingSettings = false;
|
||||
device->startHeartbeat();
|
||||
|
||||
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
||||
|
||||
@@ -299,10 +306,10 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||
return false;
|
||||
}
|
||||
|
||||
applyingSettings = true;
|
||||
device->stopHeartbeat();
|
||||
|
||||
std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() {
|
||||
return com->sendCommand(Command::SetDefaultSettings);
|
||||
std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(device->com->waitForMessageSync([this]() {
|
||||
return device->com->sendCommand(Command::SetDefaultSettings);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetDefaultSettings), std::chrono::milliseconds(5000)));
|
||||
if(!msg || msg->data[0] != 1) {
|
||||
// Attempt to get the settings from the device so we're up to date if possible
|
||||
@@ -336,8 +343,8 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||
bytestream[6] = (uint8_t)(*gsChecksum >> 8);
|
||||
memcpy(bytestream.data() + 7, getMutableRawStructurePointer(), settings.size());
|
||||
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
|
||||
return com->sendCommand(Command::SetSettings, bytestream);
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(device->com->waitForMessageSync([this, &bytestream]() {
|
||||
return device->com->sendCommand(Command::SetSettings, bytestream);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(5000)));
|
||||
if(!msg || msg->data[0] != 1) {
|
||||
// Attempt to get the settings from the device so we're up to date if possible
|
||||
@@ -349,12 +356,12 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||
}
|
||||
|
||||
if(!temporary) {
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() {
|
||||
return com->sendCommand(Command::SaveSettings);
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(device->com->waitForMessageSync([this]() {
|
||||
return device->com->sendCommand(Command::SaveSettings);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SaveSettings), std::chrono::milliseconds(5000)));
|
||||
}
|
||||
|
||||
applyingSettings = false;
|
||||
device->startHeartbeat();
|
||||
|
||||
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
||||
|
||||
|
||||
@@ -74,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
|
||||
============
|
||||
|
||||
@@ -106,3 +114,11 @@ PerfTest
|
||||
.. 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
|
||||
|
||||
|
||||
@@ -8,10 +8,12 @@ option(LIBICSNEO_BUILD_C2_DISKFORMAT_EXAMPLE "Build the C2 disk format example."
|
||||
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)
|
||||
@@ -77,6 +79,10 @@ 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()
|
||||
@@ -93,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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ int main() {
|
||||
}
|
||||
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_netid_t network_id;
|
||||
icsneoc2_mac_network_id_get(cur, &network_id);
|
||||
printf(" Network %-5u ", (unsigned)network_id);
|
||||
uint8_t address[6];
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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()
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -296,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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -472,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-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()
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef __HEARTBEAT_H__
|
||||
#define __HEARTBEAT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class Device;
|
||||
|
||||
class Heartbeat {
|
||||
public:
|
||||
Heartbeat(Device& device);
|
||||
~Heartbeat();
|
||||
|
||||
private:
|
||||
enum class Mode {
|
||||
Passive, // ResetStatus messages arrive without requesting
|
||||
Active, // RequestStatusUpdate needs to be sent
|
||||
};
|
||||
Device& device;
|
||||
const Mode mode;
|
||||
bool stop = false;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
std::thread thread;
|
||||
|
||||
void run();
|
||||
};
|
||||
|
||||
} // icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __HEARTBEAT_H__
|
||||
@@ -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_
|
||||
@@ -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,
|
||||
@@ -57,10 +73,14 @@ enum class ExtendedCommand : uint16_t {
|
||||
GetComponentVersions = 0x001A,
|
||||
SoftwareUpdate = 0x001B,
|
||||
Reboot = 0x001C,
|
||||
ReadGenericAPIStatus = 0x001D,
|
||||
SetRootFSEntryFlags = 0x0027,
|
||||
TransmitCoreminiMessage = 0x0028,
|
||||
ReadGenericAPIData = 0x002E,
|
||||
WriteGenericAPICommand = 0x002F,
|
||||
GenericBinaryInfo = 0x0030,
|
||||
LiveData = 0x0035,
|
||||
ExecuteSPIPortKeyOperation = 0x003C,
|
||||
RequestTC10Wake = 0x003D,
|
||||
RequestTC10Sleep = 0x003E,
|
||||
GetTC10Status = 0x003F,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
#include "icsneo/device/deviceversion.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "icsneo/api/heartbeat.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/encoder.h"
|
||||
#include "icsneo/communication/decoder.h"
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
virtual driver_finder_t getFinder() = 0;
|
||||
|
||||
inline bool isDisconnected() const { return disconnected; };
|
||||
inline void setIsDisconnected(bool isDisconnected) { disconnected = isDisconnected; }
|
||||
inline bool isClosing() const { return closing; }
|
||||
|
||||
bool waitForRx(size_t limit, std::chrono::milliseconds timeout);
|
||||
@@ -62,7 +63,6 @@ protected:
|
||||
};
|
||||
|
||||
inline void setIsClosing(bool isClosing) { closing = isClosing; }
|
||||
inline void setIsDisconnected(bool isDisconnected) { disconnected = isDisconnected; }
|
||||
|
||||
// Overridable in case the driver doesn't want to use writeTask and writeQueue
|
||||
virtual bool writeQueueFull() { return writeQueue.size_approx() > writeQueueSize; }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "icsneo/communication/packet/ethphyregpacket.h"
|
||||
#include "icsneo/communication/message/message.h"
|
||||
#include "icsneo/communication/packet.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef __GENERICAPIDATAMESSAGE_H_
|
||||
#define __GENERICAPIDATAMESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class GenericAPIDataMessage : public Message {
|
||||
public:
|
||||
static constexpr size_t GENERIC_API_BUFFER_SIZE = 513;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct GenericAPIDataHeader {
|
||||
uint16_t bufferLength;
|
||||
uint8_t apiIndex;
|
||||
uint8_t instance;
|
||||
uint8_t functionId;
|
||||
};
|
||||
|
||||
struct GenericAPIDataPacket
|
||||
{
|
||||
GenericAPIDataHeader header;
|
||||
uint8_t buffer[GENERIC_API_BUFFER_SIZE];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static std::shared_ptr<GenericAPIDataMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||
|
||||
GenericAPIDataMessage() : Message(Type::GenericAPIData) {}
|
||||
|
||||
uint8_t functionId;
|
||||
std::vector<uint8_t> buffer;
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __GENERICAPIDATAMESSAGE_H_
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef __GENERICAPISTATUSMESSAGE_H_
|
||||
#define __GENERICAPISTATUSMESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class GenericAPIStatusMessage : public Message {
|
||||
public:
|
||||
#pragma pack(push, 2)
|
||||
struct GenericAPIStatusResponsePacket
|
||||
{
|
||||
uint8_t apiIndex;
|
||||
uint8_t instance;
|
||||
uint8_t functionId;
|
||||
uint8_t functionError;
|
||||
uint8_t callbackError;
|
||||
uint8_t finishedProcessing;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static std::shared_ptr<GenericAPIStatusMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||
|
||||
GenericAPIStatusMessage() : Message(Type::GenericAPIStatus) {}
|
||||
|
||||
uint8_t functionId;
|
||||
bool finishedProcessing;
|
||||
uint8_t functionError;
|
||||
uint8_t callbackError;
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __GENERICAPISTATUSMESSAGE_H_
|
||||
@@ -48,6 +48,9 @@ public:
|
||||
NetworkMutex = 0x8016,
|
||||
ClientId = 0x8017,
|
||||
AllMACAddresses = 0x8018,
|
||||
SPIPortKeyOperation = 0x8019,
|
||||
GenericAPIData = 0x8020,
|
||||
GenericAPIStatus = 0x8021,
|
||||
};
|
||||
|
||||
Message(Type t) : type(t) {}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef __SPIPORTKEYMESSAGE_H_
|
||||
#define __SPIPORTKEYMESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class SPIPortKeyMessage : public Message {
|
||||
public:
|
||||
enum class Operation : uint8_t {
|
||||
WriteKey = 0,
|
||||
IsKeySet = 1,
|
||||
ClearKey = 2
|
||||
};
|
||||
|
||||
#pragma pack(push, 2)
|
||||
struct SPIPortKeyPacket
|
||||
{
|
||||
Operation op;
|
||||
uint8_t portIndex;
|
||||
bool isKeyLoaded;
|
||||
uint8_t rsvd;
|
||||
uint8_t key[16];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static std::shared_ptr<SPIPortKeyMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||
|
||||
SPIPortKeyMessage() : Message(Type::SPIPortKeyOperation) {}
|
||||
|
||||
bool isKeyLoaded;
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __SPIPORTKEYMESSAGE_H_
|
||||
@@ -126,6 +126,7 @@ enum class ChipID : icsneoc2_chip_id_t {
|
||||
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,
|
||||
RADBMS_WIL = icsneoc2_chip_id_radbms_wil,
|
||||
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,
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
#include "icsneo/communication/message/extendeddatamessage.h"
|
||||
#include "icsneo/communication/message/livedatamessage.h"
|
||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||
#include "icsneo/communication/message/spiportkeymessage.h"
|
||||
#include "icsneo/communication/message/genericapidatamessage.h"
|
||||
#include "icsneo/communication/message/genericapistatusmessage.h"
|
||||
#include "icsneo/core/macseccfg.h"
|
||||
#include "icsneo/communication/packet/genericbinarystatuspacket.h"
|
||||
#include "icsneo/communication/packet/livedatapacket.h"
|
||||
@@ -133,6 +136,7 @@ public:
|
||||
RADA2B = 40,
|
||||
SFPModule_88q2112 = 41,
|
||||
RADGalaxy2 = 47,
|
||||
RADwBMS = 48,
|
||||
RADMoon3 = 49,
|
||||
RADComet2 = 50,
|
||||
Connect = 51,
|
||||
@@ -231,9 +235,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 =
|
||||
@@ -716,6 +729,8 @@ public:
|
||||
|
||||
std::optional<EthPhyMessage> sendEthPhyMsg(const EthPhyMessage& message, std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
|
||||
|
||||
|
||||
bool sendSPIPortKeyOperation(uint8_t portIndex, SPIPortKeyMessage::Operation op, std::array<uint8_t, 16> key = {});
|
||||
|
||||
/**
|
||||
* Set the flags of the root directory entry specified at given address
|
||||
@@ -730,6 +745,7 @@ public:
|
||||
*/
|
||||
std::optional<bool> SetRootDirectoryEntryFlags(uint8_t mask, uint8_t values, uint32_t collectionEntryByteAddress);
|
||||
|
||||
device_eventhandler_t report;
|
||||
std::shared_ptr<Communication> com;
|
||||
std::shared_ptr<IDeviceSettings> settings;
|
||||
|
||||
@@ -887,11 +903,14 @@ public:
|
||||
bool unlockAllNetworks();
|
||||
std::shared_ptr<NetworkMutexMessage> getNetworkMutexStatus(Network::NetID network);
|
||||
|
||||
void startHeartbeat();
|
||||
void stopHeartbeat();
|
||||
void restartHeartbeat();
|
||||
|
||||
protected:
|
||||
bool online = false;
|
||||
int messagePollingCallbackID = 0;
|
||||
int internalHandlerCallbackID = 0;
|
||||
device_eventhandler_t report;
|
||||
|
||||
std::mutex ioMutex;
|
||||
std::optional<bool> ethActivationStatus;
|
||||
@@ -924,7 +943,7 @@ protected:
|
||||
std::move(decoder)
|
||||
);
|
||||
setupCommunication(*com);
|
||||
settings = makeSettings<Settings>(com);
|
||||
settings = makeSettings<Settings>(this);
|
||||
setupSettings(*settings);
|
||||
diskReadDriver = std::unique_ptr<DiskRead>(new DiskRead());
|
||||
diskWriteDriver = std::unique_ptr<DiskWrite>(new DiskWrite());
|
||||
@@ -960,8 +979,8 @@ protected:
|
||||
}
|
||||
|
||||
template<typename Settings>
|
||||
std::shared_ptr<IDeviceSettings> makeSettings(std::shared_ptr<Communication> comm) {
|
||||
return std::make_shared<Settings>(comm);
|
||||
std::shared_ptr<IDeviceSettings> makeSettings(Device* device) {
|
||||
return std::make_shared<Settings>(device);
|
||||
}
|
||||
virtual void setupSettings(IDeviceSettings&) {}
|
||||
|
||||
@@ -1026,10 +1045,6 @@ private:
|
||||
|
||||
APIEvent::Type attemptToBeginCommunication();
|
||||
|
||||
// Use heartbeatSuppressed instead when reading
|
||||
std::atomic<int> heartbeatSuppressedByUser{0};
|
||||
bool heartbeatSuppressed() const { return heartbeatSuppressedByUser > 0 || (settings && settings->applyingSettings); }
|
||||
|
||||
void handleNeoVIMessage(std::shared_ptr<CANMessage> message);
|
||||
|
||||
bool firmwareUpdateSupported();
|
||||
@@ -1040,10 +1055,6 @@ private:
|
||||
moodycamel::BlockingConcurrentQueue<std::shared_ptr<Message>> pollingContainer;
|
||||
void enforcePollingMessageLimit();
|
||||
|
||||
std::atomic<bool> stopHeartbeatThread{false};
|
||||
std::mutex heartbeatMutex;
|
||||
std::thread heartbeatThread;
|
||||
|
||||
std::mutex diskMutex;
|
||||
|
||||
// Wireless neoVI Stack
|
||||
@@ -1166,6 +1177,7 @@ private:
|
||||
|
||||
// Keeponline (keepalive for online)
|
||||
std::unique_ptr<Periodic> keeponline;
|
||||
std::unique_ptr<Heartbeat> heartbeat;
|
||||
|
||||
std::optional<uint32_t> assignedClientId;
|
||||
std::unordered_set<icsneo::Network::NetID> lockedNetworks;
|
||||
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
RADEpsilon = icsneoc2_devicetype_rad_epsilon,
|
||||
RADEpsilonXL = icsneoc2_devicetype_rad_epsilon_xl,
|
||||
RADGalaxy2 = icsneoc2_devicetype_rad_galaxy2,
|
||||
RADwBMS = icsneoc2_devicetype_rad_wbms,
|
||||
RADMoon3 = icsneoc2_devicetype_rad_moon3,
|
||||
RADComet2 = icsneoc2_devicetype_rad_comet2,
|
||||
FIRE3_FlexRay = icsneoc2_devicetype_fire3_flexray,
|
||||
@@ -216,6 +217,8 @@ public:
|
||||
return "neoVI Connect";
|
||||
case RADGigastar2:
|
||||
return "RAD-Gigastar 2";
|
||||
case RADwBMS:
|
||||
return "RAD-wBMS";
|
||||
case DONT_REUSE0:
|
||||
case DONT_REUSE1:
|
||||
case DONT_REUSE2:
|
||||
@@ -268,6 +271,7 @@ private:
|
||||
#define ICSNEO_DEVICETYPE_RADEPSILON ((devicetype_t)icsneoc2_devicetype_rad_epsilon)
|
||||
#define ICSNEO_DEVICETYPE_RADEPSILONXL ((devicetype_t)icsneoc2_devicetype_rad_epsilon_xl)
|
||||
#define ICSNEO_DEVICETYPE_RADGALAXY2 ((devicetype_t)icsneoc2_devicetype_rad_galaxy2)
|
||||
#define ICSNEO_DEVICETYPE_RADWBMS ((devicetype_t)icsneoc2_devicetype_rad_wbms)
|
||||
#define ICSNEO_DEVICETYPE_RADMoon3 ((devicetype_t)icsneoc2_devicetype_rad_moon3)
|
||||
#define ICSNEO_DEVICETYPE_RADCOMET2 ((devicetype_t)icsneoc2_devicetype_rad_comet2)
|
||||
#define ICSNEO_DEVICETYPE_FIRE3FLEXRAY ((devicetype_t)icsneoc2_devicetype_fire3_flexray)
|
||||
|
||||
@@ -753,16 +753,75 @@ typedef struct
|
||||
uint16_t cmp_device_id;
|
||||
} CMP_GLOBAL_DATA;
|
||||
|
||||
/* wBMS Structs */
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint8_t byte;
|
||||
struct
|
||||
{
|
||||
uint8_t onboard_external : 1;
|
||||
uint8_t type : 1;
|
||||
uint8_t mode: 3;
|
||||
uint8_t reserved : 3;
|
||||
} config;
|
||||
} sSPI_PORT_SETTING;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sSPI_PORT_SETTING port_a; //1
|
||||
sSPI_PORT_SETTING port_b; //1
|
||||
} sSPI_PORT_SETTINGS;
|
||||
|
||||
#define WBMS_GATEWAY_NETWORK_NONE (0)
|
||||
#define WBMS_GATEWAY_NETWORK_DWCAN_01 (1)
|
||||
#define WBMS_GATEWAY_NETWORK_DWCAN_02 (2)
|
||||
#define WBMS_GATEWAY_NETWORK_UDP_MULTICAST (3)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t wbms1_network;
|
||||
uint8_t wbms1_canfd_enable;
|
||||
uint8_t wbms2_network;
|
||||
uint8_t wbms2_canfd_enable;
|
||||
uint16_t reserved[6];
|
||||
} WBMSGatewaySettings;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t wBMSDeviceID;
|
||||
uint8_t enabled;
|
||||
} sWIL_FAULT_SERVICING_SETTINGS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t enabled;
|
||||
} sWIL_NETWORK_DATA_CAPTURE_SETTINGS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t using_port_a;
|
||||
uint8_t using_port_b;
|
||||
uint8_t attemptConnect;
|
||||
sWIL_FAULT_SERVICING_SETTINGS fault_servicing_config;
|
||||
sWIL_NETWORK_DATA_CAPTURE_SETTINGS network_data_capture_config;
|
||||
uint16_t sensor_buffer_size;
|
||||
} sWIL_CONNECTION_SETTINGS;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "icsneo/communication/communication.h"
|
||||
#include "icsneo/communication/network.h"
|
||||
#include "icsneo/api/event.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include <optional>
|
||||
#include <iostream>
|
||||
#include <atomic>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class Device;
|
||||
|
||||
enum class MiscIOAnalogVoltage : uint8_t
|
||||
{
|
||||
V0 = icsneoc2_misc_io_analog_voltage_v0,
|
||||
@@ -790,7 +849,7 @@ public:
|
||||
static int64_t GetBaudrateValueForEnum(CANBaudrate enumValue);
|
||||
static bool ValidateLINBaudrate(int64_t baudrate);
|
||||
|
||||
IDeviceSettings(std::shared_ptr<Communication> com, size_t size) : com(com), report(com->report), structSize(size) {}
|
||||
IDeviceSettings(Device* device, size_t size);
|
||||
virtual ~IDeviceSettings() {}
|
||||
bool ok() const { return !disabled && settingsLoaded; }
|
||||
|
||||
@@ -1337,10 +1396,8 @@ public:
|
||||
bool disabled = false;
|
||||
|
||||
bool readonly = false;
|
||||
|
||||
std::atomic<bool> applyingSettings{false};
|
||||
protected:
|
||||
std::shared_ptr<Communication> com;
|
||||
Device* device;
|
||||
device_eventhandler_t report;
|
||||
size_t structSize;
|
||||
|
||||
@@ -1352,8 +1409,7 @@ protected:
|
||||
|
||||
// Parameter createInoperableSettings exists because it is serving as a warning that you probably don't want to do this
|
||||
typedef void* warn_t;
|
||||
IDeviceSettings(warn_t createInoperableSettings, std::shared_ptr<Communication> com)
|
||||
: disabled(true), readonly(true), report(com->report), structSize(0) { (void)createInoperableSettings; }
|
||||
IDeviceSettings(warn_t createInoperableSettings, Device* device);
|
||||
|
||||
// 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
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace icsneo {
|
||||
class NullSettings : public IDeviceSettings {
|
||||
public:
|
||||
// Calls the protected base constructor with "createInoperableSettings"
|
||||
NullSettings(std::shared_ptr<Communication> com) : IDeviceSettings(nullptr, com) {}
|
||||
NullSettings(Device* device) : IDeviceSettings(nullptr, device) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ static_assert(sizeof(etherbadge_settings_t) == 316, "EtherBadge settings size mi
|
||||
|
||||
class EtherBADGESettings : public IDeviceSettings {
|
||||
public:
|
||||
EtherBADGESettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(etherbadge_settings_t)) {}
|
||||
EtherBADGESettings(Device* device) : IDeviceSettings(device, sizeof(etherbadge_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<etherbadge_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -88,7 +88,7 @@ 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)) {}
|
||||
NeoVIConnectSettings(Device* device) : IDeviceSettings(device, sizeof(neoviconnect_settings_t)) {}
|
||||
const Fire3LinuxSettings* getLinuxSettings() const override {
|
||||
auto cfg = getStructurePointer<neoviconnect_settings_t>();
|
||||
return cfg ? &cfg->os_settings : nullptr;
|
||||
|
||||
@@ -101,7 +101,7 @@ static_assert(sizeof(neovifire_settings_t) == 744, "NeoVIFire settings size mism
|
||||
|
||||
class NeoVIFIRESettings : public IDeviceSettings {
|
||||
public:
|
||||
NeoVIFIRESettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovifire_settings_t)) {}
|
||||
NeoVIFIRESettings(Device* device) : IDeviceSettings(device, sizeof(neovifire_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<neovifire_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -125,7 +125,7 @@ static_assert(sizeof(neovifire2_settings_t) == 936, "NeoVIFire2 settings size mi
|
||||
|
||||
class NeoVIFIRE2Settings : public IDeviceSettings {
|
||||
public:
|
||||
NeoVIFIRE2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(neovifire2_settings_t)) {}
|
||||
NeoVIFIRE2Settings(Device* device) : IDeviceSettings(device, sizeof(neovifire2_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<neovifire2_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -71,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)
|
||||
|
||||
@@ -166,7 +166,7 @@ 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)) {}
|
||||
NeoVIFIRE3Settings(Device* device) : IDeviceSettings(device, sizeof(neovifire3_settings_t)) {}
|
||||
const Fire3LinuxSettings* getLinuxSettings() const override {
|
||||
auto cfg = getStructurePointer<neovifire3_settings_t>();
|
||||
return cfg ? &cfg->os_settings : nullptr;
|
||||
@@ -262,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)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,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)
|
||||
|
||||
@@ -149,7 +149,7 @@ 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)) {}
|
||||
NeoVIFIRE3FlexRaySettings(Device* device) : IDeviceSettings(device, sizeof(neovifire3flexray_settings_t)) {}
|
||||
const Fire3LinuxSettings* getLinuxSettings() const override {
|
||||
auto cfg = getStructurePointer<neovifire3flexray_settings_t>();
|
||||
return cfg ? &cfg->os_settings : nullptr;
|
||||
@@ -213,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)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -79,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)
|
||||
|
||||
@@ -158,7 +158,7 @@ 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)) {}
|
||||
NeoVIFIRE3T1SLINSettings(Device* device) : IDeviceSettings(device, sizeof(neovifire3t1slin_settings_t)) {}
|
||||
const Fire3LinuxSettings* getLinuxSettings() const override {
|
||||
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
|
||||
return cfg ? &cfg->os_settings : nullptr;
|
||||
@@ -222,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)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,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)
|
||||
|
||||
@@ -111,7 +111,7 @@ 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)) {}
|
||||
NeoVIRED2Settings(Device* device) : IDeviceSettings(device, sizeof(neovired2_settings_t)) {}
|
||||
const Fire3LinuxSettings* getLinuxSettings() const override {
|
||||
auto cfg = getStructurePointer<neovired2_settings_t>();
|
||||
return cfg ? &cfg->os_settings : nullptr;
|
||||
@@ -175,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)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
Node
|
||||
};
|
||||
|
||||
RADA2BSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(rada2b_settings_t)) {}
|
||||
RADA2BSettings(Device* device) : IDeviceSettings(device, sizeof(rada2b_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<rada2b_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
@@ -141,27 +141,27 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
TDMMode getTDMMode(RADA2BDevice device) const {
|
||||
TDMMode getTDMMode(RADA2BDevice a2bDevice) const {
|
||||
auto cfg = getStructurePointer<rada2b_settings_t>();
|
||||
auto &deviceSettings = device == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
auto &deviceSettings = a2bDevice == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
|
||||
return static_cast<TDMMode>(deviceSettings.tdmMode);
|
||||
}
|
||||
|
||||
uint8_t getNumChannels(RADA2BDevice device) const {
|
||||
return tdmModeToChannelNum(getTDMMode(device));
|
||||
uint8_t getNumChannels(RADA2BDevice a2bDevice) const {
|
||||
return tdmModeToChannelNum(getTDMMode(a2bDevice));
|
||||
}
|
||||
|
||||
ChannelSize getChannelSize(RADA2BDevice device) const {
|
||||
ChannelSize getChannelSize(RADA2BDevice a2bDevice) const {
|
||||
auto cfg = getStructurePointer<rada2b_settings_t>();
|
||||
auto &deviceSettings = device == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
auto &deviceSettings = a2bDevice == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
|
||||
return static_cast<ChannelSize>(deviceSettings.flags & a2bSettingsFlag16bit);
|
||||
}
|
||||
|
||||
uint8_t getChannelOffset(RADA2BDevice device, A2BMessage::Direction dir) const {
|
||||
uint8_t getChannelOffset(RADA2BDevice a2bDevice, A2BMessage::Direction dir) const {
|
||||
auto cfg = getStructurePointer<rada2b_settings_t>();
|
||||
auto &deviceSettings = device == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
auto &deviceSettings = a2bDevice == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
|
||||
if(dir == A2BMessage::Direction::Upstream) {
|
||||
return deviceSettings.upstreamChannelOffset;
|
||||
@@ -170,30 +170,30 @@ public:
|
||||
return deviceSettings.downstreamChannelOffset;
|
||||
}
|
||||
|
||||
NodeType getNodeType(RADA2BDevice device) const {
|
||||
NodeType getNodeType(RADA2BDevice a2bDevice) const {
|
||||
auto cfg = getStructurePointer<rada2b_settings_t>();
|
||||
auto &deviceSettings = device == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
auto &deviceSettings = a2bDevice == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
|
||||
return static_cast<NodeType>(deviceSettings.nodeType);
|
||||
}
|
||||
|
||||
void setNodeType(RADA2BDevice device, NodeType newType) {
|
||||
void setNodeType(RADA2BDevice a2bDevice, NodeType newType) {
|
||||
auto cfg = getMutableStructurePointer<rada2b_settings_t>();
|
||||
auto &deviceSettings = device == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
auto &deviceSettings = a2bDevice == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
|
||||
deviceSettings.nodeType = static_cast<uint8_t>(newType);
|
||||
}
|
||||
|
||||
void setTDMMode(RADA2BDevice device, TDMMode newMode) {
|
||||
void setTDMMode(RADA2BDevice a2bDevice, TDMMode newMode) {
|
||||
auto cfg = getMutableStructurePointer<rada2b_settings_t>();
|
||||
auto &deviceSettings = device == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
auto &deviceSettings = a2bDevice == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
|
||||
deviceSettings.tdmMode = static_cast<uint8_t>(newMode);
|
||||
}
|
||||
|
||||
void setChannelOffset(RADA2BDevice device, A2BMessage::Direction dir, uint8_t newOffset) {
|
||||
void setChannelOffset(RADA2BDevice a2bDevice, A2BMessage::Direction dir, uint8_t newOffset) {
|
||||
auto cfg = getMutableStructurePointer<rada2b_settings_t>();
|
||||
auto &deviceSettings = device == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
auto &deviceSettings = a2bDevice == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
|
||||
if(dir == A2BMessage::Direction::Upstream) {
|
||||
deviceSettings.upstreamChannelOffset = newOffset;
|
||||
@@ -203,9 +203,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void setChannelSize(RADA2BDevice device, ChannelSize newChannelSize) {
|
||||
void setChannelSize(RADA2BDevice a2bDevice, ChannelSize newChannelSize) {
|
||||
auto cfg = getMutableStructurePointer<rada2b_settings_t>();
|
||||
auto &deviceSettings = device == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
auto &deviceSettings = a2bDevice == RADA2BDevice::Monitor ? cfg->a2b_monitor : cfg->a2b_node;
|
||||
|
||||
if(newChannelSize == ChannelSize::chSize16) {
|
||||
deviceSettings.flags |= a2bSettingsFlag16bit;
|
||||
|
||||
@@ -47,6 +47,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::RADComet2;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ static_assert(sizeof(radcomet2_settings_t) == 498, "RADComet2 settings size mism
|
||||
|
||||
class RADComet2Settings : public IDeviceSettings {
|
||||
public:
|
||||
RADComet2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radcomet2_settings_t)) {}
|
||||
RADComet2Settings(Device* device) : IDeviceSettings(device, sizeof(radcomet2_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radcomet2_settings_t>();
|
||||
if(cfg == 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;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ static_assert(sizeof(radcomet3_settings_t) == 674, "RADComet3 settings size mism
|
||||
|
||||
class RADComet3Settings : public IDeviceSettings {
|
||||
public:
|
||||
RADComet3Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radcomet3_settings_t)) {}
|
||||
RADComet3Settings(Device* device) : IDeviceSettings(device, sizeof(radcomet3_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radcomet3_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -86,7 +86,7 @@ static_assert(sizeof(radepsilon_settings_t) == 400, "RADEpsilon settings size mi
|
||||
|
||||
class RADEpsilonSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADEpsilonSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radepsilon_settings_t)) {}
|
||||
RADEpsilonSettings(Device* device) : IDeviceSettings(device, sizeof(radepsilon_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radepsilon_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -109,7 +109,7 @@ static_assert(sizeof(radgalaxy_settings_t) == 776, "RADGalaxy settings size mism
|
||||
|
||||
class RADGalaxySettings : public IDeviceSettings {
|
||||
public:
|
||||
RADGalaxySettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radgalaxy_settings_t)) {}
|
||||
RADGalaxySettings(Device* device) : IDeviceSettings(device, sizeof(radgalaxy_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radgalaxy_settings_t>();
|
||||
if(cfg == 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;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ static_assert(sizeof(radgalaxy2_settings_t) == 960, "RADGalaxy2 settings size mi
|
||||
|
||||
class RADGalaxy2Settings : public IDeviceSettings {
|
||||
public:
|
||||
RADGalaxy2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radgalaxy2_settings_t)) {}
|
||||
RADGalaxy2Settings(Device* device) : IDeviceSettings(device, sizeof(radgalaxy2_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radgalaxy2_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -42,7 +42,7 @@ static_assert(sizeof(radgemini_settings_t) == 86, "RADGemini settings size misma
|
||||
|
||||
class RADGeminiSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADGeminiSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radgemini_settings_t)) {}
|
||||
RADGeminiSettings(Device* device) : IDeviceSettings(device, sizeof(radgemini_settings_t)) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,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::RADGigastar;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ static_assert(sizeof(radgigastar_settings_t) == 1026, "RADGigastar settings size
|
||||
|
||||
class RADGigastarSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADGigastarSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radgigastar_settings_t)) {}
|
||||
RADGigastarSettings(Device* device) : IDeviceSettings(device, sizeof(radgigastar_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radgigastar_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -89,6 +89,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::RADGigastar2;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace icsneo
|
||||
class RADGigastar2Settings : public IDeviceSettings
|
||||
{
|
||||
public:
|
||||
RADGigastar2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radgigastar2_settings_t)) {}
|
||||
RADGigastar2Settings(Device* device) : IDeviceSettings(device, sizeof(radgigastar2_settings_t)) {}
|
||||
const CAN_SETTINGS *getCANSettingsFor(Network net) const override
|
||||
{
|
||||
auto cfg = getStructurePointer<radgigastar2_settings_t>();
|
||||
|
||||
@@ -90,7 +90,7 @@ static_assert(sizeof(radjupiter_settings_t) == 348, "RAD-Jupiter Settings are no
|
||||
|
||||
class RADJupiterSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADJupiterSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radjupiter_settings_t)) {}
|
||||
RADJupiterSettings(Device* device) : IDeviceSettings(device, sizeof(radjupiter_settings_t)) {}
|
||||
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radjupiter_settings_t>();
|
||||
|
||||
@@ -101,7 +101,7 @@ static_assert(sizeof(radmars_settings_t) == 666, "RAD-Mars settings size mismatc
|
||||
|
||||
class RADMarsSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADMarsSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radmars_settings_t)) {}
|
||||
RADMarsSettings(Device* device) : IDeviceSettings(device, sizeof(radmars_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radmars_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -59,6 +59,9 @@ public:
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
// Covers RADMoon2 and RADMoon2ZL; firmware reboots and ignores the safe flag
|
||||
bool supportsReboot() const override { return true; }
|
||||
|
||||
virtual uint8_t getPhyAddrOrPort() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -42,7 +42,7 @@ static_assert(sizeof(radmoon2_settings_t) == 170, "RADMoon2 settings size mismat
|
||||
|
||||
class RADMoon2Settings : public IDeviceSettings {
|
||||
public:
|
||||
RADMoon2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radmoon2_settings_t)) {}
|
||||
RADMoon2Settings(Device* device) : IDeviceSettings(device, sizeof(radmoon2_settings_t)) {}
|
||||
|
||||
const RAD_GPTP_SETTINGS* getGPTPSettings() const override {
|
||||
auto cfg = getStructurePointer<radmoon2_settings_t>();
|
||||
|
||||
@@ -30,6 +30,8 @@ public:
|
||||
|
||||
bool supportsTC10() const override { return true; }
|
||||
|
||||
bool supportsReboot() const override { return true; }
|
||||
|
||||
ProductID getProductID() const override {
|
||||
return ProductID::RADMoon3;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ static_assert(sizeof(radmoon3_settings_t) == 68, "RADMoon3 settings size mismatc
|
||||
|
||||
class RADMoon3Settings : public IDeviceSettings {
|
||||
public:
|
||||
RADMoon3Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radmoon3_settings_t)) {}
|
||||
RADMoon3Settings(Device* device) : IDeviceSettings(device, sizeof(radmoon3_settings_t)) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ static_assert(sizeof(radmoonduo_settings_t) == 38, "RAD-Moon Duo settings size e
|
||||
|
||||
class RADMoonDuoSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADMoonDuoSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radmoonduo_settings_t)) {}
|
||||
RADMoonDuoSettings(Device* device) : IDeviceSettings(device, sizeof(radmoonduo_settings_t)) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ public:
|
||||
|
||||
bool supportsTC10() const override { return true; }
|
||||
|
||||
bool supportsReboot() const override { return true; }
|
||||
|
||||
ProductID getProductID() const override {
|
||||
return ProductID::RADMoonT1S;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ static_assert(sizeof(radmoont1s_settings_t) == 160, "RADMoonT1S settings size mi
|
||||
|
||||
class RADMoonT1SSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADMoonT1SSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radmoont1s_settings_t)) {}
|
||||
RADMoonT1SSettings(Device* device) : IDeviceSettings(device, sizeof(radmoont1s_settings_t)) {}
|
||||
|
||||
std::optional<bool> isT1SPLCAEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
|
||||
@@ -74,7 +74,7 @@ static_assert(sizeof(radpluto_settings_t) == 322, "RAD-Pluto Settings are not pa
|
||||
|
||||
class RADPlutoSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADPlutoSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radpluto_settings_t)) {
|
||||
RADPlutoSettings(Device* device) : IDeviceSettings(device, sizeof(radpluto_settings_t)) {
|
||||
}
|
||||
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
|
||||
@@ -32,6 +32,8 @@ public:
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
||||
bool supportsReboot() const override { return true; }
|
||||
|
||||
ProductID getProductID() const override {
|
||||
return ProductID::RADStar2;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ static_assert(sizeof(radstar2_settings_t) == 422, "RADStar2 settings size mismat
|
||||
|
||||
class RADStar2Settings : public IDeviceSettings {
|
||||
public:
|
||||
RADStar2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radstar2_settings_t)) {
|
||||
RADStar2Settings(Device* device) : IDeviceSettings(device, sizeof(radstar2_settings_t)) {
|
||||
}
|
||||
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef struct {
|
||||
|
||||
class RADSupermoonSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADSupermoonSettings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radsupermoon_settings_t)) {}
|
||||
RADSupermoonSettings(Device* device) : IDeviceSettings(device, sizeof(radsupermoon_settings_t)) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
#ifndef __RADWBMS_H_
|
||||
#define __RADWBMS_H_
|
||||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/device/tree/radwbms/radwbmssettings.h"
|
||||
#include "icsneo/disk/neomemorydiskdriver.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADwBMS : public Device {
|
||||
public:
|
||||
enum class FirmwareVariant {
|
||||
Invalid = 0,
|
||||
WIL_1_1 = 0x0101000C,
|
||||
WIL_2_0 = 0x02000058,
|
||||
WIL_2_0_9_26 = 0x0200091A,
|
||||
WIL_2_1 = 0x02010047,
|
||||
WIL_2_2 = 0x0202000F,
|
||||
WIL_2_3 = 0x0203020B,
|
||||
WIL_3_1_0_9 = 0x03010009,
|
||||
WIL_3_2_0 = 0x03020000,
|
||||
WIL_3_3_0_27 = 0x0303001B,
|
||||
};
|
||||
|
||||
// Serial numbers start with BS
|
||||
// USB PID is 0x110B, standard driver is CDACM
|
||||
// Ethernet MAC allocation is 0x1B, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(RADwBMS, DeviceType::RADwBMS, "BS");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::DWCAN_01,
|
||||
Network::NetID::DWCAN_02,
|
||||
Network::NetID::ETHERNET_01,
|
||||
};
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
|
||||
bool supportsReboot() const override { return true; }
|
||||
|
||||
ProductID getProductID() const override {
|
||||
return ProductID::RADwBMS;
|
||||
}
|
||||
|
||||
FirmwareVariant variantToFlash = FirmwareVariant::Invalid;
|
||||
void setVariantToFlash(FirmwareVariant variant) {
|
||||
variantToFlash = variant;
|
||||
}
|
||||
|
||||
FirmwareVariant getCurrentVariant() {
|
||||
if(supportsComponentVersions()) {
|
||||
refreshComponentVersions();
|
||||
|
||||
const auto& components = getComponentVersions();
|
||||
for(const auto& component : components) {
|
||||
if(!component.valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(component.identifier == static_cast<uint32_t>(ChipID::RADBMS_WIL)) {
|
||||
FirmwareVariant res = FirmwareVariant::Invalid;
|
||||
switch(static_cast<FirmwareVariant>(component.dotVersion)) {
|
||||
case FirmwareVariant::WIL_1_1:
|
||||
case FirmwareVariant::WIL_2_0:
|
||||
case FirmwareVariant::WIL_2_0_9_26:
|
||||
case FirmwareVariant::WIL_2_1:
|
||||
case FirmwareVariant::WIL_2_2:
|
||||
case FirmwareVariant::WIL_2_3:
|
||||
case FirmwareVariant::WIL_3_1_0_9:
|
||||
case FirmwareVariant::WIL_3_2_0:
|
||||
case FirmwareVariant::WIL_3_3_0_27:
|
||||
res = static_cast<FirmwareVariant>(component.dotVersion);
|
||||
break;
|
||||
default:
|
||||
res = FirmwareVariant::Invalid;
|
||||
break;
|
||||
}
|
||||
if(variantToFlash == FirmwareVariant::Invalid) {
|
||||
// Set the variantToFlash if it hasn't been set yet, we always flash the same firmware variant as the current if it is unspecified
|
||||
variantToFlash = res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FirmwareVariant::Invalid;
|
||||
}
|
||||
|
||||
const std::vector<ChipInfo>& getChipInfo() const override {
|
||||
switch (variantToFlash) {
|
||||
case FirmwareVariant::WIL_1_1: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_1_1_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::WIL_2_0: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_2_0_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::WIL_2_0_9_26: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_2_0_9_26_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::WIL_2_1: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_2_1_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::WIL_2_2: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_2_2_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::WIL_2_3: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_2_3_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::WIL_3_1_0_9: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_3_1_0_9_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::WIL_3_2_0: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_3_2_0_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::WIL_3_3_0_27: {
|
||||
static std::vector<ChipInfo> chips = {{ChipID::RADBMS_MCHIP, true, "MCHIP", "rad_bms_mchip_WIL_3_3_0_27_ief", 0, FirmwareType::IEF}};
|
||||
return chips;
|
||||
}
|
||||
case FirmwareVariant::Invalid:
|
||||
break; // invalid will be handled below
|
||||
}
|
||||
// Return empty chip information if the WIL version is not set
|
||||
static std::vector<ChipInfo> chips = {};
|
||||
return chips;
|
||||
}
|
||||
|
||||
BootloaderPipeline getBootloader() override {
|
||||
return BootloaderPipeline()
|
||||
.add<EnterBootloaderPhase>()
|
||||
.add<FlashPhase>(ChipID::RADBMS_MCHIP, BootloaderCommunication::RED)
|
||||
.add<EnterApplicationPhase>(ChipID::RADBMS_MCHIP)
|
||||
.add<WaitPhase>(std::chrono::milliseconds(3000))
|
||||
.add<ReconnectPhase>();
|
||||
}
|
||||
|
||||
std::vector<VersionReport> getChipVersions(bool refreshComponents = true) override {
|
||||
if(variantToFlash == FirmwareVariant::Invalid) {
|
||||
getCurrentVariant();
|
||||
}
|
||||
return Device::getChipVersions(refreshComponents);
|
||||
}
|
||||
|
||||
protected:
|
||||
RADwBMS(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADwBMSSettings, Disk::NeoMemoryDiskDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
|
||||
}
|
||||
|
||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
for(auto& netid : GetSupportedNetworks())
|
||||
rxNetworks.emplace_back(netid);
|
||||
}
|
||||
|
||||
// The supported TX networks are the same as the supported RX networks for this device
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
std::optional<MemoryAddress> getCoreminiStartAddressFlash() const override {
|
||||
return 2048 * 512;
|
||||
}
|
||||
|
||||
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool supportsEraseMemory() const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace icsneo
|
||||
|
||||
#endif // __RADWBMS_H_
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef __RADWBMSSETTINGS_H_
|
||||
#define __RADWBMSSETTINGS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "icsneo/device/idevicesettings.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#pragma pack(push, 2)
|
||||
typedef struct
|
||||
{
|
||||
uint16_t perf_en;
|
||||
|
||||
uint64_t termination_enables;
|
||||
|
||||
CAN_SETTINGS can1;
|
||||
CANFD_SETTINGS canfd1;
|
||||
|
||||
CAN_SETTINGS can2;
|
||||
CANFD_SETTINGS canfd2;
|
||||
|
||||
uint16_t network_enables;
|
||||
uint16_t network_enables_2;
|
||||
uint16_t network_enables_3;
|
||||
|
||||
int16_t iso15765_separation_time_offset;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t disableUsbCheckOnBoot : 1;
|
||||
uint32_t enableLatencyTest : 1;
|
||||
uint32_t enablePcEthernetComm : 1;
|
||||
uint32_t reserved : 29;
|
||||
} flags;
|
||||
|
||||
ETHERNET_SETTINGS ethernet;
|
||||
ETHERNET_SETTINGS2 ethernet2;
|
||||
|
||||
uint32_t pwr_man_timeout;
|
||||
uint16_t pwr_man_enable;
|
||||
uint16_t network_enabled_on_boot;
|
||||
|
||||
uint8_t rsvd[10]; //Was sWILBridgeConfig
|
||||
|
||||
sSPI_PORT_SETTINGS spi_config;
|
||||
|
||||
sWIL_CONNECTION_SETTINGS wbms_wil_1;
|
||||
sWIL_CONNECTION_SETTINGS wbms_wil_2;
|
||||
|
||||
uint16_t wil1_nwk_metadata_buff_count;
|
||||
uint16_t wil2_nwk_metadata_buff_count;
|
||||
|
||||
WBMSGatewaySettings gateway;
|
||||
|
||||
uint16_t network_enables_4;
|
||||
uint64_t network_enables_5;
|
||||
} radwbms_settings_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
static_assert(sizeof(radwbms_settings_t) == 156, "RAD-wBMS settings size mismatch");
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class RADwBMSSettings : public IDeviceSettings {
|
||||
public:
|
||||
RADwBMSSettings(Device* device) : IDeviceSettings(device, sizeof(radwbms_settings_t)) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __RADWBMSSETTINGS_H_
|
||||
@@ -37,7 +37,7 @@ static_assert(sizeof(valuecan3_settings_t) == 40, "ValueCAN3 settings size misma
|
||||
|
||||
class ValueCAN3Settings : public IDeviceSettings {
|
||||
public:
|
||||
ValueCAN3Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(valuecan3_settings_t)) {}
|
||||
ValueCAN3Settings(Device* device) : IDeviceSettings(device, sizeof(valuecan3_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<valuecan3_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace icsneo {
|
||||
|
||||
class ValueCAN4_1_2Settings : public IDeviceSettings {
|
||||
public:
|
||||
ValueCAN4_1_2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(valuecan4_1_2_settings_t)) {}
|
||||
ValueCAN4_1_2Settings(Device* device) : IDeviceSettings(device, sizeof(valuecan4_1_2_settings_t)) {}
|
||||
// We do not override getCANSettingsFor or getCANFDSettingsFor here because they will be device specific
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user