9
9
#include < lwip/dhcp.h>
10
10
11
11
#include < IPAddress.h>
12
+ #include < FunctionalInterrupt.h>
12
13
13
14
#ifdef ESP8266
14
15
#include < user_interface.h> // wifi_get_macaddr()
@@ -21,15 +22,15 @@ boolean Wiznet5500lwIP::begin (SPIparam(SPIClass& spi,) const uint8_t* macAddres
21
22
uint8_t zeros[6 ] = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 };
22
23
if (!macAddress)
23
24
macAddress = zeros;
24
-
25
+
25
26
if (!Wiznet5500::begin (SPIparam (spi,) macAddress))
26
27
return false ;
27
28
_mtu = mtu;
28
29
29
30
switch (start_with_dhclient ())
30
31
{
31
32
case ERR_OK:
32
- return true ;
33
+ break ;
33
34
34
35
case ERR_IF:
35
36
return false ;
@@ -38,19 +39,36 @@ boolean Wiznet5500lwIP::begin (SPIparam(SPIClass& spi,) const uint8_t* macAddres
38
39
netif_remove (&_netif);
39
40
return false ;
40
41
}
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 ;
41
59
}
42
60
43
61
err_t Wiznet5500lwIP::start_with_dhclient ()
44
62
{
45
63
ip4_addr_t ip, mask, gw;
46
-
64
+
47
65
ip4_addr_set_zero (&ip);
48
66
ip4_addr_set_zero (&mask);
49
67
ip4_addr_set_zero (&gw);
50
-
68
+
51
69
_netif.hwaddr_len = sizeof _mac_address;
52
70
memcpy (_netif.hwaddr , _mac_address, sizeof _mac_address);
53
-
71
+
54
72
if (!netif_add (&_netif, &ip, &mask, &gw, this , netif_init_s, ethernet_input))
55
73
return ERR_IF;
56
74
@@ -62,7 +80,7 @@ err_t Wiznet5500lwIP::start_with_dhclient ()
62
80
err_t Wiznet5500lwIP::linkoutput_s (netif *netif, struct pbuf *pbuf)
63
81
{
64
82
Wiznet5500lwIP* ths = (Wiznet5500lwIP*)netif->state ;
65
-
83
+
66
84
#ifdef ESP8266
67
85
if (pbuf->len != pbuf->tot_len || pbuf->next )
68
86
Serial.println (" ERRTOT\r\n " );
@@ -74,7 +92,7 @@ err_t Wiznet5500lwIP::linkoutput_s (netif *netif, struct pbuf *pbuf)
74
92
if (phy_capture)
75
93
phy_capture (ths->_netif .num , (const char *)pbuf->payload , pbuf->len , /* out*/ 1 , /* success*/ len == pbuf->len );
76
94
#endif
77
-
95
+
78
96
return len == pbuf->len ? ERR_OK: ERR_MEM;
79
97
}
80
98
@@ -116,21 +134,21 @@ err_t Wiznet5500lwIP::netif_init ()
116
134
_netif.name [1 ] = ' 0' + _netif.num ;
117
135
_netif.mtu = _mtu;
118
136
_netif.chksum_flags = NETIF_CHECKSUM_ENABLE_ALL;
119
- _netif.flags =
137
+ _netif.flags =
120
138
NETIF_FLAG_ETHARP
121
139
| NETIF_FLAG_IGMP
122
- | NETIF_FLAG_BROADCAST
140
+ | NETIF_FLAG_BROADCAST
123
141
| NETIF_FLAG_LINK_UP;
124
142
125
143
// lwIP's doc: This function typically first resolves the hardware
126
144
// address, then sends the packet. For ethernet physical layer, this is
127
145
// usually lwIP's etharp_output()
128
146
_netif.output = etharp_output;
129
-
147
+
130
148
// lwIP's doc: This function outputs the pbuf as-is on the link medium
131
149
// (this must points to the raw ethernet driver, meaning: us)
132
150
_netif.linkoutput = linkoutput_s;
133
-
151
+
134
152
_netif.status_callback = netif_status_callback_s;
135
153
136
154
return ERR_OK;
@@ -144,55 +162,62 @@ void Wiznet5500lwIP::netif_status_callback ()
144
162
netif_set_default (nullptr );
145
163
}
146
164
147
- err_t Wiznet5500lwIP::loop ()
165
+ err_t Wiznet5500lwIP::handlePackets ()
148
166
{
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 )
163
169
{
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 " );
165
202
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
+ }
180
205
181
- err_t err = _netif.input (pbuf, &_netif);
206
+ err_t err = _netif.input (pbuf, &_netif);
182
207
183
208
#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);
186
211
#endif
187
212
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
194
219
195
- return ERR_OK;
220
+ }
196
221
}
197
222
198
223
void Wiznet5500lwIP::setDefault ()
0 commit comments