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

Add feature receive Wake-On-Lan WOL on Arduino #429

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
47 changes: 47 additions & 0 deletions examples/receiveWOLPacket/receiveWOLPacket.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Demo receiving WOL magic packets on Arduino, it can be used to send push notifications to Arduino.
rpm based linux: ether-wake 42:41:52:52:59:33
deb based linux: etherwake -i enp1s0 42:41:52:52:59:33 (replace enp1s0 with your network card id)

*/

#include <EtherCard.h>

// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x42, 0x41, 0x52, 0x52, 0x59, 0x33 }; //ASCII: BARRY1
byte Ethernet::buffer[700];
const char hostname[] = "device.example.com";

static uint32_t timer;

void setup () {
Serial.begin(115200);
// Change 'SS' to your Slave Select pin, if you arn't using the default pin
if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0)
Serial.println(F("Failed to access Ethernet controller"));
if (!ether.dhcpSetup(hostname, true))
{
Serial.println(F("DHCP failed"));
}

ether.printIp("IP: ", ether.myip);
ether.printIp("GW: ", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
}

void loop () {
ether.packetLoop(ether.packetReceive());

if (ether.pollWOLInterrupt())
{
wolReceived();
}
}

/* Method called when a WOL magic packet is received
*/
void wolReceived()
{
ether.clearWOLInterrupt();
Serial.println(F("Magic Packet received!"));
}
35 changes: 34 additions & 1 deletion src/enc28j60.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,22 @@ bool ENC28J60::promiscuous_enabled = false;
#define EIR_WOLIF 0x04
#define EIR_TXERIF 0x02
#define EIR_RXERIF 0x01
// ENC28J60 EWOLIE Register Bit Definitions
#define EWOLIE_UCWOLIE 0x80
#define EWOLIE_AWOLIE 0x40
#define EWOLIE_PMWOLIE 0x10
#define EWOLIE_MPWOLIE 0x08
#define EWOLIE_HTWOLIE 0x04
#define EWOLIE_MCWOLIE 0x02
#define EWOLIE_BCWOLIE 0x01
// ENC28J60 EWOLIR Register Bit Definitions
#define EWOLIR_UCWOLIF 0x80
#define EWOLIR_AWOLIF 0x40
#define EWOLIR_PMWOLIF 0x10
#define EWOLIR_MPWOLIF 0x08
#define EWOLIR_HTWOLIF 0x04
#define EWOLIR_MCWOLIF 0x02
#define EWOLIR_BCWOLIF 0x01
// ENC28J60 ESTAT Register Bit Definitions
#define ESTAT_INT 0x80
#define ESTAT_LATECOL 0x10
Expand Down Expand Up @@ -405,7 +421,8 @@ byte ENC28J60::initialize (uint16_t size, const byte* macaddr, byte csPin) {
writeRegByte(MAADR0, macaddr[5]);
writePhy(PHCON2, PHCON2_HDLDIS);
SetBank(ECON1);
writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE|EIE_WOLIE);
writeRegByte(EWOLIE, EWOLIE_MPWOLIE);
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);

byte rev = readRegByte(EREVID);
Expand All @@ -417,6 +434,22 @@ byte ENC28J60::initialize (uint16_t size, const byte* macaddr, byte csPin) {
return rev;
}

void ENC28J60::clearWOLInterrupt () {
writeOp(ENC28J60_BIT_FIELD_CLR, EWOLIR, EWOLIR_MPWOLIF);
writeOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_WOLIF);
}

bool ENC28J60::pollWOLInterrupt () {
if((readRegByte(EWOLIR) & (EWOLIR_MPWOLIF)) == EWOLIR_MPWOLIF)
{
return true;
}
else
{
return false;
}
}

bool ENC28J60::isLinkUp() {
return (readPhyByte(PHSTAT2) >> 2) & 1;
}
Expand Down
8 changes: 8 additions & 0 deletions src/enc28j60.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ class ENC28J60 {
static uint8_t initialize (const uint16_t size, const uint8_t* macaddr,
uint8_t csPin = 8);

/** @brief Clear magic packet WOL interrupt flag
*/
static void clearWOLInterrupt ();

/** @brief Read the WOL interrupt flag
*/
static bool pollWOLInterrupt ();

/** @brief Check if network link is connected
* @return <i>bool</i> True if link is up
*/
Expand Down