Bindings: Python: Add EthPhyMessage

Also fixes PhyMessages for RADEpsilon(XL)
pull/76/merge
Kyle Schwarz 2025-09-29 17:17:26 -04:00
parent f22d666f94
commit 11643e2281
11 changed files with 82 additions and 31 deletions

View File

@ -34,6 +34,7 @@ pybind11_add_module(icsneopy
icsneopy/communication/message/spimessage.cpp icsneopy/communication/message/spimessage.cpp
icsneopy/communication/message/macsecmessage.cpp icsneopy/communication/message/macsecmessage.cpp
icsneopy/communication/message/scriptstatusmessage.cpp icsneopy/communication/message/scriptstatusmessage.cpp
icsneopy/communication/message/ethphymessage.cpp
icsneopy/communication/message/callback/messagecallback.cpp icsneopy/communication/message/callback/messagecallback.cpp
icsneopy/communication/message/filter/messagefilter.cpp icsneopy/communication/message/filter/messagefilter.cpp
icsneopy/flexray/flexray.cpp icsneopy/flexray/flexray.cpp

View File

@ -0,0 +1,36 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/ethphymessage.h"
namespace icsneo {
void init_ethphymessage(pybind11::module_& m) {
pybind11::class_<PhyMessage, std::shared_ptr<PhyMessage>>(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_<Clause22Message>(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_<Clause45Message>(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_<EthPhyMessage, std::shared_ptr<EthPhyMessage>, Message>(m, "EthPhyMessage")
.def(pybind11::init())
.def_readwrite("messages", &EthPhyMessage::messages);
}
} // namespace icsneo

View File

@ -55,6 +55,7 @@ void init_device(pybind11::module_& m) {
.def("transmit", pybind11::overload_cast<std::shared_ptr<Frame>>(&Device::transmit), pybind11::call_guard<pybind11::gil_scoped_release>()) .def("transmit", pybind11::overload_cast<std::shared_ptr<Frame>>(&Device::transmit), pybind11::call_guard<pybind11::gil_scoped_release>())
.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<pybind11::gil_scoped_release>()) .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<pybind11::gil_scoped_release>())
.def("write_macsec_config", &Device::writeMACsecConfig, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("write_macsec_config", &Device::writeMACsecConfig, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("send_eth_phy_msg", &Device::sendEthPhyMsg, pybind11::arg("message"), pybind11::arg("timeout") = std::chrono::milliseconds(50), pybind11::call_guard<pybind11::gil_scoped_release>())
.def_readonly("settings", &Device::settings); .def_readonly("settings", &Device::settings);
} }

View File

@ -32,6 +32,7 @@ void init_messagecallback(pybind11::module_&);
void init_version(pybind11::module_&); void init_version(pybind11::module_&);
void init_flexray(pybind11::module_& m); void init_flexray(pybind11::module_& m);
void init_idevicesettings(pybind11::module_&); void init_idevicesettings(pybind11::module_&);
void init_ethphymessage(pybind11::module_&);
PYBIND11_MODULE(icsneopy, m) { PYBIND11_MODULE(icsneopy, m) {
pybind11::options options; pybind11::options options;
@ -61,6 +62,7 @@ PYBIND11_MODULE(icsneopy, m) {
init_messagecallback(m); init_messagecallback(m);
init_diskdriver(m); init_diskdriver(m);
init_flexray(m); init_flexray(m);
init_ethphymessage(m);
init_device(m); init_device(m);
init_deviceextension(m); init_deviceextension(m);
init_idevicesettings(m); init_idevicesettings(m);

View File

@ -8,7 +8,7 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph
msg->Clause45Enable = clause45; msg->Clause45Enable = clause45;
msg->Enabled = enabled; msg->Enabled = enabled;
msg->WriteEnable = writeEnable; msg->WriteEnable = writeEnable;
msg->version = 1u; msg->Version = 1u;
if( (FiveBits < phyAddrOrPort) || if( (FiveBits < phyAddrOrPort) ||
(clause45 && (FiveBits < pageOrDevice)) || (clause45 && (FiveBits < pageOrDevice)) ||
(!clause45 && (FiveBits < regAddr)) ) (!clause45 && (FiveBits < regAddr)) )
@ -18,17 +18,17 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph
if(clause45) if(clause45)
{ {
msg->clause45.port = phyAddrOrPort; msg->Clause45.port = phyAddrOrPort;
msg->clause45.device = pageOrDevice; msg->Clause45.device = pageOrDevice;
msg->clause45.regAddr = regAddr; msg->Clause45.regAddr = regAddr;
msg->clause45.regVal = regVal; msg->Clause45.regVal = regVal;
} }
else else
{ {
msg->clause22.phyAddr = phyAddrOrPort; msg->Clause22.phyAddr = phyAddrOrPort;
msg->clause22.page = pageOrDevice; msg->Clause22.page = pageOrDevice;
msg->clause22.regAddr = regAddr; msg->Clause22.regAddr = regAddr;
msg->clause22.regVal = regVal; msg->Clause22.regVal = regVal;
} }
return appendPhyMessage(msg); return appendPhyMessage(msg);
} }

View File

@ -34,11 +34,12 @@ std::shared_ptr<EthPhyMessage> HardwareEthernetPhyRegisterPacket::DecodeToMessag
phyMessage->Enabled = (pEntry->Enabled != 0u); phyMessage->Enabled = (pEntry->Enabled != 0u);
phyMessage->WriteEnable = (pEntry->WriteEnable != 0u); phyMessage->WriteEnable = (pEntry->WriteEnable != 0u);
phyMessage->Clause45Enable = (pEntry->Clause45Enable != 0u); phyMessage->Clause45Enable = (pEntry->Clause45Enable != 0u);
phyMessage->version = static_cast<uint8_t>(pEntry->version); phyMessage->BusIndex = static_cast<uint8_t>(pEntry->BusIndex);
phyMessage->Version = static_cast<uint8_t>(pEntry->version);
if(phyMessage->Clause45Enable) if(phyMessage->Clause45Enable)
phyMessage->clause45 = pEntry->clause45; phyMessage->Clause45 = pEntry->clause45;
else else
phyMessage->clause22 = pEntry->clause22; phyMessage->Clause22 = pEntry->clause22;
msg->messages.push_back(phyMessage); msg->messages.push_back(phyMessage);
} }
} }
@ -69,34 +70,35 @@ bool HardwareEthernetPhyRegisterPacket::EncodeFromMessage(const EthPhyMessage& m
PhyRegisterPacket_t tempPacket; PhyRegisterPacket_t tempPacket;
tempPacket.Enabled = phyMessage->Enabled ? 0x1u : 0x0u; tempPacket.Enabled = phyMessage->Enabled ? 0x1u : 0x0u;
tempPacket.WriteEnable = phyMessage->WriteEnable ? 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(phyMessage->Clause45Enable)
{ {
if( (FiveBits < phyMessage->clause45.port) || if( (FiveBits < phyMessage->Clause45.port) ||
(FiveBits < phyMessage->clause45.device) ) (FiveBits < phyMessage->Clause45.device) )
{ {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false; return false;
} }
tempPacket.Clause45Enable = 0x1u; tempPacket.Clause45Enable = 0x1u;
tempPacket.clause45.port = phyMessage->clause45.port; tempPacket.clause45.port = phyMessage->Clause45.port;
tempPacket.clause45.device = phyMessage->clause45.device; tempPacket.clause45.device = phyMessage->Clause45.device;
tempPacket.clause45.regAddr = phyMessage->clause45.regAddr; tempPacket.clause45.regAddr = phyMessage->Clause45.regAddr;
tempPacket.clause45.regVal = phyMessage->clause45.regVal; tempPacket.clause45.regVal = phyMessage->Clause45.regVal;
} }
else else
{ {
if( (FiveBits < phyMessage->clause22.phyAddr) || if( (FiveBits < phyMessage->Clause22.phyAddr) ||
(FiveBits < phyMessage->clause22.regAddr) ) (FiveBits < phyMessage->Clause22.regAddr) )
{ {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false; return false;
} }
tempPacket.Clause45Enable = 0x0u; tempPacket.Clause45Enable = 0x0u;
tempPacket.clause22.phyAddr = phyMessage->clause22.phyAddr; tempPacket.clause22.phyAddr = phyMessage->Clause22.phyAddr;
tempPacket.clause22.page = phyMessage->clause22.page; tempPacket.clause22.page = phyMessage->Clause22.page;
tempPacket.clause22.regAddr = phyMessage->clause22.regAddr; tempPacket.clause22.regAddr = phyMessage->Clause22.regAddr;
tempPacket.clause22.regVal = phyMessage->clause22.regVal; tempPacket.clause22.regVal = phyMessage->Clause22.regVal;
} }
uint8_t* pktPtr = reinterpret_cast<uint8_t*>(&tempPacket); uint8_t* pktPtr = reinterpret_cast<uint8_t*>(&tempPacket);
bytestream.insert(bytestream.end(), pktPtr, pktPtr + sizeof(PhyRegisterPacket_t)); bytestream.insert(bytestream.end(), pktPtr, pktPtr + sizeof(PhyRegisterPacket_t));

View File

@ -1846,7 +1846,7 @@ std::optional<EthPhyMessage> Device::sendEthPhyMsg(const EthPhyMessage& message,
HardwareEthernetPhyRegisterPacket::EncodeFromMessage(message, bytes, report); HardwareEthernetPhyRegisterPacket::EncodeFromMessage(message, bytes, report);
std::shared_ptr<Message> response = com->waitForMessageSync( std::shared_ptr<Message> response = com->waitForMessageSync(
[this, bytes](){ return com->sendCommand(Command::PHYControlRegisters, bytes); }, [this, bytes](){ return com->sendCommand(Command::PHYControlRegisters, bytes); },
std::make_shared<MessageFilter>(Network::NetID::EthPHYControl), timeout); std::make_shared<MessageFilter>(Message::Type::EthernetPhyRegister), timeout);
if(!response) { if(!response) {
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);

View File

@ -21,10 +21,11 @@ struct PhyMessage {
bool Enabled; bool Enabled;
bool WriteEnable; bool WriteEnable;
bool Clause45Enable; bool Clause45Enable;
uint8_t version; uint8_t BusIndex;
uint8_t Version;
union { union {
Clause22Message clause22; Clause22Message Clause22;
Clause45Message clause45; Clause45Message Clause45;
}; };
}; };

View File

@ -45,7 +45,9 @@ struct PhyRegisterPacket_t {
uint16_t Enabled : 1; uint16_t Enabled : 1;
uint16_t WriteEnable : 1; uint16_t WriteEnable : 1;
uint16_t Clause45Enable : 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 version : 4;
}; };
uint16_t flags; uint16_t flags;

View File

@ -25,6 +25,10 @@ public:
return supportedNetworks; return supportedNetworks;
} }
bool supportsComponentVersions() const override { return true; }
bool getEthPhyRegControlSupported() const override { return true; }
protected: protected:
RADEpsilon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { RADEpsilon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<RADEpsilonSettings, Disk::NeoMemoryDiskDriver, Disk::NeoMemoryDiskDriver>(makeDriver); initialize<RADEpsilonSettings, Disk::NeoMemoryDiskDriver, Disk::NeoMemoryDiskDriver>(makeDriver);

View File

@ -27,6 +27,8 @@ public:
bool supportsComponentVersions() const override { return true; } bool supportsComponentVersions() const override { return true; }
bool getEthPhyRegControlSupported() const override { return true; }
protected: protected:
RADEpsilonXL(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { RADEpsilonXL(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<RADEpsilonSettings, Disk::NeoMemoryDiskDriver, Disk::NeoMemoryDiskDriver>(makeDriver); initialize<RADEpsilonSettings, Disk::NeoMemoryDiskDriver, Disk::NeoMemoryDiskDriver>(makeDriver);