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

📄 cs8900if.c

📁 cs8900网络驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/** @file * *  Ethernet network driver for IP *//* * Copyright (c) 2001-2003 Leon Woestenberg <address@hidden> * Copyright (c) 2001-2003 Axon Digital Design B.V., The Netherlands. * 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: Leon Woestenberg <address@hidden> * Modified by: Eric Shufro <address@hidden> * * This is a device driver for the Crystal Semiconductor CS8900 * chip in combination with the lwIP stack. * * This is work under development. Please coordinate changes * and requests with Leon Woestenberg <address@hidden> * * The Swedish Institute of Computer Science and Adam Dunkels * are specifically granted permission to redistribute this * source code under any conditions they seem fit. * * A quick function roadmap: * * cs8900_*() are low level, cs8900 hardware specific functions. * These are declared static in the device driver source and * SHOULD NOT need to be called from outside this source. * * cs8900if_*() are the lwIP network interface functions. * * cs8900_init() sets up the cs8900, using its register set. When * using the driver on your particular hardware platform, make sure * the register setups match. * Function is called from cs8900if_init(). * * cs8900_input() transfers a received packet from the chip. * Function is called from cs8900if_input(). * * cs8900_output() transfers a packet to the chip for transmission. * Function is called from cs8900if_output(). * * cs8900if_init() initializes the lwIP network interface, and * calls cs8900_init() to initialize the hardware. * Function is called from lwIP. * * cs8900if_input() calls cs8900_input() to get a received packet * and then forwards the packet to protocol(s) handler(s). * Function is called from cs8900_service(). * * cs8900if_output() resolves the hardware address, then * calls cs8900_output() to transfer the packet. * Function is called from lwIP. */#include "lwip/opt.h"#include "lwip/def.h"#include "lwip/err.h"#include "lwip/mem.h"#include "lwip/pbuf.h"#include "lwip/stats.h"#include "lwip/sys.h"#include "netif/etharp.h"#include "netif/cs8900if.h"#include "bsp.h"/***********************************************************************************************************                              global variables**********************************************************************************************************/       OS_EVENT      *CS8900_Service_Sem;extern OS_CPU_SR      cpu_sr;/***********************************************************************************************************                      Initialize the CS8900 Ethernet MAC/PHY and its device driver.** Description : Initialize the CS8900 interface and then call the low level hardware initializing*               function to setup the ethernet controller.*               * Arguments   : netif: The lwIP network interface data structure belonging to this device.*               MAY be NULL as we do not support multiple devices yet.**********************************************************************************************************/err_t cs8900if_init(struct netif *netif){  struct cs8900if *cs8900if;  cs8900if = mem_malloc(sizeof(struct cs8900if));  if (cs8900if == NULL)  {    LWIP_DEBUGF(NETIF_DEBUG, ("cs8900_input: out of memory for cs8900if\n"));    return ERR_MEM;  }  // initialize lwip network interface  netif->name[0] = IFNAME0;  netif->name[1] = IFNAME1;    // set the interface's mac address  netif->hwaddr[0] = 0x00;  netif->hwaddr[1] = 0x50;  netif->hwaddr[2] = 0xc2;  netif->hwaddr[3] = 0x25;  netif->hwaddr[4] = 0x60;  netif->hwaddr[5] = 0x0b;       /* downward functions */  netif->output = cs8900if_output;  netif->linkoutput = cs8900_output;  // initialize cs8900 specific interface state data pointer  netif->state = cs8900if;  /* maximum transfer unit */  netif->mtu = 1500;  /* broadcast capability */  netif->flags = NETIF_FLAG_BROADCAST;  /* hardware address length */  netif->hwaddr_len = 6;  // initially assume no ISQ event  cs8900if->needs_service = 0;  // set to 1 if polling method is used  cs8900if->use_polling = 0;#if (CS8900_STATS > 0)  // number of interrupt service routine calls  cs8900if->interrupts = 0;  cs8900if->missed = 0;  cs8900if->dropped = 0;  cs8900if->sentpackets = 0;  cs8900if->sentbytes = 0;#endif  // intialize the cs8900a chip  return cs8900_init();}/***********************************************************************************************************                              cs8900_init()** Description : Calls for a CS8900 hardware reset and then initializes the cs8900 registers*                * Arguments   : netif: The lwIP network interface data structure belonging to this device. ** Returns     : return error codes*               - ERR_OK: packet transferred to hardware***********************************************************************************************************/static err_t cs8900_init(void){    CS8900_Service_Sem = OSSemCreate(0);   /* semaphore to awaken the cs8900 service routine after an isr occurs */            while((cs8900_reset() & 0x8000) != 0x8000) { // if device is not ready...(initd should be set when ready)  //todo add timeout       OSTimeDly(10);    }         ppWrite(CS_PP_INTNUM,  0x0000U);        //set the cs8900 interrupt to use to pin cs8900 pin 0, (connected to 9s12 micro using IRQ pin)	 ppWrite(CS_PP_RXCFG,   0x0301U);        //receiver configuration register	 ppWrite(CS_PP_RXCTL,   0x050DU);        //receiver control register	 ppWrite(CS_PP_BUFCFG,  0x0B05U);        //bus configuration register	 ppWrite(CS_PP_BUSCTL,  0x1780U);        //bus control register	 ppWrite(CS_PP_LINECTL, 0xD300U);        //line control register	 ppWrite(CS_PP_IA1,     0x0050U);        //mac address high bytes	 ppWrite(CS_PP_IA2,     0xC225U); 		   //mac address middle bytes	 ppWrite(CS_PP_IA3,     0x600BU);				 //mac address low bytes 	 	 INTCR = 0x40;                           //re-enable the irq pin now the the cs8900 is ready to go      return ERR_OK;}/***********************************************************************************************************                 Reset the CS8900A using a hardware reset** Description : Pulls the CS8900's reset pin high to reset the ethernet controller.*               * Arguments   : None* Notes       : Not User Accessible.            **********************************************************************************************************/static INT16U cs8900_reset(void){	 //default state for the signal bus (no inputs asserted)	 Signal_B = 0x06;	    /* pull reset pin and wait a bit */   Signal_B |= CS8900_RESET;   OSTimeDly(10);   /* release reset pin and wait a bit*/   Signal_B &= ~CS8900_RESET;   OSTimeDly(10);     //toggle SBHE to enter 16 bit mode (as specified in the datasheet)   Signal_B |= CS8900_SBHE;  //SBHE active   OSTimeDly(10);   Signal_B &= ~CS8900_SBHE; //SBHE inactive   OSTimeDly(10);   Signal_B |= CS8900_SBHE;  //SBHE active   OSTimeDly(10);   Signal_B &= ~CS8900_SBHE; //SBHE inactive   OSTimeDly(10);   //return the value of the selftest register which tells us if the device has finished resetting   return  ppRead(CS_PP_SELFTEST); }/***********************************************************************************************************                              CS8900 Interrupt Service Routine** Description : function which gets called after the cs8900 asserts a hardware interrupt *               this posts a semaphore to the OS in order to awaken ServiceCS8900 which *               actually does the dirty work. The hardware interrupt pin is disabled here as well.*                * Arguments   : None**********************************************************************************************************/void CS8900_Interrupt(void) {   INT8U  err;   INT16U isq_data;               //hold the isq event register number   INTCR = 0x00;                  //disable the irq pin!     /* do      {         isq_data = IORead(CS8900_ISQ) >> 8;			            switch(isq_data & 0x3f)	       {	          case 0x00:                   //isq is empty. exit.	             break;	          case 0x04:										//receieve event	             cs8900if_input(&netif);	             break;	          case 0x08:										//transmit event	             break;            case 0x0C:										//buffer event   	             break; 	          case 0x10:										//receiver miss event  	           break;	          case 0x12:										//transmit collision event 	             break;            default:										  //should never be here event. 	             break;	       }       }while(isq_data != 0);            */   err = OSSemPost(CS8900_Service_Sem);   //signal ServiceCS8900 to run.	 }/***********************************************************************************************************                              CS8900 Service Routine** Description : function which gets called after the cs8900 interrupt routine runs and posts a *               semaphore to awaken this task and service the cs8900 ISQ and get data etc...*               When done servicing the cs8900, the hardware interrupt pin is re-enabled.*                * Arguments   : None**********************************************************************************************************/void ServiceCS8900(void){   INT8U err;   INT16U isq_data;               //hold the isq event register number     while(1)   {      OSSemPend(CS8900_Service_Sem, 0, &err);                         do      {         isq_data = IORead(CS8900_ISQ) >> 8;			            switch(isq_data & 0x3f)	       {	          case 0x00:                   //isq is empty. exit.	             break;	          case 0x04:										//receieve event	             cs8900if_input(&netif);	             break;	          case 0x08:										//transmit event	             break;            case 0x0C:										//buffer event   	             break; 	          case 0x10:										//receiver miss event  	           break;	          case 0x12:										//transmit collision event 	             break;            default:										  //should never be here event. 	             break;	       }       }while(isq_data != 0);                    INTCR = 0x40;                       //re-enable interrupts   	    }}												/***********************************************************************************************************                 Read a received packet from the CS8900.** Description : This function should be called when a packet is received by the CS8900*               and is fully available to read. It moves the received packet to a pbuf*               which is forwarded to the IP network layer or ARP module. It transmits*               a resulting ARP reply or queued packet.*               * Arguments   : netif: The lwIP network interface to read from.* * Notes       : Uses cs8900_input() to move the packet from the CS8900 to a*               newly allocated pbuf.**********************************************************************************************************/void cs8900if_input(struct netif *netif){  struct cs8900if *cs8900if = netif->state;  struct eth_hdr *ethhdr = NULL;  struct pbuf *p = NULL, *q = NULL;  /* move received packet into a new pbuf */  p = cs8900_input(netif);  /* no packet could be read */  if (p == NULL) {    /* silently ignore this */    return;  }  /* points to packet payload, which starts with an Ethernet header */  ethhdr = p->payload;

⌨️ 快捷键说明

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