33#include "dev/ethernet/enc28j60/enc28j60.h"
39#define PRINTF(...) printf(__VA_ARGS__)
50#define ESTAT_CLKRDY 0x01
51#define ESTAT_TXABRT 0x02
53#define ECON1_RXEN 0x04
54#define ECON1_TXRTS 0x08
56#define ECON2_AUTOINC 0x80
57#define ECON2_PKTDEC 0x40
61#define ERXTX_BANK 0x00
78#define RX_BUF_START 0x0000
79#define RX_BUF_END 0x0fff
81#define TX_BUF_START 0x1200
84#define MACONX_BANK 0x02
95#define MACON1_TXPAUS 0x08
96#define MACON1_RXPAUS 0x04
97#define MACON1_MARXEN 0x01
99#define MACON3_PADCFG_FULL 0xe0
100#define MACON3_TXCRCEN 0x10
101#define MACON3_FRMLNEN 0x02
102#define MACON3_FULDPX 0x01
104#define MAX_MAC_LENGTH 1518
106#define MAADRX_BANK 0x03
116#define EPKTCNT_BANK 0x01
120#define ERXFCON_UCEN 0x80
121#define ERXFCON_ANDOR 0x40
122#define ERXFCON_CRCEN 0x20
123#define ERXFCON_MCEN 0x02
124#define ERXFCON_BCEN 0x01
127PROCESS(enc_watchdog_process,
"Enc28j60 watchdog");
129static uint8_t initialized = 0;
130static uint8_t bank = ERXTX_BANK;
131static uint8_t enc_mac_addr[6];
132static int received_packets = 0;
133static int sent_packets = 0;
137is_mac_mii_reg(uint8_t reg)
144 return reg <= MAADR2 || reg == MISTAT;
156 enc28j60_arch_spi_select();
157 enc28j60_arch_spi_write(0x00 | (reg & 0x1f));
158 if(is_mac_mii_reg(reg)) {
160 enc28j60_arch_spi_read();
162 r = enc28j60_arch_spi_read();
163 enc28j60_arch_spi_deselect();
168writereg(uint8_t reg, uint8_t data)
170 enc28j60_arch_spi_select();
171 enc28j60_arch_spi_write(0x40 | (reg & 0x1f));
172 enc28j60_arch_spi_write(data);
173 enc28j60_arch_spi_deselect();
177setregbitfield(uint8_t reg, uint8_t mask)
179 if(is_mac_mii_reg(reg)) {
180 writereg(reg, readreg(reg) | mask);
182 enc28j60_arch_spi_select();
183 enc28j60_arch_spi_write(0x80 | (reg & 0x1f));
184 enc28j60_arch_spi_write(mask);
185 enc28j60_arch_spi_deselect();
190clearregbitfield(uint8_t reg, uint8_t mask)
192 if(is_mac_mii_reg(reg)) {
193 writereg(reg, readreg(reg) & ~mask);
195 enc28j60_arch_spi_select();
196 enc28j60_arch_spi_write(0xa0 | (reg & 0x1f));
197 enc28j60_arch_spi_write(mask);
198 enc28j60_arch_spi_deselect();
203setregbank(uint8_t new_bank)
205 writereg(ECON1, (readreg(ECON1) & 0xfc) | (new_bank & 0x03));
210writedata(
const uint8_t *data,
int datalen)
213 enc28j60_arch_spi_select();
215 enc28j60_arch_spi_write(0x7a);
216 for(i = 0; i < datalen; i++) {
217 enc28j60_arch_spi_write(data[i]);
219 enc28j60_arch_spi_deselect();
223writedatabyte(uint8_t
byte)
229readdata(uint8_t *buf,
int len)
232 enc28j60_arch_spi_select();
234 enc28j60_arch_spi_write(0x3a);
235 for(i = 0; i < len; i++) {
236 buf[i] = enc28j60_arch_spi_read();
238 enc28j60_arch_spi_deselect();
253 enc28j60_arch_spi_select();
255 enc28j60_arch_spi_write(0xff);
256 enc28j60_arch_spi_deselect();
265 setregbank(MAADRX_BANK);
266 rev = readreg(EREVID);
281 PRINTF(
"enc28j60: resetting chip\n");
283 enc28j60_arch_spi_init();
349 while((readreg(ESTAT) & ESTAT_CLKRDY) == 0);
351 setregbank(ERXTX_BANK);
353 writereg(ERXSTL, RX_BUF_START & 0xff);
354 writereg(ERXSTH, RX_BUF_START >> 8);
355 writereg(ERXNDL, RX_BUF_END & 0xff);
356 writereg(ERXNDH, RX_BUF_END >> 8);
357 writereg(ERDPTL, RX_BUF_START & 0xff);
358 writereg(ERDPTH, RX_BUF_START >> 8);
359 writereg(ERXRDPTL, RX_BUF_END & 0xff);
360 writereg(ERXRDPTH, RX_BUF_END >> 8);
363 setregbank(EPKTCNT_BANK);
364 writereg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
414 setregbank(MACONX_BANK);
417 setregbitfield(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
420 setregbitfield(MACON3, MACON3_PADCFG_FULL | MACON3_TXCRCEN | MACON3_FULDPX |
426 writereg(MAMXFLL, MAX_MAC_LENGTH & 0xff);
427 writereg(MAMXFLH, MAX_MAC_LENGTH >> 8);
430 writereg(MABBIPG, 0x15);
433 writereg(MAIPGL, 0x12);
436 setregbank(MAADRX_BANK);
437 writereg(MAADR6, enc_mac_addr[5]);
438 writereg(MAADR5, enc_mac_addr[4]);
439 writereg(MAADR4, enc_mac_addr[3]);
440 writereg(MAADR3, enc_mac_addr[2]);
441 writereg(MAADR2, enc_mac_addr[1]);
442 writereg(MAADR1, enc_mac_addr[0]);
473 setregbitfield(ECON2, ECON2_AUTOINC);
476 writereg(ECON1, ECON1_RXEN);
480enc28j60_init(
const uint8_t *mac_addr)
486 memcpy(enc_mac_addr, mac_addr, 6);
493 PRINTF(
"ENC28J60 rev. B%d\n", readrev());
499enc28j60_send(
const uint8_t *data, uint16_t datalen)
528 setregbank(ERXTX_BANK);
530 writereg(ETXSTL, TX_BUF_START & 0xff);
531 writereg(ETXSTH, TX_BUF_START >> 8);
532 writereg(EWRPTL, TX_BUF_START & 0xff);
533 writereg(EWRPTH, TX_BUF_START >> 8);
540 writedata(data, datalen);
543 dataend = TX_BUF_START + datalen;
544 writereg(ETXNDL, dataend & 0xff);
545 writereg(ETXNDH, dataend >> 8);
548 clearregbitfield(EIR, EIR_TXIF);
553 setregbitfield(ECON1, ECON1_TXRTS);
554 while((readreg(ECON1) & ECON1_TXRTS) > 0);
557 if((readreg(ESTAT) & ESTAT_TXABRT) != 0) {
560 erdpt = (readreg(ERDPTH) << 8) | readreg(ERDPTL);
561 writereg(ERDPTL, (dataend + 1) & 0xff);
562 writereg(ERDPTH, (dataend + 1) >> 8);
563 readdata(tsv,
sizeof(tsv));
564 writereg(ERDPTL, erdpt & 0xff);
565 writereg(ERDPTH, erdpt >> 8);
566 PRINTF(
"enc28j60: tx err: %d: %02x:%02x:%02x:%02x:%02x:%02x\n"
567 " tsv: %02x%02x%02x%02x%02x%02x%02x\n", datalen,
568 0xff & data[0], 0xff & data[1], 0xff & data[2],
569 0xff & data[3], 0xff & data[4], 0xff & data[5],
570 tsv[6], tsv[5], tsv[4], tsv[3], tsv[2], tsv[1], tsv[0]);
572 PRINTF(
"enc28j60: tx: %d: %02x:%02x:%02x:%02x:%02x:%02x\n", datalen,
573 0xff & data[0], 0xff & data[1], 0xff & data[2],
574 0xff & data[3], 0xff & data[4], 0xff & data[5]);
579 PRINTF(
"enc28j60: sent_packets %d\n", sent_packets);
584enc28j60_read(uint8_t *buffer, uint16_t bufsize)
586 int n, len, next, err;
598 setregbank(EPKTCNT_BANK);
599 n = readreg(EPKTCNT);
605 PRINTF(
"enc28j60: EPKTCNT 0x%02x\n", n);
607 setregbank(ERXTX_BANK);
609 nxtpkt[0] = readdatabyte();
610 nxtpkt[1] = readdatabyte();
612 PRINTF(
"enc28j60: nxtpkt 0x%02x%02x\n", nxtpkt[1], nxtpkt[0]);
614 length[0] = readdatabyte();
615 length[1] = readdatabyte();
617 PRINTF(
"enc28j60: length 0x%02x%02x\n", length[1], length[0]);
619 status[0] = readdatabyte();
620 status[1] = readdatabyte();
623 status[0] = status[0];
624 PRINTF(
"enc28j60: status 0x%02x%02x\n", status[1], status[0]);
626 len = (length[1] << 8) + length[0];
628 readdata(buffer, len);
635 for(i = 0; i < len; i++) {
646 next = (nxtpkt[1] << 8) + nxtpkt[0];
647 if(next == RX_BUF_START) {
652 writereg(ERXRDPTL, next & 0xff);
653 writereg(ERXRDPTH, next >> 8);
655 setregbitfield(ECON2, ECON2_PKTDEC);
658 PRINTF(
"enc28j60: rx err: flushed %d\n", len);
661 PRINTF(
"enc28j60: rx: %d: %02x:%02x:%02x:%02x:%02x:%02x\n", len,
662 0xff & buffer[0], 0xff & buffer[1], 0xff & buffer[2],
663 0xff & buffer[3], 0xff & buffer[4], 0xff & buffer[5]);
666 PRINTF(
"enc28j60: received_packets %d\n", received_packets);
677#define RESET_PERIOD (30 * CLOCK_SECOND)
681 PRINTF(
"enc28j60: test received_packet %d > sent_packets %d\n", received_packets, sent_packets);
682 if(received_packets <= sent_packets) {
683 PRINTF(
"enc28j60: resetting chip\n");
686 received_packets = 0;
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
static bool etimer_expired(struct etimer *et)
Check if an event timer has expired.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define PROCESS(name, strname)
Declare a process.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
#define PROCESS_END()
Define the end of a process.
void process_start(struct process *p, process_data_t data)
Start a process.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.