From 1d050f61cc6d74653b0fc6182f42028256df0b42 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 25 Apr 2010 23:05:35 +0000 Subject: [PATCH] Add ENC28J80 control reg logic git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2628 42af7a65-404d-4744-a932-0658087f49c3 --- drivers/net/enc28j60.c | 309 +++++++++++++++++++++++++++++++----- drivers/net/enc28j60.h | 350 ++++++++++++++++++++++------------------- drivers/net/skeleton.c | 26 ++- 3 files changed, 469 insertions(+), 216 deletions(-) diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index c82de47672..87ae285f69 100755 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -42,11 +42,11 @@ ****************************************************************************/ #include -#if defined(CONFIG_NET) && defined(CONFIG_ENC28J60_NET) +#if defined(CONFIG_NET) && defined(CONFIG_NET_ENC28J60) #include #include -#include +#include #include #include #include @@ -80,7 +80,7 @@ * devices that will be supported. */ -#ifdef CONFIG_ENC28J60_SPIMODE +#ifndef CONFIG_ENC28J60_SPIMODE # define CONFIG_ENC28J60_SPIMODE SPIDEV_MODE2 #endif @@ -105,6 +105,15 @@ /* Misc. Helper Macros ******************************************************/ +#define enc28j60_rdglobal(priv,ctrlref) \ + enc28j60_rdglobal2(priv, ENC28J60_RCR | GETADDR(ctrlreg)) +#define enc28j60_wrglobal(priv,ctrlreg,wrdata) \ + enc28j60_wrglobal2(priv, ENC28J60_WCR | GETADDR(ctrlreg), wrdata) +#define enc28j60_clrglobal(priv,ctrlreg,clrbits) \ + enc28j60_wrglobal2(priv, ENC28J60_BFC | GETADDR(ctrlreg), clrbits) +#define enc28j60_setglobal(priv,ctrlreg,setbits) \ + enc28j60_wrglobal2(priv, ENC28J60_BFS | GETADDR(ctrlreg), setbits) + /* This is a helper pointer for accessing the contents of the Ethernet header */ #define BUF ((struct uip_eth_hdr *)priv->dev.d_buf) @@ -147,16 +156,32 @@ static struct enc28j60_driver_s g_enc28j60[CONFIG_ENC28J60_NINTERFACES]; /* Low-level SPI helpers */ static inline void enc28j60_configspi(FAR struct spi_dev_s *spi); +#ifdef CONFIG_ENC28J60_OWNBUS +static inline uint8_t enc28j60_select(FAR struct spi_dev_s *spi); +static inline uint8_t enc28j60_deselect(FAR struct spi_dev_s *spi); +#else +static uint8_t enc28j60_select(FAR struct spi_dev_s *spi); +static uint8_t enc28j60_deselect(FAR struct spi_dev_s *spi); +#endif +static uint8_t enc28j60_rdglobal2(FAR struct enc28j60_driver_s *priv, + uint8_t cmd); +static void enc28j60_wrglobal2(FAR struct enc28j60_driver_s *priv, + uint8_t cmd, uint8_t wrdata); +static void enc28j60_setbank(FAR struct enc28j60_driver_s *priv, uint8_t bank); +static uint8_t enc28j60_rdbank(FAR struct enc28j60_driver_s *priv, + uint8_t ctrlreg); +static uint8_t enc28j60_rdphymac(FAR struct enc28j60_driver_s *priv, + uint8_t ctrlreg); /* Common TX logic */ -static int enc28j60_transmit(FAR struct enc28j60_drver_s *priv); +static int enc28j60_transmit(FAR struct enc28j60_driver_s *priv); static int enc28j60_uiptxpoll(struct uip_driver_s *dev); /* Interrupt handling */ -static void enc28j60_receive(FAR struct enc28j60_drver_s *priv); -static void enc28j60_txdone(FAR struct enc28j60_drver_s *priv); +static void enc28j60_receive(FAR struct enc28j60_driver_s *priv); +static void enc28j60_txdone(FAR struct enc28j60_driver_s *priv); static int enc28j60_interrupt(int irq, FAR void *context); /* Watchdog timer expirations */ @@ -259,6 +284,219 @@ static uint8_t enc28j60_deselect(FAR struct spi_dev_s *spi) } #endif +/**************************************************************************** + * Function: enc28j60_rdglobal2 + * + * Description: + * Read a global register (EIE, EIR, ESTAT, ECON2, or ECON1). The cmd + * include the CMD 'OR'd with the the global address register. + * + ****************************************************************************/ + +static uint8_t enc28j60_rdglobal2(FAR struct enc28j60_driver_s *priv, + uint8_t cmd) +{ + FAR struct spi_dev_s *spi; + uint8_t rddata; + + DEBUGASSERT(priv && priv->spi); + spi = priv->spi; + + /* Select ENC2J60 chip */ + + enc28j60_select(spi); + + /* Send the read command and (maybe collect the return data) */ + + rddata = SPI_SEND(spi, cmd); + + /* De-select ENC28J60 chip */ + + enc28j60_deselect(spi); + return rddata; +} + +/**************************************************************************** + * Function: enc28j60_wrglobal2 + * + * Description: + * Write to a global register (EIE, EIR, ESTAT, ECON2, or ECON1). The cmd + * include the CMD 'OR'd with the the global address register. + * + ****************************************************************************/ + +static void enc28j60_wrglobal2(FAR struct enc28j60_driver_s *priv, + uint8_t cmd, uint8_t wrdata) +{ + FAR struct spi_dev_s *spi; + + DEBUGASSERT(priv && priv->spi); + spi = priv->spi; + + /* Select ENC2J60 chip */ + + enc28j60_select(spi); + + /* Send the write command */ + + (void)SPI_SEND(spi, cmd); + + /* Send the data byte */ + + (void)SPI_SEND(spi, wrdata); + + /* De-select ENC28J60 chip. */ + + enc28j60_deselect(spi); +} + +/**************************************************************************** + * Function: enc28j60_setbank + * + * Description: + * Set the bank for these next control register access. + * + * Assumption: + * The caller has exclusive access to the SPI bus + * + ****************************************************************************/ + +static void enc28j60_setbank(FAR struct enc28j60_driver_s *priv, uint8_t bank) +{ + /* Check if the bank setting has changed*/ + + if (bank != priv->bank) + { + /* Select bank 0 (just so that all of the bits are cleared) */ + + enc28j60_clrglobal(priv, ECON1, ECON1_BSEL_MASK); + + /* Then OR in bits to get the correct bank */ + + if (bank != 0) + { + enc28j60_setglobal(priv, ECON1, (bank << ECON1_BSEL_SHIFT)); + } + + /* Then remember the bank setting */ + + priv->bank = bank; + } +} + +/**************************************************************************** + * Function: enc28j60_rdbank + * + * Description: + * Set the bank for these next control register access. + * + ****************************************************************************/ + +static uint8_t enc28j60_rdbank(FAR struct enc28j60_driver_s *priv, + uint8_t ctrlreg) +{ + FAR struct spi_dev_s *spi; + uint8_t rddata; + + DEBUGASSERT(priv && priv->spi); + spi = priv->spi; + + /* Select ENC2J60 chip */ + + enc28j60_select(spi); + + /* set the bank */ + + enc28j60_setbank(priv, GETBANK(ctrlreg)); + + /* Send the read command and collect the return data. */ + + rddata = SPI_SEND(spi, ENC28J60_RCR | GETADDR(ctrlreg)); + + /* De-select ENC28J60 chip */ + + enc28j60_deselect(spi); + return rddata; +} + +/**************************************************************************** + * Function: enc28j60_rdphymac + * + * Description: + * Somewhat different timing is required to read from any PHY or MAC + * registers. The PHY/MAC data is returned on the second byte after the + * command. + * + ****************************************************************************/ + +static uint8_t enc28j60_rdphymac(FAR struct enc28j60_driver_s *priv, + uint8_t ctrlreg) +{ + FAR struct spi_dev_s *spi; + uint8_t rddata; + + DEBUGASSERT(priv && priv->spi); + spi = priv->spi; + + /* Select ENC2J60 chip */ + + enc28j60_select(spi); + + /* Set the bank */ + + enc28j60_setbank(priv, GETBANK(ctrlreg)); + + /* Send the read command (discarding the return data) */ + + (void)SPI_SEND(spi, ENC28J60_RCR | GETADDR(ctrlreg)); + + /* Do an extra transfer to get the data from the MAC or PHY */ + + rddata = SPI_SEND(spi, 0); + + /* De-select ENC28J60 chip */ + + enc28j60_deselect(spi); + return rddata; +} + +/**************************************************************************** + * Function: enc28j60_wrbank + * + * Description: + * Set the bank for these next control register access. + * + ****************************************************************************/ + +static void enc28j60_wrbank(FAR struct enc28j60_driver_s *priv, + uint8_t ctrlreg, uint8_t wrdata) +{ + FAR struct spi_dev_s *spi; + + DEBUGASSERT(priv && priv->spi); + spi = priv->spi; + + /* Select ENC2J60 chip */ + + enc28j60_select(spi); + + /* Set the bank */ + + enc28j60_setbank(priv, GETBANK(ctrlreg)); + + /* Send the write command */ + + (void)SPI_SEND(spi, ENC28J60_WCR | GETADDR(ctrlreg)); + + /* Send the data byte */ + + (void)SPI_SEND(spi, wrdata); + + /* De-select ENC28J60 chip. */ + + enc28j60_deselect(spi); +} + /**************************************************************************** * Function: enc28j60_transmit * @@ -276,7 +514,7 @@ static uint8_t enc28j60_deselect(FAR struct spi_dev_s *spi) * ****************************************************************************/ -static int enc28j60_transmit(FAR struct enc28j60_drver_s *priv) +static int enc28j60_transmit(FAR struct enc28j60_driver_s *priv) { /* Verify that the hardware is ready to send another packet */ @@ -317,7 +555,7 @@ static int enc28j60_transmit(FAR struct enc28j60_drver_s *priv) static int enc28j60_uiptxpoll(struct uip_driver_s *dev) { - FAR struct enc28j60_drver_s *priv = (FAR struct enc28j60_drver_s *)dev->d_private; + FAR struct enc28j60_driver_s *priv = (FAR struct enc28j60_driver_s *)dev->d_private; /* If the polling resulted in data that should be sent out on the network, * the field d_len is set to a value > 0. @@ -356,7 +594,7 @@ static int enc28j60_uiptxpoll(struct uip_driver_s *dev) * ****************************************************************************/ -static void enc28j60_receive(FAR struct enc28j60_drver_s *priv) +static void enc28j60_receive(FAR struct enc28j60_driver_s *priv) { do { @@ -384,27 +622,26 @@ static void enc28j60_receive(FAR struct enc28j60_drver_s *priv) */ if (priv->dev.d_len > 0) - { - uip_arp_out(&priv->dev); - enc28j60_transmit(priv); - } + { + uip_arp_out(&priv->dev); + enc28j60_transmit(priv); + } + } + else if (BUF->type == htons(UIP_ETHTYPE_ARP)) + { + uip_arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + enc28j60_transmit(priv); + } } - else if (BUF->type == htons(UIP_ETHTYPE_ARP)) - { - uip_arp_arpin(&priv->dev); - - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. - */ - - if (priv->dev.d_len > 0) - { - enc28j60_transmit(priv); - } - } - } - } - while (); /* While there are more packets to be processed */ + } + while (false); /* While there are more packets to be processed */ } /**************************************************************************** @@ -423,7 +660,7 @@ static void enc28j60_receive(FAR struct enc28j60_drver_s *priv) * ****************************************************************************/ -static void enc28j60_txdone(FAR struct enc28j60_drver_s *priv) +static void enc28j60_txdone(FAR struct enc28j60_driver_s *priv) { /* Check for errors and update statistics */ @@ -455,7 +692,7 @@ static void enc28j60_txdone(FAR struct enc28j60_drver_s *priv) static int enc28j60_interrupt(int irq, FAR void *context) { - register FAR struct enc28j60_drver_s *priv = &g_enc28j60[0]; + register FAR struct enc28j60_driver_s *priv = &g_enc28j60[0]; /* Disable Ethernet interrupts */ @@ -498,7 +735,7 @@ static int enc28j60_interrupt(int irq, FAR void *context) static void enc28j60_txtimeout(int argc, uint32_t arg, ...) { - FAR struct enc28j60_drver_s *priv = (FAR struct enc28j60_drver_s *)arg; + FAR struct enc28j60_driver_s *priv = (FAR struct enc28j60_driver_s *)arg; /* Increment statistics and dump debug info */ @@ -528,7 +765,7 @@ static void enc28j60_txtimeout(int argc, uint32_t arg, ...) static void enc28j60_polltimer(int argc, uint32_t arg, ...) { - FAR struct enc28j60_drver_s *priv = (FAR struct enc28j60_drver_s *)arg; + FAR struct enc28j60_driver_s *priv = (FAR struct enc28j60_driver_s *)arg; /* Check if there is room in the send another TXr packet. */ @@ -560,7 +797,7 @@ static void enc28j60_polltimer(int argc, uint32_t arg, ...) static int enc28j60_ifup(struct uip_driver_s *dev) { - FAR struct enc28j60_drver_s *priv = (FAR struct enc28j60_drver_s *)dev->d_private; + FAR struct enc28j60_driver_s *priv = (FAR struct enc28j60_driver_s *)dev->d_private; ndbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, @@ -597,7 +834,7 @@ static int enc28j60_ifup(struct uip_driver_s *dev) static int enc28j60_ifdown(struct uip_driver_s *dev) { - FAR struct enc28j60_drver_s *priv = (FAR struct enc28j60_drver_s *)dev->d_private; + FAR struct enc28j60_driver_s *priv = (FAR struct enc28j60_driver_s *)dev->d_private; irqstate_t flags; /* Disable the Ethernet interrupt */ @@ -638,7 +875,7 @@ static int enc28j60_ifdown(struct uip_driver_s *dev) static int enc28j60_txavail(struct uip_driver_s *dev) { - FAR struct enc28j60_drver_s *priv = (FAR struct enc28j60_drver_s *)dev->d_private; + FAR struct enc28j60_driver_s *priv = (FAR struct enc28j60_driver_s *)dev->d_private; irqstate_t flags; flags = irqsave(); diff --git a/drivers/net/enc28j60.h b/drivers/net/enc28j60.h index 8083219251..a3840128b1 100755 --- a/drivers/net/enc28j60.h +++ b/drivers/net/enc28j60.h @@ -1,166 +1,184 @@ -/**************************************************************************** - * drivers/net/enc28j60.h - * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#ifndef __DRIVERS_NET_ENC28J60_H -#define __DRIVERS_NET_ENC28J60_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* A total of seven instructions are implemented on the ENC28J60 */ - -#define ENC28J60_RCR (0x00) /* Read Control Register - * 000 | aaaaa | (Registe value returned)) */ -#define ENC28J60_RBM (0x3a) /* Read Buffer Memory - * 001 | 11010 | (Read buffer data follows) */ -#define ENC28J60_WCR (0x40) /* Write Control Register - * 010 | aaaaa | dddddddd */ -#define ENC28J60_WBM (0x7a) /* Write Buffer Memory - * 011 | 11010 | (Write buffer data follows) */ -#define ENC28J60_BFS (0x80) /* Bit Field Set - * 100 | aaaaa | dddddddd */ -#define ENC28J60_BFC (0xa0) /* Bit Field Clear - * 101 | aaaaa | dddddddd */ -#define ENC28J60_SRC (0xff) /* System Reset - * 111 | 11111 | (No data) */ - -/* Control registers are accessed with the RCR, RBM, WCR, BFS, and BFC commands. - * The following identifies all ENC28J60 control registers. The Control register - * memory is partitioned into four banks, selectable by the bank select bits, - * BSEL1:BSEL0, in the ECON1 register. - * - * The last five locations (0x1b to 0x1f) of all banks point to a common set of - * registers: EIE, EIR, ESTAT, ECON2 and ECON1. These are key registers used - * in controlling and monitoring the operation of the device. Their common - * mapping allows easy access without switching the bank. - * - * Control registers for the ENC28J60 are generically grouped as ETH, MAC and - * MII registers. Register names starting with E belong to the ETH group. Similarly, - * registers names starting with MA belong to the MAC group and registers prefixed - * with MI belong to the MII group. - */ - -#define EIE (0x1b) /* Ethernet Interrupt Enable Register */ -#define EIR (0x1c) /* Ethernet Interupt Request Register */ -#define ESTAT (0x1d) /* Ethernet Status Register */ -#define ECON2 (0x1e) /* Ethernet Control 2 Register */ -#define ECON1 (0x1f) /* Ethernet Control 1 Register */ - -/* Ethernet Interrupt Enable Register Bit Definitions */ - -#define EIE_RXERIE (1 << 0) /* Bit 0: Receive Error Interrupt Enable */ -#define EIE_TXERIE (1 << 1) /* Bit 1: Transmit Error Interrupt Enable */ - /* Bit 2: Reserved */ -#define EIE_TXIE (1 << 3) /* Bit 3: Transmit Enable */ -#define EIE_LINKIE (1 << 4) /* Bit 4: Link Status Change Interrupt Enable */ -#define EIE_DMAIE (1 << 5) /* Bit 5: DMA Interrupt Enable */ -#define EIE_PKTIE (1 << 6) /* Bit 6: Receive Packet Pending Interrupt Enable */ -#define EIE_INTIE (1 << 7) /* Bit 7: Global INT Interrupt Enable */ - -/* Ethernet Interupt Request Register Bit Definitions */ - -#define EIR_RXERIF (1 << 0) /* Bit 0: Receive Error Interrupt */ -#define EIR_TXERIF (1 << 1) /* Bit 1: Transmit Error Interrupt */ - /* Bit 2: Reserved */ -#define EIR_TXIF (1 << 3) /* Bit 3: Transmit Interrupt */ -#define EIR_LINKIF (1 << 4) /* Bit 4: Link Change Interrupt */ -#define EIR_DMAIF (1 << 5) /* Bit 5: DMA Interrupt */ -#define EIR_PKTIF (1 << 6) /* Bit 6: Receive Packet Pending Interrupt */ - /* Bit 7: Reserved */ - -/* Ethernet Status Register Bit Definitions */ - -#define ESTAT_CLKRDY (1 << 0) /* Bit 0: Clock Ready */ -#define ESTAT_TXABRT (1 << 1) /* Bit 1: Transmit Abort Error */ -#define ESTAT_RXBUSY (1 << 2) /* Bit 2: Receive Busy */ - /* Bit 3: Reserved */ -#define ESTAT_LATECOL (1 << 4) /* Bit 4: Late Collision Error */ - /* Bit 5: Reserved */ -#define ESTAT_BUFER (1 << 6) /* Bit 6: Ethernet Buffer Error Status */ -#define ESTAT_INT (1 << 7) /* Bit 7: INT Interrupt */ - -/* Ethernet Control 1 Register Bit Definitions */ - -#define ECON1_BSEL_SHIFT (0) /* Bits 0-1: Bank select */ -#define ECON1_BSEL_MASK (3 << ECON1_BSEL_SHIFT) -# define ECON1_BSEL_BANK0 (0 << 0) /* Bank 0 */ -# define ECON1_BSEL_BANK1 (1 << 1) /* Bank 1 */ -# define ECON1_BSEL_BANK2 (2 << 0) /* Bank 2 */ -# define ECON1_BSEL_BANK3 (3 << 0) /* Bank 3 */ -#define ECON1_RXEN (1 << 2) /* Bit 2: Receive Enable */ -#define ECON1_TXRTS (1 << 3) /* Bit 3: Transmit Request to Send */ -#define ECON1_CSUMEN (1 << 4) /* Bit 4: DMA Checksum Enable */ -#define ECON1_DMAST (1 << 5) /* Bit 5: DMA Start and Busy Status */ -#define ECON1_RXRST (1 << 6) /* Bit 6: Receive Logic Reset */ -#define ECON1_TXRST (1 << 7) /* Bit 7: Transmit Logic Reset */ - -/* Ethernet Control 2 Register */ - /* Bits 0-2: Reserved */ -#define ECON2_VRPS (1 << 3) /* Bit 3: Voltage Regulator Power Save Enable */ - /* Bit 4: Reserved */ -#define ECON2_PWRSV (1 << 5) /* Bit 5: Power Save Enable */ -#define ECON2_PKTDEC (1 << 6) /* Bit 6: Packet Decrement */ -#define ECON2_AUTOINC (1 << 7) /* Bit 7: Automatic Buffer Pointer Increment Enable */ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" { -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#undef EXTERN -#ifdef __cplusplus -} -#endif - -#endif /* __DRIVERS_NET_ENC28J60_H */ +/**************************************************************************** + * drivers/net/enc28j60.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __DRIVERS_NET_ENC28J60_H +#define __DRIVERS_NET_ENC28J60_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* A total of seven instructions are implemented on the ENC28J60 */ + +#define ENC28J60_RCR (0x00) /* Read Control Register + * 000 | aaaaa | (Registe value returned)) */ +#define ENC28J60_RBM (0x3a) /* Read Buffer Memory + * 001 | 11010 | (Read buffer data follows) */ +#define ENC28J60_WCR (0x40) /* Write Control Register + * 010 | aaaaa | dddddddd */ +#define ENC28J60_WBM (0x7a) /* Write Buffer Memory + * 011 | 11010 | (Write buffer data follows) */ +#define ENC28J60_BFS (0x80) /* Bit Field Set + * 100 | aaaaa | dddddddd */ +#define ENC28J60_BFC (0xa0) /* Bit Field Clear + * 101 | aaaaa | dddddddd */ +#define ENC28J60_SRC (0xff) /* System Reset + * 111 | 11111 | (No data) */ + +/* Control registers are accessed with the RCR, RBM, WCR, BFS, and BFC commands. + * The following identifies all ENC28J60 control registers. The Control register + * memory is partitioned into four banks, selectable by the bank select bits, + * BSEL1:BSEL0, in the ECON1 register. + * + * The last five locations (0x1b to 0x1f) of all banks point to a common set of + * registers: EIE, EIR, ESTAT, ECON2 and ECON1. These are key registers used + * in controlling and monitoring the operation of the device. Their common + * mapping allows easy access without switching the bank. + * + * Control registers for the ENC28J60 are generically grouped as ETH, MAC and + * MII registers. Register names starting with E belong to the ETH group. Similarly, + * registers names starting with MA belong to the MAC group and registers prefixed + * with MI belong to the MII group. + */ + +#define EIE (0x1b) /* Ethernet Interrupt Enable Register */ +#define EIR (0x1c) /* Ethernet Interupt Request Register */ +#define ESTAT (0x1d) /* Ethernet Status Register */ +#define ECON2 (0x1e) /* Ethernet Control 2 Register */ +#define ECON1 (0x1f) /* Ethernet Control 1 Register */ + +/* The remaining control registers are identified with a a 5 bit address and a + * bank selection. We pack the bank number and the control register address + * together to keep the design simpler. + */ + +#define ENC28J60_ADDR_SHIFT (0) /* Bits 0-4: Register address */ +#define ENC28J60_ADDR_MASK (0x1f << ENC28J60_ADDR_SHIFT) +#define ENC28J60_BANK_SHIFT (5) /* Bits 5-6: Bank number */ +#define ENC28J60_BANK_MASK (3 << ENC28J60_BSEL_SHIFT) +# define ENC28J60_BANK0 (0 << ENC28J60_BSEL_SHIFT) +# define ENC28J60_BANK1 (1 << ENC28J60_BSEL_SHIFT) +# define ENC28J60_BANK2 (2 << ENC28J60_BSEL_SHIFT) +# define ENC28J60_BANK3 (3 << ENC28J60_BSEL_SHIFT) + +#define REGADDR(a,b) ((b) << ENC28J60_BANK_SHIFT | (a)) +#define GETADDR(a) ((a) & ENC28J60_ADDR_MASK) +#define GETBANK(a) (((a) >> ENC28J60_BANK_SHIFT) & 3) + +/* Ethernet Interrupt Enable Register Bit Definitions */ + +#define EIE_RXERIE (1 << 0) /* Bit 0: Receive Error Interrupt Enable */ +#define EIE_TXERIE (1 << 1) /* Bit 1: Transmit Error Interrupt Enable */ + /* Bit 2: Reserved */ +#define EIE_TXIE (1 << 3) /* Bit 3: Transmit Enable */ +#define EIE_LINKIE (1 << 4) /* Bit 4: Link Status Change Interrupt Enable */ +#define EIE_DMAIE (1 << 5) /* Bit 5: DMA Interrupt Enable */ +#define EIE_PKTIE (1 << 6) /* Bit 6: Receive Packet Pending Interrupt Enable */ +#define EIE_INTIE (1 << 7) /* Bit 7: Global INT Interrupt Enable */ + +/* Ethernet Interupt Request Register Bit Definitions */ + +#define EIR_RXERIF (1 << 0) /* Bit 0: Receive Error Interrupt */ +#define EIR_TXERIF (1 << 1) /* Bit 1: Transmit Error Interrupt */ + /* Bit 2: Reserved */ +#define EIR_TXIF (1 << 3) /* Bit 3: Transmit Interrupt */ +#define EIR_LINKIF (1 << 4) /* Bit 4: Link Change Interrupt */ +#define EIR_DMAIF (1 << 5) /* Bit 5: DMA Interrupt */ +#define EIR_PKTIF (1 << 6) /* Bit 6: Receive Packet Pending Interrupt */ + /* Bit 7: Reserved */ + +/* Ethernet Status Register Bit Definitions */ + +#define ESTAT_CLKRDY (1 << 0) /* Bit 0: Clock Ready */ +#define ESTAT_TXABRT (1 << 1) /* Bit 1: Transmit Abort Error */ +#define ESTAT_RXBUSY (1 << 2) /* Bit 2: Receive Busy */ + /* Bit 3: Reserved */ +#define ESTAT_LATECOL (1 << 4) /* Bit 4: Late Collision Error */ + /* Bit 5: Reserved */ +#define ESTAT_BUFER (1 << 6) /* Bit 6: Ethernet Buffer Error Status */ +#define ESTAT_INT (1 << 7) /* Bit 7: INT Interrupt */ + +/* Ethernet Control 1 Register Bit Definitions */ + +#define ECON1_BSEL_SHIFT (0) /* Bits 0-1: Bank select */ +#define ECON1_BSEL_MASK (3 << ECON1_BSEL_SHIFT) +# define ECON1_BSEL_BANK0 (0 << 0) /* Bank 0 */ +# define ECON1_BSEL_BANK1 (1 << 1) /* Bank 1 */ +# define ECON1_BSEL_BANK2 (2 << 0) /* Bank 2 */ +# define ECON1_BSEL_BANK3 (3 << 0) /* Bank 3 */ +#define ECON1_RXEN (1 << 2) /* Bit 2: Receive Enable */ +#define ECON1_TXRTS (1 << 3) /* Bit 3: Transmit Request to Send */ +#define ECON1_CSUMEN (1 << 4) /* Bit 4: DMA Checksum Enable */ +#define ECON1_DMAST (1 << 5) /* Bit 5: DMA Start and Busy Status */ +#define ECON1_RXRST (1 << 6) /* Bit 6: Receive Logic Reset */ +#define ECON1_TXRST (1 << 7) /* Bit 7: Transmit Logic Reset */ + +/* Ethernet Control 2 Register */ + /* Bits 0-2: Reserved */ +#define ECON2_VRPS (1 << 3) /* Bit 3: Voltage Regulator Power Save Enable */ + /* Bit 4: Reserved */ +#define ECON2_PWRSV (1 << 5) /* Bit 5: Power Save Enable */ +#define ECON2_PKTDEC (1 << 6) /* Bit 6: Packet Decrement */ +#define ECON2_AUTOINC (1 << 7) /* Bit 7: Automatic Buffer Pointer Increment Enable */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __DRIVERS_NET_ENC28J60_H */ diff --git a/drivers/net/skeleton.c b/drivers/net/skeleton.c index 399c871312..a9621edd8a 100644 --- a/drivers/net/skeleton.c +++ b/drivers/net/skeleton.c @@ -264,21 +264,20 @@ static void skel_receive(FAR struct skel_driver_s *skel) uip_arp_out(&skel->sk_dev); skel_transmit(skel); } - } - else if (BUF->type == htons(UIP_ETHTYPE_ARP)) - { - uip_arp_arpin(&skel->sk_dev); + } + else if (BUF->type == htons(UIP_ETHTYPE_ARP)) + { + uip_arp_arpin(&skel->sk_dev); - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. - */ + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ - if (skel->sk_dev.d_len > 0) - { - skel_transmit(skel); - } - } - } + if (skel->sk_dev.d_len > 0) + { + skel_transmit(skel); + } + } } while (); /* While there are more packets to be processed */ } @@ -592,4 +591,3 @@ int skel_initialize(void) } #endif /* CONFIG_NET && CONFIG_skeleton_NET */ -