mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
MDIO: Network support
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
||||
#include "icsneo/communication/message/i2cmessage.h"
|
||||
#include "icsneo/communication/message/linmessage.h"
|
||||
#include "icsneo/communication/message/mdiomessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
@@ -28,6 +29,7 @@
|
||||
#include "icsneo/communication/packet/linpacket.h"
|
||||
#include "icsneo/communication/packet/componentversionpacket.h"
|
||||
#include "icsneo/communication/packet/supportedfeaturespacket.h"
|
||||
#include "icsneo/communication/packet/mdiopacket.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace icsneo;
|
||||
@@ -166,6 +168,18 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
msg.network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case Network::Type::MDIO: {
|
||||
result = HardwareMDIOPacket::DecodeToMessage(packet->data);
|
||||
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // A nullptr was returned, the packet was not long enough to decode
|
||||
}
|
||||
|
||||
MDIOMessage& msg = *static_cast<MDIOMessage*>(result.get());
|
||||
msg.network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case Network::Type::Internal: {
|
||||
switch(packet->network.getNetID()) {
|
||||
case Network::NetID::Reset_Status: {
|
||||
@@ -252,7 +266,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
switch(resp.header.command) {
|
||||
case ExtendedCommand::GetComponentVersions:
|
||||
result = ComponentVersionPacket::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
return true;
|
||||
case ExtendedCommand::GetSupportedFeatures:
|
||||
result = SupportedFeaturesPacket::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
@@ -262,7 +276,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
default:
|
||||
// No defined handler, treat this as a RawMessage
|
||||
break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case Network::NetID::FlexRayControl: {
|
||||
auto frResult = std::make_shared<FlexRayControlMessage>(*packet);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "icsneo/communication/message/i2cmessage.h"
|
||||
#include "icsneo/communication/packet/a2bpacket.h"
|
||||
#include "icsneo/communication/packet/linpacket.h"
|
||||
#include "icsneo/communication/packet/mdiopacket.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
@@ -108,6 +109,18 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
}
|
||||
break;
|
||||
} // End of Network::Type::LIN
|
||||
case Network::Type::MDIO: {
|
||||
auto mdiomsg = std::dynamic_pointer_cast<MDIOMessage>(message);
|
||||
if(!mdiomsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
buffer = &result;
|
||||
if(!HardwareMDIOPacket::EncodeFromMessage(*mdiomsg, result, report)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
} // End of Network::Type::MDIO
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "icsneo/communication/packet/mdiopacket.h"
|
||||
|
||||
namespace icsneo
|
||||
{
|
||||
|
||||
const size_t HardwareMDIOPacket::mdioDataSize = 2;
|
||||
|
||||
std::shared_ptr<Message> HardwareMDIOPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream)
|
||||
{
|
||||
auto msg = std::make_shared<MDIOMessage>();
|
||||
const HardwareMDIOPacket* packet = reinterpret_cast<const HardwareMDIOPacket*>(bytestream.data());
|
||||
if((sizeof(HardwareMDIOPacket) != (bytestream.size())) || (packet->length != 0))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
msg->network = Network::GetNetIDFromCoreMiniNetwork(static_cast<Network::CoreMini>(packet->networkID));
|
||||
msg->clause = static_cast<MDIOMessage::Clause>(packet->header.ST);
|
||||
msg->direction = static_cast<MDIOMessage::Direction>((packet->header.OP & 0x2) ? 1 : 0);
|
||||
msg->isTXMsg = static_cast<bool>(packet->header.TRANSMIT & 0x01u);
|
||||
msg->phyAddress = (packet->header.PHY_ADDR & 0x1Fu);
|
||||
if (msg->clause == MDIOMessage::Clause::Clause45)
|
||||
{ // 16-bit register address
|
||||
msg->devAddress = (packet->header.C45_DEVTYPE & 0x1Fu);
|
||||
msg->regAddress = (packet->header.REG_ADDR & 0xFFFFu);
|
||||
}
|
||||
else
|
||||
{ // 5-bit register address
|
||||
msg->devAddress = 0;
|
||||
msg->regAddress = (packet->header.REG_ADDR & 0x1Fu);
|
||||
}
|
||||
|
||||
msg->isTXMsg = static_cast<bool>(packet->header.TRANSMIT & 0x01u);
|
||||
msg->txTimeout = static_cast<bool>(packet->header.ERR_TIMEOUT & 0x01u);
|
||||
msg->txAborted = static_cast<bool>(packet->header.ERR_JOB_CANCELLED & 0x01u);
|
||||
msg->txInvalidBus = static_cast<bool>(packet->header.ERR_INVALID_BUS & 0x01u);
|
||||
msg->txInvalidPhyAddr = static_cast<bool>(packet->header.ERR_INVALID_PHYADDR & 0x01u);
|
||||
msg->txInvalidRegAddr = static_cast<bool>(packet->header.ERR_INVALID_REGADDR & 0x01u);
|
||||
msg->txInvalidClause = static_cast<bool>(packet->header.ERR_UNSUPPORTED_CLAUSE & 0x01u);
|
||||
msg->txInvalidOpcode = static_cast<bool>(packet->header.ERR_UNSUPPORTED_OPCODE & 0x01u);
|
||||
//We don't care about 0xTRB0Dx in this case...
|
||||
//copy 0xTRB0STAT even though we likely won't use it either
|
||||
msg->description = packet->stats;
|
||||
msg->timestamp = (packet->timestamp & (0x7FFFFFFFFFFFFFFFull));
|
||||
|
||||
std::copy(packet->data, packet->data + mdioDataSize, std::back_inserter(msg->data));
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool HardwareMDIOPacket::EncodeFromMessage(const MDIOMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report)
|
||||
{
|
||||
const size_t numDataBytes = message.data.size();
|
||||
if(mdioDataSize < numDataBytes)
|
||||
{
|
||||
report(APIEvent::Type::MDIOMessageExceedsMaxLength, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t st = (message.clause == MDIOMessage::Clause::Clause45) ? 0x0 : 0x1;
|
||||
uint8_t op = (message.direction == MDIOMessage::Direction::Read) ? 0x2 : 0x1;
|
||||
uint8_t phyAddr = message.phyAddress & 0x1F;
|
||||
uint16_t regAddr = (message.clause == MDIOMessage::Clause::Clause45) ? message.regAddress : message.regAddress & 0x1F;
|
||||
uint8_t c45DevType = (message.clause == MDIOMessage::Clause::Clause45) ? message.devAddress & 0x1F : 0;
|
||||
|
||||
bytestream.push_back(static_cast<uint8_t>((message.description >> 8) & 0xFF)); // MSB first
|
||||
bytestream.push_back(static_cast<uint8_t>(message.description & 0xFF)); // LSB
|
||||
bytestream.push_back(op); // opcode
|
||||
bytestream.push_back(st); // st (clause)
|
||||
bytestream.push_back(phyAddr); // st (clause)
|
||||
bytestream.push_back(c45DevType); // clause 45 device type
|
||||
bytestream.push_back(regAddr & 0xFF); // reg addr LSB
|
||||
bytestream.push_back((regAddr >> 8) & 0xFF); // reg addr MSB
|
||||
|
||||
std::copy(message.data.begin(), message.data.end(), std::back_inserter(bytestream));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user