Device: Add T1S extended settings

master
Thomas Stoddard 2026-04-03 16:14:17 +00:00 committed by Kyle Schwarz
parent 6f2ad54adc
commit 146ddaf23c
13 changed files with 2004 additions and 1 deletions

View File

@ -104,6 +104,18 @@ void init_idevicesettings(pybind11::module_& m) {
.def("set_t1s_max_burst", &IDeviceSettings::setT1SMaxBurstFor, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("set_t1s_max_burst", &IDeviceSettings::setT1SMaxBurstFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_t1s_burst_timer", &IDeviceSettings::getT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("get_t1s_burst_timer", &IDeviceSettings::getT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_t1s_burst_timer", &IDeviceSettings::setT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("set_t1s_burst_timer", &IDeviceSettings::setT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_t1s_local_id_alternate", &IDeviceSettings::getT1SLocalIDAlternateFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_t1s_local_id_alternate", &IDeviceSettings::setT1SLocalIDAlternateFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("is_t1s_termination_enabled", &IDeviceSettings::isT1STerminationEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_t1s_termination", &IDeviceSettings::setT1STerminationFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("is_t1s_bus_decoding_beacons_enabled", &IDeviceSettings::isT1SBusDecodingBeaconsEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_t1s_bus_decoding_beacons", &IDeviceSettings::setT1SBusDecodingBeaconsFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("is_t1s_bus_decoding_all_enabled", &IDeviceSettings::isT1SBusDecodingAllEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_t1s_bus_decoding_all", &IDeviceSettings::setT1SBusDecodingAllFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_t1s_multi_id_enable_mask", &IDeviceSettings::getT1SMultiIDEnableMaskFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_t1s_multi_id_enable_mask", &IDeviceSettings::setT1SMultiIDEnableMaskFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_t1s_multi_id", &IDeviceSettings::getT1SMultiIDFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_t1s_multi_id", &IDeviceSettings::setT1SMultiIDFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_misc_io_analog_output_enabled", &IDeviceSettings::setMiscIOAnalogOutputEnabled, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("set_misc_io_analog_output_enabled", &IDeviceSettings::setMiscIOAnalogOutputEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_misc_io_analog_output", &IDeviceSettings::setMiscIOAnalogOutput, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("set_misc_io_analog_output", &IDeviceSettings::setMiscIOAnalogOutput, pybind11::call_guard<pybind11::gil_scoped_release>())

View File

@ -19,6 +19,7 @@ option(LIBICSNEO_BUILD_CPP_SPI_EXAMPLE "Build the SPI example." ON)
option(LIBICSNEO_BUILD_CPP_MUTEX_EXAMPLE "Build the NetworkMutex example." ON) option(LIBICSNEO_BUILD_CPP_MUTEX_EXAMPLE "Build the NetworkMutex example." ON)
option(LIBICSNEO_BUILD_CPP_ANALOG_OUT_EXAMPLE "Build the analog output example." ON) option(LIBICSNEO_BUILD_CPP_ANALOG_OUT_EXAMPLE "Build the analog output example." ON)
option(LIBICSNEO_BUILD_CPP_DISKFORMAT_EXAMPLE "Build the disk format example." ON) option(LIBICSNEO_BUILD_CPP_DISKFORMAT_EXAMPLE "Build the disk format example." ON)
option(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE "Build the T1S example." ON)
add_compile_options(${LIBICSNEO_COMPILER_WARNINGS}) add_compile_options(${LIBICSNEO_COMPILER_WARNINGS})
@ -105,3 +106,7 @@ endif()
if(LIBICSNEO_BUILD_CPP_DISKFORMAT_EXAMPLE) if(LIBICSNEO_BUILD_CPP_DISKFORMAT_EXAMPLE)
add_subdirectory(cpp/diskformat) add_subdirectory(cpp/diskformat)
endif() endif()
if(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE)
add_subdirectory(cpp/t1s)
endif()

View File

@ -0,0 +1,5 @@
add_executable(libicsneocpp-t1s-settings src/T1SSettingsExample.cpp)
target_link_libraries(libicsneocpp-t1s-settings icsneocpp)
add_executable(libicsneocpp-t1s-symbol-decoding src/T1SSymbolDecodingExample.cpp)
target_link_libraries(libicsneocpp-t1s-symbol-decoding icsneocpp)

View File

@ -0,0 +1,326 @@
#include <iostream>
#include <iomanip>
#include <vector>
#include <optional>
#include <string>
#include <limits>
#include <sstream>
#include <algorithm>
#include "icsneo/icsneocpp.h"
template<typename T>
std::string optToString(const std::optional<T>& opt) {
if (!opt.has_value())
return "N/A";
if constexpr (std::is_same_v<T, bool>)
return opt.value() ? "true" : "false";
else
return std::to_string(opt.value());
}
bool getUserConfirmation(const std::string& prompt) {
std::string input;
std::cout << prompt << " (y/n): " << std::flush;
std::getline(std::cin, input);
if (!input.empty()) {
char c = std::tolower(input[0]);
return (c == 'y');
}
return false;
}
std::vector<icsneo::Network::NetID> selectNetworks(const std::vector<icsneo::Network::NetID>& availableNetworks) {
std::vector<icsneo::Network::NetID> selectedNetworks;
std::cout << "\n" << std::string(70, '=') << std::endl;
std::cout << "Select T1S Networks to Configure" << std::endl;
std::cout << std::string(70, '=') << std::endl;
for (size_t i = 0; i < availableNetworks.size(); i++) {
std::cout << " [" << (i + 1) << "] " << icsneo::Network(availableNetworks[i]) << std::endl;
}
std::cout << "\nEnter network numbers to configure (e.g., '1,3' or '1-3' or 'all'): " << std::flush;
std::string input;
std::getline(std::cin, input);
if (input.empty())
return selectedNetworks;
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
if (input == "all") {
return availableNetworks;
}
std::stringstream ss(input);
std::string token;
while (std::getline(ss, token, ',')) {
token.erase(0, token.find_first_not_of(" \t"));
token.erase(token.find_last_not_of(" \t") + 1);
size_t dashPos = token.find('-');
if (dashPos != std::string::npos) {
try {
int start = std::stoi(token.substr(0, dashPos));
int end = std::stoi(token.substr(dashPos + 1));
for (int i = start; i <= end; i++) {
if (i >= 1 && i <= (int)availableNetworks.size()) {
selectedNetworks.push_back(availableNetworks[i - 1]);
}
}
} catch (...) {}
} else {
try {
int num = std::stoi(token);
if (num >= 1 && num <= (int)availableNetworks.size()) {
selectedNetworks.push_back(availableNetworks[num - 1]);
}
} catch (...) {}
}
}
return selectedNetworks;
}
uint8_t getUint8Input(const std::string& prompt, uint8_t defaultValue) {
std::string input;
std::cout << prompt << " [" << (int)defaultValue << "]: " << std::flush;
std::getline(std::cin, input);
if (input.empty())
return defaultValue;
try {
int val = std::stoi(input);
if (val >= 0 && val <= 255)
return static_cast<uint8_t>(val);
} catch (...) {}
return defaultValue;
}
uint16_t getUint16Input(const std::string& prompt, uint16_t defaultValue) {
std::string input;
std::cout << prompt << " [" << (int)defaultValue << "]: " << std::flush;
std::getline(std::cin, input);
if (input.empty())
return defaultValue;
try {
int val = std::stoi(input);
if (val >= 0 && val <= 65535)
return static_cast<uint16_t>(val);
} catch (...) {}
return defaultValue;
}
void displayT1SSettings(const std::shared_ptr<icsneo::Device>& device, icsneo::Network::NetID netId) {
std::cout << "\t" << icsneo::Network(netId) << " T1S Settings:" << std::endl;
std::cout << "\t PLCA Enabled: " << optToString(device->settings->isT1SPLCAEnabledFor(netId)) << std::endl;
std::cout << "\t Local ID: " << optToString(device->settings->getT1SLocalIDFor(netId)) << std::endl;
std::cout << "\t Max Nodes: " << optToString(device->settings->getT1SMaxNodesFor(netId)) << std::endl;
std::cout << "\t TX Opp Timer: " << optToString(device->settings->getT1STxOppTimerFor(netId)) << std::endl;
std::cout << "\t Max Burst: " << optToString(device->settings->getT1SMaxBurstFor(netId)) << std::endl;
std::cout << "\t Burst Timer: " << optToString(device->settings->getT1SBurstTimerFor(netId)) << std::endl;
auto termEnabled = device->settings->isT1STerminationEnabledFor(netId);
if (termEnabled.has_value())
std::cout << "\t Termination: " << optToString(termEnabled) << std::endl;
auto localIdAlt = device->settings->getT1SLocalIDAlternateFor(netId);
if (localIdAlt.has_value()) {
std::cout << "\t Local ID Alternate: " << optToString(localIdAlt) << std::endl;
std::cout << "\t Bus Dec Beacons: " << optToString(device->settings->isT1SBusDecodingBeaconsEnabledFor(netId)) << std::endl;
std::cout << "\t Bus Dec All: " << optToString(device->settings->isT1SBusDecodingAllEnabledFor(netId)) << std::endl;
auto multiIdMask = device->settings->getT1SMultiIDEnableMaskFor(netId);
if (multiIdMask.has_value()) {
std::cout << "\t Multi-ID Mask: 0x" << std::hex << std::setw(2) << std::setfill('0')
<< (int)multiIdMask.value() << std::dec << std::endl;
std::cout << "\t Multi-IDs: ";
for (uint8_t i = 0; i < 7; i++) {
if (i > 0) std::cout << ", ";
auto multiId = device->settings->getT1SMultiIDFor(netId, i);
std::cout << "[" << (int)i << "]=" << optToString(multiId);
}
std::cout << std::endl;
}
}
std::cout << std::endl;
}
void configureT1SNetwork(std::shared_ptr<icsneo::Device>& device, icsneo::Network::NetID netId) {
std::cout << "\n" << std::string(70, '=') << std::endl;
std::cout << "Configuring T1S Network: " << icsneo::Network(netId) << std::endl;
std::cout << std::string(70, '=') << std::endl;
std::cout << "\n--- Basic PLCA Settings ---" << std::endl;
bool plcaEnabled = getUserConfirmation("Enable PLCA");
device->settings->setT1SPLCAFor(netId, plcaEnabled);
uint8_t localId = getUint8Input("Local ID (0-255)", 1);
device->settings->setT1SLocalIDFor(netId, localId);
uint8_t maxNodes = getUint8Input("Max Nodes (0-255)", 8);
device->settings->setT1SMaxNodesFor(netId, maxNodes);
uint8_t txOppTimer = getUint8Input("TX Opportunity Timer (0-255)", 20);
device->settings->setT1STxOppTimerFor(netId, txOppTimer);
uint16_t maxBurst = getUint16Input("Max Burst (0-65535)", 128);
device->settings->setT1SMaxBurstFor(netId, maxBurst);
uint16_t burstTimer = getUint16Input("Burst Timer (0-65535)", 64);
device->settings->setT1SBurstTimerFor(netId, burstTimer);
if (device->settings->isT1STerminationEnabledFor(netId).has_value()) {
std::cout << "\n--- Termination Settings ---" << std::endl;
bool termEnabled = getUserConfirmation("Enable Termination");
device->settings->setT1STerminationFor(netId, termEnabled);
}
if (device->settings->getT1SLocalIDAlternateFor(netId).has_value()) {
std::cout << "\n--- Extended Settings ---" << std::endl;
uint8_t localIdAlt = getUint8Input("Local ID Alternate (0-255)", 0);
device->settings->setT1SLocalIDAlternateFor(netId, localIdAlt);
bool busDecBeacons = getUserConfirmation("Enable Bus Decoding (Beacons)");
device->settings->setT1SBusDecodingBeaconsFor(netId, busDecBeacons);
bool busDecAll = getUserConfirmation("Enable Bus Decoding (All Symbols)");
device->settings->setT1SBusDecodingAllFor(netId, busDecAll);
if (getUserConfirmation("Configure Multi-ID settings?")) {
uint8_t multiIdMask = getUint8Input("Multi-ID Enable Mask (0x00-0xFF, hex)", 0x00);
device->settings->setT1SMultiIDEnableMaskFor(netId, multiIdMask);
std::cout << "Configure Multi-IDs (7 slots):" << std::endl;
for (uint8_t i = 0; i < 7; i++) {
uint8_t multiId = getUint8Input(" Multi-ID [" + std::to_string(i) + "]", 0);
device->settings->setT1SMultiIDFor(netId, i, multiId);
}
}
}
std::cout << "\n✓ Configuration complete for " << icsneo::Network(netId) << std::endl;
}
int main() {
std::cout << "\n" << std::string(70, '=') << std::endl;
std::cout << "10BASE-T1S SETTINGS CONFIGURATION EXAMPLE" << std::endl;
std::cout << std::string(70, '=') << std::endl;
std::cout << "libicsneo " << icsneo::GetVersion() << std::endl;
std::cout << std::string(70, '=') << std::endl;
std::cout << "\nFinding devices... " << std::flush;
auto devices = icsneo::FindAllDevices();
std::cout << "OK, " << devices.size() << " device" << (devices.size() == 1 ? "" : "s") << " found" << std::endl;
if (devices.empty()) {
std::cout << "No devices found!" << std::endl;
return 1;
}
for(auto& device : devices)
std::cout << " " << device->describe() << std::endl;
std::shared_ptr<icsneo::Device> selectedDevice;
for(auto& device : devices) {
if (device->getType() == icsneo::DeviceType::RADComet3) {
selectedDevice = device;
break;
}
}
if (!selectedDevice && !devices.empty())
selectedDevice = devices[0];
if (!selectedDevice) {
std::cout << "No suitable device found!" << std::endl;
return 1;
}
std::cout << "\nSelected device: " << selectedDevice->describe() << std::endl;
std::cout << "Serial: " << selectedDevice->getSerial() << std::endl;
std::cout << "\nOpening device... " << std::flush;
if (!selectedDevice->open()) {
std::cout << "✗ Failed" << std::endl;
std::cout << icsneo::GetLastError() << std::endl;
return 1;
}
std::cout << "" << std::endl;
std::vector<icsneo::Network::NetID> candidateNetworks = {
icsneo::Network::NetID::AE_01, icsneo::Network::NetID::AE_02,
icsneo::Network::NetID::AE_03, icsneo::Network::NetID::AE_04,
icsneo::Network::NetID::AE_05, icsneo::Network::NetID::AE_06,
icsneo::Network::NetID::AE_07, icsneo::Network::NetID::AE_08,
icsneo::Network::NetID::AE_09, icsneo::Network::NetID::AE_10
};
std::vector<icsneo::Network::NetID> t1sNetworks;
for (auto netId : candidateNetworks) {
auto localId = selectedDevice->settings->getT1SLocalIDFor(netId);
if (localId.has_value())
t1sNetworks.push_back(netId);
}
if (t1sNetworks.empty()) {
std::cout << "No T1S networks found on this device" << std::endl;
selectedDevice->close();
return 1;
}
std::cout << "\nFound " << t1sNetworks.size() << " T1S network"
<< (t1sNetworks.size() == 1 ? "" : "s") << ":" << std::endl;
for (size_t i = 0; i < t1sNetworks.size(); i++)
std::cout << " [" << (i + 1) << "] " << icsneo::Network(t1sNetworks[i]) << std::endl;
std::cout << "\n" << std::string(70, '-') << std::endl;
std::cout << "Current T1S Settings:" << std::endl;
std::cout << std::string(70, '-') << std::endl;
for (auto netId : t1sNetworks)
displayT1SSettings(selectedDevice, netId);
auto networksToConfig = selectNetworks(t1sNetworks);
if (networksToConfig.empty()) {
std::cout << "\nNo networks selected for configuration." << std::endl;
std::cout << "Closing device... " << std::flush;
selectedDevice->close();
std::cout << "" << std::endl;
return 0;
}
std::cout << "\nConfiguring " << networksToConfig.size() << " network"
<< (networksToConfig.size() == 1 ? "" : "s") << "..." << std::endl;
for (auto netId : networksToConfig)
configureT1SNetwork(selectedDevice, netId);
std::cout << "\n" << std::string(70, '=') << std::endl;
bool saveToEEPROM = getUserConfirmation("Save settings to EEPROM (permanent)?");
std::cout << std::string(70, '=') << std::endl;
std::cout << "\nApplying settings" << (saveToEEPROM ? " to EEPROM" : " temporarily") << "... " << std::flush;
bool success = selectedDevice->settings->apply(!saveToEEPROM);
if (!success) {
std::cout << "✗ Failed" << std::endl;
std::cout << icsneo::GetLastError() << std::endl;
selectedDevice->close();
return 1;
}
std::cout << "" << std::endl;
std::cout << "\n" << std::string(70, '-') << std::endl;
std::cout << "Updated T1S Settings:" << std::endl;
std::cout << std::string(70, '-') << std::endl;
for (auto netId : t1sNetworks)
displayT1SSettings(selectedDevice, netId);
std::cout << "Closing device... " << std::flush;
selectedDevice->close();
std::cout << "" << std::endl;
return 0;
}

View File

@ -0,0 +1,357 @@
// 10BASE-T1S Symbol Decoding Example
// Demonstrates T1S bus symbol decoding and analysis
#include <iostream>
#include <iomanip>
#include <thread>
#include <chrono>
#include <map>
#include <string>
#include <atomic>
#include "icsneo/icsneocpp.h"
enum class T1SSymbol : uint8_t {
SSD = 0x04,
ESDOK = 0x07,
BEACON = 0x08,
ESD = 0x0D,
ESDERR = 0x11,
SYNC = 0x18,
ESDJAB = 0x19,
SILENCE = 0x1F
};
std::string getSymbolName(uint8_t value) {
switch(static_cast<T1SSymbol>(value)) {
case T1SSymbol::SSD: return "SSD";
case T1SSymbol::ESDOK: return "ESDOK";
case T1SSymbol::BEACON: return "BEACON";
case T1SSymbol::ESD: return "ESD";
case T1SSymbol::ESDERR: return "ESDERR";
case T1SSymbol::SYNC: return "SYNC";
case T1SSymbol::ESDJAB: return "ESDJAB";
case T1SSymbol::SILENCE: return "SILENCE";
default:
if (value <= 0x0F) {
std::stringstream ss;
ss << "DATA(0x" << std::hex << std::uppercase << (int)value << ")";
return ss.str();
}
std::stringstream ss;
ss << "UNKNOWN(0x" << std::hex << std::uppercase << std::setw(2)
<< std::setfill('0') << (int)value << std::setfill(' ') << ")";
return ss.str();
}
}
struct T1SStatistics {
std::atomic<uint64_t> symbolCount{0};
std::atomic<uint64_t> beaconCount{0};
std::atomic<uint64_t> wakeCount{0};
std::atomic<uint64_t> burstCount{0};
std::atomic<uint64_t> dataFrameCount{0};
std::map<std::string, uint64_t> symbolStats;
void reset() {
symbolCount = 0;
beaconCount = 0;
wakeCount = 0;
burstCount = 0;
dataFrameCount = 0;
symbolStats.clear();
}
void print() const {
std::cout << std::setfill(' ');
std::cout << "\n" << std::string(70, '=') << std::endl;
std::cout << "T1S SYMBOL DECODING STATISTICS" << std::endl;
std::cout << std::string(70, '=') << std::endl;
std::cout << "Total Symbols: " << symbolCount << std::endl;
std::cout << "Total Beacons: " << beaconCount << std::endl;
std::cout << "Total Wake Signals: " << wakeCount << std::endl;
std::cout << "Total Bursts: " << burstCount << std::endl;
std::cout << "Total Data Frames: " << dataFrameCount << std::endl;
if (!symbolStats.empty()) {
std::cout << "\n" << std::string(70, '-') << std::endl;
std::cout << "Symbol Type Breakdown:" << std::endl;
std::cout << std::string(70, '-') << std::endl;
std::vector<std::pair<std::string, uint64_t>> sortedStats(
symbolStats.begin(), symbolStats.end());
std::sort(sortedStats.begin(), sortedStats.end(),
[](const auto& a, const auto& b) { return a.second > b.second; });
for (const auto& [name, count] : sortedStats) {
std::cout << " " << std::left << std::setw(20) << name
<< std::right << std::setw(10) << count << std::endl;
}
}
std::cout << std::string(70, '=') << std::endl;
}
};
bool getUserConfirmation(const std::string& prompt) {
std::string input;
std::cout << prompt << " (y/n): " << std::flush;
std::getline(std::cin, input);
if (!input.empty()) {
char c = std::tolower(input[0]);
return (c == 'y');
}
return false;
}
bool configureT1SDecoding(std::shared_ptr<icsneo::Device>& device, icsneo::Network::NetID network,
bool enableSymbols, bool enableBeacons) {
std::cout << "\nConfiguring T1S decoding on network " << icsneo::Network(network) << "..." << std::endl;
if (!device->settings->setT1SBusDecodingAllFor(network, enableSymbols)) {
std::cerr << " ✗ Failed to set T1S symbol decoding" << std::endl;
return false;
}
if (enableSymbols) {
std::cout << " ✓ Enabled decoding of all T1S symbols" << std::endl;
} else {
std::cout << " • T1S symbol decoding disabled" << std::endl;
}
if (!device->settings->setT1SBusDecodingBeaconsFor(network, enableBeacons)) {
std::cerr << " ✗ Failed to set T1S beacon decoding" << std::endl;
return false;
}
if (enableBeacons) {
std::cout << " ✓ Enabled T1S beacon decoding" << std::endl;
} else {
std::cout << " • T1S beacon decoding disabled" << std::endl;
}
if (!device->settings->apply(true)) {
std::cerr << " ✗ Failed to apply settings to device" << std::endl;
std::cerr << " " << icsneo::GetLastError() << std::endl;
return false;
}
std::cout << " ✓ Settings applied successfully" << std::endl;
return true;
}
void setupSymbolMonitoring(std::shared_ptr<icsneo::Device>& device,
icsneo::Network::NetID network,
T1SStatistics& stats) {
auto callback = std::make_shared<icsneo::MessageCallback>(
icsneo::MessageFilter(network),
[&stats](std::shared_ptr<icsneo::Message> message) {
if (message->type != icsneo::Message::Type::Frame)
return;
auto frame = std::static_pointer_cast<icsneo::Frame>(message);
auto netType = frame->network.getType();
if (netType != icsneo::Network::Type::Ethernet && netType != icsneo::Network::Type::AutomotiveEthernet)
return;
auto ethMsg = std::static_pointer_cast<icsneo::EthernetMessage>(frame);
if (!ethMsg->isT1S)
return;
double timestamp_ms = ethMsg->timestamp / 1000000.0;
if (ethMsg->isT1SSymbol) {
size_t numSymbols = ethMsg->data.size();
std::cout << std::fixed << std::setprecision(3)
<< "[" << std::setw(12) << timestamp_ms << " ms] "
<< "T1S Symbols";
if (numSymbols > 0) {
std::cout << " (" << numSymbols << " symbol" << (numSymbols > 1 ? "s" : "") << ")";
}
std::cout << " | Node ID: " << (int)ethMsg->t1sNodeId << std::endl;
for (size_t i = 0; i < numSymbols; i++) {
uint8_t symbolValue = ethMsg->data[i];
std::string symbolName = getSymbolName(symbolValue);
stats.symbolCount++;
stats.symbolStats[symbolName]++;
if (symbolValue == static_cast<uint8_t>(T1SSymbol::BEACON)) {
stats.beaconCount++;
}
std::cout << " [" << i << "] " << std::left << std::setw(10) << symbolName << std::right
<< " = 0x" << std::hex << std::uppercase << std::setw(2)
<< std::setfill('0') << (int)symbolValue << std::setfill(' ')
<< std::dec << std::endl;
}
if (numSymbols == 0 && ethMsg->t1sSymbolType != 0) {
uint8_t symbolValue = ethMsg->t1sSymbolType;
std::string symbolName = getSymbolName(symbolValue);
stats.symbolCount++;
stats.symbolStats[symbolName]++;
if (symbolValue == static_cast<uint8_t>(T1SSymbol::BEACON)) {
stats.beaconCount++;
}
std::cout << " " << std::left << std::setw(10) << symbolName << std::right
<< " = 0x" << std::hex << std::uppercase << std::setw(2)
<< std::setfill('0') << (int)symbolValue << std::setfill(' ')
<< std::dec << " (from t1sSymbolType field)" << std::endl;
}
}
else if (ethMsg->isT1SBurst) {
stats.burstCount++;
std::cout << std::fixed << std::setprecision(3)
<< "[" << std::setw(12) << timestamp_ms << " ms] "
<< "BURST | "
<< "Node ID: " << (int)ethMsg->t1sNodeId << " | "
<< "Burst Count: " << (int)ethMsg->t1sBurstCount << std::endl;
}
else if (ethMsg->isT1SWake) {
stats.wakeCount++;
std::cout << std::fixed << std::setprecision(3)
<< "[" << std::setw(12) << timestamp_ms << " ms] "
<< "WAKE signal detected | "
<< "Node ID: " << (int)ethMsg->t1sNodeId << std::endl;
}
else {
stats.dataFrameCount++;
std::cout << std::fixed << std::setprecision(3)
<< "[" << std::setw(12) << timestamp_ms << " ms] "
<< "T1S Data Frame | "
<< "Length: " << ethMsg->data.size() << " bytes | "
<< "Node ID: " << (int)ethMsg->t1sNodeId << std::endl;
if (!ethMsg->data.empty()) {
std::cout << " Data: ";
size_t preview_len = std::min(ethMsg->data.size(), size_t(16));
for (size_t i = 0; i < preview_len; i++) {
std::cout << std::hex << std::uppercase << std::setw(2)
<< std::setfill('0') << (int)ethMsg->data[i] << " ";
}
if (ethMsg->data.size() > 16)
std::cout << "...";
std::cout << std::setfill(' ') << std::dec << std::endl;
}
}
}
);
device->addMessageCallback(callback);
}
int main() {
const icsneo::Network::NetID MONITOR_NETWORK = icsneo::Network::NetID::AE_02;
const int MONITOR_DURATION_SECONDS = 30;
std::cout << "\n" << std::string(70, '=') << std::endl;
std::cout << "10BASE-T1S SYMBOL DECODING EXAMPLE" << std::endl;
std::cout << std::string(70, '=') << std::endl;
std::cout << "libicsneo " << icsneo::GetVersion() << std::endl;
std::cout << std::string(70, '=') << std::endl;
std::cout << "\nFinding devices... " << std::flush;
auto devices = icsneo::FindAllDevices();
std::cout << "OK, " << devices.size() << " device" << (devices.size() == 1 ? "" : "s") << " found" << std::endl;
if (devices.empty()) {
std::cerr << "No devices found!" << std::endl;
return 1;
}
// List devices
for (const auto& device : devices) {
std::cout << " " << device->describe() << std::endl;
}
std::shared_ptr<icsneo::Device> device;
for (auto& dev : devices) {
if (dev->getType() == icsneo::DeviceType::RADComet3) {
device = dev;
break;
}
}
if (!device && !devices.empty())
device = devices[0];
if (!device) {
std::cerr << "No suitable device found!" << std::endl;
return 1;
}
std::cout << "\nSelected device: " << device->describe() << std::endl;
std::cout << "Serial: " << device->getSerial() << std::endl;
std::cout << "\n" << std::string(70, '-') << std::endl;
std::cout << "T1S DECODING CONFIGURATION" << std::endl;
std::cout << std::string(70, '-') << std::endl;
bool enableSymbols = getUserConfirmation("Enable T1S symbol decoding (all symbols)");
bool enableBeacons = getUserConfirmation("Enable T1S beacon decoding");
std::cout << std::string(70, '-') << std::endl;
std::cout << "\nOpening device... " << std::flush;
if (!device->open()) {
std::cerr << "✗ Failed" << std::endl;
std::cerr << " " << icsneo::GetLastError() << std::endl;
return 1;
}
std::cout << "" << std::endl;
std::cout << "Enabling message polling... " << std::flush;
if (!device->enableMessagePolling()) {
std::cerr << "✗ Failed" << std::endl;
std::cerr << " " << icsneo::GetLastError() << std::endl;
device->close();
return 1;
}
device->setPollingMessageLimit(100000);
std::cout << "" << std::endl;
if (!configureT1SDecoding(device, MONITOR_NETWORK, enableSymbols, enableBeacons)) {
device->close();
return 1;
}
std::cout << "Going online... " << std::flush;
if (!device->goOnline()) {
std::cerr << "✗ Failed" << std::endl;
std::cerr << " " << icsneo::GetLastError() << std::endl;
device->close();
return 1;
}
std::cout << "" << std::endl;
T1SStatistics stats;
setupSymbolMonitoring(device, MONITOR_NETWORK, stats);
std::cout << "\n" << std::string(70, '-') << std::endl;
std::cout << "Monitoring T1S traffic for " << MONITOR_DURATION_SECONDS << " seconds..." << std::endl;
std::cout << std::string(70, '-') << std::endl;
auto startTime = std::chrono::steady_clock::now();
std::vector<std::shared_ptr<icsneo::Message>> messages;
messages.reserve(10000);
while (std::chrono::steady_clock::now() - startTime < std::chrono::seconds(MONITOR_DURATION_SECONDS)) {
device->getMessages(messages);
messages.clear();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
std::cout << "\n" << std::string(70, '-') << std::endl;
std::cout << "Closing device... " << std::flush;
device->close();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "" << std::endl;
stats.print();
return 0;
}

View File

@ -0,0 +1,325 @@
"""
10BASE-T1S Settings Configuration Example
Demonstrates interactive T1S network configuration
"""
import icsneopy
def get_user_confirmation(prompt):
"""Get yes/no confirmation from user."""
response = input(f"{prompt} (y/n): ").strip().lower()
return response == 'y'
def select_networks(available_networks):
"""Let user select which networks to configure."""
print("\n" + "=" * 70)
print("Select T1S Networks to Configure")
print("=" * 70)
for i, net_id in enumerate(available_networks, 1):
print(f" [{i}] {net_id}")
response = input("\nEnter network numbers to configure (e.g., '1,3' or '1-3' or 'all'): ").strip().lower()
if not response:
return []
if response == 'all':
return available_networks
selected = []
tokens = response.split(',')
for token in tokens:
token = token.strip()
if '-' in token:
try:
parts = token.split('-')
start = int(parts[0])
end = int(parts[1])
for i in range(start, end + 1):
if 1 <= i <= len(available_networks):
selected.append(available_networks[i - 1])
except (ValueError, IndexError):
pass
else:
try:
num = int(token)
if 1 <= num <= len(available_networks):
selected.append(available_networks[num - 1])
except ValueError:
pass
return selected
def get_uint8_input(prompt, default_value):
"""Get uint8 input from user with default."""
response = input(f"{prompt} [{default_value}]: ").strip()
if not response:
return default_value
try:
val = int(response)
if 0 <= val <= 255:
return val
except ValueError:
pass
return default_value
def get_uint16_input(prompt, default_value):
"""Get uint16 input from user with default."""
response = input(f"{prompt} [{default_value}]: ").strip()
if not response:
return default_value
try:
val = int(response)
if 0 <= val <= 65535:
return val
except ValueError:
pass
return default_value
def opt_to_string(opt):
"""Convert optional value to string for display."""
if opt is None:
return "N/A"
if isinstance(opt, bool):
return "true" if opt else "false"
return str(opt)
def display_t1s_settings(device, network):
"""Display T1S settings for a network."""
print(f"\t{network} T1S Settings:")
settings = device.get_settings()
if not settings:
print("\t Unable to read settings")
return
print(f"\t PLCA Enabled: {opt_to_string(settings.get_t1s_plca_enabled(network))}")
print(f"\t Local ID: {opt_to_string(settings.get_t1s_local_id(network))}")
print(f"\t Max Nodes: {opt_to_string(settings.get_t1s_max_nodes(network))}")
print(f"\t TX Opp Timer: {opt_to_string(settings.get_t1s_tx_opp_timer(network))}")
print(f"\t Max Burst: {opt_to_string(settings.get_t1s_max_burst(network))}")
print(f"\t Burst Timer: {opt_to_string(settings.get_t1s_burst_timer(network))}")
term_enabled = settings.get_t1s_termination_enabled(network)
if term_enabled is not None:
print(f"\t Termination: {opt_to_string(term_enabled)}")
local_id_alt = settings.get_t1s_local_id_alternate(network)
if local_id_alt is not None:
print(f"\t Local ID Alternate: {opt_to_string(local_id_alt)}")
print(f"\t Bus Dec Beacons: {opt_to_string(settings.get_t1s_bus_decoding_beacons_enabled(network))}")
print(f"\t Bus Dec All: {opt_to_string(settings.get_t1s_bus_decoding_all_enabled(network))}")
multi_id_mask = settings.get_t1s_multi_id_enable_mask(network)
if multi_id_mask is not None:
print(f"\t Multi-ID Mask: 0x{multi_id_mask:02X}")
print("\t Multi-IDs: ", end="")
multi_ids = []
for i in range(7):
multi_id = settings.get_t1s_multi_id(network, i)
multi_ids.append(f"[{i}]={opt_to_string(multi_id)}")
print(", ".join(multi_ids))
print()
def configure_t1s_network(device, network):
"""Interactively configure T1S settings for a network."""
print("\n" + "=" * 70)
print(f"Configuring T1S Network: {network}")
print("=" * 70)
settings = device.get_settings()
if not settings:
print("Unable to read settings")
return
print("\n--- Basic PLCA Settings ---")
plca_enabled = get_user_confirmation("Enable PLCA")
settings.set_t1s_plca(network, plca_enabled)
local_id = get_uint8_input("Local ID (0-255)", 1)
settings.set_t1s_local_id(network, local_id)
max_nodes = get_uint8_input("Max Nodes (0-255)", 8)
settings.set_t1s_max_nodes(network, max_nodes)
tx_opp_timer = get_uint8_input("TX Opportunity Timer (0-255)", 20)
settings.set_t1s_tx_opp_timer(network, tx_opp_timer)
max_burst = get_uint16_input("Max Burst (0-65535)", 128)
settings.set_t1s_max_burst(network, max_burst)
burst_timer = get_uint16_input("Burst Timer (0-65535)", 64)
settings.set_t1s_burst_timer(network, burst_timer)
if settings.get_t1s_termination_enabled(network) is not None:
print("\n--- Termination Settings ---")
term_enabled = get_user_confirmation("Enable Termination")
settings.set_t1s_termination(network, term_enabled)
if settings.get_t1s_local_id_alternate(network) is not None:
print("\n--- Extended Settings ---")
local_id_alt = get_uint8_input("Local ID Alternate (0-255)", 0)
settings.set_t1s_local_id_alternate(network, local_id_alt)
bus_dec_beacons = get_user_confirmation("Enable Bus Decoding (Beacons)")
settings.set_t1s_bus_decoding_beacons(network, bus_dec_beacons)
bus_dec_all = get_user_confirmation("Enable Bus Decoding (All Symbols)")
settings.set_t1s_bus_decoding_all(network, bus_dec_all)
if get_user_confirmation("Configure Multi-ID settings?"):
multi_id_mask = get_uint8_input("Multi-ID Enable Mask (0x00-0xFF, hex)", 0x00)
settings.set_t1s_multi_id_enable_mask(network, multi_id_mask)
print("Configure Multi-IDs (7 slots):")
for i in range(7):
multi_id = get_uint8_input(f" Multi-ID [{i}]", 0)
settings.set_t1s_multi_id(network, i, multi_id)
if not device.set_settings(settings):
print("✗ Failed to update device settings")
else:
print(f"\n✓ Configuration complete for {network}")
def main():
"""Main T1S settings configuration example."""
device = None
try:
print("\n" + "=" * 70)
print("10BASE-T1S SETTINGS CONFIGURATION EXAMPLE")
print("=" * 70)
print(f"libicsneo {icsneopy.get_version()}")
print("=" * 70)
print("\nFinding devices... ", end="", flush=True)
devices = icsneopy.find_all_devices()
print(f"OK, {len(devices)} device{'s' if len(devices) != 1 else ''} found")
if not devices:
print("No devices found!")
return 1
for d in devices:
print(f" {d}")
device = None
for d in devices:
if d.get_type() == icsneopy.DeviceType.RADComet3:
device = d
break
if not device and devices:
device = devices[0]
if not device:
print("No suitable device found!")
return 1
print(f"\nSelected device: {device}")
print(f"Serial: {device.get_serial()}")
print("\nOpening device... ", end="", flush=True)
if not device.open():
print("✗ Failed")
return 1
print("")
candidate_networks = [
icsneopy.Network.NetID.AE_01, icsneopy.Network.NetID.AE_02,
icsneopy.Network.NetID.AE_03, icsneopy.Network.NetID.AE_04,
icsneopy.Network.NetID.AE_05, icsneopy.Network.NetID.AE_06,
icsneopy.Network.NetID.AE_07, icsneopy.Network.NetID.AE_08,
icsneopy.Network.NetID.AE_09, icsneopy.Network.NetID.AE_10
]
settings = device.get_settings()
t1s_networks = []
for net_id in candidate_networks:
local_id = settings.get_t1s_local_id(net_id)
if local_id is not None:
t1s_networks.append(net_id)
if not t1s_networks:
print("No T1S networks found on this device")
device.close()
return 1
print(f"\nFound {len(t1s_networks)} T1S network{'s' if len(t1s_networks) != 1 else ''}:")
for i, net_id in enumerate(t1s_networks, 1):
print(f" [{i}] {net_id}")
print("\n" + "-" * 70)
print("Current T1S Settings:")
print("-" * 70)
for net_id in t1s_networks:
display_t1s_settings(device, net_id)
networks_to_config = select_networks(t1s_networks)
if not networks_to_config:
print("\nNo networks selected for configuration.")
print("Closing device... ", end="", flush=True)
device.close()
print("")
return 0
print(f"\nConfiguring {len(networks_to_config)} network{'s' if len(networks_to_config) != 1 else ''}...")
for net_id in networks_to_config:
configure_t1s_network(device, net_id)
print("\n" + "=" * 70)
save_to_eeprom = get_user_confirmation("Save settings to EEPROM (permanent)?")
print("=" * 70)
settings = device.get_settings()
print(f"\nApplying settings{' to EEPROM' if save_to_eeprom else ' temporarily'}... ", end="", flush=True)
success = settings.apply(not save_to_eeprom)
if not success:
print("✗ Failed")
device.close()
return 1
print("")
print("\n" + "-" * 70)
print("Updated T1S Settings:")
print("-" * 70)
for net_id in t1s_networks:
display_t1s_settings(device, net_id)
print("Closing device... ", end="", flush=True)
device.close()
print("")
except KeyboardInterrupt:
print("\n\nInterrupted by user")
return 1
except Exception as e:
print(f"\nError: {e}")
import traceback
traceback.print_exc()
return 1
finally:
if device and device.is_open():
device.close()
return 0
if __name__ == "__main__":
exit(main())

View File

@ -0,0 +1,282 @@
"""
10BASE-T1S Symbol Decoding Example
Demonstrates T1S bus symbol decoding and analysis
"""
import icsneopy
import time
from enum import IntEnum
class T1SSymbol(IntEnum):
"""10BASE-T1S Symbol Types"""
SSD = 0x04
ESDOK = 0x07
BEACON = 0x08
ESD = 0x0D
ESDERR = 0x11
SYNC = 0x18
ESDJAB = 0x19
SILENCE = 0x1F
@classmethod
def get_name(cls, value):
"""Get human-readable name for symbol value."""
try:
return cls(value).name
except ValueError:
if 0x00 <= value <= 0x0F:
return f"DATA(0x{value:X})"
return f"UNKNOWN(0x{value:02X})"
def get_user_confirmation(prompt):
"""Get yes/no confirmation from user."""
response = input(f"{prompt} (y/n): ").strip().lower()
return response == 'y'
def configure_t1s_decoding(device, network, enable_symbols, enable_beacons):
"""Configure T1S bus decoding settings."""
settings = device.get_settings()
if not settings:
raise RuntimeError("Failed to get device settings")
print(f"\nConfiguring T1S decoding on network {network}...")
if not settings.set_t1s_bus_decoding_all(network, enable_symbols):
raise RuntimeError("Failed to set T1S symbol decoding")
if enable_symbols:
print(" ✓ Enabled decoding of all T1S symbols")
else:
print(" • T1S symbol decoding disabled")
if not settings.set_t1s_bus_decoding_beacons(network, enable_beacons):
raise RuntimeError("Failed to set T1S beacon decoding")
if enable_beacons:
print(" ✓ Enabled T1S beacon decoding")
else:
print(" • T1S beacon decoding disabled")
if not device.set_settings(settings):
raise RuntimeError("Failed to apply settings to device")
print(" ✓ Settings applied successfully")
def setup_symbol_monitoring(device, network):
"""Setup callback to monitor and decode T1S symbols."""
state = {
'symbol_count': 0,
'beacon_count': 0,
'wake_count': 0,
'burst_count': 0,
'symbol_stats': {},
'data_frame_count': 0
}
def symbol_handler(msg):
"""Handle incoming T1S messages."""
if not isinstance(msg, icsneopy.EthernetMessage):
return
if not msg.isT1S:
return
timestamp_ms = msg.timestamp / 1000000.0
if msg.isT1SSymbol:
num_symbols = len(msg.data)
print(f"[{timestamp_ms:12.3f} ms] T1S Symbols", end="")
if num_symbols > 0:
print(f" ({num_symbols} symbol{'s' if num_symbols > 1 else ''})", end="")
print(f" | Node ID: {msg.t1sNodeId}")
for i, symbol_value in enumerate(msg.data):
symbol_name = T1SSymbol.get_name(symbol_value)
state['symbol_count'] += 1
if symbol_name not in state['symbol_stats']:
state['symbol_stats'][symbol_name] = 0
state['symbol_stats'][symbol_name] += 1
if symbol_value == T1SSymbol.BEACON:
state['beacon_count'] += 1
print(f" [{i}] {symbol_name:10s} = 0x{symbol_value:02X}")
if num_symbols == 0 and msg.t1sSymbolType != 0:
symbol_value = msg.t1sSymbolType
symbol_name = T1SSymbol.get_name(symbol_value)
state['symbol_count'] += 1
if symbol_name not in state['symbol_stats']:
state['symbol_stats'][symbol_name] = 0
state['symbol_stats'][symbol_name] += 1
if symbol_value == T1SSymbol.BEACON:
state['beacon_count'] += 1
print(f" {symbol_name:10s} = 0x{symbol_value:02X} (from t1sSymbolType field)")
elif msg.isT1SBurst:
state['burst_count'] += 1
print(f"[{timestamp_ms:12.3f} ms] BURST | "
f"Node ID: {msg.t1sNodeId} | "
f"Burst Count: {msg.t1sBurstCount}")
elif msg.isT1SWake:
state['wake_count'] += 1
print(f"[{timestamp_ms:12.3f} ms] WAKE signal detected | "
f"Node ID: {msg.t1sNodeId}")
else:
state['data_frame_count'] += 1
print(f"[{timestamp_ms:12.3f} ms] T1S Data Frame | "
f"Length: {len(msg.data)} bytes | "
f"Node ID: {msg.t1sNodeId}")
if msg.data and len(msg.data) > 0:
preview = ' '.join([f"{b:02X}" for b in msg.data[:16]])
if len(msg.data) > 16:
preview += " ..."
print(f" Data: {preview}")
frame_filter = icsneopy.MessageFilter(network)
callback = icsneopy.MessageCallback(symbol_handler, frame_filter)
device.add_message_callback(callback)
return state
def print_statistics(state):
"""Print monitoring statistics."""
print("\n" + "=" * 70)
print("T1S SYMBOL DECODING STATISTICS")
print("=" * 70)
print(f"Total Symbols: {state['symbol_count']}")
print(f"Total Beacons: {state['beacon_count']}")
print(f"Total Wake Signals: {state['wake_count']}")
print(f"Total Bursts: {state['burst_count']}")
print(f"Total Data Frames: {state['data_frame_count']}")
if state['symbol_stats']:
print("\n" + "-" * 70)
print("Symbol Type Breakdown:")
print("-" * 70)
for symbol_name, count in sorted(state['symbol_stats'].items(),
key=lambda x: x[1], reverse=True):
print(f" {symbol_name:20s}{count:>10d}")
print("=" * 70)
def main():
"""Main T1S symbol decoding example."""
device = None
try:
MONITOR_NETWORK = icsneopy.Network.NetID.AE_02
MONITOR_DURATION = 30
print("\n" + "=" * 70)
print("10BASE-T1S SYMBOL DECODING EXAMPLE")
print("=" * 70)
print(f"libicsneo {icsneopy.get_version()}")
print("=" * 70)
print("\nFinding devices... ", end="", flush=True)
devices = icsneopy.find_all_devices()
print(f"OK, {len(devices)} device{'s' if len(devices) != 1 else ''} found")
if not devices:
print("No devices found!")
return 1
for d in devices:
print(f" {d}")
device = None
for d in devices:
if d.get_type() == icsneopy.DeviceType.RADComet3:
device = d
break
if not device and devices:
device = devices[0]
if not device:
print("No suitable device found!")
return 1
print(f"\nSelected device: {device}")
print(f"Serial: {device.get_serial()}")
print("\n" + "-" * 70)
print("T1S DECODING CONFIGURATION")
print("-" * 70)
enable_symbols = get_user_confirmation("Enable T1S symbol decoding (all symbols)")
enable_beacons = get_user_confirmation("Enable T1S beacon decoding")
print("-" * 70)
print("\nOpening device... ", end="", flush=True)
if not device.open():
print("✗ Failed")
return 1
print("")
print("Enabling message polling... ", end="", flush=True)
if not device.enable_message_polling():
print("✗ Failed")
device.close()
return 1
device.set_polling_message_limit(100000)
print("")
configure_t1s_decoding(device, MONITOR_NETWORK, enable_symbols, enable_beacons)
print("Going online... ", end="", flush=True)
if not device.go_online():
print("✗ Failed")
device.close()
return 1
print("")
state = setup_symbol_monitoring(device, MONITOR_NETWORK)
print("\n" + "-" * 70)
print(f"Monitoring T1S traffic for {MONITOR_DURATION} seconds...")
print("-" * 70)
start_time = time.time()
while time.time() - start_time < MONITOR_DURATION:
device.get_messages()
time.sleep(0.01)
print("\n" + "-" * 70)
print("Closing device... ", end="", flush=True)
device.close()
time.sleep(0.1)
print("")
print_statistics(state)
except KeyboardInterrupt:
print("\n\nMonitoring interrupted by user")
if 'state' in locals():
print_statistics(state)
except Exception as e:
print(f"\nError: {e}")
import traceback
traceback.print_exc()
return 1
finally:
if device and device.is_open():
device.close()
return 0
if __name__ == "__main__":
exit(main())

View File

@ -1194,6 +1194,77 @@ public:
return false; return false;
} }
virtual std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const {
(void)net;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
virtual bool setT1SLocalIDAlternateFor(Network net, uint8_t id) {
(void)net; (void)id;
return false;
}
virtual std::optional<bool> isT1STerminationEnabledFor(Network net) const {
(void)net;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
virtual bool setT1STerminationFor(Network net, bool enable) {
(void)net; (void)enable;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
virtual std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const {
(void)net;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
virtual bool setT1SBusDecodingBeaconsFor(Network net, bool enable) {
(void)net; (void)enable;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
virtual std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const {
(void)net;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
virtual bool setT1SBusDecodingAllFor(Network net, bool enable) {
(void)net; (void)enable;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
virtual std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const {
(void)net;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
virtual bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) {
(void)net; (void)mask;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
virtual std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const {
(void)net; (void)index;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return std::nullopt;
}
virtual bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) {
(void)net; (void)index; (void)id;
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
return false;
}
virtual bool setMiscIOAnalogOutputEnabled(uint8_t pin, bool enabled); virtual bool setMiscIOAnalogOutputEnabled(uint8_t pin, bool enabled);
virtual bool setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage voltage); virtual bool setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage voltage);

View File

@ -363,6 +363,109 @@ public:
return true; return true;
} }
std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional(t1s->local_id_alternate);
}
bool setT1SLocalIDAlternateFor(Network net, uint8_t id) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
t1s->local_id_alternate = id;
return true;
}
std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS) != 0);
}
bool setT1SBusDecodingBeaconsFor(Network net, bool enable) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
if(enable)
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
else
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
return true;
}
std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL) != 0);
}
bool setT1SBusDecodingAllFor(Network net, bool enable) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
if(enable)
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
else
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
return true;
}
std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const override {
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return std::nullopt;
return std::make_optional(t1sExt->enable_multi_id);
}
bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) override {
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return false;
t1sExt->enable_multi_id = mask;
return true;
}
std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const override {
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return std::nullopt;
if(index >= 7) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
return std::make_optional(t1sExt->multi_id[index]);
}
bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) override {
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return false;
if(index >= 7) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
t1sExt->multi_id[index] = id;
return true;
}
private: private:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const { const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>(); auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
@ -404,6 +507,46 @@ private:
} }
} }
const ETHERNET10T1S_SETTINGS_EXT* getT1SSettingsExtFor(Network net) const {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr)
return nullptr;
switch(net.getNetID()) {
case Network::NetID::AE_03: return &(cfg->t1s1Ext);
case Network::NetID::AE_04: return &(cfg->t1s2Ext);
case Network::NetID::AE_05: return &(cfg->t1s3Ext);
case Network::NetID::AE_06: return &(cfg->t1s4Ext);
case Network::NetID::AE_07: return &(cfg->t1s5Ext);
case Network::NetID::AE_08: return &(cfg->t1s6Ext);
case Network::NetID::AE_09: return &(cfg->t1s7Ext);
case Network::NetID::AE_10: return &(cfg->t1s8Ext);
default:
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return nullptr;
}
}
ETHERNET10T1S_SETTINGS_EXT* getMutableT1SSettingsExtFor(Network net) {
auto cfg = getMutableStructurePointer<neovifire3t1slin_settings_t>();
if(cfg == nullptr)
return nullptr;
switch(net.getNetID()) {
case Network::NetID::AE_03: return &(cfg->t1s1Ext);
case Network::NetID::AE_04: return &(cfg->t1s2Ext);
case Network::NetID::AE_05: return &(cfg->t1s3Ext);
case Network::NetID::AE_06: return &(cfg->t1s4Ext);
case Network::NetID::AE_07: return &(cfg->t1s5Ext);
case Network::NetID::AE_08: return &(cfg->t1s6Ext);
case Network::NetID::AE_09: return &(cfg->t1s7Ext);
case Network::NetID::AE_10: return &(cfg->t1s8Ext);
default:
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return nullptr;
}
}
protected: protected:
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override { ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>(); auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();

View File

@ -223,6 +223,27 @@ public:
return true; return true;
} }
std::optional<bool> isT1STerminationEnabledFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_TERMINATION) != 0);
}
bool setT1STerminationFor(Network net, bool enable) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
if(enable)
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_TERMINATION;
else
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_TERMINATION;
return true;
}
private: private:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const { const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radcomet_settings_t>(); auto cfg = getStructurePointer<radcomet_settings_t>();

View File

@ -258,6 +258,109 @@ public:
return true; return true;
} }
std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional(t1s->local_id_alternate);
}
bool setT1SLocalIDAlternateFor(Network net, uint8_t id) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
t1s->local_id_alternate = id;
return true;
}
std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS) != 0);
}
bool setT1SBusDecodingBeaconsFor(Network net, bool enable) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
if(enable)
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
else
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
return true;
}
std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL) != 0);
}
bool setT1SBusDecodingAllFor(Network net, bool enable) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
if(enable)
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
else
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
return true;
}
std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const override {
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return std::nullopt;
return std::make_optional(t1sExt->enable_multi_id);
}
bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) override {
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return false;
t1sExt->enable_multi_id = mask;
return true;
}
std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const override {
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return std::nullopt;
if(index >= 7) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
return std::make_optional(t1sExt->multi_id[index]);
}
bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) override {
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return false;
if(index >= 7) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
t1sExt->multi_id[index] = id;
return true;
}
bool setPhyRoleFor(Network net, AELinkMode mode) override { bool setPhyRoleFor(Network net, AELinkMode mode) override {
if (mode != AE_LINK_AUTO && mode != AE_LINK_MASTER && mode != AE_LINK_SLAVE) { if (mode != AE_LINK_AUTO && mode != AE_LINK_MASTER && mode != AE_LINK_SLAVE) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
@ -571,6 +674,42 @@ private:
return nullptr; return nullptr;
} }
} }
const ETHERNET10T1S_SETTINGS_EXT* getT1SSettingsExtFor(Network net) const {
auto cfg = getStructurePointer<radcomet3_settings_t>();
if(cfg == nullptr)
return nullptr;
switch(net.getNetID()) {
case Network::NetID::AE_02: return &(cfg->t1s1Ext);
case Network::NetID::AE_03: return &(cfg->t1s2Ext);
case Network::NetID::AE_04: return &(cfg->t1s3Ext);
case Network::NetID::AE_05: return &(cfg->t1s4Ext);
case Network::NetID::AE_06: return &(cfg->t1s5Ext);
case Network::NetID::AE_07: return &(cfg->t1s6Ext);
default:
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return nullptr;
}
}
ETHERNET10T1S_SETTINGS_EXT* getMutableT1SSettingsExtFor(Network net) {
auto cfg = getMutableStructurePointer<radcomet3_settings_t>();
if(cfg == nullptr)
return nullptr;
switch(net.getNetID()) {
case Network::NetID::AE_02: return &(cfg->t1s1Ext);
case Network::NetID::AE_03: return &(cfg->t1s2Ext);
case Network::NetID::AE_04: return &(cfg->t1s3Ext);
case Network::NetID::AE_05: return &(cfg->t1s4Ext);
case Network::NetID::AE_06: return &(cfg->t1s5Ext);
case Network::NetID::AE_07: return &(cfg->t1s6Ext);
default:
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return nullptr;
}
}
}; };
} }

