mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-02 14:22:55 +03:00
PHY status API for ethernet drivers (#8784)
* PHY status API for W5500 & ENC28J60 drivers * move linkStatus() from ArduinoEthernet:: to LwipIntfDev:: * LwipIntfDev: include PHY status into ::connected()
This commit is contained in:
@ -46,6 +46,13 @@
|
|||||||
#define DEFAULT_MTU 1500
|
#define DEFAULT_MTU 1500
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum EthernetLinkStatus
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
LinkON,
|
||||||
|
LinkOFF
|
||||||
|
};
|
||||||
|
|
||||||
template<class RawDev>
|
template<class RawDev>
|
||||||
class LwipIntfDev: public LwipIntf, public RawDev
|
class LwipIntfDev: public LwipIntf, public RawDev
|
||||||
{
|
{
|
||||||
@ -93,9 +100,11 @@ public:
|
|||||||
void setDefault(bool deflt = true);
|
void setDefault(bool deflt = true);
|
||||||
|
|
||||||
// true if interface has a valid IPv4 address
|
// true if interface has a valid IPv4 address
|
||||||
|
// (and ethernet link status is not detectable or is up)
|
||||||
bool connected()
|
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()
|
bool routable()
|
||||||
@ -106,6 +115,9 @@ public:
|
|||||||
// ESP8266WiFi API compatibility
|
// ESP8266WiFi API compatibility
|
||||||
wl_status_t status();
|
wl_status_t status();
|
||||||
|
|
||||||
|
// Arduino Ethernet compatibility
|
||||||
|
EthernetLinkStatus linkStatus();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
err_t netif_init();
|
err_t netif_init();
|
||||||
void check_route();
|
void check_route();
|
||||||
@ -282,6 +294,12 @@ wl_status_t LwipIntfDev<RawDev>::status()
|
|||||||
return _started ? (connected() ? WL_CONNECTED : WL_DISCONNECTED) : WL_NO_SHIELD;
|
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>
|
template<class RawDev>
|
||||||
err_t LwipIntfDev<RawDev>::linkoutput_s(netif* netif, struct pbuf* pbuf)
|
err_t LwipIntfDev<RawDev>::linkoutput_s(netif* netif, struct pbuf* pbuf)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,8 @@ void loop() {
|
|||||||
Serial.print(':');
|
Serial.print(':');
|
||||||
Serial.println(port);
|
Serial.println(port);
|
||||||
|
|
||||||
|
Serial.printf("Link sense: %d (detectable: %d)\n", eth.isLinked(), eth.isLinkDetectable());
|
||||||
|
|
||||||
// Use WiFiClient class to create TCP connections
|
// Use WiFiClient class to create TCP connections
|
||||||
// (this class could have been named TCPClient)
|
// (this class could have been named TCPClient)
|
||||||
WiFiClient client;
|
WiFiClient client;
|
||||||
|
@ -10,13 +10,6 @@ using EthernetUDP = WiFiUDP;
|
|||||||
using EthernetClient = WiFiClient;
|
using EthernetClient = WiFiClient;
|
||||||
using EthernetServer = ArduinoWiFiServer;
|
using EthernetServer = ArduinoWiFiServer;
|
||||||
|
|
||||||
enum EthernetLinkStatus
|
|
||||||
{
|
|
||||||
Unknown,
|
|
||||||
LinkON,
|
|
||||||
LinkOFF
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
DHCP_CHECK_NONE = 0,
|
DHCP_CHECK_NONE = 0,
|
||||||
@ -40,7 +33,6 @@ public:
|
|||||||
LwipIntfDev<RawDev>(cs, spi, intr)
|
LwipIntfDev<RawDev>(cs, spi, intr)
|
||||||
{
|
{
|
||||||
_hardwareStatus = EthernetNoHardware;
|
_hardwareStatus = EthernetNoHardware;
|
||||||
_linkStatus = Unknown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arduino-Ethernet API compatibility, order can be either:
|
// Arduino-Ethernet API compatibility, order can be either:
|
||||||
@ -70,7 +62,6 @@ public:
|
|||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
_hardwareStatus = EthernetHardwareFound;
|
_hardwareStatus = EthernetHardwareFound;
|
||||||
_linkStatus = LinkON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -81,19 +72,13 @@ public:
|
|||||||
return _hardwareStatus;
|
return _hardwareStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
EthernetLinkStatus linkStatus() const
|
|
||||||
{
|
|
||||||
return _linkStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
int maintain() const
|
int maintain() const
|
||||||
{
|
{
|
||||||
return DHCP_CHECK_NONE;
|
return DHCP_CHECK_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HardwareStatus _hardwareStatus;
|
HardwareStatus _hardwareStatus;
|
||||||
EthernetLinkStatus _linkStatus;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using ArduinoWiznet5500lwIP = ArduinoEthernet<Wiznet5500>;
|
using ArduinoWiznet5500lwIP = ArduinoEthernet<Wiznet5500>;
|
||||||
|
@ -106,6 +106,7 @@ void serial_printf(const char* fmt, ...)
|
|||||||
#define MACONX_BANK 0x02
|
#define MACONX_BANK 0x02
|
||||||
|
|
||||||
#define MACON1 0x00
|
#define MACON1 0x00
|
||||||
|
#define MACSTAT1 0x01
|
||||||
#define MACON3 0x02
|
#define MACON3 0x02
|
||||||
#define MACON4 0x03
|
#define MACON4 0x03
|
||||||
#define MABBIPG 0x04
|
#define MABBIPG 0x04
|
||||||
@ -113,6 +114,16 @@ void serial_printf(const char* fmt, ...)
|
|||||||
#define MAIPGH 0x07
|
#define MAIPGH 0x07
|
||||||
#define MAMXFLL 0x0a
|
#define MAMXFLL 0x0a
|
||||||
#define MAMXFLH 0x0b
|
#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_TXPAUS 0x08
|
||||||
#define MACON1_RXPAUS 0x04
|
#define MACON1_RXPAUS 0x04
|
||||||
@ -135,6 +146,9 @@ void serial_printf(const char* fmt, ...)
|
|||||||
#define MISTAT 0x0a
|
#define MISTAT 0x0a
|
||||||
#define EREVID 0x12
|
#define EREVID 0x12
|
||||||
|
|
||||||
|
/* MISTAT Register Bit Definitions */
|
||||||
|
#define MISTAT_BUSY 0x01
|
||||||
|
|
||||||
#define EPKTCNT_BANK 0x01
|
#define EPKTCNT_BANK 0x01
|
||||||
#define ERXFCON 0x18
|
#define ERXFCON 0x18
|
||||||
#define EPKTCNT 0x19
|
#define EPKTCNT 0x19
|
||||||
@ -720,3 +734,26 @@ uint16_t ENC28J60::readFrameData(uint8_t* buffer, uint16_t framesize)
|
|||||||
|
|
||||||
return _len;
|
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);
|
||||||
|
}
|
||||||
|
@ -79,6 +79,21 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual uint16_t readFrame(uint8_t* buffer, uint16_t bufsize);
|
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:
|
protected:
|
||||||
static constexpr bool interruptIsPossible()
|
static constexpr bool interruptIsPossible()
|
||||||
{
|
{
|
||||||
@ -133,6 +148,8 @@ private:
|
|||||||
// Previously defined in contiki/core/sys/clock.h
|
// Previously defined in contiki/core/sys/clock.h
|
||||||
void clock_delay_usec(uint16_t dt);
|
void clock_delay_usec(uint16_t dt);
|
||||||
|
|
||||||
|
uint16_t phyread(uint8_t reg);
|
||||||
|
|
||||||
uint8_t _bank;
|
uint8_t _bank;
|
||||||
int8_t _cs;
|
int8_t _cs;
|
||||||
SPIClass& _spi;
|
SPIClass& _spi;
|
||||||
|
@ -79,6 +79,24 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint16_t readFrame(uint8_t* buffer, uint16_t bufsize);
|
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:
|
protected:
|
||||||
static constexpr bool interruptIsPossible()
|
static constexpr bool interruptIsPossible()
|
||||||
{
|
{
|
||||||
|
@ -79,6 +79,24 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint16_t readFrame(uint8_t* buffer, uint16_t bufsize);
|
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:
|
protected:
|
||||||
static constexpr bool interruptIsPossible()
|
static constexpr bool interruptIsPossible()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user