|
|
|
@ -112,15 +112,15 @@ static void _isr(netdev2_t *netdev)
|
|
|
|
|
uint16_t eir; |
|
|
|
|
|
|
|
|
|
lock(dev); |
|
|
|
|
cmd(dev, CLREIE); |
|
|
|
|
cmd(dev, ENC_CLREIE); |
|
|
|
|
|
|
|
|
|
eir = reg_get(dev, EIR); |
|
|
|
|
eir = reg_get(dev, ENC_EIR); |
|
|
|
|
|
|
|
|
|
/* check & handle link state change */ |
|
|
|
|
if (eir & LINKIF) { |
|
|
|
|
uint16_t estat = reg_get(dev, ESTAT); |
|
|
|
|
if (eir & ENC_LINKIF) { |
|
|
|
|
uint16_t estat = reg_get(dev, ENC_ESTAT); |
|
|
|
|
|
|
|
|
|
netdev2_event_t event = (estat & PHYLNK) ? |
|
|
|
|
netdev2_event_t event = (estat & ENC_PHYLNK) ? |
|
|
|
|
NETDEV2_EVENT_LINK_DOWN : |
|
|
|
|
NETDEV2_EVENT_LINK_UP; |
|
|
|
|
|
|
|
|
@ -128,7 +128,7 @@ static void _isr(netdev2_t *netdev)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* check & handle available packets */ |
|
|
|
|
if (eir & PKTIF) { |
|
|
|
|
if (eir & ENC_PKTIF) { |
|
|
|
|
while (_packets_available(dev)) { |
|
|
|
|
unlock(dev); |
|
|
|
|
netdev->event_callback(netdev, NETDEV2_EVENT_RX_COMPLETE, |
|
|
|
@ -138,11 +138,11 @@ static void _isr(netdev2_t *netdev)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* drop all flags */ |
|
|
|
|
reg_clear_bits(dev, EIR, LINKIF); |
|
|
|
|
reg_clear_bits(dev, ENC_EIR, ENC_LINKIF); |
|
|
|
|
|
|
|
|
|
/* re-enable interrupt */ |
|
|
|
|
gpio_irq_enable(dev->int_pin); |
|
|
|
|
cmd(dev, SETEIE); |
|
|
|
|
cmd(dev, ENC_SETEIE); |
|
|
|
|
|
|
|
|
|
unlock(dev); |
|
|
|
|
} |
|
|
|
@ -158,7 +158,7 @@ static inline void enc_spi_transfer(encx24j600_t *dev, char *out, char *in, int
|
|
|
|
|
|
|
|
|
|
static inline uint16_t reg_get(encx24j600_t *dev, uint8_t reg) |
|
|
|
|
{ |
|
|
|
|
char cmd[4] = { RCRU, reg, 0, 0 }; |
|
|
|
|
char cmd[4] = { ENC_RCRU, reg, 0, 0 }; |
|
|
|
|
char result[4]; |
|
|
|
|
|
|
|
|
|
enc_spi_transfer(dev, cmd, result, 4); |
|
|
|
@ -167,8 +167,8 @@ static inline uint16_t reg_get(encx24j600_t *dev, uint8_t reg)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void phy_reg_set(encx24j600_t *dev, uint8_t reg, uint16_t value) { |
|
|
|
|
reg_set(dev, MIREGADR, reg | (1<<8)); |
|
|
|
|
reg_set(dev, MIWR, value); |
|
|
|
|
reg_set(dev, ENC_MIREGADR, reg | (1<<8)); |
|
|
|
|
reg_set(dev, ENC_MIWR, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void cmd(encx24j600_t *dev, char cmd) { |
|
|
|
@ -190,19 +190,19 @@ static void cmdn(encx24j600_t *dev, uint8_t cmd, char *out, char *in, int len) {
|
|
|
|
|
|
|
|
|
|
static void reg_set(encx24j600_t *dev, uint8_t reg, uint16_t value) |
|
|
|
|
{ |
|
|
|
|
char cmd[4] = { WCRU, reg, value, value >> 8 }; |
|
|
|
|
char cmd[4] = { ENC_WCRU, reg, value, value >> 8 }; |
|
|
|
|
enc_spi_transfer(dev, cmd, NULL, 4); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void reg_set_bits(encx24j600_t *dev, uint8_t reg, uint16_t mask) |
|
|
|
|
{ |
|
|
|
|
char cmd[4] = { BFSU, reg, mask, mask >> 8 }; |
|
|
|
|
char cmd[4] = { ENC_BFSU, reg, mask, mask >> 8 }; |
|
|
|
|
enc_spi_transfer(dev, cmd, NULL, 4); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void reg_clear_bits(encx24j600_t *dev, uint8_t reg, uint16_t mask) |
|
|
|
|
{ |
|
|
|
|
char cmd[4] = { BFCU, reg, mask, mask >> 8 }; |
|
|
|
|
char cmd[4] = { ENC_BFCU, reg, mask, mask >> 8 }; |
|
|
|
|
enc_spi_transfer(dev, cmd, NULL, 4); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -210,7 +210,7 @@ static void reg_clear_bits(encx24j600_t *dev, uint8_t reg, uint16_t mask)
|
|
|
|
|
* @brief Read/Write to encx24j600's SRAM |
|
|
|
|
* |
|
|
|
|
* @param[in] dev ptr to encx24j600 device handle |
|
|
|
|
* @param[in] cmd either WGPDATA, RGPDATA, WRXDATA, RRXDATA, WUDADATA, RUDADATA |
|
|
|
|
* @param[in] cmd either ENC_WGPDATA, ENC_RGPDATA, ENC_WRXDATA, ENC_RRXDATA, ENC_WUDADATA, ENC_RUDADATA |
|
|
|
|
* @param[in] addr SRAM address to start reading. 0xFFFF means continue from old address |
|
|
|
|
* @param ptr pointer to buffer to read from / write to |
|
|
|
|
* @param[in] len nr of bytes to read/write |
|
|
|
@ -265,35 +265,35 @@ static int _init(netdev2_t *encdev)
|
|
|
|
|
do { |
|
|
|
|
do { |
|
|
|
|
xtimer_usleep(ENCX24J600_INIT_DELAY); |
|
|
|
|
reg_set(dev, EUDAST, 0x1234); |
|
|
|
|
reg_set(dev, ENC_EUDAST, 0x1234); |
|
|
|
|
xtimer_usleep(ENCX24J600_INIT_DELAY); |
|
|
|
|
} while (reg_get(dev, EUDAST) != 0x1234); |
|
|
|
|
} while (reg_get(dev, ENC_EUDAST) != 0x1234); |
|
|
|
|
|
|
|
|
|
while (!(reg_get(dev, ESTAT) & CLKRDY)); |
|
|
|
|
while (!(reg_get(dev, ENC_ESTAT) & ENC_CLKRDY)); |
|
|
|
|
|
|
|
|
|
/* issue System Reset */ |
|
|
|
|
cmd(dev, SETETHRST); |
|
|
|
|
cmd(dev, ENC_SETETHRST); |
|
|
|
|
|
|
|
|
|
/* make sure initialization finalizes */ |
|
|
|
|
xtimer_usleep(1000); |
|
|
|
|
} while (!(reg_get(dev, EUDAST) == 0x0000)); |
|
|
|
|
} while (!(reg_get(dev, ENC_EUDAST) == 0x0000)); |
|
|
|
|
|
|
|
|
|
/* configure flow control */ |
|
|
|
|
phy_reg_set(dev, PHANA, 0x05E1); |
|
|
|
|
reg_set_bits(dev, ECON2, AUTOFC); |
|
|
|
|
phy_reg_set(dev, ENC_PHANA, 0x05E1); |
|
|
|
|
reg_set_bits(dev, ENC_ECON2, ENC_AUTOFC); |
|
|
|
|
|
|
|
|
|
/* setup receive buffer */ |
|
|
|
|
reg_set(dev, ERXST, RX_BUFFER_START); |
|
|
|
|
reg_set(dev, ERXTAIL, RX_BUFFER_END); |
|
|
|
|
reg_set(dev, ENC_ERXST, RX_BUFFER_START); |
|
|
|
|
reg_set(dev, ENC_ERXTAIL, RX_BUFFER_END); |
|
|
|
|
dev->rx_next_ptr = RX_BUFFER_START; |
|
|
|
|
|
|
|
|
|
/* configure receive filter to receive multicast frames */ |
|
|
|
|
reg_set_bits(dev, ERXFCON, MCEN); |
|
|
|
|
reg_set_bits(dev, ENC_ERXFCON, ENC_MCEN); |
|
|
|
|
|
|
|
|
|
/* setup interrupts */ |
|
|
|
|
reg_set_bits(dev, EIE, PKTIE | LINKIE); |
|
|
|
|
cmd(dev, ENABLERX); |
|
|
|
|
cmd(dev, SETEIE); |
|
|
|
|
reg_set_bits(dev, ENC_EIE, ENC_PKTIE | ENC_LINKIE); |
|
|
|
|
cmd(dev, ENC_ENABLERX); |
|
|
|
|
cmd(dev, ENC_SETEIE); |
|
|
|
|
|
|
|
|
|
DEBUG("encx24j600: initialization complete.\n"); |
|
|
|
|
|
|
|
|
@ -314,26 +314,26 @@ static int _send(netdev2_t *netdev, const struct iovec *vector, int count) {
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* wait until previous packet has been sent */ |
|
|
|
|
while ((reg_get(dev, ECON1) & TXRTS)); |
|
|
|
|
while ((reg_get(dev, ENC_ECON1) & ENC_TXRTS)); |
|
|
|
|
|
|
|
|
|
/* copy packet to SRAM */ |
|
|
|
|
size_t len = 0; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < count; i++) { |
|
|
|
|
sram_op(dev, WGPDATA, (i ? 0xFFFF : TX_BUFFER_START), vector[i].iov_base, vector[i].iov_len); |
|
|
|
|
sram_op(dev, ENC_WGPDATA, (i ? 0xFFFF : TX_BUFFER_START), vector[i].iov_base, vector[i].iov_len); |
|
|
|
|
len += vector[i].iov_len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* set start of TX packet and length */ |
|
|
|
|
reg_set(dev, ETXST, TX_BUFFER_START); |
|
|
|
|
reg_set(dev, ETXLEN, len); |
|
|
|
|
reg_set(dev, ENC_ETXST, TX_BUFFER_START); |
|
|
|
|
reg_set(dev, ENC_ETXLEN, len); |
|
|
|
|
|
|
|
|
|
/* initiate sending */ |
|
|
|
|
cmd(dev, SETTXRTS); |
|
|
|
|
cmd(dev, ENC_SETTXRTS); |
|
|
|
|
|
|
|
|
|
/* wait for sending to complete */ |
|
|
|
|
/* (not sure if it is needed, keeping the line uncommented) */ |
|
|
|
|
/*while ((reg_get(dev, ECON1) & TXRTS));*/ |
|
|
|
|
/*while ((reg_get(dev, ENC_ECON1) & ENC_TXRTS));*/ |
|
|
|
|
|
|
|
|
|
unlock(dev); |
|
|
|
|
|
|
|
|
@ -342,8 +342,8 @@ static int _send(netdev2_t *netdev, const struct iovec *vector, int count) {
|
|
|
|
|
|
|
|
|
|
static inline int _packets_available(encx24j600_t *dev) |
|
|
|
|
{ |
|
|
|
|
/* return PKTCNT (low byte of ESTAT) */ |
|
|
|
|
return reg_get(dev, ESTAT) & ~0xFF00; |
|
|
|
|
/* return ENC_PKTCNT (low byte of ENC_ESTAT) */ |
|
|
|
|
return reg_get(dev, ENC_ESTAT) & ~0xFF00; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void _get_mac_addr(netdev2_t *encdev, uint8_t* buf) |
|
|
|
@ -353,9 +353,9 @@ static void _get_mac_addr(netdev2_t *encdev, uint8_t* buf)
|
|
|
|
|
|
|
|
|
|
lock(dev); |
|
|
|
|
|
|
|
|
|
addr[0] = reg_get(dev, MAADR1); |
|
|
|
|
addr[1] = reg_get(dev, MAADR2); |
|
|
|
|
addr[2] = reg_get(dev, MAADR3); |
|
|
|
|
addr[0] = reg_get(dev, ENC_MAADR1); |
|
|
|
|
addr[1] = reg_get(dev, ENC_MAADR2); |
|
|
|
|
addr[2] = reg_get(dev, ENC_MAADR3); |
|
|
|
|
|
|
|
|
|
unlock(dev); |
|
|
|
|
} |
|
|
|
@ -369,7 +369,7 @@ static int _recv(netdev2_t *netdev, char* buf, int len, void *info)
|
|
|
|
|
lock(dev); |
|
|
|
|
|
|
|
|
|
/* read frame header */ |
|
|
|
|
sram_op(dev, RRXDATA, dev->rx_next_ptr, (char*)&hdr, sizeof(hdr)); |
|
|
|
|
sram_op(dev, ENC_RRXDATA, dev->rx_next_ptr, (char*)&hdr, sizeof(hdr)); |
|
|
|
|
|
|
|
|
|
/* hdr.frame_len given by device contains 4 bytes checksum */ |
|
|
|
|
size_t payload_len = hdr.frame_len - 4; |
|
|
|
@ -380,14 +380,14 @@ static int _recv(netdev2_t *netdev, char* buf, int len, void *info)
|
|
|
|
|
netdev2->stats.rx_bytes += len; |
|
|
|
|
#endif |
|
|
|
|
/* read packet (without 4 bytes checksum) */ |
|
|
|
|
sram_op(dev, RRXDATA, 0xFFFF, buf, payload_len); |
|
|
|
|
sram_op(dev, ENC_RRXDATA, 0xFFFF, buf, payload_len); |
|
|
|
|
|
|
|
|
|
/* decrement available packet count */ |
|
|
|
|
cmd(dev, SETPKTDEC); |
|
|
|
|
cmd(dev, ENC_SETPKTDEC); |
|
|
|
|
|
|
|
|
|
dev->rx_next_ptr = hdr.rx_next_ptr; |
|
|
|
|
|
|
|
|
|
reg_set(dev, ERXTAIL, dev->rx_next_ptr - 2); |
|
|
|
|
reg_set(dev, ENC_ERXTAIL, dev->rx_next_ptr - 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unlock(dev); |
|
|
|
|