View File

@ -355,6 +355,130 @@ namespace icsneo
return true; return true;
} }
std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional(t1s->local_id_alternate);
}
bool setT1SLocalIDAlternateFor(Network net, uint8_t id) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
t1s->local_id_alternate = id;
return true;
}
std::optional<bool> isT1STerminationEnabledFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_TERMINATION) != 0);
}
bool setT1STerminationFor(Network net, bool enable) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
if(enable)
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_TERMINATION;
else
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_TERMINATION;
return true;
}
std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS) != 0);
}
bool setT1SBusDecodingBeaconsFor(Network net, bool enable) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
if(enable)
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
else
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
return true;
}
std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const override {
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
if(t1s == nullptr)
return std::nullopt;
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL) != 0);
}
bool setT1SBusDecodingAllFor(Network net, bool enable) override {
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
if(t1s == nullptr)
return false;
if(enable)
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
else
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
return true;
}
std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const override {
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return std::nullopt;
return std::make_optional(t1sExt->enable_multi_id);
}
bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) override {
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return false;
t1sExt->enable_multi_id = mask;
return true;
}
std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const override {
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return std::nullopt;
if(index >= 7) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
return std::make_optional(t1sExt->multi_id[index]);
}
bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) override {
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
if(t1sExt == nullptr)
return false;
if(index >= 7) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
t1sExt->multi_id[index] = id;
return true;
}
private: private:
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const { const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
auto cfg = getStructurePointer<radgigastar2_settings_t>(); auto cfg = getStructurePointer<radgigastar2_settings_t>();
@ -396,6 +520,46 @@ namespace icsneo
} }
} }
const ETHERNET10T1S_SETTINGS_EXT* getT1SSettingsExtFor(Network net) const {
auto cfg = getStructurePointer<radgigastar2_settings_t>();
if(cfg == nullptr)
return nullptr;
switch(net.getNetID()) {
case Network::NetID::AE_03: return &(cfg->t1s1Ext);
case Network::NetID::AE_04: return &(cfg->t1s2Ext);
case Network::NetID::AE_05: return &(cfg->t1s3Ext);
case Network::NetID::AE_06: return &(cfg->t1s4Ext);
case Network::NetID::AE_07: return &(cfg->t1s5Ext);
case Network::NetID::AE_08: return &(cfg->t1s6Ext);
case Network::NetID::AE_09: return &(cfg->t1s7Ext);
case Network::NetID::AE_10: return &(cfg->t1s8Ext);
default:
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return nullptr;
}
}
ETHERNET10T1S_SETTINGS_EXT* getMutableT1SSettingsExtFor(Network net) {
auto cfg = getMutableStructurePointer<radgigastar2_settings_t>();
if(cfg == nullptr)
return nullptr;
switch(net.getNetID()) {
case Network::NetID::AE_03: return &(cfg->t1s1Ext);
case Network::NetID::AE_04: return &(cfg->t1s2Ext);
case Network::NetID::AE_05: return &(cfg->t1s3Ext);
case Network::NetID::AE_06: return &(cfg->t1s4Ext);
case Network::NetID::AE_07: return &(cfg->t1s5Ext);
case Network::NetID::AE_08: return &(cfg->t1s6Ext);
case Network::NetID::AE_09: return &(cfg->t1s7Ext);
case Network::NetID::AE_10: return &(cfg->t1s8Ext);
default:
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return nullptr;
}
}
protected: protected:
ICSNEO_UNALIGNED(const uint64_t *) ICSNEO_UNALIGNED(const uint64_t *)
getTerminationEnables() const override getTerminationEnables() const override

