www.pudn.com > TCPmodbushy.rar > ethernetif.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* */ /* * 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. */ #include "o:/lwip/opt.h" #include "o:/lwip/def.h" #include "o:/lwip/mem.h" #include "o:/lwip/pbuf.h" #include "o:/lwip/sys.h" #include "o:/netif/OP_FlashOfCP220.h" #include "o:/netif/CP220X_Core.h" #include "o:/netif/CP220X_Reg.h" #include "o:/lwip/stats.h" #include "o:/netif/ethernetif.h" #include "o:/netif/etharp.h" /* Define those to better describe your network interface. */ #define IFNAME0 'e' #define IFNAME1 'n' struct ethernetif { struct eth_addr xdata *ethaddr; /****************************************************************************** * Addes( Begin ) ******************************************************************************/ /* Add whatever per-interface state that is needed here. */ unsigned char Low_Level_Init_Result; /****************************************************************************** * Addes( End ) ******************************************************************************/ }; //static code struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; /* Forward declarations. */ static err_t ethernetif_output(struct pbuf xdata *p, struct ip_addr xdata *ipaddr); static void low_level_init() { struct ethernetif xdata *ethernetif = netif->state; /****************************************************************************** * Addes( Begin ) ******************************************************************************/ INT0EN = 0xFF; if( INT0EN != 0xFF ) { ethernetif->Low_Level_Init_Result = OSC_ERROR; return; } INT0EN = 0x00; if( INT0EN != 0x00 ) { ethernetif->Low_Level_Init_Result = OSC_ERROR; return; } ReadBytesFromFlash( 0x1FFA, 6, netif->hwaddr ); if( (netif->hwaddr[0] != 0x00) ||(netif->hwaddr[1] != 0x0b) ||(netif->hwaddr[2] != 0x3c) ) { ethernetif->Low_Level_Init_Result = OSC_ERROR; return; } /* netif->hwaddr[0] = ReadByteFromFlash( 0x1FFA ); netif->hwaddr[1] = ReadByteFromFlash( 0x1FFB ); netif->hwaddr[2] = ReadByteFromFlash( 0x1FFC ); netif->hwaddr[3] = ReadByteFromFlash( 0x1FFD ); netif->hwaddr[4] = ReadByteFromFlash( 0x1FFE ); netif->hwaddr[5] = ReadByteFromFlash( 0x1FFF );*/ /****************************************************************************** * Addes( End ) ******************************************************************************/ /* maximum transfer unit */ // netif->mtu = 500; /* broadcast capability */ netif->flags = NETIF_FLAG_BROADCAST; /****************************************************************************** * Addes( Begin ) ******************************************************************************/ /* Do whatever else is needed to initialize interface. */ ethernetif->Low_Level_Init_Result = CP220x_HW_Reset(); if( ethernetif->Low_Level_Init_Result & (OSC_ERROR | CAL_ERROR | MEM_ERROR) ) { return; } ethernetif->Low_Level_Init_Result = PHY_Init(); // Initialize the physical layer if(ethernetif->Low_Level_Init_Result & LINK_ERROR) // Check for the possible error codes { return; } MAC_Init(); // Initialize the MAC RXFILT = 0x0d;//ignor mulbroadcast ethernetif->Low_Level_Init_Result = ERR_OK; /****************************************************************************** * Addes( End ) ******************************************************************************/ } /* * low_level_output(): * * Should do the actual transmission of the packet. The packet is * contained in the pbuf that is passed to the function. This pbuf * might be chained. * */ err_t low_level_output(struct pbuf xdata *p) { struct ethernetif xdata *ethernetif = netif->state; unsigned int data ramaddr; unsigned char xdata *temp; // Step 1: Poll TXBUSY until it becomes 0x00 while(TXBUSY); #ifdef TESTDEBUG if( TXSTA3&0xf8 ) test[8]++; #endif // Step 2: Set the TXSTARTH:TXSTARTL address to 0x0000 TXSTARTH = 0x00; TXSTARTL = 0x00; // Step 3: Load data into transmit buffer // When the random access method is used, we do not need to check for // aborted packets. This method will be slightly slower than the Autowrite // method, however, it reduces code space requirements. ramaddr = 0x0000; //send data from(q->payload, q->len); temp = ( unsigned char xdata * )(p->payload); while( ramaddr < p->len ) { TXAUTOWR = *temp; temp++; ramaddr++; } // Step 3e: Pad short packets while(ramaddr < 64){ TXAUTOWR = 0; ramaddr++; } // Step 4: Set the TXSTARTH:TXSTARTL address back to 0x0000 TXSTARTH = 0x00; TXSTARTL = 0x00; // Step 5: Write '1' to TXGO to begin transmission TXCN = 0x01; /****************************************************************************** * Addes( End ) ******************************************************************************/ return ERR_OK; } /* * low_level_input(): * * Should allocate a pbuf and transfer the bytes of the incoming * packet from the interface into the pbuf. * */ /* !!according to Low_level_input, when read the packet only leave the five packet, open receved!!!!!!!!! */ static struct pbuf xdata * low_level_input(void) { struct ethernetif xdata *ethernetif = netif->state; struct pbuf xdata *p; u16_t data len; bit rx_ok; /* Obtain the size of the packet and put it into the "len" variable. */ // Step 1: Check the RXOK bit to see if packet was received correctly if( TLBVALID ) { rx_ok = (CPINFOL & RXOK); if( rx_ok ) { len = MAKE_WORD( CPLENH,CPLENL ); p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); if( p == NULL ) return p; } else { p = NULL; #ifdef TESTDEBUG test[3]++; #endif } EA = OFF; RcvedNum--; if( RcvedNum <= 6 ) RXCN = 0; EA = ON; if (p != NULL) { //read data into(q->payload, q->len); unsigned char xdata *data TmpPayload = ( unsigned char xdata * )( p->payload ); while( len != 0 ) { len--; *TmpPayload = RXAUTORD; TmpPayload++; } RXCN |= 0x04; // Clear the valid bit only //acknowledge that packet has been read(); } else { RXCN |= 0x02; // Skip the packet } }else{ p = NULL; } return p; } /* * ethernetif_output(): * * This function is called by the TCP/IP stack when an IP packet * should be sent. It calls the function called low_level_output() to * do the actual transmission of the packet. * */ err_t ethernetif_output(struct pbuf xdata *p, struct ip_addr xdata *ipaddr) { /* resolve hardware address, then send (or queue) packet */ return etharp_output(ipaddr, p); } /* * ethernetif_input(): * * This function should be called when a packet is ready to be read * from the interface. It uses the function low_level_input() that * should handle the actual reception of bytes from the network * interface. * */ void ethernetif_input(void) { struct ethernetif xdata *ethernetif; struct eth_hdr xdata *ethhdr; struct pbuf xdata *p; ethernetif = netif->state; /* move received packet into a new pbuf */ p = low_level_input(); /* no packet could be read, silently ignore this */ if (p == NULL) { return; } /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; switch( htons(ethhdr->type) ){ /* IP packet? */ case ETHTYPE_IP: /* update ARP table */ etharp_ip_input( p ); /* skip Ethernet header */ pbuf_header(p, -sizeof(struct eth_hdr)); /* pass to network layer */ // netif->input(p, netif); ip_input(p); break; case ETHTYPE_ARP: /* pass p to ARP module */ etharp_arp_input(ethernetif->ethaddr, p); break; default: pbuf_free(p); p = NULL; break; } } /* * ethernetif_init(): * * Should be called at the beginning of the program to set up the * network interface. It calls the function low_level_init() to do the * actual setup of the hardware. * */ err_t ethernetif_init(void) { struct ethernetif xdata *ethernetif; ethernetif = mem_malloc(sizeof(struct ethernetif)); if (ethernetif == NULL) { return ERR_MEM; } netif->state = ethernetif; ethernetif->ethaddr = (struct eth_addr xdata *)&(netif->hwaddr[0]); low_level_init(); /****************************************************************************** * Addes( Begin ) ******************************************************************************/ if( ethernetif->Low_Level_Init_Result != ERR_OK ) { mem_free(ethernetif); return( (err_t)ethernetif->Low_Level_Init_Result ); } /****************************************************************************** * Addes( End ) ******************************************************************************/ etharp_init(); return ERR_OK; }