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:
Kyle Johannes
2021-12-08 19:07:07 -05:00
committed by Paul Hollinsky
parent 890eb1e1bc
commit 2d1bb381f6
21 changed files with 421 additions and 1 deletions
+1
View File
@@ -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,
+2 -1
View File
@@ -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 {
+2
View File
@@ -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) {}
+5
View File
@@ -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
+9
View File
@@ -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
+1
View File
@@ -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 {