diff options
Diffstat (limited to 'nuttx/drivers')
-rwxr-xr-x | nuttx/drivers/net/enc28j60.c | 309 | ||||
-rwxr-xr-x | nuttx/drivers/net/enc28j60.h | 350 | ||||
-rw-r--r-- | nuttx/drivers/net/skeleton.c | 30 |
3 files changed, 471 insertions, 218 deletions
diff --git a/nuttx/drivers/net/enc28j60.c b/nuttx/drivers/net/enc28j60.c index c82de4767..87ae285f6 100755 --- a/nuttx/drivers/net/enc28j60.c +++ b/nuttx/drivers/net/enc28j60.c @@ -42,11 +42,11 @@ ****************************************************************************/ #include <nuttx/config.h> -#if defined(CONFIG_NET) && defined(CONFIG_ENC28J60_NET) +#if defined(CONFIG_NET) && defined(CONFIG_NET_ENC28J60) #include <stdint.h> #include <stdbool.h> -#include <stding.h> +#include <stdint.h> #include <time.h> #include <string.h> #include <debug.h> @@ -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 */ @@ -260,6 +285,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 * * Description: @@ -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/nuttx/drivers/net/enc28j60.h b/nuttx/drivers/net/enc28j60.h index 808321925..a3840128b 100755 --- a/nuttx/drivers/net/enc28j60.h +++ b/nuttx/drivers/net/enc28j60.h @@ -1,166 +1,184 @@ -/****************************************************************************
- * drivers/net/enc28j60.h
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
- *
- * 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 <spudmonkey@racsa.co.cr> + * + * 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/nuttx/drivers/net/skeleton.c b/nuttx/drivers/net/skeleton.c index 399c87131..a9621edd8 100644 --- a/nuttx/drivers/net/skeleton.c +++ b/nuttx/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); - - /* 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); - } - } - } + } + 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 (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 */ - |