⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm90x0.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 4 页
字号:
/**************************************************************************** * drivers/net/dm9x.c * *   Copyright (C) 2007 Gregory Nutt. All rights reserved. *   Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * References: Davicom data sheets (DM9000-DS-F03-041906.pdf, *   DM9010-DS-F01-103006.pdf) and looking at lots of other DM90x0 *   drivers. * * 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. * ****************************************************************************//**************************************************************************** * Included Files ****************************************************************************/#include <nuttx/config.h>#if defined(CONFIG_NET) && defined(CONFIG_NET_DM90x0)/* Only one hardware interface supported at present (although there are * hooks throughout the design to that extending the support to multiple * interfaces should not be that difficult) */#undef  CONFIG_DM9X_NINTERFACES#define CONFIG_DM9X_NINTERFACES 1#include <time.h>#include <string.h>#include <debug.h>#include <wdog.h>#include <errno.h>#include <nuttx/irq.h>#include <nuttx/arch.h>#include <net/ethernet.h>#include <net/uip/uip.h>#include <net/uip/uip-arp.h>#include <net/uip/uip-arch.h>/**************************************************************************** * Definitions ****************************************************************************//* DM90000 and DM9010 register offets */#define DM9X_NETC          0x00 /* Network control register */#define DM9X_NETS          0x01 /* Network Status register */#define DM9X_TXC           0x02 /* TX control register */#define DM9X_TXS1          0x03 /* TX status register 1 */#define DM9X_TXS2          0x03 /* TX status register 2 */#define DM9X_RXC           0x05 /* RX control register */#define DM9X_RXS           0x06 /* RX status register */#define DM9X_RXOVF         0x07 /* Receive overflow counter register */#define DM9X_BPTHRES       0x08 /* Back pressure threshold register */#define DM9X_FCTHRES       0x09 /* Flow control threshold register */#define DM9X_FC            0x0a /* RX/TX flow control register */#define DM9X_EEPHYC        0x0b /* EEPROM & PHY control register */#define DM9X_EEPHYA        0x0c /* EEPROM & PHY address register */#define DM9X_EEPHYDL       0x0d /* EEPROM & PHY data register (lo) */#define DM9X_EEPHYDH       0x0e /* EEPROM & PHY data register (hi) */#define DM9X_WAKEUP        0x0f /* Wake-up control register */#define DM9X_PAB0          0x10 /* Physical address register (byte 0) */#define DM9X_PAB1          0x11 /* Physical address register (byte 1) */#define DM9X_PAB2          0x12 /* Physical address register (byte 2) */#define DM9X_PAB3          0x13 /* Physical address register (byte 3) */#define DM9X_PAB4          0x14 /* Physical address register (byte 4) */#define DM9X_PAB5          0x15 /* Physical address register (byte 5) */#define DM9X_MAB0          0x16 /* Multicast address register (byte 0) */#define DM9X_MAB1          0x17 /* Multicast address register (byte 1) */#define DM9X_MAB2          0x18 /* Multicast address register (byte 2) */#define DM9X_MAB3          0x19 /* Multicast address register (byte 3) */#define DM9X_MAB4          0x1a /* Multicast address register (byte 4) */#define DM9X_MAB5          0x1b /* Multicast address register (byte 5) */#define DM9X_MAB6          0x1c /* Multicast address register (byte 6) */#define DM9X_MAB7          0x1d /* Multicast address register (byte 7) */#define DM9X_GPC           0x1e /* General purpose control register */#define DM9X_GPD           0x1f /* General purpose register */#define DM9X_TRPAL         0x22 /* TX read pointer address (lo) */#define DM9X_TRPAH         0x23 /* TX read pointer address (hi) */#define DM9X_RWPAL         0x24 /* RX write pointer address (lo) */#define DM9X_RWPAH         0x25 /* RX write pointer address (hi) */#define DM9X_VIDL          0x28 /* Vendor ID (lo) */#define DM9X_VIDH          0x29 /* Vendor ID (hi) */#define DM9X_PIDL          0x2a /* Product ID (lo) */#define DM9X_PIDH          0x2b /* Product ID (hi) */#define DM9X_CHIPR         0x2c /* Product ID (lo) */#define DM9X_TXC2          0x2d /* Transmit control register 2 (dm9010) */#define DM9X_OTC           0x2e /* Operation test control register (dm9010) */#define DM9X_SMODEC        0x2f /* Special mode control register */#define DM9X_ETXCSR        0x30 /* Early transmit control/status register (dm9010) */#define DM9X_TCCR          0x31 /* Transmit checksum control register (dm9010) */#define DM9X_RCSR          0x32 /* Receive checksum control/status register (dm9010) */#define DM9X_EPHYA         0x33 /* External PHY address register (dm9010) */#define DM9X_GPC2          0x34 /* General purpose control register 2 (dm9010) */#define DM9X_GPD2          0x35 /* General purpose register 2 */#define DM9X_GPC3          0x36 /* General purpose control register 3 (dm9010) */#define DM9X_GPD3          0x37 /* General purpose register 3 */#define DM9X_PBUSC         0x38 /* Processor bus control register (dm9010) */#define DM9X_IPINC         0x39 /* INT pin control register (dm9010) */#define DM9X_MON1          0x40 /* Monitor register 1 (dm9010) */#define DM9X_MON2          0x41 /* Monitor register 2 (dm9010) */#define DM9X_SCLKC         0x50 /* System clock turn ON control register (dm9010) */#define DM9X_SCLKR         0x51 /* Resume system clock control register (dm9010) */#define DM9X_MRCMDX        0xf0 /* Memory data pre-fetch read command without address increment */#define DM9X_MRCMDX1       0xf1 /* memory data read command without address increment (dm9010) */#define DM9X_MRCMD         0xf2 /* Memory data read command with address increment */#define DM9X_MDRAL         0xf4 /* Memory data read address register (lo) */#define DM9X_MDRAH         0xf5 /* Memory data read address register (hi) */#define DM9X_MWCMDX        0xf6 /* Memory data write command without address increment */#define DM9X_MWCMD         0xf8 /* Memory data write command with address increment */#define DM9X_MDWAL         0xfa /* Memory data write address register (lo) */#define DM9X_MDWAH         0xfb /* Memory data write address register (lo) */#define DM9X_TXPLL         0xfc /* Memory data write address register (lo) */#define DM9X_TXPLH         0xfd /* Memory data write address register (hi) */#define DM9X_ISR           0xfe /* Interrupt status register */#define DM9X_IMR           0xff /* Interrupt mask register *//* Network control register bit definitions */#define DM9X_NETC_RST      (1 << 0) /* Software reset */#define DM9X_NETC_LBKM     (3 << 1) /* Loopback mode mask */#define DM9X_NETC_LBK0     (0 << 1) /*   0: Normal */#define DM9X_NETC_LBK1     (1 << 1) /*   1: MAC internal loopback */#define DM9X_NETC_LBK2     (2 << 1) /*   2: Internal PHY 100M mode loopback */#define DM9X_NETC_FDX      (1 << 3) /* Full dupliex mode */#define DM9X_NETC_FCOL     (1 << 4) /* Force collision mode */#define DM9X_NETC_WAKEEN   (1 << 6) /* Wakeup event enable */#define DM9X_NETC_EXTPHY   (1 << 7) /* Select external PHY *//* Network status bit definitions */#define DM9X_NETS_RXOV     (1 << 1) /* RX Fifo overflow */#define DM9X_NETS_TX1END   (1 << 2) /* TX packet 1 complete status */#define DM9X_NETS_TX2END   (1 << 3) /* TX packet 2 complete status */#define DM9X_NETS_WAKEST   (1 << 5) /* Wakeup event status */#define DM9X_NETS_LINKST   (1 << 6) /* Link status */#define DM9X_NETS_SPEED    (1 << 7) /* Media speed *//* IMR/ISR bit definitions */#define DM9X_INT_PR        (1 << 0) /* Packet received interrupt */#define DM9X_INT_PT        (1 << 1) /* Packet transmitted interrupt */#define DM9X_INT_RO        (1 << 2) /* Receive overflow interrupt */#define DM9X_INT_ROO       (1 << 3) /* Receive overflow counter overflow int */#define DM9X_INT_UDRUN     (1 << 4) /* Transmit underrun interrupt */#define DM9X_INT_LNKCHG    (1 << 5) /* Link status change interrupt */#define DM9X_INT_ALL       (0x3f)#define DM9X_IMR_UNUSED    (1 << 6) /* (not used) */#define DM9X_IMR_PAR       (1 << 7) /* Enable auto R/W pointer reset */#define DM9X_ISR_IOMODEM   (3 << 6) /* IO mode mask */#define DM9X_ISR_IOMODE8   (2 << 6) /*   IO mode = 8 bit */#define DM9X_ISR_IOMODE16  (0 << 6) /*   IO mode = 16 bit */#define DM9X_ISR_IOMODE32  (1 << 6) /*   IO mode = 32 bit */#define DM9X_IMRENABLE     (DM9X_INT_PR|DM9X_INT_PT|DM9X_INT_LNKCHG|DM9X_IMR_PAR)#define DM9X_IMRRXDISABLE  (DM9X_INT_PT|DM9X_INT_LNKCHG|DM9X_IMR_PAR)#define DM9X_IMRDISABLE    (DM9X_IMR_PAR)/* EEPROM/PHY control regiser bits */#define DM9X_EEPHYC_ERRE   (1 << 0) /* EEPROM (vs PHY) access status */#define DM9X_EEPHYC_ERPRW  (1 << 1) /* EEPROM/PHY write access */#define DM9X_EEPHYC_ERPRR  (1 << 2) /* EEPROM/PHY read access */#define DM9X_EEPHYC_EPOS   (1 << 3) /* EEPROM/PHY operation select */#define DM9X_EEPHYC_WEP    (1 << 4) /* Write EEPROM enable */#define DM9X_EEPHYC_REEP   (1 << 5) /* Reload EEPROM *//* Supported values from the vendor and product ID register */#define DM9X_DAVICOMVID    0x0a46#define DM9X_DM9000PID     0x9000#define DM9X_DM9010PID     0x9010/* RX control register bit settings */#define DM9X_RXC_RXEN      (1 << 0) /* RX enable */#define DM9X_RXC_PRMSC     (1 << 1) /* Promiscuous mode */#define DM9X_RXC_RUNT      (1 << 2) /* Pass runt packet */#define DM9X_RXC_ALL       (1 << 3) /* Pass all multicast */#define DM9X_RXC_DISCRC    (1 << 4) /* Discard CRC error packets */#define DM9X_RXC_DISLONG   (1 << 5) /* Discard long packets */#define DM9X_RXC_WTDIS     (1 << 6) /* Disable watchdog timer */#define DM9X_RXC_HASHALL   (1 << 7) /* Filter all addresses in hash table */#define DM9X_RXCSETUP      (DM9X_RXC_DISCRC|DM9X_RXC_DISLONG)/* EEPHY bit settings */#define DM9X_EEPHYA_EROA   0x40 /* PHY register address 0x01 */#define DM9X_PKTRDY        0x01 /* Packet ready to receive *//* The RX interrupt will be disabled if more than the following RX * interrupts are received back-to-back. */#define DM9X_CRXTHRES 10/* All access is via an index register and a data regist.  Select accecss * according to user supplied base address and bus width. */#if defined(CONFIG_DM9X_BUSWIDTH8)#  define DM9X_INDEX *(volatile uint8*)(CONFIG_DM9X_BASE)#  define DM9X_DATA  *(volatile uint8*)(CONFIG_DM9X_BASE + 2)#elif defined(CONFIG_DM9X_BUSWIDTH16)#  define DM9X_INDEX *(volatile uint16*)(CONFIG_DM9X_BASE)#  define DM9X_DATA  *(volatile uint16*)(CONFIG_DM9X_BASE + 2)#elif defined(CONFIG_DM9X_BUSWIDTH32)#  define DM9X_INDEX *(volatile uint32*)(CONFIG_DM9X_BASE)#  define DM9X_DATA  *(volatile uint32*)(CONFIG_DM9X_BASE + 2)#endif/* Phy operating mode.  Default is AUTO, but this setting can be overridden * in the NuttX configuration file. */#define DM9X_MODE_AUTO    0#define DM9X_MODE_10MHD   1#define DM9X_MODE_100MHD  2#define DM9X_MODE_10MFD   3#define DM9X_MODE_100MFD  4#ifndef CONFIG_DM9X_MODE# define CONFIG_DM9X_MODE DM9X_MODE_AUTO#endif/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */#define DM6X_WDDELAY   (1*CLK_TCK)#define DM6X_POLLHSEC  (1*2)/* TX timeout = 1 minute */#define DM6X_TXTIMEOUT (60*CLK_TCK)/* This is a helper pointer for accessing the contents of the Ethernet header */#define BUF ((struct uip_eth_hdr *)dm9x->dm_dev.d_buf)/**************************************************************************** * Private Types ****************************************************************************/union rx_desc_u{  uint8 rx_buf[4];  struct  {    uint8  rx_byte;    uint8  rx_status;    uint16 rx_len;  } desc;};/* The dm9x_driver_s encapsulates all DM90x0 state information for a single * DM90x0 hardware interface */struct dm9x_driver_s{  boolean dm_bifup;            /* TRUE:ifup FALSE:ifdown */  boolean dm_b100M;            /* TRUE:speed == 100M; FALSE:speed == 10M */  WDOG_ID dm_txpoll;           /* TX poll timer */  WDOG_ID dm_txtimeout;        /* TX timeout timer */  uint8   dm_ntxpending;       /* Count of packets pending transmission */  uint8   ncrxpackets;         /* Number of continuous rx packets  */  /* Mode-dependent function to move data in 8/16/32 I/O modes */  void (*dm_read)(uint8 *ptr, int len);  void (*dm_write)(const uint8 *ptr, int len);  void (*dm_discard)(int len);#if defined(CONFIG_DM9X_STATS)  uint32 dm_ntxpackets;        /* Count of packets sent */  uint32 dm_ntxbytes;          /* Count of bytes sent */  uint32 dm_ntxerrors;         /* Count of TX errors */  uint32 dm_nrxpackets;        /* Count of packets received */  uint32 dm_nrxbytes;          /* Count of bytes received */  uint32 dm_nrxfifoerrors;     /* Count of RX FIFO overflow errors */  uint32 dm_nrxcrcerrors;      /* Count of RX CRC errors */  uint32 dm_nrxlengtherrors;   /* Count of RX length errors */  uint32 dm_nphyserrors;       /* Count of physical layer errors */  uint32 dm_nresets;           /* Counts number of resets */  uint32 dm_ntxtimeouts;       /* Counts resets caused by TX timeouts */#endif  /* This holds the information visible to uIP/NuttX */  struct uip_driver_s dm_dev;};/**************************************************************************** * Private Data ****************************************************************************//* At present, only a single DM90x0 device is supported. */static struct dm9x_driver_s g_dm9x[CONFIG_DM9X_NINTERFACES];/**************************************************************************** * Private Function Prototypes ****************************************************************************//* Utility functions */static uint8 getreg(int reg);static void putreg(int reg, uint8 value);static void read8(uint8 *ptr, int len);static void read16(uint8 *ptr, int len);static void read32(uint8 *ptr, int len);static void discard8(int len);static void discard16(int len);static void discard32(int len);static void write8(const uint8 *ptr, int len);static void write16(const uint8 *ptr, int len);static void write32(const uint8 *ptr, int len);/* static uint16 dm9x_readsrom(struct dm9x_driver_s *dm9x, int offset); */static uint16 dm9x_phyread(struct dm9x_driver_s *dm9x, int reg);static void dm9x_phywrite(struct dm9x_driver_s *dm9x, int reg, uint16 value);#if defined(CONFIG_DM9X_STATS)static void dm9x_resetstatistics(struct dm9x_driver_s *dm9x);#else# define dm9x_resetstatistics(dm9x)#endif#if defined(CONFIG_DM9X_STATS) && defined(CONFIG_DEBUG)static void dm9x_dumpstatistics(struct dm9x_driver_s *dm9x);#else# define dm9x_dumpstatistics(dm9x)#endif#if defined(CONFIG_DM9X_CHECKSUM)static boolean dm9x_rxchecksumready(uint8);#else#  define dm9x_rxchecksumready(a) ((a) == 0x01)#endif/* Common TX logic */static int  dm9x_transmit(struct dm9x_driver_s *dm9x);static int  dm9x_uiptxpoll(struct uip_driver_s *dev);/* Interrupt handling */static void dm9x_receive(struct dm9x_driver_s *dm9x);static void dm9x_txdone(struct dm9x_driver_s *dm9x);static int  dm9x_interrupt(int irq, FAR void *context);/* Watchdog timer expirations */static void dm9x_polltimer(int argc, uint32 arg, ...);static void dm9x_txtimeout(int argc, uint32 arg, ...);/* NuttX callback functions */static int dm9x_ifup(struct uip_driver_s *dev);static int dm9x_ifdown(struct uip_driver_s *dev);static int dm9x_txavail(struct uip_driver_s *dev);/* Initialization functions */static void dm9x_bringup(struct dm9x_driver_s *dm9x);static void dm9x_reset(struct dm9x_driver_s *dm9x);/**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Function: getreg and setreg * * Description: *   Access to memory-mapped DM90x0 8-bit registers * * Parameters: *   reg - Register number *   value - Value to write to the register (setreg only) * * Returned Value: *   Value read from the register (getreg only) * * Assumptions: * ****************************************************************************/static uint8 getreg(int reg){  DM9X_INDEX = reg;  return DM9X_DATA & 0xff;}static void putreg(int reg, uint8 value){  DM9X_INDEX = reg;  DM9X_DATA  = value & 0xff;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -