Skip to content

Commit d5ca838

Browse files
committed
Update UIPEthernet library
1 parent f71ed97 commit d5ca838

File tree

8 files changed

+106
-48
lines changed

8 files changed

+106
-48
lines changed

libraries/UIPEthernet/README

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
This is UIPEthernet version 1.07
1+
This is UIPEthernet version 1.09
22

33
An plugin-replacement of the stock Arduino Ethernet library for ENC28J60 shields and breakout boards. Full support for persistent (streaming) TCP-connections and UDP (Client and Server each), ARP, ICMP, DHCP and DNS.
44
Just include 'UIPEthernet.h' instead of 'Ethernet.h' and use all your code written for the stock Arduino Ethernet lib!
@@ -28,7 +28,7 @@ On a Mac, you will want to create a folder named "libraries" in in the "Document
2828

2929
Or you download the zipped version of the library from https://github.com/ntruchsess/arduino_uip/releases, and copy the contained directory UIPEthernet to [path to Arduino distribution]\libraries\UIPEthernet.
3030

31-
If you are running Arduino-IDE 1.5.x use release-version 1.57 or checkout branch 'Arduino_1.5.5'
31+
If you are running Arduino-IDE 1.5.x use release-version 1.59 or checkout branch 'Arduino_1.5.x'
3232

3333
Additional information can be found on the Arduino website: http://www.arduino.cc/en/Hacking/Libraries
3434

libraries/UIPEthernet/UIPClient.cpp

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ UIPClient::_write(uip_userdata_t* u, const uint8_t *buf, size_t size)
226226
goto newpacket;
227227
}
228228
ready:
229+
#if UIP_CLIENT_TIMER >= 0
230+
u->timer = millis()+UIP_CLIENT_TIMER;
231+
#endif
229232
return size-remain;
230233
}
231234
return -1;
@@ -326,6 +329,7 @@ UIPClient::flush()
326329
void
327330
uipclient_appcall(void)
328331
{
332+
uint16_t send_len = 0;
329333
uip_userdata_t *u = (uip_userdata_t*)uip_conn->appstate;
330334
if (!u && uip_connected())
331335
{
@@ -357,17 +361,16 @@ uipclient_appcall(void)
357361
#endif
358362
if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED)))
359363
{
360-
memhandle newPacket = Enc28J60Network::allocBlock(uip_len);
361-
if (newPacket != NOBLOCK)
364+
for (uint8_t i=0; i < UIP_SOCKET_NUMPACKETS; i++)
362365
{
363-
for (uint8_t i=0; i < UIP_SOCKET_NUMPACKETS; i++)
366+
if (u->packets_in[i] == NOBLOCK)
364367
{
365-
if (u->packets_in[i] == NOBLOCK)
368+
u->packets_in[i] = Enc28J60Network::allocBlock(uip_len);
369+
if (u->packets_in[i] != NOBLOCK)
366370
{
371+
Enc28J60Network::copyPacket(u->packets_in[i],0,UIPEthernetClass::in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len);
367372
if (i == UIP_SOCKET_NUMPACKETS-1)
368373
uip_stop();
369-
Enc28J60Network::copyPacket(newPacket,0,UIPEthernetClass::in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len);
370-
u->packets_in[i] = newPacket;
371374
goto finish_newdata;
372375
}
373376
}
@@ -404,7 +407,7 @@ uipclient_appcall(void)
404407
UIPClient::_dumpAllData();
405408
#endif
406409
uip_conn->appstate = NULL;
407-
goto nodata;
410+
goto finish;
408411
}
409412
if (uip_acked())
410413
{
@@ -422,26 +425,25 @@ uipclient_appcall(void)
422425
{
423426
if (u->packets_out[1] == NOBLOCK)
424427
{
425-
uip_len = u->out_pos;
426-
if (uip_len > 0)
428+
send_len = u->out_pos;
429+
if (send_len > 0)
427430
{
428-
Enc28J60Network::resizeBlock(u->packets_out[0],0,uip_len);
431+
Enc28J60Network::resizeBlock(u->packets_out[0],0,send_len);
429432
}
430433
}
431434
else
432-
uip_len = Enc28J60Network::blockSize(u->packets_out[0]);
433-
if (uip_len > 0)
435+
send_len = Enc28J60Network::blockSize(u->packets_out[0]);
436+
if (send_len > 0)
434437
{
435438
UIPEthernetClass::uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf;
436-
UIPEthernetClass::uip_packet = Enc28J60Network::allocBlock(UIPEthernetClass::uip_hdrlen+uip_len);
439+
UIPEthernetClass::uip_packet = Enc28J60Network::allocBlock(UIPEthernetClass::uip_hdrlen+send_len);
437440
if (UIPEthernetClass::uip_packet != NOBLOCK)
438441
{
439-
Enc28J60Network::copyPacket(UIPEthernetClass::uip_packet,UIPEthernetClass::uip_hdrlen,u->packets_out[0],0,uip_len);
442+
Enc28J60Network::copyPacket(UIPEthernetClass::uip_packet,UIPEthernetClass::uip_hdrlen,u->packets_out[0],0,send_len);
440443
UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET;
441-
uip_send(uip_appdata,uip_len);
442444
}
443-
return;
444445
}
446+
goto finish;
445447
}
446448
}
447449
// don't close connection unless all outgoing packets are sent
@@ -470,9 +472,9 @@ uipclient_appcall(void)
470472
}
471473
}
472474
}
473-
nodata:
474-
UIPEthernetClass::uip_packet = NOBLOCK;
475-
uip_len=0;
475+
finish:
476+
uip_send(uip_appdata,send_len);
477+
uip_len = send_len;
476478
}
477479

478480
uip_userdata_t *

libraries/UIPEthernet/UIPClient.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ typedef struct {
5555
memhandle packets_in[UIP_SOCKET_NUMPACKETS];
5656
memhandle packets_out[UIP_SOCKET_NUMPACKETS];
5757
memaddress out_pos;
58+
#if UIP_CLIENT_TIMER >= 0
59+
unsigned long timer;
60+
#endif
5861
} uip_userdata_t;
5962

6063
class UIPClient : public Client {

libraries/UIPEthernet/UIPEthernet.cpp

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ uint8_t UIPEthernetClass::packetstate(0);
4545
IPAddress UIPEthernetClass::_dnsServerAddress;
4646
DhcpClass* UIPEthernetClass::_dhcp(NULL);
4747

48-
struct uip_timer UIPEthernetClass::periodic_timer;
48+
unsigned long UIPEthernetClass::periodic_timer;
4949

5050
// Because uIP isn't encapsulated within a class we have to use global
5151
// variables, so we can only have one TCP/IP stack per program.
@@ -183,7 +183,7 @@ UIPEthernetClass::tick()
183183
Enc28J60Network::readPacket(in_packet,0,(uint8_t*)uip_buf,UIP_BUFSIZE);
184184
if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_IP))
185185
{
186-
uip_packet = in_packet;
186+
uip_packet = in_packet; //required for upper_layer_checksum of in_packet!
187187
#ifdef UIPETHERNET_DEBUG
188188
Serial.print(F("readPacket type IP, uip_len: "));
189189
Serial.println(uip_len);
@@ -220,22 +220,50 @@ UIPEthernetClass::tick()
220220
}
221221
}
222222

