📄 ne2kif.c
字号:
/* * Copyright (c) 2001-2004 Swedish Institute of Computer Science. * 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. * * This file is part of the lwIP TCP/IP stack. * * Author: Adam Dunkels <adam@sics.se> * *//* * This file is a skeleton for developing Ethernet network interface * drivers for lwIP. Add code to the low_level functions and do a * search-and-replace for the word "ethernetif" to replace it with * something that better describes your network interface. *//* * modified by hugang <hgxxx@51eda.com> * date : 2004-07-02 */ #include "lwip/opt.h"#include "lwip/def.h"#include "lwip/mem.h"#include "lwip/pbuf.h"#include "lwip/sys.h"#include "lwip/stats.h"#include "lwip/err.h"#include "lwip/debug.h"#include "netif/etharp.h"#include "ne2kif.h"#include "string.h"#include <sal_os.h>#include <drv/drv_44b0.h>#include <drv/drv_bsp.h>/* Define those to better describe your network interface. */#define IFNAME0 'e'#define IFNAME1 'n'struct ethernetif { struct eth_addr *ethaddr; /* Add whatever per-interface state that is needed here. */};static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};extern struct netif *rtl8019_netif;extern void Delay(INT16U time);static void ethernetif_input(struct netif *netif);static err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);unsigned char convert_8(unsigned char in){ unsigned char temp = 0; temp |= (0x01 & in); temp = (temp<<2); temp |= (0x02 & in); temp = (temp<<2); temp |= (0x04 & in); temp = (temp<<2); temp |= (0x08 & in); temp = (temp <<1); in = (in >>1); temp |= (0x08 & in); in = (in >>2); temp |= (0x04 & in); in = (in >>2); temp |= (0x02 & in); in = (in >>2); temp |= (0x01 & in); return temp;}unsigned int convert_16(unsigned int in){ unsigned int out; out = convert_8(in & 0xff) + convert_8(in/0x100)*0x100; return out;}/* * Read the specified number of bytes from the device DMA port into * the supplied buffer. */static void ne2k_copyin(u16_t len, u8_t *buf){ u16_t count; u16_t *dataw; count = NE_WORDMODE ? len >> 1 : len; #if NE_WORDMODE dataw = (unsigned short *)buf; // Use pointer for speed while(count--) // Get words *dataw++ = convert_16(NE_DATAW); if (len & 0x01) // If odd length, do last byte *(unsigned char *)dataw = convert_8(NE_DATAB);#else while(count--) // Get bytes *buf++ = convert_8(NE_DATAB);#endif}/* * Write the specified number of bytes from the device DMA port into * the supplied buffer. */ static void ne2k_copyout(u16_t len, u8_t *buf){ u16_t count; count = NE_WORDMODE ? len >> 1 : len; #if NE_WORDMODE // Word transfer? if((u32_t)buf & 0x01) { /* 若为奇数地址则按字节读取*/ while(count--) { NE_DATAW = convert_16((*buf) | ((u16_t)*(buf + 1)) << 8); buf += 2; } if (len & 0x01) /* If odd length, do last byte */ NE_DATAW = convert_16(*buf); } else { /* 若为偶数地址则按半字读取 */ u16_t *dataw; dataw = (u16_t *)buf; while(count--) NE_DATAW = convert_16(*dataw++); if (len & 0x01) /* If odd length, do last byte */ NE_DATAW = convert_16(*(u8_t *)dataw); }#else while(count--) NE_DATAB = convert_8(*buf++);#endif }static void ne2k_outpad(u16_t len){ u16_t count; count = NE_WORDMODE ? len >> 1 : len; #if NE_WORDMODE /* Word transfer? */ while(count--) NE_DATAW = 0;#else while(count--) /* O/P bytes */ NE_DATAB = 0;#endif }/* * Pull the specified number of bytes from the device DMA port, * and throw them away. */static void ne2k_discard(u16_t len){ u8_t tmp; u16_t tmpw; u16_t count; count = NE_WORDMODE ? len >> 1 : len;#if NE_WORDMODE while(count--) tmpw = convert_16(NE_DATAW); if (len & 0x01) tmp = convert_8(NE_DATAB);#else while(count--) tmp = convert_8(NE_DATAB);#endif}/* void NICISR(void) interrupt */void ne2k_isr(void){ u8_t isr,curr,bnry; rI_ISPC = BIT_EINT0; rINTMSK = rINTMSK | BIT_EINT0; /* close nic */ NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_STOP); isr = convert_8(NE_ISR); if (isr & ENISR_OVER) { NE_ISR = convert_8(ENISR_OVER); } if (isr & ENISR_TX_ERR) { NE_ISR = convert_8(ENISR_TX_ERR); } /* Rx error , reset BNRY pointer to CURR (use SEND PACKET mode) */ if (isr & ENISR_RX_ERR) { NE_ISR = convert_8(ENISR_RX_ERR); NE_CR = convert_8(ENCR_PAGE1 | ENCR_NODMA | ENCR_STOP); curr = convert_8(NE_CURR); NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_STOP); NE_BNRY = convert_8(curr); } /* got packet with no errors */ if (isr & ENISR_RX) { NE_ISR = convert_8(ENISR_RX); NE_CR = convert_8(ENCR_PAGE1 | ENCR_NODMA | ENCR_STOP); curr = convert_8(NE_CURR); NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_STOP); bnry = convert_8(NE_BNRY); /* get more than one packet until receive buffer is empty */ while(curr != bnry) { ethernetif_input(rtl8019_netif); NE_CR = convert_8(ENCR_PAGE1 | ENCR_NODMA | ENCR_STOP); curr = convert_8(NE_CURR); NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_STOP); bnry = convert_8(NE_BNRY); } } /* Transfer complelte, do nothing here */ if( isr & ENISR_TX) { NE_ISR =convert_8( ENISR_TX); } NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_STOP); NE_ISR = 0xff; /* open nic for next packet */ NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_START); rINTMSK = rINTMSK & (~BIT_EINT0); }static void net2k_int_init(){ DisableIrq(INT_EXTINT0); bsp_int_connect(INT_EXTINT0, ne2k_isr); ClrIrqPnd(INT_EXTINT0); // clear pending INT EnableIrq(INT_EXTINT0);}//low_level_init()8019 hard rst + soft rst + reg configstatic voidlow_level_init(struct netif *netif){ struct ethernetif *ethernetif; u8_t mac_addr[6]; u8_t temp; mac_addr[0] = 0x0a; mac_addr[1] = 0x0b; mac_addr[2] = 0x0c; mac_addr[3] = 0x0d; mac_addr[4] = 0x0e; mac_addr[5] = 0x0f; ethernetif = netif->state; /* set MAC hardware address length */ netif->hwaddr_len = 6; /* set MAC hardware address */ netif->hwaddr[0] = mac_addr[0]; netif->hwaddr[1] = mac_addr[1]; netif->hwaddr[2] = mac_addr[2]; netif->hwaddr[3] = mac_addr[3]; netif->hwaddr[4] = mac_addr[4]; netif->hwaddr[5] = mac_addr[5]; /* maximum transfer unit */ netif->mtu = 1500; /* broadcast capability */ netif->flags = NETIF_FLAG_BROADCAST; ICS_RST &= ~RTL8019_BIT; Delay(10); ICS_RST |= RTL8019_BIT; Delay(500); /* Do whatever else is needed to initialize interface. */ NE_CR = convert_8(ENCR_PAGE0 + ENCR_NODMA + ENCR_START); Delay(100); Delay(500); temp = NE_RESET; NE_RESET = temp; Delay(3000); NE_CR = convert_8(ENCR_PAGE0 + ENCR_NODMA + ENCR_STOP); Delay(100); NE_DCR = convert_8(NE_DCRVAL); NE_RBCR0 = 0x00; /* MSB remote byte count reg */ NE_RBCR1 = 0x00; /* LSB remote byte count reg */ NE_RCR = convert_8(ENRCR_RXOFF); /* RX configuration reg Monitor mode (no packet receive) */ NE_TCR = convert_8(ENTCR_TXOFF); /* TX configuration reg set internal loopback mode */ NE_TPSR = convert_8(TX_START_PG); NE_PSTART = convert_8(RX_START_PG); /* DMA START PAGE 46h */ NE_PSTOP = convert_8(RX_STOP_PG); /* Ending page +1 of ring buffer */ NE_BNRY = convert_8(RX_START_PG); /* Boundary page of ring buffer */ NE_ISR = 0xff; /* INTerrupt stauts reg */ NE_IMR = convert_8(ENIMR_RX | ENIMR_RX_ERR | ENIMR_TX | ENIMR_TX_ERR); //hgxxx 2003-10-11 add NE_CR = convert_8(ENCR_PAGE1 + ENCR_NODMA + ENCR_STOP); Delay(100); NE_PAR0 = convert_8(mac_addr[0]); NE_PAR1 = convert_8(mac_addr[1]); NE_PAR2 = convert_8(mac_addr[2]); NE_PAR3 = convert_8(mac_addr[3]); NE_PAR4 = convert_8(mac_addr[4]); NE_PAR5 = convert_8(mac_addr[5]); NE_MAR0 = 0xff; NE_MAR1 = 0xff; NE_MAR2 = 0xff; NE_MAR3 = 0xff; NE_MAR4 = 0xff; NE_MAR5 = 0xff; NE_MAR6 = 0xff; NE_MAR7 = 0xff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -