Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHY status API for ethernet drivers #8784

Merged
merged 8 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion cores/esp8266/LwipIntfDev.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@
#define DEFAULT_MTU 1500
#endif

enum EthernetLinkStatus
{
Unknown,
LinkON,
LinkOFF
};

template<class RawDev>
class LwipIntfDev: public LwipIntf, public RawDev
{
Expand Down Expand Up @@ -93,9 +100,11 @@ class LwipIntfDev: public LwipIntf, public RawDev
void setDefault(bool deflt = true);

// true if interface has a valid IPv4 address
// (and ethernet link status is not detectable or is up)
bool connected()
{
return !!ip4_addr_get_u32(ip_2_ip4(&_netif.ip_addr));
return !!ip4_addr_get_u32(ip_2_ip4(&_netif.ip_addr))
&& (!RawDev::isLinkDetectable() || RawDev::isLinked());
}

bool routable()
Expand All @@ -106,6 +115,9 @@ class LwipIntfDev: public LwipIntf, public RawDev
// ESP8266WiFi API compatibility
wl_status_t status();

// Arduino Ethernet compatibility
EthernetLinkStatus linkStatus();

protected:
err_t netif_init();
void check_route();
Expand Down Expand Up @@ -282,6 +294,12 @@ wl_status_t LwipIntfDev<RawDev>::status()
return _started ? (connected() ? WL_CONNECTED : WL_DISCONNECTED) : WL_NO_SHIELD;
}

template<class RawDev>
EthernetLinkStatus LwipIntfDev<RawDev>::linkStatus()
{
return RawDev::isLinkDetectable() ? _started && RawDev::isLinked() ? LinkON : LinkOFF : Unknown;
}

template<class RawDev>
err_t LwipIntfDev<RawDev>::linkoutput_s(netif* netif, struct pbuf* pbuf)
{
Expand Down
2 changes: 2 additions & 0 deletions libraries/lwIP_Ethernet/examples/EthClient/EthClient.ino
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ void loop() {
Serial.print(':');
Serial.println(port);

Serial.printf("Link sense: %d (detectable: %d)\n", eth.isLinked(), eth.isLinkDetectable());

// Use WiFiClient class to create TCP connections
// (this class could have been named TCPClient)
WiFiClient client;
Expand Down
17 changes: 1 addition & 16 deletions libraries/lwIP_Ethernet/src/EthernetCompat.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ using EthernetUDP = WiFiUDP;
using EthernetClient = WiFiClient;
using EthernetServer = ArduinoWiFiServer;

enum EthernetLinkStatus
{
Unknown,
LinkON,
LinkOFF
};

enum
{
DHCP_CHECK_NONE = 0,
Expand All @@ -40,7 +33,6 @@ class ArduinoEthernet: public LwipIntfDev<RawDev>
LwipIntfDev<RawDev>(cs, spi, intr)
{
_hardwareStatus = EthernetNoHardware;
_linkStatus = Unknown;
}

// Arduino-Ethernet API compatibility, order can be either:
Expand Down Expand Up @@ -70,7 +62,6 @@ class ArduinoEthernet: public LwipIntfDev<RawDev>
if (ret)
{
_hardwareStatus = EthernetHardwareFound;
_linkStatus = LinkON;
}

return ret;
Expand All @@ -81,19 +72,13 @@ class ArduinoEthernet: public LwipIntfDev<RawDev>
return _hardwareStatus;
}

EthernetLinkStatus linkStatus() const
{
return _linkStatus;
}

int maintain() const
{
return DHCP_CHECK_NONE;
}

protected:
HardwareStatus _hardwareStatus;
EthernetLinkStatus _linkStatus;
HardwareStatus _hardwareStatus;
};

using ArduinoWiznet5500lwIP = ArduinoEthernet<Wiznet5500>;
Expand Down
37 changes: 37 additions & 0 deletions libraries/lwIP_enc28j60/src/utility/enc28j60.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,24 @@ void serial_printf(const char* fmt, ...)
#define MACONX_BANK 0x02

#define MACON1 0x00
#define MACSTAT1 0x01
#define MACON3 0x02
#define MACON4 0x03
#define MABBIPG 0x04
#define MAIPGL 0x06
#define MAIPGH 0x07
#define MAMXFLL 0x0a
#define MAMXFLH 0x0b
#define MACON2 0x10
#define MACSTAT2 0x11
#define MICMD 0x12
#define MIREGADR 0x14
#define MIRDL 0x18
#define MIRDH 0x19

/* MICMD Register Bit Definitions */
#define MICMD_MIISCAN 0x02
#define MICMD_MIIRD 0x01

#define MACON1_TXPAUS 0x08
#define MACON1_RXPAUS 0x04
Expand All @@ -135,6 +146,9 @@ void serial_printf(const char* fmt, ...)
#define MISTAT 0x0a
#define EREVID 0x12

/* MISTAT Register Bit Definitions */
#define MISTAT_BUSY 0x01

#define EPKTCNT_BANK 0x01
#define ERXFCON 0x18
#define EPKTCNT 0x19
Expand Down Expand Up @@ -720,3 +734,26 @@ uint16_t ENC28J60::readFrameData(uint8_t* buffer, uint16_t framesize)

return _len;
}

