From 11643e2281106a1d59742a0b024816398ee4d28e Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Mon, 29 Sep 2025 17:17:26 -0400 Subject: [PATCH] Bindings: Python: Add EthPhyMessage Also fixes PhyMessages for RADEpsilon(XL) --- bindings/python/CMakeLists.txt | 1 + .../communication/message/ethphymessage.cpp | 36 +++++++++++++++++++ bindings/python/icsneopy/device/device.cpp | 1 + bindings/python/icsneopy/icsneocpp.cpp | 2 ++ communication/message/ethphymessage.cpp | 18 +++++----- communication/packet/ethphyregpacket.cpp | 34 +++++++++--------- device/device.cpp | 2 +- .../communication/message/ethphymessage.h | 7 ++-- .../communication/packet/ethphyregpacket.h | 4 ++- .../device/tree/radepsilon/radepsilon.h | 4 +++ .../device/tree/radepsilonxl/radepsilonxl.h | 4 ++- 11 files changed, 82 insertions(+), 31 deletions(-) create mode 100644 bindings/python/icsneopy/communication/message/ethphymessage.cpp diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index e178777..441825f 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -34,6 +34,7 @@ pybind11_add_module(icsneopy icsneopy/communication/message/spimessage.cpp icsneopy/communication/message/macsecmessage.cpp icsneopy/communication/message/scriptstatusmessage.cpp + icsneopy/communication/message/ethphymessage.cpp icsneopy/communication/message/callback/messagecallback.cpp icsneopy/communication/message/filter/messagefilter.cpp icsneopy/flexray/flexray.cpp diff --git a/bindings/python/icsneopy/communication/message/ethphymessage.cpp b/bindings/python/icsneopy/communication/message/ethphymessage.cpp new file mode 100644 index 0000000..586504f --- /dev/null +++ b/bindings/python/icsneopy/communication/message/ethphymessage.cpp @@ -0,0 +1,36 @@ +#include +#include +#include + +#include "icsneo/communication/message/ethphymessage.h" + +namespace icsneo { + +void init_ethphymessage(pybind11::module_& m) { + pybind11::class_>(m, "PhyMessage") + .def(pybind11::init()) + .def_readwrite("Enabled", &PhyMessage::Enabled) + .def_readwrite("WriteEnable", &PhyMessage::WriteEnable) + .def_readwrite("Clause45Enable", &PhyMessage::Clause45Enable) + .def_readwrite("Version", &PhyMessage::Version) + .def_readwrite("BusIndex", &PhyMessage::BusIndex) + .def_readwrite("Clause22", &PhyMessage::Clause22) + .def_readwrite("Clause45", &PhyMessage::Clause45); + pybind11::class_(m, "Clause22Message") + .def(pybind11::init()) + .def_readwrite("phyAddr", &Clause22Message::phyAddr) + .def_readwrite("page", &Clause22Message::page) + .def_readwrite("regAddr", &Clause22Message::regAddr) + .def_readwrite("regVal", &Clause22Message::regVal); + pybind11::class_(m, "Clause45Message") + .def(pybind11::init()) + .def_readwrite("port", &Clause45Message::port) + .def_readwrite("device", &Clause45Message::device) + .def_readwrite("regAddr", &Clause45Message::regAddr) + .def_readwrite("regVal", &Clause45Message::regVal); + pybind11::class_, Message>(m, "EthPhyMessage") + .def(pybind11::init()) + .def_readwrite("messages", &EthPhyMessage::messages); +} + +} // namespace icsneo diff --git a/bindings/python/icsneopy/device/device.cpp b/bindings/python/icsneopy/device/device.cpp index ea2c1e4..3cbe905 100644 --- a/bindings/python/icsneopy/device/device.cpp +++ b/bindings/python/icsneopy/device/device.cpp @@ -55,6 +55,7 @@ void init_device(pybind11::module_& m) { .def("transmit", pybind11::overload_cast>(&Device::transmit), pybind11::call_guard()) .def("upload_coremini", [](Device& device, std::string& path, Disk::MemoryType memType) { std::ifstream ifs(path, std::ios::binary); return device.uploadCoremini(ifs, memType); }, pybind11::call_guard()) .def("write_macsec_config", &Device::writeMACsecConfig, pybind11::call_guard()) + .def("send_eth_phy_msg", &Device::sendEthPhyMsg, pybind11::arg("message"), pybind11::arg("timeout") = std::chrono::milliseconds(50), pybind11::call_guard()) .def_readonly("settings", &Device::settings); } diff --git a/bindings/python/icsneopy/icsneocpp.cpp b/bindings/python/icsneopy/icsneocpp.cpp index 87ee928..fe074f9 100644 --- a/bindings/python/icsneopy/icsneocpp.cpp +++ b/bindings/python/icsneopy/icsneocpp.cpp @@ -32,6 +32,7 @@ void init_messagecallback(pybind11::module_&); void init_version(pybind11::module_&); void init_flexray(pybind11::module_& m); void init_idevicesettings(pybind11::module_&); +void init_ethphymessage(pybind11::module_&); PYBIND11_MODULE(icsneopy, m) { pybind11::options options; @@ -61,6 +62,7 @@ PYBIND11_MODULE(icsneopy, m) { init_messagecallback(m); init_diskdriver(m); init_flexray(m); + init_ethphymessage(m); init_device(m); init_deviceextension(m); init_idevicesettings(m); diff --git a/communication/message/ethphymessage.cpp b/communication/message/ethphymessage.cpp index b129d33..39b6fc6 100644 --- a/communication/message/ethphymessage.cpp +++ b/communication/message/ethphymessage.cpp @@ -8,7 +8,7 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph msg->Clause45Enable = clause45; msg->Enabled = enabled; msg->WriteEnable = writeEnable; - msg->version = 1u; + msg->Version = 1u; if( (FiveBits < phyAddrOrPort) || (clause45 && (FiveBits < pageOrDevice)) || (!clause45 && (FiveBits < regAddr)) ) @@ -18,17 +18,17 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph if(clause45) { - msg->clause45.port = phyAddrOrPort; - msg->clause45.device = pageOrDevice; - msg->clause45.regAddr = regAddr; - msg->clause45.regVal = regVal; + msg->Clause45.port = phyAddrOrPort; + msg->Clause45.device = pageOrDevice; + msg->Clause45.regAddr = regAddr; + msg->Clause45.regVal = regVal; } else { - msg->clause22.phyAddr = phyAddrOrPort; - msg->clause22.page = pageOrDevice; - msg->clause22.regAddr = regAddr; - msg->clause22.regVal = regVal; + msg->Clause22.phyAddr = phyAddrOrPort; + msg->Clause22.page = pageOrDevice; + msg->Clause22.regAddr = regAddr; + msg->Clause22.regVal = regVal; } return appendPhyMessage(msg); } diff --git a/communication/packet/ethphyregpacket.cpp b/communication/packet/ethphyregpacket.cpp index 06db93a..33b8bfb 100644 --- a/communication/packet/ethphyregpacket.cpp +++ b/communication/packet/ethphyregpacket.cpp @@ -34,11 +34,12 @@ std::shared_ptr HardwareEthernetPhyRegisterPacket::DecodeToMessag phyMessage->Enabled = (pEntry->Enabled != 0u); phyMessage->WriteEnable = (pEntry->WriteEnable != 0u); phyMessage->Clause45Enable = (pEntry->Clause45Enable != 0u); - phyMessage->version = static_cast(pEntry->version); + phyMessage->BusIndex = static_cast(pEntry->BusIndex); + phyMessage->Version = static_cast(pEntry->version); if(phyMessage->Clause45Enable) - phyMessage->clause45 = pEntry->clause45; + phyMessage->Clause45 = pEntry->clause45; else - phyMessage->clause22 = pEntry->clause22; + phyMessage->Clause22 = pEntry->clause22; msg->messages.push_back(phyMessage); } } @@ -69,34 +70,35 @@ bool HardwareEthernetPhyRegisterPacket::EncodeFromMessage(const EthPhyMessage& m PhyRegisterPacket_t tempPacket; tempPacket.Enabled = phyMessage->Enabled ? 0x1u : 0x0u; tempPacket.WriteEnable = phyMessage->WriteEnable ? 0x1u : 0x0u; - tempPacket.version = (phyMessage->version & 0xF); + tempPacket.BusIndex = (phyMessage->BusIndex & 0xF); + tempPacket.version = (phyMessage->Version & 0xF); if(phyMessage->Clause45Enable) { - if( (FiveBits < phyMessage->clause45.port) || - (FiveBits < phyMessage->clause45.device) ) + if( (FiveBits < phyMessage->Clause45.port) || + (FiveBits < phyMessage->Clause45.device) ) { report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); return false; } tempPacket.Clause45Enable = 0x1u; - tempPacket.clause45.port = phyMessage->clause45.port; - tempPacket.clause45.device = phyMessage->clause45.device; - tempPacket.clause45.regAddr = phyMessage->clause45.regAddr; - tempPacket.clause45.regVal = phyMessage->clause45.regVal; + tempPacket.clause45.port = phyMessage->Clause45.port; + tempPacket.clause45.device = phyMessage->Clause45.device; + tempPacket.clause45.regAddr = phyMessage->Clause45.regAddr; + tempPacket.clause45.regVal = phyMessage->Clause45.regVal; } else { - if( (FiveBits < phyMessage->clause22.phyAddr) || - (FiveBits < phyMessage->clause22.regAddr) ) + if( (FiveBits < phyMessage->Clause22.phyAddr) || + (FiveBits < phyMessage->Clause22.regAddr) ) { report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); return false; } tempPacket.Clause45Enable = 0x0u; - tempPacket.clause22.phyAddr = phyMessage->clause22.phyAddr; - tempPacket.clause22.page = phyMessage->clause22.page; - tempPacket.clause22.regAddr = phyMessage->clause22.regAddr; - tempPacket.clause22.regVal = phyMessage->clause22.regVal; + tempPacket.clause22.phyAddr = phyMessage->Clause22.phyAddr; + tempPacket.clause22.page = phyMessage->Clause22.page; + tempPacket.clause22.regAddr = phyMessage->Clause22.regAddr; + tempPacket.clause22.regVal = phyMessage->Clause22.regVal; } uint8_t* pktPtr = reinterpret_cast(&tempPacket); bytestream.insert(bytestream.end(), pktPtr, pktPtr + sizeof(PhyRegisterPacket_t)); diff --git a/device/device.cpp b/device/device.cpp index 65b95b2..7dcfa2a 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -1846,7 +1846,7 @@ std::optional Device::sendEthPhyMsg(const EthPhyMessage& message, HardwareEthernetPhyRegisterPacket::EncodeFromMessage(message, bytes, report); std::shared_ptr response = com->waitForMessageSync( [this, bytes](){ return com->sendCommand(Command::PHYControlRegisters, bytes); }, - std::make_shared(Network::NetID::EthPHYControl), timeout); + std::make_shared(Message::Type::EthernetPhyRegister), timeout); if(!response) { report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); diff --git a/include/icsneo/communication/message/ethphymessage.h b/include/icsneo/communication/message/ethphymessage.h index 470208e..531fb2d 100644 --- a/include/icsneo/communication/message/ethphymessage.h +++ b/include/icsneo/communication/message/ethphymessage.h @@ -21,10 +21,11 @@ struct PhyMessage { bool Enabled; bool WriteEnable; bool Clause45Enable; - uint8_t version; + uint8_t BusIndex; + uint8_t Version; union { - Clause22Message clause22; - Clause45Message clause45; + Clause22Message Clause22; + Clause45Message Clause45; }; }; diff --git a/include/icsneo/communication/packet/ethphyregpacket.h b/include/icsneo/communication/packet/ethphyregpacket.h index 2f0a805..7c2bfcb 100644 --- a/include/icsneo/communication/packet/ethphyregpacket.h +++ b/include/icsneo/communication/packet/ethphyregpacket.h @@ -45,7 +45,9 @@ struct PhyRegisterPacket_t { uint16_t Enabled : 1; uint16_t WriteEnable : 1; uint16_t Clause45Enable : 1; - uint16_t reserved : 9; + uint16_t status : 3; + uint16_t reserved : 2; + uint16_t BusIndex : 4; uint16_t version : 4; }; uint16_t flags; diff --git a/include/icsneo/device/tree/radepsilon/radepsilon.h b/include/icsneo/device/tree/radepsilon/radepsilon.h index c3cd594..3394bcc 100644 --- a/include/icsneo/device/tree/radepsilon/radepsilon.h +++ b/include/icsneo/device/tree/radepsilon/radepsilon.h @@ -25,6 +25,10 @@ public: return supportedNetworks; } + bool supportsComponentVersions() const override { return true; } + + bool getEthPhyRegControlSupported() const override { return true; } + protected: RADEpsilon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h b/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h index 6824e43..604659d 100644 --- a/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h +++ b/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h @@ -26,7 +26,9 @@ public: } bool supportsComponentVersions() const override { return true; } - + + bool getEthPhyRegControlSupported() const override { return true; } + protected: RADEpsilonXL(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver);