mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Device: Implement Ethernet PHY MDIO Communication
The following fixups were added during the squash/merge: Fix formatting in EthPhyMessage and EthPhyRegPacket Device: Use std::make_shared when creating the EthPHYControl filter Network: Create NetID String for EthPHYControl EthPhyRegPacket: Constants in PascalCase
This commit is contained in:
committed by
Paul Hollinsky
parent
890eb1e1bc
commit
2d1bb381f6
@@ -12,6 +12,7 @@
|
||||
#include "icsneo/communication/packet/flexraypacket.h"
|
||||
#include "icsneo/communication/packet/iso9141packet.h"
|
||||
#include "icsneo/communication/packet/versionpacket.h"
|
||||
#include "icsneo/communication/packet/ethphyregpacket.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace icsneo;
|
||||
@@ -263,6 +264,15 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
result = msg;
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::EthPHYControl: {
|
||||
result = HardwareEthernetPhyRegisterPacket::DecodeToMessage(packet->data, report);
|
||||
if(!result)
|
||||
{
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "icsneo/communication/packet/ethernetpacket.h"
|
||||
#include "icsneo/communication/packet/iso9141packet.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
#include "icsneo/communication/packet/ethphyregpacket.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
@@ -126,6 +127,21 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
m51msg->data.insert(m51msg->data.begin(), { uint8_t(m51msg->command) });
|
||||
shortFormat = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Message::Type::EthernetPhyRegister: {
|
||||
if(!supportEthPhy) {
|
||||
report(APIEvent::Type::EthPhyRegisterControlNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
auto ethPhyMessage = std::dynamic_pointer_cast<EthPhyMessage>(message);
|
||||
if(!ethPhyMessage) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(!HardwareEthernetPhyRegisterPacket::EncodeFromMessage(*ethPhyMessage, result, report))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "icsneo/communication/message/ethphymessage.h"
|
||||
|
||||
namespace icsneo
|
||||
{
|
||||
bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t phyAddrOrPort, uint8_t pageOrDevice, uint16_t regAddr, uint16_t regVal, bool enabled)
|
||||
{
|
||||
auto msg = std::make_shared<PhyMessage>();
|
||||
msg->Clause45Enable = clause45;
|
||||
msg->Enabled = enabled;
|
||||
msg->WriteEnable = writeEnable;
|
||||
msg->version = 1u;
|
||||
if( (FiveBits < phyAddrOrPort) ||
|
||||
(clause45 && (FiveBits < pageOrDevice)) ||
|
||||
(!clause45 && (FiveBits < regAddr)) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(clause45)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return appendPhyMessage(msg);
|
||||
}
|
||||
|
||||
bool EthPhyMessage::appendPhyMessage(std::shared_ptr<PhyMessage> message)
|
||||
{
|
||||
if(message != nullptr)
|
||||
{
|
||||
messages.push_back(message);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t EthPhyMessage::getMessageCount() const
|
||||
{
|
||||
return messages.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
#include "icsneo/communication/packet/ethphyregpacket.h"
|
||||
#include "icsneo/communication/message/ethphymessage.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
namespace icsneo
|
||||
{
|
||||
std::shared_ptr<EthPhyMessage> HardwareEthernetPhyRegisterPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report)
|
||||
{
|
||||
if(bytestream.empty() || (bytestream.size() < sizeof(PhyRegisterHeader_t)))
|
||||
{
|
||||
report(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
auto msg = std::make_shared<EthPhyMessage>();
|
||||
const PhyRegisterHeader_t* pHeader = reinterpret_cast<const PhyRegisterHeader_t*>(bytestream.data());
|
||||
const size_t numEntries = static_cast<size_t>(pHeader->numEntries);
|
||||
if(
|
||||
(PhyPacketVersion == pHeader->version) &&
|
||||
(sizeof(PhyRegisterPacket_t) == pHeader->entryBytes) &&
|
||||
(numEntries <= MaxPhyEntries) &&
|
||||
((bytestream.size() - sizeof(PhyRegisterHeader_t))
|
||||
== (sizeof(PhyRegisterPacket_t) * numEntries))
|
||||
)
|
||||
{
|
||||
msg->messages.reserve(numEntries);
|
||||
const PhyRegisterPacket_t* pFirstEntry = reinterpret_cast<const PhyRegisterPacket_t*>(bytestream.data() + sizeof(PhyRegisterHeader_t));
|
||||
for(size_t entryIdx{0}; entryIdx < numEntries; ++entryIdx)
|
||||
{
|
||||
const PhyRegisterPacket_t* pEntry = (pFirstEntry + entryIdx);
|
||||
auto phyMessage = std::make_shared<PhyMessage>();
|
||||
phyMessage->Enabled = (pEntry->Enabled != 0u);
|
||||
phyMessage->WriteEnable = (pEntry->WriteEnable != 0u);
|
||||
phyMessage->Clause45Enable = (pEntry->Clause45Enable != 0u);
|
||||
phyMessage->version = static_cast<uint8_t>(pEntry->version);
|
||||
if(phyMessage->Clause45Enable)
|
||||
{
|
||||
phyMessage->clause45 =
|
||||
{
|
||||
.port = pEntry->clause45.port,
|
||||
.device = pEntry->clause45.device,
|
||||
.regAddr = pEntry->clause45.regAddr,
|
||||
.regVal = pEntry->clause45.regVal
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
phyMessage->clause22 =
|
||||
{
|
||||
.phyAddr = pEntry->clause22.phyAddr,
|
||||
.page = pEntry->clause22.page,
|
||||
.regAddr = pEntry->clause22.regAddr,
|
||||
.regVal = pEntry->clause22.regVal
|
||||
};
|
||||
}
|
||||
msg->messages.push_back(phyMessage);
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool HardwareEthernetPhyRegisterPacket::EncodeFromMessage(const EthPhyMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report)
|
||||
{
|
||||
const size_t messageCount = message.getMessageCount();
|
||||
if(!messageCount)
|
||||
{
|
||||
report(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
else if (messageCount > MaxPhyEntries)
|
||||
{
|
||||
report(APIEvent::Type::MessageMaxLengthExceeded, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
auto byteSize = (messageCount * sizeof(PhyRegisterPacket_t)) + sizeof(PhyRegisterHeader_t);
|
||||
bytestream.reserve(byteSize);
|
||||
bytestream.push_back(static_cast<uint8_t>(messageCount & 0xFF));
|
||||
bytestream.push_back(static_cast<uint8_t>((messageCount >> 8) & 0xFF));
|
||||
bytestream.push_back(PhyPacketVersion);
|
||||
bytestream.push_back(static_cast<uint8_t>(sizeof(PhyRegisterPacket_t)));
|
||||
for(auto& phyMessage : message.messages)
|
||||
{
|
||||
PhyRegisterPacket_t tempPacket;
|
||||
tempPacket.Enabled = phyMessage->Enabled ? 0x1u : 0x0u;
|
||||
tempPacket.WriteEnable = phyMessage->WriteEnable ? 0x1u : 0x0u;
|
||||
tempPacket.version = (phyMessage->version & 0xF);
|
||||
if(phyMessage->Clause45Enable)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
uint8_t* pktPtr = reinterpret_cast<uint8_t*>(&tempPacket);
|
||||
bytestream.insert(bytestream.end(), pktPtr, pktPtr + sizeof(PhyRegisterPacket_t));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user