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 PascalCasev0.3.0-dev
parent
890eb1e1bc
commit
2d1bb381f6
|
|
@ -129,11 +129,13 @@ endforeach()
|
|||
set(SRC_FILES
|
||||
communication/message/flexray/control/flexraycontrolmessage.cpp
|
||||
communication/message/neomessage.cpp
|
||||
communication/message/ethphymessage.cpp
|
||||
communication/packet/flexraypacket.cpp
|
||||
communication/packet/canpacket.cpp
|
||||
communication/packet/ethernetpacket.cpp
|
||||
communication/packet/versionpacket.cpp
|
||||
communication/packet/iso9141packet.cpp
|
||||
communication/packet/ethphyregpacket.cpp
|
||||
communication/decoder.cpp
|
||||
communication/encoder.cpp
|
||||
communication/ethernetpacketizer.cpp
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ static constexpr const char* ONLINE_NOT_SUPPORTED = "This device does not suppor
|
|||
static constexpr const char* TERMINATION_NOT_SUPPORTED_DEVICE = "This device does not support software selectable termination.";
|
||||
static constexpr const char* TERMINATION_NOT_SUPPORTED_NETWORK = "This network does not support software selectable termination on this device.";
|
||||
static constexpr const char* ANOTHER_IN_TERMINATION_GROUP_ENABLED = "A mutually exclusive network already has termination enabled.";
|
||||
static constexpr const char* ETH_PHY_REGISTER_CONTROL_NOT_AVAILABLE = "Ethernet PHY register control is not available for this device.";
|
||||
|
||||
// Transport Errors
|
||||
static constexpr const char* FAILED_TO_READ = "A read operation failed.";
|
||||
|
|
@ -211,6 +212,8 @@ const char* APIEvent::DescriptionForType(Type type) {
|
|||
return NO_SERIAL_NUMBER_12V;
|
||||
case Type::NoSerialNumberFW12V:
|
||||
return NO_SERIAL_NUMBER_FW_12V;
|
||||
case Type::EthPhyRegisterControlNotAvailable:
|
||||
return ETH_PHY_REGISTER_CONTROL_NOT_AVAILABLE;
|
||||
|
||||
// Transport Errors
|
||||
case Type::FailedToRead:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include "icsneo/api/eventmanager.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/device/extensions/deviceextension.h"
|
||||
#include "icsneo/platform/optional.h"
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
|
@ -786,4 +787,35 @@ APIEvent::Type Device::getCommunicationNotEstablishedError() {
|
|||
void Device::updateLEDState() {
|
||||
std::vector<uint8_t> args {(uint8_t) ledState};
|
||||
com->sendCommand(Command::UpdateLEDState, args);
|
||||
}
|
||||
|
||||
optional<EthPhyMessage> Device::sendEthPhyMsg(const EthPhyMessage& message, std::chrono::milliseconds timeout) {
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return nullopt;
|
||||
}
|
||||
if(!getEthPhyRegControlSupported()) {
|
||||
report(APIEvent::Type::EthPhyRegisterControlNotAvailable, APIEvent::Severity::Error);
|
||||
return nullopt;
|
||||
}
|
||||
if(!isOnline()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> bytes;
|
||||
HardwareEthernetPhyRegisterPacket::EncodeFromMessage(message, bytes, report);
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
[this, bytes](){ return com->sendCommand(Command::PHYControlRegisters, bytes); },
|
||||
std::make_shared<MessageFilter>(Network::NetID::EthPHYControl), timeout);
|
||||
|
||||
if(!response) {
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||
return nullopt;
|
||||
}
|
||||
auto retMsg = std::static_pointer_cast<EthPhyMessage>(response);
|
||||
if(!retMsg) {
|
||||
return nullopt;
|
||||
}
|
||||
return make_optional<EthPhyMessage>(*retMsg);
|
||||
}
|
||||
|
|
@ -79,6 +79,7 @@ public:
|
|||
NoSerialNumberFW = 0x2027, // A firmware update was already attempted
|
||||
NoSerialNumber12V = 0x2028, // The device must be powered with 12V for communication to be established
|
||||
NoSerialNumberFW12V = 0x2029, // The device must be powered with 12V for communication to be established, a firmware update was already attempted
|
||||
EthPhyRegisterControlNotAvailable = 0x2030, //The device doesn't support Ethernet PHY MDIO access
|
||||
|
||||
// Transport Events
|
||||
FailedToRead = 0x3000,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ enum class Command : uint8_t {
|
|||
GetVBattReq = 0xDF, // Previously known as RED_CMD_VBATT_REQUEST
|
||||
MiscControl = 0xE7,
|
||||
Extended = 0xF0,
|
||||
FlexRayControl = 0xF3
|
||||
FlexRayControl = 0xF3,
|
||||
PHYControlRegisters = 0xEF
|
||||
};
|
||||
|
||||
enum class ExtendedCommand : uint16_t {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ public:
|
|||
bool encode(const Packetizer& packetizer, std::vector<uint8_t>& result, Command cmd, std::vector<uint8_t> arguments = {});
|
||||
|
||||
bool supportCANFD = false;
|
||||
bool supportEthPhy = false;
|
||||
|
||||
private:
|
||||
device_eventhandler_t report;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef __ETHPHYMESSAGE_H__
|
||||
#define __ETHPHYMESSAGE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/packet/ethphyregpacket.h"
|
||||
#include "icsneo/communication/message/message.h"
|
||||
#include "icsneo/communication/packet.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct Clause22Message
|
||||
{
|
||||
uint8_t phyAddr;
|
||||
uint8_t page;
|
||||
uint16_t regAddr;
|
||||
uint16_t regVal;
|
||||
};
|
||||
|
||||
struct Clause45Message
|
||||
{
|
||||
uint8_t port;
|
||||
uint8_t device;
|
||||
uint16_t regAddr;
|
||||
uint16_t regVal;
|
||||
};
|
||||
|
||||
struct PhyMessage
|
||||
{
|
||||
bool Enabled;
|
||||
bool WriteEnable;
|
||||
bool Clause45Enable;
|
||||
uint8_t version;
|
||||
union
|
||||
{
|
||||
Clause22Message clause22;
|
||||
Clause45Message clause45;
|
||||
};
|
||||
};
|
||||
|
||||
//Internal message which provides an interface with device ethernet PHY registers,
|
||||
//with Clause22 and Clause45 message support
|
||||
class EthPhyMessage : public Message {
|
||||
public:
|
||||
EthPhyMessage() : Message(Message::Type::EthernetPhyRegister) {}
|
||||
bool appendPhyMessage(bool writeEnable, bool clause45, uint8_t phyAddrOrPort, uint8_t pageOrDevice, uint16_t regAddr, uint16_t regVal = 0x0000u, bool enabled = true);
|
||||
bool appendPhyMessage(std::shared_ptr<PhyMessage> message);
|
||||
size_t getMessageCount() const;
|
||||
|
||||
std::vector<std::shared_ptr<PhyMessage>> messages;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -26,6 +26,7 @@ public:
|
|||
DeviceVersion = 0x8004,
|
||||
Main51 = 0x8005,
|
||||
FlexRayControl = 0x8006,
|
||||
EthernetPhyRegister = 0x8007,
|
||||
};
|
||||
|
||||
Message(Type t) : type(t) {}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ public:
|
|||
HSCAN7 = 97,
|
||||
LIN6 = 98,
|
||||
LSFTCAN2 = 99,
|
||||
EthPHYControl = 239,
|
||||
FlexRayControl = 243,
|
||||
HW_COM_Latency_Test = 512,
|
||||
DeviceStatus = 513,
|
||||
|
|
@ -270,6 +271,7 @@ public:
|
|||
case NetID::FlexRayControl:
|
||||
case NetID::Main51:
|
||||
case NetID::ReadSettings:
|
||||
case NetID::EthPHYControl:
|
||||
return Type::Internal;
|
||||
case NetID::Invalid:
|
||||
case NetID::Any:
|
||||
|
|
@ -504,6 +506,8 @@ public:
|
|||
return "LIN 6";
|
||||
case NetID::LSFTCAN2:
|
||||
return "LSFTCAN 2";
|
||||
case NetID::EthPHYControl:
|
||||
return "Ethernet PHY Register Control";
|
||||
case NetID::FlexRayControl:
|
||||
return "FlexRay Control";
|
||||
case NetID::HW_COM_Latency_Test:
|
||||
|
|
@ -902,6 +906,7 @@ private:
|
|||
#define ICSNEO_NETID_HSCAN7 97
|
||||
#define ICSNEO_NETID_LIN6 98
|
||||
#define ICSNEO_NETID_LSFTCAN2 99
|
||||
#define ICSNEO_NETID_ETH_PHY_CONTROL 239
|
||||
#define ICSNEO_NETID_FLEXRAY_CONTROL 243
|
||||
#define ICSNEO_NETID_HW_COM_LATENCY_TEST 512
|
||||
#define ICSNEO_NETID_DEVICE_STATUS 513
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
#ifndef __ETHPHYREGPACKET_H__
|
||||
#define __ETHPHYREGPACKET_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/ethphymessage.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace icsneo
|
||||
{
|
||||
|
||||
class Packetizer;
|
||||
class EthPhyMessage;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t numEntries;
|
||||
uint8_t version;
|
||||
uint8_t entryBytes;
|
||||
} PhyRegisterHeader_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t phyAddr; //5 bits
|
||||
uint8_t page; //8 bits
|
||||
uint16_t regAddr; //5 bits
|
||||
uint16_t regVal;
|
||||
} Clause22Message_t; //6 bytes
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t port; //5 bits
|
||||
uint8_t device; //5 bits
|
||||
uint16_t regAddr;
|
||||
uint16_t regVal;
|
||||
} Clause45Message_t; //6 bytes
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16_t Enabled : 1;
|
||||
uint16_t WriteEnable : 1;
|
||||
uint16_t Clause45Enable : 1;
|
||||
uint16_t reserved : 9;
|
||||
uint16_t version : 4;
|
||||
};
|
||||
uint16_t flags;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
Clause22Message_t clause22;
|
||||
Clause45Message_t clause45;
|
||||
};
|
||||
} PhyRegisterPacket_t;
|
||||
|
||||
static constexpr size_t MaxPhyEntries = 128u;
|
||||
static constexpr size_t MaxBytesPhyEntries = MaxPhyEntries * sizeof(PhyRegisterHeader_t);
|
||||
static constexpr uint8_t PhyPacketVersion = 1u;
|
||||
static constexpr uint8_t FiveBits = 0x1Fu;
|
||||
|
||||
struct HardwareEthernetPhyRegisterPacket
|
||||
{
|
||||
static std::shared_ptr<EthPhyMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
|
||||
static bool EncodeFromMessage(const EthPhyMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
#include "icsneo/communication/message/resetstatusmessage.h"
|
||||
#include "icsneo/device/extensions/flexray/controller.h"
|
||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
||||
#include "icsneo/communication/message/ethphymessage.h"
|
||||
#include "icsneo/third-party/concurrentqueue/concurrentqueue.h"
|
||||
#include "icsneo/platform/optional.h"
|
||||
#include "icsneo/platform/nodiscard.h"
|
||||
|
|
@ -224,6 +225,14 @@ public:
|
|||
|
||||
const device_eventhandler_t& getEventHandler() const { return report; }
|
||||
|
||||
/**
|
||||
* Tell whether the current device supports reading and writing
|
||||
* Ethernet PHY registers through MDIO.
|
||||
*/
|
||||
virtual bool getEthPhyRegControlSupported() const { return false; }
|
||||
|
||||
optional<EthPhyMessage> sendEthPhyMsg(const EthPhyMessage& message, std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
|
||||
|
||||
std::shared_ptr<Communication> com;
|
||||
std::unique_ptr<IDeviceSettings> settings;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ public:
|
|||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADGigastar(neodevice_t neodevice) : Device(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
|
|
@ -35,6 +37,7 @@ protected:
|
|||
void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportCANFD = true;
|
||||
encoder.supportEthPhy = true;
|
||||
}
|
||||
|
||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADMoon2(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<FTDI3, RADMoon2Settings>();
|
||||
|
|
@ -80,6 +82,11 @@ protected:
|
|||
packetizer.align16bit = false;
|
||||
}
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportEthPhy = true;
|
||||
}
|
||||
|
||||
void setupDecoder(Decoder& decoder) override {
|
||||
Device::setupDecoder(decoder);
|
||||
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ public:
|
|||
return supportedNetworks;
|
||||
}
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADMoonDuo(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<CDCACM, RADMoonDuoSettings>();
|
||||
|
|
@ -40,6 +42,11 @@ protected:
|
|||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
}
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportEthPhy = true;
|
||||
}
|
||||
|
||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
for(auto& netid : GetSupportedNetworks())
|
||||
rxNetworks.emplace_back(netid);
|
||||
|
|
@ -49,6 +56,7 @@ protected:
|
|||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,10 +40,13 @@ public:
|
|||
productId = PRODUCT_ID;
|
||||
}
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportCANFD = true;
|
||||
encoder.supportEthPhy = true;
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ public:
|
|||
return Device::getProductName();
|
||||
}
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADSupermoon(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<FTDI3, RADSupermoonSettings>();
|
||||
|
|
@ -70,6 +72,11 @@ protected:
|
|||
packetizer.align16bit = false;
|
||||
}
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportEthPhy = true;
|
||||
}
|
||||
|
||||
void setupDecoder(Decoder& decoder) override {
|
||||
Device::setupDecoder(decoder);
|
||||
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
||||
#include "icsneo/communication/message/iso9141message.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/ethphymessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue