Skip to content

Commit

Permalink
Updates - see readme
Browse files Browse the repository at this point in the history
  • Loading branch information
thiseldo committed Dec 24, 2011
1 parent 008ff78 commit d402a53
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 19 deletions.
6 changes: 6 additions & 0 deletions EtherCard.cpp
Expand Up @@ -325,6 +325,12 @@ uint8_t EtherCard::begin (const uint16_t size, const uint8_t* macaddr) {
return initialize(size, mymac);
}

uint8_t EtherCard::begin (const uint16_t size, const uint8_t* macaddr, uint8_t csPin ) {
Stash::initMap(56);
copyMac(mymac, macaddr);
return initialize(size, mymac, csPin);
}

bool EtherCard::staticSetup (const uint8_t* my_ip,
const uint8_t* gw_ip,
const uint8_t* dns_ip) {
Expand Down
2 changes: 2 additions & 0 deletions EtherCard.h
Expand Up @@ -25,6 +25,7 @@

#include <avr/pgmspace.h>
#include "enc28j60.h"
#include "net.h"

typedef struct {
uint8_t count; // number of allocated pages
Expand Down Expand Up @@ -129,6 +130,7 @@ class EtherCard : public Ethernet {
static uint16_t hisport; // tcp port to connect to (default 80)

static uint8_t begin (const uint16_t size, const uint8_t* macaddr);
static uint8_t begin (const uint16_t size, const uint8_t* macaddr, uint8_t csPin );

// tcpip.cpp
static bool staticSetup (const uint8_t* my_ip =0,
Expand Down
24 changes: 21 additions & 3 deletions README.md
Expand Up @@ -4,10 +4,28 @@ Derived from code by Guido Socher and Pascal Stang, hence under GPL2 license.

The home page for this library is <http://jeelabs.org/ethercard>

You can download this project in either
[zip](https://github.com/jcw/ethercard/zipball/master) or
[tar](https://github.com/jcw/ethercard/tarball/master) formats.
This is a development branch and may contain bugs.

Unpack the archive and rename the result to `EtherCard`.
Put it in the `libraries` folder in your Arduino sketches area.
Restart the Arduino IDE to make sure it sees the new files.

Updates by Andrew Lindsay, December 2011:

1. Add alternative begin with 3rd parameter to specify CS pin to use. Only 8, 9 and 10 are usable.
Default without 3rd parameter is pin 8.

2. Updated DHCP to allow broadcast packets to be recieved as some DHCP servers (Some Linux and
Windows DHCP servers) send responses to mac address ff:ff:ff:ff:ff:ff which would otherwise be
filtered out. At end of DHCP process the broadcast filter is returned to block broadcast packets.
ARP broadcasts are not affected as they have their own filter.

3. Cleared up a number of Arduino 1.0 IDE warnings.

4. Experimental - commented out line 609 of tcpip.cpp to no longer terminate client connections
after 1 packet has been received. This is to allow larger packets and streamed data to be received.
However, this may not terminate connections correctly. It needs more work to decide if other host
is wanting to close connection. To remove this feature, remove the comment characters // on line 609.



5 changes: 5 additions & 0 deletions dhcp.cpp
Expand Up @@ -188,6 +188,9 @@ bool EtherCard::dhcpSetup () {
hostname[9] = 'A' + (mymac[5] & 0x0F);
myip[0] = 0; // force invalid IP address

// Enable reception of broadcast packets as some DHCP servers
// use this to send responses
enableBroadcast();
for (byte i = 0; i < 3; ++i) {
dhcpState = DHCP_STATE_INIT;
word start = millis();
Expand All @@ -214,10 +217,12 @@ bool EtherCard::dhcpSetup () {
if (myip[0] != 0) {
if (gwip[0] != 0)
setGwIp(gwip);
disableBroadcast();
return true;
}
}
}
disableBroadcast();
return false;
}

Expand Down
62 changes: 56 additions & 6 deletions enc28j60.cpp
Expand Up @@ -15,6 +15,8 @@
#endif
#include "enc28j60.h"

#define DEFAULT_CS_PIN 8

uint16_t ENC28J60::bufferSize;

// ENC28J60 Control Registers
Expand Down Expand Up @@ -239,8 +241,11 @@ uint16_t ENC28J60::bufferSize;

static byte Enc28j60Bank;
static int16_t gNextPacketPtr;
static uint8_t erxfcon;

#define SELECT_BIT 0 // 0 = B0 = pin 8, 2 = B2 = pin 10
static uint8_t selectBit = SELECT_BIT;

#define FULL_SPEED 1 // use full-speed SPI for bulk transfers

void ENC28J60::initSPI () {
Expand All @@ -264,11 +269,11 @@ void ENC28J60::initSPI () {

static void enableChip () {
cli();
bitClear(PORTB, SELECT_BIT);
bitClear(PORTB, selectBit);
}

static void disableChip () {
bitSet(PORTB, SELECT_BIT);
bitSet(PORTB, selectBit);
sei();
}

Expand Down Expand Up @@ -368,11 +373,15 @@ static void writePhy (byte address, word data) {
}

byte ENC28J60::initialize (word size, const byte* macaddr) {
return initialize( size, macaddr, (uint8_t)DEFAULT_CS_PIN );
}

byte ENC28J60::initialize (word size, const byte* macaddr, uint8_t csPin ) {
bufferSize = size;
if (bitRead(SPCR, SPE) == 0)
initSPI();

bitSet(DDRB, SELECT_BIT);
selectBit = (csPin == 8 ? 0 : 2 );
bitSet(DDRB, selectBit);
disableChip();

writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
Expand All @@ -385,7 +394,10 @@ byte ENC28J60::initialize (word size, const byte* macaddr) {
writeReg(ERXND, RXSTOP_INIT);
writeReg(ETXST, TXSTART_INIT);
writeReg(ETXND, TXSTOP_INIT);
writeRegByte(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
//Change to add ERXFCON_BCEN recommended by epam
erxfcon = ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN;
writeRegByte(ERXFCON, erxfcon);
// writeRegByte(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN);
writeReg(EPMM0, 0x303f);
writeReg(EPMCS, 0xf7f9);
writeRegByte(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
Expand All @@ -406,7 +418,15 @@ byte ENC28J60::initialize (word size, const byte* macaddr) {
writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);

return readRegByte(EREVID);
//return readRegByte(EREVID);
uint8_t rev;
rev=readRegByte(EREVID);
// microchip forgot to step the number on the silcon when they
// released the revision B7. 6 is now rev B7. We still have
// to see what they do when they release B8. At the moment
// there is no B8 out yet
if (rev>5) rev++;
return(rev);
}

bool ENC28J60::isLinkUp() {
Expand Down Expand Up @@ -482,3 +502,33 @@ byte ENC28J60::peekin (byte page, byte off) {
}
return result;
}

// Contributed by Alex M. Based on code from: http://blog.derouineau.fr
// /2011/07/putting-enc28j60-ethernet-controler-in-sleep-mode/
void ENC28J60::powerDown() {
writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);
while(readRegByte(ESTAT) & ESTAT_RXBUSY);
while(readRegByte(ECON1) & ECON1_TXRTS);
writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_VRPS);
writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV);
}

void ENC28J60::powerUp() {
writeOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);
while(!readRegByte(ESTAT) & ESTAT_CLKRDY);
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
}


// Functions to enable/disable broadcast filter bits
// With the bit set, broadcast packets are filtered.
void ENC28J60::enableBroadcast( void ) {
erxfcon |= ERXFCON_BCEN;
writeRegByte(ERXFCON, erxfcon);
}

void ENC28J60::disableBroadcast( void ) {
erxfcon &= (0xff ^ ERXFCON_BCEN);
writeRegByte(ERXFCON, erxfcon);
}

7 changes: 7 additions & 0 deletions enc28j60.h
Expand Up @@ -22,6 +22,7 @@ class ENC28J60 {

static void initSPI ();
static uint8_t initialize (const uint16_t size, const uint8_t* macaddr);
static uint8_t initialize (const uint16_t size, const uint8_t* macaddr, uint8_t csPin );
static bool isLinkUp ();

static void packetSend (uint16_t len);
Expand All @@ -30,6 +31,12 @@ class ENC28J60 {
static void copyout (uint8_t page, const uint8_t* data);
static void copyin (uint8_t page, uint8_t* data);
static uint8_t peekin (uint8_t page, uint8_t off);

static void powerDown(); // contrib by Alex M.
static void powerUp(); // contrib by Alex M.

static void enableBroadcast();
static void disableBroadcast();
};

typedef ENC28J60 Ethernet;
Expand Down
13 changes: 5 additions & 8 deletions examples/JeeUdp/JeeUdp.ino
Expand Up @@ -24,7 +24,6 @@ struct Config {

// ethernet interface mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static char myIpAddr [16];

// buffer for an outgoing data packet
static byte outBuf[RF12_MAXDATA], outDest;
Expand Down Expand Up @@ -83,8 +82,6 @@ void setup (){
if (!ether.dhcpSetup())
Serial.println("DHCP failed");
ether.printIp("IP: ", ether.myip);
sprintf(myIpAddr, "%d.%d.%d.%d",
ether.myip[0], ether.myip[1], ether.myip[2], ether.myip[3]);
}

char okHeader[] PROGMEM =
Expand All @@ -97,11 +94,10 @@ static void homePage (BufferFiller& buf) {
word mhz = config.band == 4 ? 433 : config.band == 8 ? 868 : 915;
buf.emit_p(PSTR("$F\r\n"
"<title>RF12 JeeUdp</title>"
"<h2>RF12 JeeUdp - $S :$D - RF12 @ $D.$D</h2>"
"<h2>RF12 JeeUdp @ $D - RF12 @ $D.$D</h2>"
"<a href='c'>Configure</a> - <a href='s'>Send Packet</a>"
"<h3>Last $D messages:</h3>"
"<pre>"), okHeader, myIpAddr, config.port,
mhz, config.group, NUM_MESSAGES);
"<pre>"), okHeader, config.port, mhz, config.group, NUM_MESSAGES);
for (byte i = 0; i < NUM_MESSAGES; ++i) {
byte j = (next_msg + i) % NUM_MESSAGES;
if (history_len[j] > 0) {
Expand Down Expand Up @@ -165,7 +161,7 @@ static void configPage (const char* data, BufferFiller& buf) {
"Freq band <input type=text name=b value='$D' size=1> (4, 8, or 9)<br>"
"Net group <input type=text name=g value='$D' size=3> (1..250)<br>"
"Collect mode: <input type=checkbox name=c value='1' $S> "
"Don't send ACKs<br><br>"
"(don't send ACKs)<br><br>"
"UDP Port <input type=text name=p value='$D' size=5> (1024..30000)"
"</p>"
"<input type=submit value=Set>"
Expand Down Expand Up @@ -252,7 +248,7 @@ static void forwardToUDP () {
char buf[10];

collPos = 0;
collectStr(0x0000, myIpAddr);
collectStr(0x0000, "JeeUdp");
collectStr(0x0002, "RF12");
word mhz = config.band == 4 ? 433 : config.band == 8 ? 868 : 915;
sprintf(buf, "%d.%d", mhz, config.group);
Expand Down Expand Up @@ -321,3 +317,4 @@ void loop (){
outCount = -1;
}
}

8 changes: 6 additions & 2 deletions tcpip.cpp
Expand Up @@ -245,6 +245,8 @@ static void make_tcp_ack_with_data_noflags(word dlen) {
gPB[TCP_CHECKSUM_H_P] = 0;
gPB[TCP_CHECKSUM_L_P] = 0;
fill_checksum(TCP_CHECKSUM_H_P, IP_SRC_P, 8+TCP_HEADER_LEN_PLAIN+dlen,2);

Serial.println((char*)&gPB[54]);
EtherCard::packetSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlen+ETH_HEADER_LEN);
}

Expand Down Expand Up @@ -523,6 +525,7 @@ static word tcp_datafill_cb(byte fd) {
static byte tcp_result_cb(byte fd, byte status, word datapos, word datalen) {
Serial.println("REPLY:");
Serial.println((char*) ether.buffer + datapos);
return 1;
}

byte EtherCard::tcpSend () {
Expand Down Expand Up @@ -577,7 +580,7 @@ word EtherCard::packetLoop (word plen) {
return 0;
if (gPB[TCP_FLAGS_P] & TCP_FLAGS_RST_V) {
if (client_tcp_result_cb)
(*client_tcp_result_cb)((gPB[TCP_DST_PORT_L_P]>>5)&0x7,3,0,0);
(*client_tcp_result_cb)((gPB[TCP_DST_PORT_L_P]>>5)&0x7,3,0,0);
tcp_client_state = 5;
return 0;
}
Expand All @@ -602,7 +605,8 @@ word EtherCard::packetLoop (word plen) {
return 0;
}
if (tcp_client_state==3 && len>0) {
tcp_client_state = 4;
// Comment out to enable large files, e.g. mp3 streams to be downloaded
// tcp_client_state = 4;
if (client_tcp_result_cb) {
word tcpstart = TCP_DATA_START; // TCP_DATA_START is a formula
if (tcpstart>plen-8)
Expand Down

0 comments on commit d402a53

Please sign in to comment.