Update UIPEthernet library

This commit is contained in:
Henrik Ekblad
2014-10-21 23:44:52 +02:00
parent f71ed97aaa
commit d5ca838371
8 changed files with 106 additions and 48 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
This is UIPEthernet version 1.07
This is UIPEthernet version 1.09
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.
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
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.
If you are running Arduino-IDE 1.5.x use release-version 1.57 or checkout branch 'Arduino_1.5.5'
If you are running Arduino-IDE 1.5.x use release-version 1.59 or checkout branch 'Arduino_1.5.x'
Additional information can be found on the Arduino website: http://www.arduino.cc/en/Hacking/Libraries
+21 -19
View File
@@ -226,6 +226,9 @@ newpacket:
goto newpacket;
}
ready:
#if UIP_CLIENT_TIMER >= 0
u->timer = millis()+UIP_CLIENT_TIMER;
#endif
return size-remain;
}
return -1;
@@ -326,6 +329,7 @@ UIPClient::flush()
void
uipclient_appcall(void)
{
uint16_t send_len = 0;
uip_userdata_t *u = (uip_userdata_t*)uip_conn->appstate;
if (!u && uip_connected())
{
@@ -357,17 +361,16 @@ uipclient_appcall(void)
#endif
if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED)))
{
memhandle newPacket = Enc28J60Network::allocBlock(uip_len);
if (newPacket != NOBLOCK)
for (uint8_t i=0; i < UIP_SOCKET_NUMPACKETS; i++)
{
for (uint8_t i=0; i < UIP_SOCKET_NUMPACKETS; i++)
if (u->packets_in[i] == NOBLOCK)
{
if (u->packets_in[i] == NOBLOCK)
u->packets_in[i] = Enc28J60Network::allocBlock(uip_len);
if (u->packets_in[i] != NOBLOCK)
{
Enc28J60Network::copyPacket(u->packets_in[i],0,UIPEthernetClass::in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len);
if (i == UIP_SOCKET_NUMPACKETS-1)
uip_stop();
Enc28J60Network::copyPacket(newPacket,0,UIPEthernetClass::in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len);
u->packets_in[i] = newPacket;
goto finish_newdata;
}
}
@@ -404,7 +407,7 @@ finish_newdata:
UIPClient::_dumpAllData();
#endif
uip_conn->appstate = NULL;
goto nodata;
goto finish;
}
if (uip_acked())
{
@@ -422,26 +425,25 @@ finish_newdata:
{
if (u->packets_out[1] == NOBLOCK)
{
uip_len = u->out_pos;
if (uip_len > 0)
send_len = u->out_pos;
if (send_len > 0)
{
Enc28J60Network::resizeBlock(u->packets_out[0],0,uip_len);
Enc28J60Network::resizeBlock(u->packets_out[0],0,send_len);
}
}
else
uip_len = Enc28J60Network::blockSize(u->packets_out[0]);
if (uip_len > 0)
send_len = Enc28J60Network::blockSize(u->packets_out[0]);
if (send_len > 0)
{
UIPEthernetClass::uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf;
UIPEthernetClass::uip_packet = Enc28J60Network::allocBlock(UIPEthernetClass::uip_hdrlen+uip_len);
UIPEthernetClass::uip_packet = Enc28J60Network::allocBlock(UIPEthernetClass::uip_hdrlen+send_len);
if (UIPEthernetClass::uip_packet != NOBLOCK)
{
Enc28J60Network::copyPacket(UIPEthernetClass::uip_packet,UIPEthernetClass::uip_hdrlen,u->packets_out[0],0,uip_len);
Enc28J60Network::copyPacket(UIPEthernetClass::uip_packet,UIPEthernetClass::uip_hdrlen,u->packets_out[0],0,send_len);
UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET;
uip_send(uip_appdata,uip_len);
}
return;
}
goto finish;
}
}
// don't close connection unless all outgoing packets are sent
@@ -470,9 +472,9 @@ finish_newdata:
}
}
}
nodata:
UIPEthernetClass::uip_packet = NOBLOCK;
uip_len=0;
finish:
uip_send(uip_appdata,send_len);
uip_len = send_len;
}
uip_userdata_t *
+3
View File
@@ -55,6 +55,9 @@ typedef struct {
memhandle packets_in[UIP_SOCKET_NUMPACKETS];
memhandle packets_out[UIP_SOCKET_NUMPACKETS];
memaddress out_pos;
#if UIP_CLIENT_TIMER >= 0
unsigned long timer;
#endif
} uip_userdata_t;
class UIPClient : public Client {
+44 -15
View File
@@ -45,7 +45,7 @@ uint8_t UIPEthernetClass::packetstate(0);
IPAddress UIPEthernetClass::_dnsServerAddress;
DhcpClass* UIPEthernetClass::_dhcp(NULL);
struct uip_timer UIPEthernetClass::periodic_timer;
unsigned long UIPEthernetClass::periodic_timer;
// Because uIP isn't encapsulated within a class we have to use global
// variables, so we can only have one TCP/IP stack per program.
@@ -183,7 +183,7 @@ UIPEthernetClass::tick()
Enc28J60Network::readPacket(in_packet,0,(uint8_t*)uip_buf,UIP_BUFSIZE);
if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_IP))
{
uip_packet = in_packet;
uip_packet = in_packet; //required for upper_layer_checksum of in_packet!
#ifdef UIPETHERNET_DEBUG
Serial.print(F("readPacket type IP, uip_len: "));
Serial.println(uip_len);
@@ -220,22 +220,50 @@ UIPEthernetClass::tick()
}
}
if (uip_timer_expired(&periodic_timer))
unsigned long now = millis();
#if UIP_CLIENT_TIMER >= 0
boolean periodic = (long)( now - periodic_timer ) >= 0;
for (int i = 0; i < UIP_CONNS; i++)
{
uip_timer_restart(&periodic_timer);
#else
if ((long)( now - periodic_timer ) >= 0)
{
periodic_timer = now + UIP_PERIODIC_TIMER;
for (int i = 0; i < UIP_CONNS; i++)
{
uip_periodic(i);
// If the above function invocation resulted in data that
// should be sent out on the Enc28J60Network, the global variable
// uip_len is set to a value > 0.
if (uip_len > 0)
{
uip_arp_out();
network_send();
}
#endif
uip_conn = &uip_conns[i];
#if UIP_CLIENT_TIMER >= 0
if (periodic)
{
#endif
uip_process(UIP_TIMER);
#if UIP_CLIENT_TIMER >= 0
}
else
{
if ((long)( now - ((uip_userdata_t*)uip_conn->appstate)->timer) >= 0)
uip_process(UIP_POLL_REQUEST);
else
continue;
}
#endif
// If the above function invocation resulted in data that
// should be sent out on the Enc28J60Network, the global variable
// uip_len is set to a value > 0.
if (uip_len > 0)
{
uip_arp_out();
network_send();
}
}
#if UIP_CLIENT_TIMER >= 0
if (periodic)
{
periodic_timer = now + UIP_PERIODIC_TIMER;
#endif
#if UIP_UDP
for (int i = 0; i < UIP_UDP_CONNS; i++)
{
@@ -263,6 +291,7 @@ boolean UIPEthernetClass::network_send()
Serial.println(uip_hdrlen);
#endif
Enc28J60Network::writePacket(uip_packet,0,uip_buf,uip_hdrlen);
packetstate &= ~ UIPETHERNET_SENDPACKET;
goto sendandfree;
}
uip_packet = Enc28J60Network::allocBlock(uip_len);
@@ -286,7 +315,7 @@ sendandfree:
}
void UIPEthernetClass::init(const uint8_t* mac) {
uip_timer_set(&periodic_timer, CLOCK_SECOND / 4);
periodic_timer = millis() + UIP_PERIODIC_TIMER;
Enc28J60Network::init((uint8_t*)mac);
uip_seteth_addr(mac);
+1 -1
View File
@@ -90,7 +90,7 @@ private:
static IPAddress _dnsServerAddress;
static DhcpClass* _dhcp;
static struct uip_timer periodic_timer;
static unsigned long periodic_timer;
static void init(const uint8_t* mac);
static void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
@@ -155,7 +155,7 @@ Enc28J60Network::receivePacket()
// The above does not work. See Rev. B4 Silicon Errata point 6.
if (readReg(EPKTCNT) != 0)
{
uint16_t readPtr = nextPacketPtr+6;
uint16_t readPtr = nextPacketPtr+6 > RXSTOP_INIT ? nextPacketPtr+6-RXSTOP_INIT+RXSTART_INIT : nextPacketPtr+6;
// Set the read pointer to the start of the received packet
writeRegPair(ERDPTL, nextPacketPtr);
// read the next packet pointer
@@ -168,6 +168,20 @@ Enc28J60Network::receivePacket()
// read the receive status (see datasheet page 43)
rxstat = readOp(ENC28J60_READ_BUF_MEM, 0);
//rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
#ifdef ENC28J60DEBUG
Serial.print("receivePacket [");
Serial.print(readPtr,HEX);
Serial.print("-");
Serial.print((readPtr+len) % (RXSTOP_INIT+1),HEX);
Serial.print("], next: ");
Serial.print(nextPacketPtr,HEX);
Serial.print(", stat: ");
Serial.print(rxstat,HEX);
Serial.print(", count: ");
Serial.print(readReg(EPKTCNT));
Serial.print(" -> ");
Serial.println((rxstat & 0x80)!=0 ? "OK" : "failed");
#endif
// decrement the packet counter indicate we are done with this packet
writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
// check CRC and symbol errors (see datasheet page 44, table 7-3):
@@ -215,10 +229,10 @@ Enc28J60Network::sendPacket(memhandle handle)
Serial.print("sendPacket(");
Serial.print(handle);
Serial.print(") [");
Serial.print(start);
Serial.print(start,HEX);
Serial.print("-");
Serial.print(end);
Serial.println("]:");
Serial.print(end,HEX);
Serial.print("]: ");
for (uint16_t i=start; i<=end; i++)
{
Serial.print(readByte(i),HEX);
@@ -248,8 +262,8 @@ uint16_t
Enc28J60Network::setReadPtr(memhandle handle, memaddress position, uint16_t len)
{
memblock *packet = handle == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[handle];
memaddress start = packet->begin + position;
memaddress start = handle == UIP_RECEIVEBUFFERHANDLE && packet->begin + position > RXSTOP_INIT ? packet->begin + position-RXSTOP_INIT+RXSTART_INIT : packet->begin + position;
writeRegPair(ERDPTL, start);
if (len > packet->size - position)
@@ -313,7 +327,8 @@ Enc28J60Network::copyPacket(memhandle dest_pkt, memaddress dest_pos, memhandle s
{
memblock *dest = &blocks[dest_pkt];
memblock *src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt];
enc28J60_mempool_block_move_callback(dest->begin+dest_pos,src->begin+src_pos,len);
memaddress start = src_pkt == UIP_RECEIVEBUFFERHANDLE && src->begin + src_pos > RXSTOP_INIT ? src->begin + src_pos-RXSTOP_INIT+RXSTART_INIT : src->begin + src_pos;
enc28J60_mempool_block_move_callback(dest->begin+dest_pos,start,len);
// Move the RX read pointer to the start of the next received packet
// This frees the memory we just read out
setERXRDPT();
+3 -2
View File
@@ -87,7 +87,7 @@ typedef unsigned short uip_stats_t;
*
* \hideinitializer
*/
#define UIP_CONF_MAX_LISTENPORTS 4
#define UIP_CONF_MAX_LISTENPORTS 1
/**
* uIP buffer size.
@@ -131,12 +131,13 @@ typedef unsigned short uip_stats_t;
*/
#define UIP_CONF_LOGGING 0
#define UIP_CONF_UDP 0
/**
* UDP support on or off
* (see uipethernet-conf.h)
* \hideinitializer
*
* #define UIP_CONF_UDP 1
*
* #define UIP_CONF_UDP_CONNS 4
*/
@@ -5,8 +5,9 @@
#define UIP_SOCKET_NUMPACKETS 5
#define UIP_CONF_MAX_CONNECTIONS 4
/* for UDP */
#define UIP_CONF_UDP 0
/* for UDP
* set UIP_CONF_UDP to 0 to disable UDP (saves aprox. 5kb flash) */
#define UIP_CONF_UDP 1
#define UIP_CONF_BROADCAST 1
#define UIP_CONF_UDP_CONNS 4
@@ -18,4 +19,11 @@
* if set to a number <= 0 connect will timeout when uIP does (which might be longer than you expect...) */
#define UIP_CONNECT_TIMEOUT -1
/* periodic timer for uip (in ms) */
#define UIP_PERIODIC_TIMER 250
/* timer to poll client for data after last write (in ms)
* set to -1 to disable fast polling and rely on periodic only (saves 100 bytes flash) */
#define UIP_CLIENT_TIMER 10
#endif