Skip to content
This repository was archived by the owner on Dec 23, 2020. It is now read-only.

Commit b468cc8

Browse files
committed
transparent polling
This is *dependant* on this esp8266 arduino core pull request: esp8266/Arduino#6039 Fix #3 (comment)
1 parent 81fd79b commit b468cc8

File tree

2 files changed

+85
-58
lines changed

2 files changed

+85
-58
lines changed

w5500-lwIP.cpp

Lines changed: 76 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <lwip/dhcp.h>
1010

1111
#include <IPAddress.h>
12+
#include <FunctionalInterrupt.h>
1213

1314
#ifdef ESP8266
1415
#include <user_interface.h> // wifi_get_macaddr()
@@ -21,15 +22,15 @@ boolean Wiznet5500lwIP::begin (SPIparam(SPIClass& spi,) const uint8_t* macAddres
2122
uint8_t zeros[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2223
if (!macAddress)
2324
macAddress = zeros;
24-
25+
2526
if (!Wiznet5500::begin(SPIparam(spi,) macAddress))
2627
return false;
2728
_mtu = mtu;
2829

2930
switch (start_with_dhclient())
3031
{
3132
case ERR_OK:
32-
return true;
33+
break;
3334

3435
case ERR_IF:
3536
return false;
@@ -38,19 +39,36 @@ boolean Wiznet5500lwIP::begin (SPIparam(SPIClass& spi,) const uint8_t* macAddres
3839
netif_remove(&_netif);
3940
return false;
4041
}
42+
43+
if (_intrPin >= 0)
44+
{
45+
::printf((PGM_P)F("w500-lwIP: Interrupt not implemented yet, enabling transparent polling\r\n"));
46+
// still need to enable interrupt in wiznet driver
47+
_intrPin = -1;
48+
}
49+
50+
if (_intrPin >= 0)
51+
attachInterrupt(_intrPin, [&]() { this->handlePackets(); }, FALLING);
52+
else if (!schedule_function_us([&]() { this->handlePackets(); return true; }, 100))
53+
{
54+
netif_remove(&_netif);
55+
return false;
56+
}
57+
58+
return true;
4159
}
4260

4361
err_t Wiznet5500lwIP::start_with_dhclient ()
4462
{
4563
ip4_addr_t ip, mask, gw;
46-
64+
4765
ip4_addr_set_zero(&ip);
4866
ip4_addr_set_zero(&mask);
4967
ip4_addr_set_zero(&gw);
50-
68+
5169
_netif.hwaddr_len = sizeof _mac_address;
5270
memcpy(_netif.hwaddr, _mac_address, sizeof _mac_address);
53-
71+
5472
if (!netif_add(&_netif, &ip, &mask, &gw, this, netif_init_s, ethernet_input))
5573
return ERR_IF;
5674

@@ -62,7 +80,7 @@ err_t Wiznet5500lwIP::start_with_dhclient ()
6280
err_t Wiznet5500lwIP::linkoutput_s (netif *netif, struct pbuf *pbuf)
6381
{
6482
Wiznet5500lwIP* ths = (Wiznet5500lwIP*)netif->state;
65-
83+
6684
#ifdef ESP8266
6785
if (pbuf->len != pbuf->tot_len || pbuf->next)
6886
Serial.println("ERRTOT\r\n");
@@ -74,7 +92,7 @@ err_t Wiznet5500lwIP::linkoutput_s (netif *netif, struct pbuf *pbuf)
7492
if (phy_capture)
7593
phy_capture(ths->_netif.num, (const char*)pbuf->payload, pbuf->len, /*out*/1, /*success*/len == pbuf->len);
7694
#endif
77-
95+
7896
return len == pbuf->len? ERR_OK: ERR_MEM;
7997
}
8098

@@ -116,21 +134,21 @@ err_t Wiznet5500lwIP::netif_init ()
116134
_netif.name[1] = '0' + _netif.num;
117135
_netif.mtu = _mtu;
118136
_netif.chksum_flags = NETIF_CHECKSUM_ENABLE_ALL;
119-
_netif.flags =
137+
_netif.flags =
120138
NETIF_FLAG_ETHARP
121139
| NETIF_FLAG_IGMP
122-
| NETIF_FLAG_BROADCAST
140+
| NETIF_FLAG_BROADCAST
123141
| NETIF_FLAG_LINK_UP;
124142

125143
// lwIP's doc: This function typically first resolves the hardware
126144
// address, then sends the packet. For ethernet physical layer, this is
127145
// usually lwIP's etharp_output()
128146
_netif.output = etharp_output;
129-
147+
130148
// lwIP's doc: This function outputs the pbuf as-is on the link medium
131149
// (this must points to the raw ethernet driver, meaning: us)
132150
_netif.linkoutput = linkoutput_s;
133-
151+
134152
_netif.status_callback = netif_status_callback_s;
135153

136154
return ERR_OK;
@@ -144,55 +162,62 @@ void Wiznet5500lwIP::netif_status_callback ()
144162
netif_set_default(nullptr);
145163
}
146164

147-
err_t Wiznet5500lwIP::loop ()
165+
err_t Wiznet5500lwIP::handlePackets ()
148166
{
149-
uint16_t tot_len = readFrameSize();
150-
if (!tot_len)
151-
return ERR_OK;
152-
153-
// from doc: use PBUF_RAM for TX, PBUF_POOL from RX
154-
// however:
155-
// PBUF_POOL can return chained pbuf (not in one piece)
156-
// and WiznetDriver does not have the proper API to deal with that
157-
// so in the meantime, we use PBUF_RAM instead which is currently
158-
// guarantying to deliver a continuous chunk of memory.
159-
// TODO: tweak the wiznet driver to allow copying partial chunk
160-
// of received data and use PBUF_POOL.
161-
pbuf* pbuf = pbuf_alloc(PBUF_RAW, tot_len, PBUF_RAM);
162-
if (!pbuf || pbuf->len < tot_len)
167+
int pkt = 0;
168+
while(1)
163169
{
164-
if (pbuf)
170+
if (++pkt == 10)
171+
// prevent starvation
172+
return ERR_OK;
173+
174+
uint16_t tot_len = readFrameSize();
175+
if (!tot_len)
176+
return ERR_OK;
177+
178+
// from doc: use PBUF_RAM for TX, PBUF_POOL from RX
179+
// however:
180+
// PBUF_POOL can return chained pbuf (not in one piece)
181+
// and WiznetDriver does not have the proper API to deal with that
182+
// so in the meantime, we use PBUF_RAM instead which is currently
183+
// guarantying to deliver a continuous chunk of memory.
184+
// TODO: tweak the wiznet driver to allow copying partial chunk
185+
// of received data and use PBUF_POOL.
186+
pbuf* pbuf = pbuf_alloc(PBUF_RAW, tot_len, PBUF_RAM);
187+
if (!pbuf || pbuf->len < tot_len)
188+
{
189+
if (pbuf)
190+
pbuf_free(pbuf);
191+
discardFrame(tot_len);
192+
return ERR_BUF;
193+
}
194+
195+
uint16_t len = readFrameData((uint8_t*)pbuf->payload, tot_len);
196+
if (len != tot_len)
197+
{
198+
// tot_len is given by readFrameSize()
199+
// and is supposed to be honoured by readFrameData()
200+
// todo: ensure this test is unneeded, remove the print
201+
Serial.println("read error?\r\n");
165202
pbuf_free(pbuf);
166-
discardFrame(tot_len);
167-
return ERR_BUF;
168-
}
169-
170-
uint16_t len = readFrameData((uint8_t*)pbuf->payload, tot_len);
171-
if (len != tot_len)
172-
{
173-
// tot_len is given by readFrameSize()
174-
// and is supposed to be honoured by readFrameData()
175-
// todo: ensure this test is unneeded, remove the print
176-
Serial.println("read error?\r\n");
177-
pbuf_free(pbuf);
178-
return ERR_BUF;
179-
}
203+
return ERR_BUF;
204+
}
180205

181-
err_t err = _netif.input(pbuf, &_netif);
206+
err_t err = _netif.input(pbuf, &_netif);
182207

183208
#if defined(ESP8266) && PHY_HAS_CAPTURE
184-
if (phy_capture)
185-
phy_capture(_netif.num, (const char*)pbuf->payload, tot_len, /*out*/0, /*success*/err == ERR_OK);
209+
if (phy_capture)
210+
phy_capture(_netif.num, (const char*)pbuf->payload, tot_len, /*out*/0, /*success*/err == ERR_OK);
186211
#endif
187212

188-
if (err != ERR_OK)
189-
{
190-
pbuf_free(pbuf);
191-
return err;
192-
}
193-
// (else) allocated pbuf is now on lwIP's responsibility
213+
if (err != ERR_OK)
214+
{
215+
pbuf_free(pbuf);
216+
return err;
217+
}
218+
// (else) allocated pbuf is now on lwIP's responsibility
194219

195-
return ERR_OK;
220+
}
196221
}
197222

198223
void Wiznet5500lwIP::setDefault ()

w5500-lwIP.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,18 @@ class Wiznet5500lwIP: public Wiznet5500 {
2121

2222
public:
2323

24-
Wiznet5500lwIP (int8_t cs = SS):
24+
Wiznet5500lwIP (int8_t cs = SS, int8_t intr = -1):
2525
Wiznet5500(cs),
2626
_mtu(DEFAULT_MTU),
27-
_default(false)
27+
_default(false),
28+
_intrPin(intr)
2829
{
2930
memset(&_netif, 0, sizeof(_netif));
3031
}
3132

3233
// start with dhcp client
33-
// default mac-address is inferred(+modified) from esp8266's STA one
34+
// default mac-address is inferred from esp8266's STA interface
3435
boolean begin (SPIparam(SPIClass& spi,) const uint8_t *macAddress = nullptr, uint16_t mtu = DEFAULT_MTU);
35-
36-
// to be called regularly
37-
err_t loop ();
3836

3937
const netif* getNetIf () const { return &_netif; }
4038

@@ -57,14 +55,18 @@ class Wiznet5500lwIP: public Wiznet5500 {
5755
netif _netif;
5856
uint16_t _mtu;
5957
bool _default;
60-
58+
int8_t _intrPin;
59+
6160
err_t start_with_dhclient ();
6261
err_t netif_init ();
6362
void netif_status_callback ();
6463

6564
static err_t netif_init_s (netif* netif);
6665
static err_t linkoutput_s (netif *netif, struct pbuf *p);
6766
static void netif_status_callback_s (netif* netif);
67+
68+
// called on a regular basis or on interrupt
69+
err_t handlePackets ();
6870
};
6971

7072
#endif // W5500LWIP_H

0 commit comments

Comments
 (0)