223-
if (uip_timer_expired(&periodic_timer))
223+
unsigned long now = millis();
224+
225+
#if UIP_CLIENT_TIMER >= 0
226+
boolean periodic = (long)( now - periodic_timer ) >= 0;
227+
for (int i = 0; i < UIP_CONNS; i++)
228+
{
229+
#else
230+
if ((long)( now - periodic_timer ) >= 0)
224231
{
225-
uip_timer_restart(&periodic_timer);
232+
periodic_timer = now + UIP_PERIODIC_TIMER;
233+
226234
for (int i = 0; i < UIP_CONNS; i++)
227235
{
228-
uip_periodic(i);
229-
// If the above function invocation resulted in data that
230-
// should be sent out on the Enc28J60Network, the global variable
231-
// uip_len is set to a value > 0.
232-
if (uip_len > 0)
233-
{
234-
uip_arp_out();
235-
network_send();
236-
}
236+
#endif
237+
uip_conn = &uip_conns[i];
238+
#if UIP_CLIENT_TIMER >= 0
239+
if (periodic)
240+
{
241+
#endif
242+
uip_process(UIP_TIMER);
243+
#if UIP_CLIENT_TIMER >= 0
237244
}
238-
245+
else
246+
{
247+
if ((long)( now - ((uip_userdata_t*)uip_conn->appstate)->timer) >= 0)
248+
uip_process(UIP_POLL_REQUEST);
249+
else
250+
continue;
251+
}
252+
#endif
253+
// If the above function invocation resulted in data that
254+
// should be sent out on the Enc28J60Network, the global variable
255+
// uip_len is set to a value > 0.
256+
if (uip_len > 0)
257+
{
258+
uip_arp_out();
259+
network_send();
260+
}
261+
}
262+
#if UIP_CLIENT_TIMER >= 0
263+
if (periodic)
264+
{
265+
periodic_timer = now + UIP_PERIODIC_TIMER;
266+
#endif
239267
#if UIP_UDP
240268
for (int i = 0; i < UIP_UDP_CONNS; i++)
241269
{
@@ -263,6 +291,7 @@ boolean UIPEthernetClass::network_send()
263291
Serial.println(uip_hdrlen);
264292
#endif
265293
Enc28J60Network::writePacket(uip_packet,0,uip_buf,uip_hdrlen);
294+
packetstate &= ~ UIPETHERNET_SENDPACKET;
266295
goto sendandfree;
267296
}
268297
uip_packet = Enc28J60Network::allocBlock(uip_len);
@@ -286,7 +315,7 @@ boolean UIPEthernetClass::network_send()
286315
}
287316

288317
void UIPEthernetClass::init(const uint8_t* mac) {
289-
uip_timer_set(&periodic_timer, CLOCK_SECOND / 4);
318+
periodic_timer = millis() + UIP_PERIODIC_TIMER;
290319

291320
Enc28J60Network::init((uint8_t*)mac);
292321
uip_seteth_addr(mac);

libraries/UIPEthernet/UIPEthernet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class UIPEthernetClass
9090
static IPAddress _dnsServerAddress;
9191
static DhcpClass* _dhcp;
9292

93-
static struct uip_timer periodic_timer;
93+
static unsigned long periodic_timer;
9494

9595
static void init(const uint8_t* mac);
9696
static void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);

libraries/UIPEthernet/utility/Enc28J60Network.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ Enc28J60Network::receivePacket()
155155
// The above does not work. See Rev. B4 Silicon Errata point 6.
156156
if (readReg(EPKTCNT) != 0)
157157
{
158-
uint16_t readPtr = nextPacketPtr+6;
158+
uint16_t readPtr = nextPacketPtr+6 > RXSTOP_INIT ? nextPacketPtr+6-RXSTOP_INIT+RXSTART_INIT : nextPacketPtr+6;
159159
// Set the read pointer to the start of the received packet
160160
writeRegPair(ERDPTL, nextPacketPtr);
161161
// read the next packet pointer
@@ -168,6 +168,20 @@ Enc28J60Network::receivePacket()
168168
// read the receive status (see datasheet page 43)
169169
rxstat = readOp(ENC28J60_READ_BUF_MEM, 0);
170170
//rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
171+
#ifdef ENC28J60DEBUG
172+
Serial.print("receivePacket [");
173+
Serial.print(readPtr,HEX);
174+
Serial.print("-");
175+
Serial.print((readPtr+len) % (RXSTOP_INIT+1),HEX);
176+
Serial.print("], next: ");
177+
Serial.print(nextPacketPtr,HEX);
178+
Serial.print(", stat: ");
179+
Serial.print(rxstat,HEX);
180+
Serial.print(", count: ");
181+
Serial.print(readReg(EPKTCNT));
182+
Serial.print(" -> ");
183+
Serial.println((rxstat & 0x80)!=0 ? "OK" : "failed");
184+
#endif
171185
// decrement the packet counter indicate we are done with this packet
172186
writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
173187
// check CRC and symbol errors (see datasheet page 44, table 7-3):
@@ -215,10 +229,10 @@ Enc28J60Network::sendPacket(memhandle handle)
215229
Serial.print("sendPacket(");
216230
Serial.print(handle);
217231
Serial.print(") [");
218-
Serial.print(start);
232+
Serial.print(start,HEX);
219233
Serial.print("-");
220-
Serial.print(end);
221-
Serial.println("]:");
234+
Serial.print(end,HEX);
235+
Serial.print("]: ");
222236
for (uint16_t i=start; i<=end; i++)
223237
{
224238
Serial.print(readByte(i),HEX);
@@ -248,8 +262,8 @@ uint16_t
248262
Enc28J60Network::setReadPtr(memhandle handle, memaddress position, uint16_t len)
249263
{
250264
memblock *packet = handle == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[handle];
251-
memaddress start = packet->begin + position;
252-
265+
memaddress start = handle == UIP_RECEIVEBUFFERHANDLE && packet->begin + position > RXSTOP_INIT ? packet->begin + position-RXSTOP_INIT+RXSTART_INIT : packet->begin + position;
266+
253267
writeRegPair(ERDPTL, start);
254268

255269
if (len > packet->size - position)
@@ -313,7 +327,8 @@ Enc28J60Network::copyPacket(memhandle dest_pkt, memaddress dest_pos, memhandle s
313327
{
314328
memblock *dest = &blocks[dest_pkt];
315329
memblock *src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt];
316-
enc28J60_mempool_block_move_callback(dest->begin+dest_pos,src->begin+src_pos,len);
330+
memaddress start = src_pkt == UIP_RECEIVEBUFFERHANDLE && src->begin + src_pos > RXSTOP_INIT ? src->begin + src_pos-RXSTOP_INIT+RXSTART_INIT : src->begin + src_pos;
331+
enc28J60_mempool_block_move_callback(dest->begin+dest_pos,start,len);
317332
// Move the RX read pointer to the start of the next received packet
318333
// This frees the memory we just read out
319334
setERXRDPT();

libraries/UIPEthernet/utility/uip-conf.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ typedef unsigned short uip_stats_t;
8787
*
8888
* \hideinitializer
8989
*/
90-
#define UIP_CONF_MAX_LISTENPORTS 4
90+
#define UIP_CONF_MAX_LISTENPORTS 1
9191

9292
/**
9393
* uIP buffer size.
@@ -131,12 +131,13 @@ typedef unsigned short uip_stats_t;
131131
*/
132132
#define UIP_CONF_LOGGING 0
133133

134+
#define UIP_CONF_UDP 0
134135
/**
135136
* UDP support on or off
136137
* (see uipethernet-conf.h)
137138
* \hideinitializer
138139
*
139-
* #define UIP_CONF_UDP 1
140+
140141
*
141142
* #define UIP_CONF_UDP_CONNS 4
142143
*/

libraries/UIPEthernet/utility/uipethernet-conf.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
#define UIP_SOCKET_NUMPACKETS 5
66
#define UIP_CONF_MAX_CONNECTIONS 4
77

8-
/* for UDP */
9-
#define UIP_CONF_UDP 0
8+
/* for UDP
9+
* set UIP_CONF_UDP to 0 to disable UDP (saves aprox. 5kb flash) */
10+
#define UIP_CONF_UDP 1
1011
#define UIP_CONF_BROADCAST 1
1112
#define UIP_CONF_UDP_CONNS 4
1213

@@ -18,4 +19,11 @@
1819
* if set to a number <= 0 connect will timeout when uIP does (which might be longer than you expect...) */
1920
#define UIP_CONNECT_TIMEOUT -1
2021

22+
/* periodic timer for uip (in ms) */
23+
#define UIP_PERIODIC_TIMER 250
24+
25+
/* timer to poll client for data after last write (in ms)
26+
* set to -1 to disable fast polling and rely on periodic only (saves 100 bytes flash) */
27+
#define UIP_CLIENT_TIMER 10
28+
2129
#endif

0 commit comments

Comments
 (0)