uint16_t ENC28J60::phyread(uint8_t reg)
{
// ( https://github.com/JAndrassy/EthernetENC/tree/master/src/utility/enc28j60.h )

setregbank(MACONX_BANK);
writereg(MIREGADR, reg);
writereg(MICMD, MICMD_MIIRD);
// wait until the PHY read completes
while (readreg(MISTAT) & MISTAT_BUSY)
{
delayMicroseconds(15);
}
writereg(MICMD, 0);
return (readreg(MIRDL) | readreg(MIRDH) << 8);
}

bool ENC28J60::isLinked()
{
// ( https://github.com/JAndrassy/EthernetENC/tree/master/src/utility/enc28j60.h )

return !!(phyread(MACSTAT2) & 0x400);
}
17 changes: 17 additions & 0 deletions libraries/lwIP_enc28j60/src/utility/enc28j60.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,21 @@ class ENC28J60
*/
virtual uint16_t readFrame(uint8_t* buffer, uint16_t bufsize);

/**
Check physical link
@return true when physical link is up
*/
bool isLinked();

/**
Report whether ::isLinked() API is implemented
@return true when ::isLinked() API is implemented
*/
constexpr bool isLinkDetectable() const
{
return true;
}

protected:
static constexpr bool interruptIsPossible()
{
Expand Down Expand Up @@ -133,6 +148,8 @@ class ENC28J60
// Previously defined in contiki/core/sys/clock.h
void clock_delay_usec(uint16_t dt);

uint16_t phyread(uint8_t reg);

uint8_t _bank;
int8_t _cs;
SPIClass& _spi;
Expand Down
18 changes: 18 additions & 0 deletions libraries/lwIP_w5100/src/utility/w5100.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ class Wiznet5100
*/
uint16_t readFrame(uint8_t* buffer, uint16_t bufsize);

/**
Check physical link
@return true when physical link is up
*/
bool isLinked() const
{
return true; //XXX TODO
}

/**
Report whether ::isLinked() API is implemented
@return true when ::isLinked() API is implemented
*/
constexpr bool isLinkDetectable() const
{
return false;
}

protected:
static constexpr bool interruptIsPossible()
{
Expand Down
18 changes: 18 additions & 0 deletions libraries/lwIP_w5500/src/utility/w5500.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ class Wiznet5500
*/
uint16_t readFrame(uint8_t* buffer, uint16_t bufsize);

/**
Check physical link
@return true when physical link is up
*/
bool isLinked()
{
return wizphy_getphylink() == PHY_LINK_ON;
}

/**
Report whether ::isLinked() API is implemented
@return true when ::isLinked() API is implemented
*/
constexpr bool isLinkDetectable() const
{
return true;
}

protected:
static constexpr bool interruptIsPossible()
{
Expand Down