View File

@ -210,10 +210,163 @@ private:
return nullptr; return nullptr;
} }
} }
std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const override {
auto cfg = getStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return std::nullopt;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
return std::make_optional(cfg->t1s.local_id_alternate);
}
bool setT1SLocalIDAlternateFor(Network net, uint8_t id) override {
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return false;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
cfg->t1s.local_id_alternate = id;
return true;
}
std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const override {
auto cfg = getStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return std::nullopt;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
return std::make_optional<bool>((cfg->t1s.flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS) != 0);
}
bool setT1SBusDecodingBeaconsFor(Network net, bool enable) override {
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return false;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
if(enable)
cfg->t1s.flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
else
cfg->t1s.flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
return true;
}
std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const override {
auto cfg = getStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return std::nullopt;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
return std::make_optional<bool>((cfg->t1s.flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL) != 0);
}
bool setT1SBusDecodingAllFor(Network net, bool enable) override {
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return false;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
if(enable)
cfg->t1s.flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
else
cfg->t1s.flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
return true;
}
std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const override {
auto cfg = getStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return std::nullopt;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
return std::make_optional(cfg->t1sExt.enable_multi_id);
}
bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) override {
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return false;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
cfg->t1sExt.enable_multi_id = mask;
return true;
}
std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const override {
auto cfg = getStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return std::nullopt;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
if(index >= 7) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return std::nullopt;
}
return std::make_optional(cfg->t1sExt.multi_id[index]);
}
bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) override {
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
if(cfg == nullptr)
return false;
if(net.getNetID() != Network::NetID::AE_01) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
if(index >= 7) {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false;
}
cfg->t1sExt.multi_id[index] = id;
return true;
}
}; };
} }
#endif // __cplusplus #endif // __cplusplus
#endif // __RADMOONT1SSETTINGS_H_ #endif // __RADMOONT1SSETTINGS_H_