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

📄 dm9000e.c

📁 avr上的RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2003-2005 by egnite Software GmbH. All rights reserved. * * 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 of the copyright holders nor the names of *    contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE * SOFTWARE GMBH 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. * * For additional information see http://www.ethernut.de/ * *//* * $Log: dm9000e.c,v $ * Revision 1.1  2005/10/24 08:49:05  haraldkipp * Initial check in. * */#include <cfg/os.h>#include <arch/arm/at91.h>#include <string.h>#include <sys/atom.h>#include <sys/heap.h>#include <sys/thread.h>#include <sys/event.h>#include <sys/timer.h>#include <sys/confnet.h>#include <netinet/if_ether.h>#include <net/ether.h>#include <net/if_var.h>#include <dev/irqreg.h>#include <dev/dm9000e.h>#ifdef NUTDEBUG#include <stdio.h>#endif#ifndef NUT_THREAD_NICRXSTACK#define NUT_THREAD_NICRXSTACK   768#endif/* * Determine ports, which had not been explicitely configured. */#ifndef NIC_BASE_ADDR#define NIC_BASE_ADDR   0x20000000#endif#ifndef NIC_DATA_ADDR#define NIC_DATA_ADDR   (NIC_BASE_ADDR + 4)#endif#define INT0    0#define INT1    1#define INT2    2#define INT3    3#define INT4    4#define INT5    5#define INT6    6#define INT7    7#ifndef NIC_SIGNAL_IRQ#define NIC_SIGNAL_IRQ  INT1#endif#ifdef NIC_RESET_BIT#if (NIC_RESET_AVRPORT == AVRPORTB)#define NIC_RESET_PORT   PORTB#define NIC_RESET_DDR    DDRB#elif (NIC_RESET_AVRPORT == AVRPORTD)#define NIC_RESET_PORT   PORTD#define NIC_RESET_DDR    DDRD#elif (NIC_RESET_AVRPORT == AVRPORTE)#define NIC_RESET_PORT   PORTE#define NIC_RESET_DDR    DDRE#elif (NIC_RESET_AVRPORT == AVRPORTF)#define NIC_RESET_PORT   PORTF#define NIC_RESET_DDR    DDRF#endif                          /* NIC_RESET_AVRPORT */#endif                          /* NIC_RESET_BIT *//* * Determine interrupt settings. * DOES NOT WORK */#if (NIC_SIGNAL_IRQ == INT0)#define NIC_SIGNAL          sig_INTERRUPT0#elif (NIC_SIGNAL_IRQ == INT2)#define NIC_SIGNAL          sig_INTERRUPT2#elif (NIC_SIGNAL_IRQ == INT3)#define NIC_SIGNAL          sig_INTERRUPT3#elif (NIC_SIGNAL_IRQ == INT4)#define NIC_SIGNAL          sig_INTERRUPT4#elif (NIC_SIGNAL_IRQ == INT5)#define NIC_SIGNAL          sig_INTERRUPT5#elif (NIC_SIGNAL_IRQ == INT6)#define NIC_SIGNAL          sig_INTERRUPT6#elif (NIC_SIGNAL_IRQ == INT7)#define NIC_SIGNAL          sig_INTERRUPT7#else#define NIC_SIGNAL          sig_INTERRUPT1#endif/*! * \addtogroup xgDm9000eRegs *//*@{*/#define NIC_NCR     0x00        /* Network control register (0x00). */#define NIC_NCR_LBM     0x06    /* Loopback mode. */#define NIC_NCR_LBNORM  0x00    /* Normal mode. */#define NIC_NCR_LBMAC   0x02    /* MAC loopback. */#define NIC_NCR_LBPHY   0x04    /* PHY loopback. */#define NIC_NCR_RST     0x01    /* Software reset, auto clear. */#define NIC_NSR     0x01        /* Network status register (0x00). */#define NIC_NSR_SPEED   0x80#define NIC_NSR_LINKST  0x40#define NIC_NSR_WAKEST  0x20#define NIC_NSR_TX2END  0x08#define NIC_NSR_TX1END  0x04#define NIC_NSR_RXOV    0x02#define NIC_TCR     0x02        /* TX control register (0x00). */#define NIC_TCR_TXREQ    0x01   /* TX request */#define NIC_TSR1    0x03        /* TX status register I (0x00). */#define NIC_TSR2    0x04        /* TX status register II (0x00). */#define NIC_RCR     0x05        /* RX control register (0x00). */#define NIC_RCR_DIS_LONG 0x20   /* Discard long packets. */#define NIC_RCR_DIS_CRC 0x10    /* Discard CRC error packets. */#define NIC_RCR_PRMSC   0x02    /* Enable promiscuous mode. */#define NIC_RCR_RXEN    0x01    /* Enable receiver. */#define NIC_RSR     0x06        /* RX status register (0x00). */#define NIC_RSR_ERRORS  0xBF    /* Error bit mask. */#define NIC_RSR_RF      0x80    /* Runt frame. */#define NIC_RSR_MF      0x40    /* Multicast frame. */#define NIC_RSR_LCS     0x20    /* Late collision. */#define NIC_RSR_RWTO    0x10    /* Receiver watchdog time out. */#define NIC_RSR_PLE     0x08    /* Physical layer error. */#define NIC_RSR_AE      0x04    /* Alignment error. */#define NIC_RSR_CE      0x02    /* CRC error. */#define NIC_RSR_FOE     0x01    /* FIFO overflow error. */#define NIC_ROCR    0x07        /* Receive overflow counter register (0x00). */#define NIC_BPTR    0x08        /* Back pressure threshold register (0x37). */#define NIC_FCTR    0x09        /* Flow control threshold register (0x38). */#define NIC_FCR     0x0A        /* RX flow control register (0x00). */#define NIC_EPCR    0x0B        /* EEPROM and PHY control register. */#define NIC_EPAR    0x0C        /* EEPROM and PHY address register. */#define NIC_EPDRL   0x0D        /* EEPROM and PHY low byte data register. */#define NIC_EPDRH   0x0E        /* EEPROM and PHY high byte data register. */#define NIC_WCR     0x0F        /* Wake up control register (0x00). */#define NIC_PAR     0x10        /* 6 byte physical address register. */#define NIC_MAR     0x16        /* 8 byte multicast address register. */#define NIC_GPCR    0x1E        /* General purpose control register (?). */#define NIC_GPR     0x1F        /* General purpose register (?). */#define NIC_TRPA    0x22        /* 2 byte TX SRAM read pointer address, low/high (0x0000). */#define NIC_RWPA    0x24        /* 2 byte RX SRAM write pointer address, low/high (0x0000). */#define NIC_VID     0x28        /* 2 byte vendor ID (0x0A46). */#define NIC_PID     0x2A        /* 2 byte product ID (0x0900). */#define NIC_CHIPR   0x2C        /* Chip revision (0x00). */#define NIC_SMCR    0x2F        /* Special mode register (0x00). */#define NIC_MRCMDX  0xF0        /* Memory data read command w/o increment (?). */#define NIC_MRCMD   0xF2        /* Memory data read command with increment (?). */#define NIC_MRR     0xF4        /* 2 byte memory data read register, low/high (?). */#define NIC_MWCMDX  0xF6        /* Memory data write command register w/o increment (?). */#define NIC_MWCMD   0xF8        /* Memory data write command register with increment (?). */#define NIC_MWR     0xFA        /* Memory data write command register with increment (?). */#define NIC_TXPL    0xFC        /* 2 byte TX packet length register. (?). */#define NIC_ISR     0xFE        /* Interrupt status register (0x00). */#define NIC_ISR_IOM     0xC0    /* I/O mode mask */#define NIC_ISR_M16     0x00    /* 16-bit I/O mode */#define NIC_ISR_M32     0x40    /* 32-bit I/O mode */#define NIC_ISR_M8      0x80    /* 8-bit I/O mode */#define NIC_ISR_ROOS    0x08    /* Receiver overflow counter interrupt. */#define NIC_ISR_ROS     0x04    /* Receiver overflow interrupt. */#define NIC_ISR_PTS     0x02    /* Transmitter interrupt. */#define NIC_ISR_PRS     0x01    /* Receiver interrupt. */#define NIC_IMR     0xFF        /* Interrupt mask register (0x00). */#define NIC_IMR_PAR     0x80    /* Enable read/write pointer wrap around. */#define NIC_IMR_ROOM    0x08    /* Enable receiver overflow counter interrupts. */#define NIC_IMR_ROM     0x04    /* Enable receiver overflow interrupts. */#define NIC_IMR_PTM     0x02    /* Enable transmitter interrupts. */#define NIC_IMR_PRM     0x01    /* Enable receiver interrupts. */#define NIC_PHY_BMCR    0x00    /* Basic mode control register. */#define NIC_PHY_BMSR    0x01    /* Basic mode status register. */#define NIC_PHY_BMSR_ANCOMPL    0x0020  /* Auto negotiation complete. */#define NIC_PHY_BMSR_LINKSTAT   0x0004  /* Link status. */#define NIC_PHY_ID1     0x02    /* PHY identifier register 1. */#define NIC_PHY_ID2     0x03    /* PHY identifier register 2. */#define NIC_PHY_ANAR    0x04    /* Auto negotiation advertisement register. */#define NIC_PHY_ANLPAR  0x05    /* Auto negotiation link partner availability register. */#define NIC_PHY_ANER    0x06    /* Auto negotiation expansion register. */#define NIC_PHY_DSCR    0x10    /* Davicom specified configuration register. */#define NIC_PHY_DSCSR   0x11    /* Davicom specified configuration and status register. */#define NIC_PHY_10BTCSR 0x12    /* 10BASE-T configuration and status register. *//*! * \brief Network interface controller information structure. */struct _NICINFO {#ifdef NUT_PERFMON    u_long ni_rx_packets;       /*!< Number of packets received. */    u_long ni_tx_packets;       /*!< Number of packets sent. */    u_long ni_overruns;         /*!< Number of packet overruns. */    u_long ni_rx_frame_errors;  /*!< Number of frame errors. */    u_long ni_rx_crc_errors;    /*!< Number of CRC errors. */    u_long ni_rx_missed_errors; /*!< Number of missed packets. */#endif    HANDLE volatile ni_rx_rdy;  /*!< Receiver event queue. */    HANDLE volatile ni_tx_rdy;  /*!< Transmitter event queue. */    HANDLE ni_mutex;            /*!< Access mutex semaphore. */    volatile int ni_tx_queued;  /*!< Number of packets in transmission queue. */    volatile int ni_tx_quelen;  /*!< Number of bytes in transmission queue not sent. */    int ni_insane;              /*!< Set by error detection. */    int ni_iomode;              /*!< 8 or 16 bit access. 32 bit is not supported. */};/*! * \brief Network interface controller information type. */typedef struct _NICINFO NICINFO;/*@}*//*! * \addtogroup xgNicDm9000e *//*@{*/static inline void nic_outb(u_char reg, u_char val){    outb(NIC_BASE_ADDR, reg);    outb(NIC_DATA_ADDR, val);}static inline u_char nic_inb(u_short reg){    outb(NIC_BASE_ADDR, reg);    return inb(NIC_DATA_ADDR);}/*! * \brief Read contents of PHY register. * * \param reg PHY register number. * * \return Contents of the specified register. */static u_short phy_inw(u_char reg){    /* Select PHY register */    nic_outb(NIC_EPAR, 0x40 | reg);    /* PHY read command. */    nic_outb(NIC_EPCR, 0x0C);    NutDelay(1);    nic_outb(NIC_EPCR, 0x00);    /* Get data from PHY data register. */    return ((u_short) nic_inb(NIC_EPDRH) << 8) | (u_short) nic_inb(NIC_EPDRL);}/*! * \brief Write value to PHY register. * * \note NIC interrupts must have been disabled before calling this routine. * * \param reg PHY register number. * \param val Value to write. */static void phy_outw(u_char reg, u_short val){    /* Select PHY register */    nic_outb(NIC_EPAR, 0x40 | reg);    /* Store value in PHY data register. */    nic_outb(NIC_EPDRL, (u_char) val);    nic_outb(NIC_EPDRH, (u_char) (val >> 8));    /* PHY write command. */    nic_outb(NIC_EPCR, 0x0A);    NutDelay(1);    nic_outb(NIC_EPCR, 0x00);}static int NicPhyInit(void){    /* Restart auto negotiation. */    phy_outw(NIC_PHY_ANAR, 0x01E1);    phy_outw(NIC_PHY_BMCR, 0x1200);    nic_outb(NIC_GPCR, 1);    nic_outb(NIC_GPR, 0);    return 0;}/*! * \brief Reset the Ethernet controller. * * \return 0 on success, -1 otherwise. */static int NicReset(void){    /* Hardware reset. */#ifdef undef_NIC_RESET_BIT    sbi(NIC_RESET_DDR, NIC_RESET_BIT);    sbi(NIC_RESET_PORT, NIC_RESET_BIT);    NutDelay(WAIT100);    cbi(NIC_RESET_PORT, NIC_RESET_BIT);    NutDelay(WAIT250);    NutDelay(WAIT250);#else    /* Software reset. */    nic_outb(NIC_NCR, NIC_NCR_RST | NIC_NCR_LBMAC);    NutDelay(1);    /* FIXME: Delay required. */#endif    return NicPhyInit();}/* * NIC interrupt entry. */static void NicInterrupt(void *arg){    u_char isr;    NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb;    /* Read interrupt status and disable interrupts. */    isr = nic_inb(NIC_ISR);    /* Receiver interrupt. */    if (isr & NIC_ISR_PRS) {        nic_outb(NIC_ISR, NIC_ISR_PRS);        NutEventPostFromIrq(&ni->ni_rx_rdy);    }    /* Transmitter interrupt. */    if (isr & NIC_ISR_PTS) {        if (ni->ni_tx_queued) {            if (ni->ni_tx_quelen) {                /* Initiate transfer of a queued packet. */                nic_outb(NIC_TXPL, (u_char) ni->ni_tx_quelen);                nic_outb(NIC_TXPL + 1, (u_char) (ni->ni_tx_quelen >> 8));                ni->ni_tx_quelen = 0;                nic_outb(NIC_TCR, NIC_TCR_TXREQ);            }            ni->ni_tx_queued--;        }        nic_outb(NIC_ISR, NIC_ISR_PTS);        NutEventPostFromIrq(&ni->ni_tx_rdy);    }    /* Receiver overflow interrupt. */    if (isr & NIC_ISR_ROS) {        nic_outb(NIC_ISR, NIC_ISR_ROS);        NutEventPostFromIrq(&ni->ni_rx_rdy);    }    /* Receiver overflow counter interrupt. */    if (isr & NIC_ISR_ROOS) {        nic_outb(NIC_ISR, NIC_ISR_ROOS);        NutEventPostFromIrq(&ni->ni_rx_rdy);    }}/*! * \brief Write data block to the NIC. * * NIC interrupts must be disabled when calling this function. */static void NicWrite8(u_char * buf, u_short len){    while (len--) {        outb(NIC_DATA_ADDR, *buf);        buf++;    }}/*! * \brief Write data block to the NIC. * * NIC interrupts must be disabled when calling this function. */static void NicWrite16(u_char * buf, u_short len){    u_short *wp = (u_short *) buf;    len = (len + 1) / 2;    while (len--) {        outw(NIC_DATA_ADDR, *wp);        wp++;    }}/*! * \brief Read data block from the NIC. * * NIC interrupts must be disabled when calling this function. */static void NicRead8(u_char * buf, u_short len){    while (len--) {        *buf++ = inb(NIC_DATA_ADDR);    }}/*! * \brief Read data block from the NIC. * * NIC interrupts must be disabled when calling this function. */static void NicRead16(u_char * buf, u_short len){    u_short *wp = (u_short *) buf;

⌨️ 快捷键说明

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