Verified ENC and W5100 ethernet modules.

This commit is contained in:
Henrik Ekblad
2015-10-04 17:02:50 +02:00
parent d71a5d567b
commit 7ecc80176d
73 changed files with 10926 additions and 205 deletions
@@ -25,19 +25,8 @@
#include "Enc28J60Network.h"
#include "Arduino.h"
#if ENC28J60_USE_SPILIB
#include <SPI.h>
#endif
extern "C" {
#if defined(ARDUINO_ARCH_AVR)
// AVR-specific code
#include <avr/io.h>
#elif defined(ARDUINO_ARCH_SAM)
// SAM-specific code
#else
// generic, non-platform specific code
#endif
#include <avr/io.h>
#include "enc28j60.h"
#include "uip.h"
}
@@ -51,15 +40,7 @@ extern "C" {
// set CS to 1 = passive
#define CSPASSIVE digitalWrite(ENC28J60_CONTROL_CS, HIGH)
//
#if defined(ARDUINO_ARCH_AVR)
#define waitspi() while(!(SPSR&(1<<SPIF)))
#elif defined(ARDUINO_ARCH_SAM)
#if ENC28J60_CONTROL_CS==BOARD_SPI_SS0 or ENC28J60_CONTROL_CS==BOARD_SPI_SS1 or ENC28J60_CONTROL_CS==BOARD_SPI_SS2 or ENC28J60_CONTROL_CS==BOARD_SPI_SS3
#define ENC28J60_USE_SPILIB_EXT 1
#endif
#endif
uint16_t Enc28J60Network::nextPacketPtr;
uint8_t Enc28J60Network::bank=0xff;
@@ -74,34 +55,25 @@ void Enc28J60Network::init(uint8_t* macaddr)
pinMode(ENC28J60_CONTROL_CS, OUTPUT);
CSPASSIVE; // ss=0
//
#if ENC28J60_USE_SPILIB
SPI.begin();
#if defined(ARDUINO_ARCH_AVR)
// AVR-specific code
SPI.setClockDivider(SPI_CLOCK_DIV2); //results in 8MHZ at 16MHZ system clock.
#elif defined(ARDUINO_ARCH_SAM)
// SAM-specific code
SPI.setClockDivider(10); //defaults to 21 which results in aprox. 4MHZ. A 10 should result in a little more than 8MHZ.
#else
// generic, non-platform specific code
#endif
#else
pinMode(SPI_MOSI, OUTPUT);
pinMode(SPI_SCK, OUTPUT);
pinMode(SPI_MISO, INPUT);
//Hardware SS must be configured as OUTPUT to enable SPI-master (regardless of which pin is configured as ENC28J60_CONTROL_CS)
pinMode(SPI_SS, OUTPUT);
digitalWrite(SPI_MOSI, LOW);
digitalWrite(SPI_SCK, LOW);
/*DDRB |= 1<<PB3 | 1<<PB5; // mosi, sck output
cbi(DDRB,PINB4); // MISO is input
//
cbi(PORTB,PB3); // MOSI low
cbi(PORTB,PB5); // SCK low
*/
//
// initialize SPI interface
// master mode and Fosc/2 clock:
SPCR = (1<<SPE)|(1<<MSTR);
SPSR |= (1<<SPI2X);
#endif
// perform system reset
writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
delay(50);
@@ -326,14 +298,6 @@ uint8_t Enc28J60Network::readByte(uint16_t addr)
writeRegPair(ERDPTL, addr);
CSACTIVE;
#if ENC28J60_USE_SPILIB
// issue read command
SPI.transfer(ENC28J60_READ_BUF_MEM);
// read data
uint8_t c = SPI.transfer(0x00);
CSPASSIVE;
return (c);
#else
// issue read command
SPDR = ENC28J60_READ_BUF_MEM;
waitspi();
@@ -342,7 +306,6 @@ uint8_t Enc28J60Network::readByte(uint16_t addr)
waitspi();
CSPASSIVE;
return (SPDR);
#endif
}
void Enc28J60Network::writeByte(uint16_t addr, uint8_t data)
@@ -350,19 +313,12 @@ void Enc28J60Network::writeByte(uint16_t addr, uint8_t data)
writeRegPair(EWRPTL, addr);
CSACTIVE;
#if ENC28J60_USE_SPILIB
// issue write command
SPI.transfer(ENC28J60_WRITE_BUF_MEM);
// write data
SPI.transfer(data);
#else
// issue write command
SPDR = ENC28J60_WRITE_BUF_MEM;
waitspi();
// write data
SPDR = data;
waitspi();
#endif
CSPASSIVE;
}
@@ -441,20 +397,6 @@ Enc28J60Network::readOp(uint8_t op, uint8_t address)
{
CSACTIVE;
// issue read command
#if ENC28J60_USE_SPILIB
SPI.transfer(op | (address & ADDR_MASK));
// read data
if(address & 0x80)
{
// do dummy read if needed (for mac and mii, see datasheet page 29)
SPI.transfer(0x00);
}
uint8_t c = SPI.transfer(0x00);
// release CS
CSPASSIVE;
return(c);
#else
// issue read command
SPDR = op | (address & ADDR_MASK);
waitspi();
// read data
@@ -469,7 +411,6 @@ Enc28J60Network::readOp(uint8_t op, uint8_t address)
// release CS
CSPASSIVE;
return(SPDR);
#endif
}
void
@@ -477,18 +418,11 @@ Enc28J60Network::writeOp(uint8_t op, uint8_t address, uint8_t data)
{
CSACTIVE;
// issue write command
#if ENC28J60_USE_SPILIB
SPI.transfer(op | (address & ADDR_MASK));
// write data
SPI.transfer(data);
#else
// issue write command
SPDR = op | (address & ADDR_MASK);
waitspi();
// write data
SPDR = data;
waitspi();
#endif
CSPASSIVE;
}
@@ -497,23 +431,15 @@ Enc28J60Network::readBuffer(uint16_t len, uint8_t* data)
{
CSACTIVE;
// issue read command
#if ENC28J60_USE_SPILIB
SPI.transfer(ENC28J60_READ_BUF_MEM);
#else
SPDR = ENC28J60_READ_BUF_MEM;
waitspi();
#endif
while(len)
{
len--;
// read data
#if ENC28J60_USE_SPILIB
*data = SPI.transfer(0x00);
#else
SPDR = 0x00;
waitspi();
*data = SPDR;
#endif
data++;
}
//*data='\0';
@@ -525,24 +451,15 @@ Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data)
{
CSACTIVE;
// issue write command
#if ENC28J60_USE_SPILIB
SPI.transfer(ENC28J60_WRITE_BUF_MEM);
#else
SPDR = ENC28J60_WRITE_BUF_MEM;
waitspi();
#endif
while(len)
{
len--;
// write data
#if ENC28J60_USE_SPILIB
SPI.transfer(*data);
data++;
#else
SPDR = *data;
data++;
waitspi();
#endif
}
CSPASSIVE;
}
@@ -635,40 +552,27 @@ Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t
len = setReadPtr(handle, pos, len)-1;
CSACTIVE;
// issue read command
#if ENC28J60_USE_SPILIB
SPI.transfer(ENC28J60_READ_BUF_MEM);
#else
SPDR = ENC28J60_READ_BUF_MEM;
waitspi();
#endif
uint16_t i;
for (i = 0; i < len; i+=2)
{
// read data
#if ENC28J60_USE_SPILIB
t = SPI.transfer(0x00) << 8;
t += SPI.transfer(0x00);
#else
SPDR = 0x00;
waitspi();
t = SPDR << 8;
SPDR = 0x00;
waitspi();
t += SPDR;
#endif
sum += t;
if(sum < t) {
sum++; /* carry */
}
}
if(i == len) {
#if ENC28J60_USE_SPILIB
t = (SPI.transfer(0x00) << 8) + 0;
#else
SPDR = 0x00;
waitspi();
t = (SPDR << 8) + 0;
#endif
sum += t;
if(sum < t) {
sum++; /* carry */
@@ -27,18 +27,11 @@
#include "mempool.h"
#define ENC28J60_CONTROL_CS SS // this is pin 10 on Uno and pin 53 on Mega256
#if defined(ARDUINO_ARCH_AVR)
// AVR-specific code
#define ENC28J60_CONTROL_CS SS
#define SPI_MOSI MOSI
#define SPI_MISO MISO
#define SPI_SCK SCK
#define SPI_SS SS
#define ENC28J60_USE_SPILIB 0
#elif defined(ARDUINO_ARCH_SAM)
#define ENC28J60_USE_SPILIB 1
#endif
#define UIP_RECEIVEBUFFERHANDLE 0xff
+56 -57
View File
@@ -190,7 +190,7 @@ static u16_t lastport; /* Keeps track of the last port used for
/* Temporary variables. */
u8_t uip_acc32[4];
static u8_t cc, opt;
static u8_t c, opt;
static u16_t tmp16;
/* Structures and definitions. */
@@ -223,7 +223,6 @@ static u16_t tmp16;
/* Macros. */
#undef BUF
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
@@ -379,19 +378,19 @@ uip_udpchksum(void)
void
uip_init(void)
{
for(cc = 0; cc < UIP_LISTENPORTS; ++cc) {
uip_listenports[cc] = 0;
for(c = 0; c < UIP_LISTENPORTS; ++c) {
uip_listenports[c] = 0;
}
for(cc = 0; cc < UIP_CONNS; ++cc) {
uip_conns[cc].tcpstateflags = UIP_CLOSED;
for(c = 0; c < UIP_CONNS; ++c) {
uip_conns[c].tcpstateflags = UIP_CLOSED;
}
#if UIP_ACTIVE_OPEN
lastport = 1024;
#endif /* UIP_ACTIVE_OPEN */
#if UIP_UDP
for(cc = 0; cc < UIP_UDP_CONNS; ++cc) {
uip_udp_conns[cc].lport = 0;
for(c = 0; c < UIP_UDP_CONNS; ++c) {
uip_udp_conns[c].lport = 0;
}
#endif /* UIP_UDP */
@@ -419,8 +418,8 @@ uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
/* Check if this port is already in use, and if so try to find
another one. */
for(cc = 0; cc < UIP_CONNS; ++cc) {
conn = &uip_conns[cc];
for(c = 0; c < UIP_CONNS; ++c) {
conn = &uip_conns[c];
if(conn->tcpstateflags != UIP_CLOSED &&
conn->lport == htons(lastport)) {
goto again;
@@ -428,8 +427,8 @@ uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
}
conn = 0;
for(cc = 0; cc < UIP_CONNS; ++cc) {
cconn = &uip_conns[cc];
for(c = 0; c < UIP_CONNS; ++c) {
cconn = &uip_conns[c];
if(cconn->tcpstateflags == UIP_CLOSED) {
conn = cconn;
break;
@@ -483,17 +482,17 @@ uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
lastport = 4096;
}
for(cc = 0; cc < UIP_UDP_CONNS; ++cc) {
if(uip_udp_conns[cc].lport == htons(lastport)) {
for(c = 0; c < UIP_UDP_CONNS; ++c) {
if(uip_udp_conns[c].lport == htons(lastport)) {
goto again;
}
}
conn = 0;
for(cc = 0; cc < UIP_UDP_CONNS; ++cc) {
if(uip_udp_conns[cc].lport == 0) {
conn = &uip_udp_conns[cc];
for(c = 0; c < UIP_UDP_CONNS; ++c) {
if(uip_udp_conns[c].lport == 0) {
conn = &uip_udp_conns[c];
break;
}
}
@@ -518,9 +517,9 @@ uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
void
uip_unlisten(u16_t port)
{
for(cc = 0; cc < UIP_LISTENPORTS; ++cc) {
if(uip_listenports[cc] == port) {
uip_listenports[cc] = 0;
for(c = 0; c < UIP_LISTENPORTS; ++c) {
if(uip_listenports[c] == port) {
uip_listenports[c] = 0;
return;
}
}
@@ -529,9 +528,9 @@ uip_unlisten(u16_t port)
void
uip_listen(u16_t port)
{
for(cc = 0; cc < UIP_LISTENPORTS; ++cc) {
if(uip_listenports[cc] == 0) {
uip_listenports[cc] = port;
for(c = 0; c < UIP_LISTENPORTS; ++c) {
if(uip_listenports[c] == 0) {
uip_listenports[c] = port;
return;
}
}
@@ -1207,8 +1206,8 @@ uip_process(u8_t flag)
tmp16 = BUF->destport;
/* Next, check listening connections. */
for(cc = 0; cc < UIP_LISTENPORTS; ++cc) {
if(tmp16 == uip_listenports[cc])
for(c = 0; c < UIP_LISTENPORTS; ++c) {
if(tmp16 == uip_listenports[c])
goto found_listen;
}
@@ -1228,21 +1227,21 @@ uip_process(u8_t flag)
BUF->tcpoffset = 5 << 4;
/* Flip the seqno and ackno fields in the TCP header. */
cc = BUF->seqno[3];
c = BUF->seqno[3];
BUF->seqno[3] = BUF->ackno[3];
BUF->ackno[3] = cc;
BUF->ackno[3] = c;
cc = BUF->seqno[2];
c = BUF->seqno[2];
BUF->seqno[2] = BUF->ackno[2];
BUF->ackno[2] = cc;
BUF->ackno[2] = c;
cc = BUF->seqno[1];
c = BUF->seqno[1];
BUF->seqno[1] = BUF->ackno[1];
BUF->ackno[1] = cc;
BUF->ackno[1] = c;
cc = BUF->seqno[0];
c = BUF->seqno[0];
BUF->seqno[0] = BUF->ackno[0];
BUF->ackno[0] = cc;
BUF->ackno[0] = c;
/* We also have to increase the sequence number we are
acknowledging. If the least significant byte overflowed, we need
@@ -1278,15 +1277,15 @@ uip_process(u8_t flag)
CLOSED connections are found. Thanks to Eddie C. Dost for a very
nice algorithm for the TIME_WAIT search. */
uip_connr = 0;
for(cc = 0; cc < UIP_CONNS; ++cc) {
if(uip_conns[cc].tcpstateflags == UIP_CLOSED) {
uip_connr = &uip_conns[cc];
for(c = 0; c < UIP_CONNS; ++c) {
if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
uip_connr = &uip_conns[c];
break;
}
if(uip_conns[cc].tcpstateflags == UIP_TIME_WAIT) {
if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
if(uip_connr == 0 ||
uip_conns[cc].timer > uip_connr->timer) {
uip_connr = &uip_conns[cc];
uip_conns[c].timer > uip_connr->timer) {
uip_connr = &uip_conns[c];
}
}
}
@@ -1326,19 +1325,19 @@ uip_process(u8_t flag)
/* Parse the TCP MSS option, if present. */
if((BUF->tcpoffset & 0xf0) > 0x50) {
for(cc = 0; cc < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + cc];
for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
if(opt == TCP_OPT_END) {
/* End of options. */
break;
} else if(opt == TCP_OPT_NOOP) {
++cc;
++c;
/* NOP option. */
} else if(opt == TCP_OPT_MSS &&
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc] == TCP_OPT_MSS_LEN) {
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
/* An MSS option with the right option length. */
tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + cc] << 8) |
(u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + cc];
tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
(u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
uip_connr->initialmss = uip_connr->mss =
tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
@@ -1347,12 +1346,12 @@ uip_process(u8_t flag)
} else {
/* All other options have a length field, so that we easily
can skip past them. */
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc] == 0) {
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
/* If the length field is zero, the options are malformed
and we don't process them further. */
break;
}
cc += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc];
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
}
}
}
@@ -1396,11 +1395,11 @@ uip_process(u8_t flag)
}
/* Calculated the length of the data, if the application has sent
any data to us. */
cc = (BUF->tcpoffset >> 4) << 2;
c = (BUF->tcpoffset >> 4) << 2;
/* uip_len will contain the length of the actual TCP data. This is
calculated by subtracing the length of the TCP header (in
c) and the length of the IP header (20 bytes). */
uip_len = uip_len - cc - UIP_IPH_LEN;
uip_len = uip_len - c - UIP_IPH_LEN;
/* First, check if the sequence number of the incoming packet is
what we're expecting next. If not, we send out an ACK with the
@@ -1495,19 +1494,19 @@ uip_process(u8_t flag)
/* Parse the TCP MSS option, if present. */
if((BUF->tcpoffset & 0xf0) > 0x50) {
for(cc = 0; cc < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + cc];
for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
if(opt == TCP_OPT_END) {
/* End of options. */
break;
} else if(opt == TCP_OPT_NOOP) {
++cc;
++c;
/* NOP option. */
} else if(opt == TCP_OPT_MSS &&
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc] == TCP_OPT_MSS_LEN) {
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
/* An MSS option with the right option length. */
tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + cc] << 8) |
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + cc];
tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
uip_connr->initialmss =
uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
@@ -1516,12 +1515,12 @@ uip_process(u8_t flag)
} else {
/* All other options have a length field, so that we easily
can skip past them. */
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc] == 0) {
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
/* If the length field is zero, the options are malformed
and we don't process them further. */
break;
}
cc += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + cc];
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
}
}
}
-1
View File
@@ -113,7 +113,6 @@ static u8_t i, c;
static u8_t arptime;
static u8_t tmpage;
#undef BUF
#define BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
/*-----------------------------------------------------------------------------------*/
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef UIP_DEBUG_H
#define UIP_DEBUG_H
extern "C" {
#include "utility/uip.h"
#import "utility/uip.h"
}
class UIPDebug {
-1
View File
@@ -2,7 +2,6 @@
#define UTIL_H
#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )
#undef ntohs
#define ntohs(x) htons(x)
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \