Merge pull request #1168 from bthebaudeau/enc28j60-fixes-and-improvements
enc28j60: Fixes and improvements
This commit is contained in:
commit
a2cae3359b
|
@ -84,7 +84,6 @@
|
||||||
#define MACONX_BANK 0x02
|
#define MACONX_BANK 0x02
|
||||||
|
|
||||||
#define MACON1 0x00
|
#define MACON1 0x00
|
||||||
#define MACON2 0x01
|
|
||||||
#define MACON3 0x02
|
#define MACON3 0x02
|
||||||
#define MACON4 0x03
|
#define MACON4 0x03
|
||||||
#define MABBIPG 0x04
|
#define MABBIPG 0x04
|
||||||
|
@ -97,8 +96,6 @@
|
||||||
#define MACON1_RXPAUS 0x04
|
#define MACON1_RXPAUS 0x04
|
||||||
#define MACON1_MARXEN 0x01
|
#define MACON1_MARXEN 0x01
|
||||||
|
|
||||||
#define MACON2_MARST 0x80
|
|
||||||
|
|
||||||
#define MACON3_PADCFG_FULL 0xe0
|
#define MACON3_PADCFG_FULL 0xe0
|
||||||
#define MACON3_TXCRCEN 0x10
|
#define MACON3_TXCRCEN 0x10
|
||||||
#define MACON3_FRMLNEN 0x02
|
#define MACON3_FRMLNEN 0x02
|
||||||
|
@ -113,6 +110,8 @@
|
||||||
#define MAADR4 0x03 /* MAADR<23:16> */
|
#define MAADR4 0x03 /* MAADR<23:16> */
|
||||||
#define MAADR5 0x00 /* MAADR<15:8> */
|
#define MAADR5 0x00 /* MAADR<15:8> */
|
||||||
#define MAADR6 0x01 /* MAADR<7:0> */
|
#define MAADR6 0x01 /* MAADR<7:0> */
|
||||||
|
#define MISTAT 0x0a
|
||||||
|
#define EREVID 0x12
|
||||||
|
|
||||||
#define EPKTCNT_BANK 0x01
|
#define EPKTCNT_BANK 0x01
|
||||||
#define ERXFCON 0x18
|
#define ERXFCON 0x18
|
||||||
|
@ -128,10 +127,27 @@
|
||||||
PROCESS(enc_watchdog_process, "Enc28j60 watchdog");
|
PROCESS(enc_watchdog_process, "Enc28j60 watchdog");
|
||||||
|
|
||||||
static uint8_t initialized = 0;
|
static uint8_t initialized = 0;
|
||||||
|
static uint8_t bank = ERXTX_BANK;
|
||||||
static uint8_t enc_mac_addr[6];
|
static uint8_t enc_mac_addr[6];
|
||||||
static int received_packets = 0;
|
static int received_packets = 0;
|
||||||
static int sent_packets = 0;
|
static int sent_packets = 0;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static uint8_t
|
||||||
|
is_mac_mii_reg(uint8_t reg)
|
||||||
|
{
|
||||||
|
/* MAC or MII register (otherwise, ETH register)? */
|
||||||
|
switch(bank) {
|
||||||
|
case MACONX_BANK:
|
||||||
|
return reg < EIE;
|
||||||
|
case MAADRX_BANK:
|
||||||
|
return reg <= MAADR2 || reg == MISTAT;
|
||||||
|
case ERXTX_BANK:
|
||||||
|
case EPKTCNT_BANK:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static uint8_t
|
static uint8_t
|
||||||
readreg(uint8_t reg)
|
readreg(uint8_t reg)
|
||||||
|
@ -139,6 +155,10 @@ readreg(uint8_t reg)
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
enc28j60_arch_spi_select();
|
enc28j60_arch_spi_select();
|
||||||
enc28j60_arch_spi_write(0x00 | (reg & 0x1f));
|
enc28j60_arch_spi_write(0x00 | (reg & 0x1f));
|
||||||
|
if(is_mac_mii_reg(reg)) {
|
||||||
|
/* MAC and MII registers require that a dummy byte be read first. */
|
||||||
|
enc28j60_arch_spi_read();
|
||||||
|
}
|
||||||
r = enc28j60_arch_spi_read();
|
r = enc28j60_arch_spi_read();
|
||||||
enc28j60_arch_spi_deselect();
|
enc28j60_arch_spi_deselect();
|
||||||
return r;
|
return r;
|
||||||
|
@ -154,19 +174,36 @@ writereg(uint8_t reg, uint8_t data)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
setregbank(uint8_t bank)
|
setregbitfield(uint8_t reg, uint8_t mask)
|
||||||
{
|
{
|
||||||
writereg(ECON1, (readreg(ECON1) & 0xfc) | (bank & 0x03));
|
if(is_mac_mii_reg(reg)) {
|
||||||
|
writereg(reg, readreg(reg) | mask);
|
||||||
|
} else {
|
||||||
|
enc28j60_arch_spi_select();
|
||||||
|
enc28j60_arch_spi_write(0x80 | (reg & 0x1f));
|
||||||
|
enc28j60_arch_spi_write(mask);
|
||||||
|
enc28j60_arch_spi_deselect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
writedatabyte(uint8_t byte)
|
clearregbitfield(uint8_t reg, uint8_t mask)
|
||||||
{
|
{
|
||||||
enc28j60_arch_spi_select();
|
if(is_mac_mii_reg(reg)) {
|
||||||
/* The Write Buffer Memory (WBM) command is 0 1 1 1 1 0 1 0 */
|
writereg(reg, readreg(reg) & ~mask);
|
||||||
enc28j60_arch_spi_write(0x7a);
|
} else {
|
||||||
enc28j60_arch_spi_write(byte);
|
enc28j60_arch_spi_select();
|
||||||
enc28j60_arch_spi_deselect();
|
enc28j60_arch_spi_write(0xa0 | (reg & 0x1f));
|
||||||
|
enc28j60_arch_spi_write(mask);
|
||||||
|
enc28j60_arch_spi_deselect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
setregbank(uint8_t new_bank)
|
||||||
|
{
|
||||||
|
writereg(ECON1, (readreg(ECON1) & 0xfc) | (new_bank & 0x03));
|
||||||
|
bank = new_bank;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
|
@ -182,16 +219,10 @@ writedata(uint8_t *data, int datalen)
|
||||||
enc28j60_arch_spi_deselect();
|
enc28j60_arch_spi_deselect();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static uint8_t
|
static void
|
||||||
readdatabyte(void)
|
writedatabyte(uint8_t byte)
|
||||||
{
|
{
|
||||||
uint8_t r;
|
writedata(&byte, 1);
|
||||||
enc28j60_arch_spi_select();
|
|
||||||
/* THe Read Buffer Memory (RBM) command is 0 0 1 1 1 0 1 0 */
|
|
||||||
enc28j60_arch_spi_write(0x3a);
|
|
||||||
r = enc28j60_arch_spi_read();
|
|
||||||
enc28j60_arch_spi_deselect();
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
|
@ -208,6 +239,14 @@ readdata(uint8_t *buf, int len)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static uint8_t
|
||||||
|
readdatabyte(void)
|
||||||
|
{
|
||||||
|
uint8_t r;
|
||||||
|
readdata(&r, 1);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
softreset(void)
|
softreset(void)
|
||||||
{
|
{
|
||||||
|
@ -215,8 +254,27 @@ softreset(void)
|
||||||
/* The System Command (soft reset) is 1 1 1 1 1 1 1 1 */
|
/* The System Command (soft reset) is 1 1 1 1 1 1 1 1 */
|
||||||
enc28j60_arch_spi_write(0xff);
|
enc28j60_arch_spi_write(0xff);
|
||||||
enc28j60_arch_spi_deselect();
|
enc28j60_arch_spi_deselect();
|
||||||
|
bank = ERXTX_BANK;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if DEBUG
|
||||||
|
static uint8_t
|
||||||
|
readrev(void)
|
||||||
|
{
|
||||||
|
uint8_t rev;
|
||||||
|
setregbank(MAADRX_BANK);
|
||||||
|
rev = readreg(EREVID);
|
||||||
|
switch(rev) {
|
||||||
|
case 2:
|
||||||
|
return 1;
|
||||||
|
case 6:
|
||||||
|
return 7;
|
||||||
|
default:
|
||||||
|
return rev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
reset(void)
|
reset(void)
|
||||||
{
|
{
|
||||||
|
@ -282,11 +340,14 @@ reset(void)
|
||||||
see Section 2.2 “Oscillator Start-up Timer.
|
see Section 2.2 “Oscillator Start-up Timer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
softreset();
|
||||||
|
|
||||||
|
/* Workaround for erratum #2. */
|
||||||
|
clock_delay_usec(1000);
|
||||||
|
|
||||||
/* Wait for OST */
|
/* Wait for OST */
|
||||||
while((readreg(ESTAT) & ESTAT_CLKRDY) == 0);
|
while((readreg(ESTAT) & ESTAT_CLKRDY) == 0);
|
||||||
|
|
||||||
softreset();
|
|
||||||
|
|
||||||
setregbank(ERXTX_BANK);
|
setregbank(ERXTX_BANK);
|
||||||
/* Set up receive buffer */
|
/* Set up receive buffer */
|
||||||
writereg(ERXSTL, RX_BUF_START & 0xff);
|
writereg(ERXSTL, RX_BUF_START & 0xff);
|
||||||
|
@ -295,16 +356,12 @@ reset(void)
|
||||||
writereg(ERXNDH, RX_BUF_END >> 8);
|
writereg(ERXNDH, RX_BUF_END >> 8);
|
||||||
writereg(ERDPTL, RX_BUF_START & 0xff);
|
writereg(ERDPTL, RX_BUF_START & 0xff);
|
||||||
writereg(ERDPTH, RX_BUF_START >> 8);
|
writereg(ERDPTH, RX_BUF_START >> 8);
|
||||||
writereg(ERXRDPTL, RX_BUF_START & 0xff);
|
writereg(ERXRDPTL, RX_BUF_END & 0xff);
|
||||||
writereg(ERXRDPTH, RX_BUF_START >> 8);
|
writereg(ERXRDPTH, RX_BUF_END >> 8);
|
||||||
|
|
||||||
/* Receive filters */
|
/* Receive filters */
|
||||||
setregbank(EPKTCNT_BANK);
|
setregbank(EPKTCNT_BANK);
|
||||||
/* writereg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN |
|
writereg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
|
||||||
ERXFCON_MCEN | ERXFCON_BCEN);*/
|
|
||||||
/* XXX: can't seem to get the unicast filter to work right now,
|
|
||||||
using promiscous mode for now. */
|
|
||||||
writereg(ERXFCON, 0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
6.5 MAC Initialization Settings
|
6.5 MAC Initialization Settings
|
||||||
|
@ -313,13 +370,11 @@ reset(void)
|
||||||
initialization. This only needs to be done once; the order of
|
initialization. This only needs to be done once; the order of
|
||||||
programming is unimportant.
|
programming is unimportant.
|
||||||
|
|
||||||
1. Clear the MARST bit in MACON2 to pull the MAC out of Reset.
|
1. Set the MARXEN bit in MACON1 to enable the MAC to receive
|
||||||
|
|
||||||
2. Set the MARXEN bit in MACON1 to enable the MAC to receive
|
|
||||||
frames. If using full duplex, most applications should also set
|
frames. If using full duplex, most applications should also set
|
||||||
TXPAUS and RXPAUS to allow IEEE defined flow control to function.
|
TXPAUS and RXPAUS to allow IEEE defined flow control to function.
|
||||||
|
|
||||||
3. Configure the PADCFG, TXCRCEN and FULDPX bits of MACON3. Most
|
2. Configure the PADCFG, TXCRCEN and FULDPX bits of MACON3. Most
|
||||||
applications should enable automatic padding to at least 60 bytes
|
applications should enable automatic padding to at least 60 bytes
|
||||||
and always append a valid CRC. For convenience, many applications
|
and always append a valid CRC. For convenience, many applications
|
||||||
may wish to set the FRMLNEN bit as well to enable frame length
|
may wish to set the FRMLNEN bit as well to enable frame length
|
||||||
|
@ -327,48 +382,43 @@ reset(void)
|
||||||
will be connected to a full-duplex configured remote node;
|
will be connected to a full-duplex configured remote node;
|
||||||
otherwise, it should be left clear.
|
otherwise, it should be left clear.
|
||||||
|
|
||||||
4. Configure the bits in MACON4. Many applications may not need to
|
3. Configure the bits in MACON4. For conformance to the IEEE 802.3
|
||||||
modify the Reset default.
|
standard, set the DEFER bit.
|
||||||
|
|
||||||
5. Program the MAMXFL registers with the maximum frame length to
|
4. Program the MAMXFL registers with the maximum frame length to
|
||||||
be permitted to be received or transmitted. Normal network nodes
|
be permitted to be received or transmitted. Normal network nodes
|
||||||
are designed to handle packets that are 1518 bytes or less.
|
are designed to handle packets that are 1518 bytes or less.
|
||||||
|
|
||||||
6. Configure the Back-to-Back Inter-Packet Gap register,
|
5. Configure the Back-to-Back Inter-Packet Gap register,
|
||||||
MABBIPG. Most applications will program this register with 15h
|
MABBIPG. Most applications will program this register with 15h
|
||||||
when Full-Duplex mode is used and 12h when Half-Duplex mode is
|
when Full-Duplex mode is used and 12h when Half-Duplex mode is
|
||||||
used.
|
used.
|
||||||
|
|
||||||
7. Configure the Non-Back-to-Back Inter-Packet Gap register low
|
6. Configure the Non-Back-to-Back Inter-Packet Gap register low
|
||||||
byte, MAIPGL. Most applications will program this register with
|
byte, MAIPGL. Most applications will program this register with
|
||||||
12h.
|
12h.
|
||||||
|
|
||||||
8. If half duplex is used, the Non-Back-to-Back Inter-Packet Gap
|
7. If half duplex is used, the Non-Back-to-Back Inter-Packet Gap
|
||||||
register high byte, MAIPGH, should be programmed. Most
|
register high byte, MAIPGH, should be programmed. Most
|
||||||
applications will program this register to 0Ch.
|
applications will program this register to 0Ch.
|
||||||
|
|
||||||
9. If Half-Duplex mode is used, program the Retransmission and
|
8. If Half-Duplex mode is used, program the Retransmission and
|
||||||
Collision Window registers, MACLCON1 and MACLCON2. Most
|
Collision Window registers, MACLCON1 and MACLCON2. Most
|
||||||
applications will not need to change the default Reset values. If
|
applications will not need to change the default Reset values. If
|
||||||
the network is spread over exceptionally long cables, the default
|
the network is spread over exceptionally long cables, the default
|
||||||
value of MACLCON2 may need to be increased.
|
value of MACLCON2 may need to be increased.
|
||||||
|
|
||||||
10. Program the local MAC address into the
|
9. Program the local MAC address into the MAADR1:MAADR6 registers.
|
||||||
MAADR0:MAADR5 registers.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setregbank(MACONX_BANK);
|
setregbank(MACONX_BANK);
|
||||||
|
|
||||||
/* Pull MAC out of reset */
|
|
||||||
writereg(MACON2, 0);//readreg(MACON2) & (~MACON2_MARST));
|
|
||||||
|
|
||||||
/* Turn on reception and IEEE-defined flow control */
|
/* Turn on reception and IEEE-defined flow control */
|
||||||
writereg(MACON1, readreg(MACON1) | (MACON1_MARXEN + MACON1_TXPAUS +
|
setregbitfield(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
|
||||||
MACON1_RXPAUS));
|
|
||||||
|
|
||||||
/* Set padding, crc, full duplex */
|
/* Set padding, crc, full duplex */
|
||||||
writereg(MACON3, readreg(MACON3) | (MACON3_PADCFG_FULL + MACON3_TXCRCEN +
|
setregbitfield(MACON3, MACON3_PADCFG_FULL | MACON3_TXCRCEN | MACON3_FULDPX |
|
||||||
MACON3_FULDPX + MACON3_FRMLNEN));
|
MACON3_FRMLNEN);
|
||||||
|
|
||||||
/* Don't modify MACON4 */
|
/* Don't modify MACON4 */
|
||||||
|
|
||||||
|
@ -381,7 +431,6 @@ reset(void)
|
||||||
|
|
||||||
/* Set non-back-to-back packet gap */
|
/* Set non-back-to-back packet gap */
|
||||||
writereg(MAIPGL, 0x12);
|
writereg(MAIPGL, 0x12);
|
||||||
writereg(MAIPGH, 0x0c);
|
|
||||||
|
|
||||||
/* Set MAC address */
|
/* Set MAC address */
|
||||||
setregbank(MAADRX_BANK);
|
setregbank(MAADRX_BANK);
|
||||||
|
@ -392,10 +441,6 @@ reset(void)
|
||||||
writereg(MAADR2, enc_mac_addr[1]);
|
writereg(MAADR2, enc_mac_addr[1]);
|
||||||
writereg(MAADR1, enc_mac_addr[0]);
|
writereg(MAADR1, enc_mac_addr[0]);
|
||||||
|
|
||||||
/* Receive filters */
|
|
||||||
setregbank(EPKTCNT_BANK);
|
|
||||||
writereg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
6.6 PHY Initialization Settings
|
6.6 PHY Initialization Settings
|
||||||
|
|
||||||
|
@ -425,7 +470,7 @@ reset(void)
|
||||||
/* Don't worry about PHY configuration for now */
|
/* Don't worry about PHY configuration for now */
|
||||||
|
|
||||||
/* Turn on autoincrement for buffer access */
|
/* Turn on autoincrement for buffer access */
|
||||||
writereg(ECON2, readreg(ECON2) | ECON2_AUTOINC);
|
setregbitfield(ECON2, ECON2_AUTOINC);
|
||||||
|
|
||||||
/* Turn on reception */
|
/* Turn on reception */
|
||||||
writereg(ECON1, ECON1_RXEN);
|
writereg(ECON1, ECON1_RXEN);
|
||||||
|
@ -445,13 +490,15 @@ enc28j60_init(uint8_t *mac_addr)
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
|
PRINTF("ENC28J60 rev. B%d\n", readrev());
|
||||||
|
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
enc28j60_send(uint8_t *data, uint16_t datalen)
|
enc28j60_send(uint8_t *data, uint16_t datalen)
|
||||||
{
|
{
|
||||||
int padding = 0;
|
uint16_t dataend;
|
||||||
|
|
||||||
if(!initialized) {
|
if(!initialized) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -488,49 +535,46 @@ enc28j60_send(uint8_t *data, uint16_t datalen)
|
||||||
/* Write the transmission control register as the first byte of the
|
/* Write the transmission control register as the first byte of the
|
||||||
output packet. We write 0x00 to indicate that the default
|
output packet. We write 0x00 to indicate that the default
|
||||||
configuration (the values in MACON3) will be used. */
|
configuration (the values in MACON3) will be used. */
|
||||||
#define WITH_MANUAL_PADDING 1
|
|
||||||
#if WITH_MANUAL_PADDING
|
|
||||||
#define PADDING_MIN_SIZE 60
|
|
||||||
writedatabyte(0x0B); /* POVERRIDE, PCRCEN, PHUGEEN. Not PPADEN */
|
|
||||||
if(datalen < PADDING_MIN_SIZE) {
|
|
||||||
padding = PADDING_MIN_SIZE - datalen;
|
|
||||||
} else {
|
|
||||||
padding = 0;
|
|
||||||
}
|
|
||||||
#else /* WITH_MANUAL_PADDING */
|
|
||||||
writedatabyte(0x00); /* MACON3 */
|
writedatabyte(0x00); /* MACON3 */
|
||||||
padding = 0;
|
|
||||||
#endif /* WITH_MANUAL_PADDING */
|
|
||||||
|
|
||||||
/* Write a pointer to the last data byte. */
|
|
||||||
writereg(ETXNDL, (TX_BUF_START + datalen + 0 + padding) & 0xff);
|
|
||||||
writereg(ETXNDH, (TX_BUF_START + datalen + 0 + padding) >> 8);
|
|
||||||
|
|
||||||
writedata(data, datalen);
|
writedata(data, datalen);
|
||||||
if(padding > 0) {
|
|
||||||
uint8_t padding_buf[60];
|
/* Write a pointer to the last data byte. */
|
||||||
memset(padding_buf, 0, padding);
|
dataend = TX_BUF_START + datalen;
|
||||||
writedata(padding_buf, padding);
|
writereg(ETXNDL, dataend & 0xff);
|
||||||
}
|
writereg(ETXNDH, dataend >> 8);
|
||||||
|
|
||||||
/* Clear EIR.TXIF */
|
/* Clear EIR.TXIF */
|
||||||
writereg(EIR, readreg(EIR) & (~EIR_TXIF));
|
clearregbitfield(EIR, EIR_TXIF);
|
||||||
|
|
||||||
/* Don't care about interrupts for now */
|
/* Don't care about interrupts for now */
|
||||||
|
|
||||||
/* Send the packet */
|
/* Send the packet */
|
||||||
writereg(ECON1, readreg(ECON1) | ECON1_TXRTS);
|
setregbitfield(ECON1, ECON1_TXRTS);
|
||||||
while((readreg(ECON1) & ECON1_TXRTS) > 0);
|
while((readreg(ECON1) & ECON1_TXRTS) > 0);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
if((readreg(ESTAT) & ESTAT_TXABRT) != 0) {
|
if((readreg(ESTAT) & ESTAT_TXABRT) != 0) {
|
||||||
PRINTF("enc28j60: tx err: %d: %02x:%02x:%02x:%02x:%02x:%02x\n", datalen,
|
uint16_t erdpt;
|
||||||
|
uint8_t tsv[7];
|
||||||
|
erdpt = (readreg(ERDPTH) << 8) | readreg(ERDPTL);
|
||||||
|
writereg(ERDPTL, (dataend + 1) & 0xff);
|
||||||
|
writereg(ERDPTH, (dataend + 1) >> 8);
|
||||||
|
readdata(tsv, sizeof(tsv));
|
||||||
|
writereg(ERDPTL, erdpt & 0xff);
|
||||||
|
writereg(ERDPTH, erdpt >> 8);
|
||||||
|
PRINTF("enc28j60: tx err: %d: %02x:%02x:%02x:%02x:%02x:%02x\n"
|
||||||
|
" tsv: %02x%02x%02x%02x%02x%02x%02x\n", datalen,
|
||||||
0xff & data[0], 0xff & data[1], 0xff & data[2],
|
0xff & data[0], 0xff & data[1], 0xff & data[2],
|
||||||
0xff & data[3], 0xff & data[4], 0xff & data[5]);
|
0xff & data[3], 0xff & data[4], 0xff & data[5],
|
||||||
|
tsv[6], tsv[5], tsv[4], tsv[3], tsv[2], tsv[1], tsv[0]);
|
||||||
} else {
|
} else {
|
||||||
PRINTF("enc28j60: tx: %d: %02x:%02x:%02x:%02x:%02x:%02x\n", datalen,
|
PRINTF("enc28j60: tx: %d: %02x:%02x:%02x:%02x:%02x:%02x\n", datalen,
|
||||||
0xff & data[0], 0xff & data[1], 0xff & data[2],
|
0xff & data[0], 0xff & data[1], 0xff & data[2],
|
||||||
0xff & data[3], 0xff & data[4], 0xff & data[5]);
|
0xff & data[3], 0xff & data[4], 0xff & data[5]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
sent_packets++;
|
sent_packets++;
|
||||||
PRINTF("enc28j60: sent_packets %d\n", sent_packets);
|
PRINTF("enc28j60: sent_packets %d\n", sent_packets);
|
||||||
return datalen;
|
return datalen;
|
||||||
|
@ -545,6 +589,10 @@ enc28j60_read(uint8_t *buffer, uint16_t bufsize)
|
||||||
uint8_t status[2];
|
uint8_t status[2];
|
||||||
uint8_t length[2];
|
uint8_t length[2];
|
||||||
|
|
||||||
|
if(!initialized) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
setregbank(EPKTCNT_BANK);
|
setregbank(EPKTCNT_BANK);
|
||||||
|
@ -604,7 +652,7 @@ enc28j60_read(uint8_t *buffer, uint16_t bufsize)
|
||||||
writereg(ERXRDPTL, next & 0xff);
|
writereg(ERXRDPTL, next & 0xff);
|
||||||
writereg(ERXRDPTH, next >> 8);
|
writereg(ERXRDPTH, next >> 8);
|
||||||
|
|
||||||
writereg(ECON2, readreg(ECON2) | ECON2_PKTDEC);
|
setregbitfield(ECON2, ECON2_PKTDEC);
|
||||||
|
|
||||||
if(err) {
|
if(err) {
|
||||||
PRINTF("enc28j60: rx err: flushed %d\n", len);
|
PRINTF("enc28j60: rx err: flushed %d\n", len);
|
||||||
|
|
Loading…
Reference in a new issue