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

📄 cs8900.c

📁 s3c2410开发板的测试代码,包括lcd
💻 C
字号:
/*********************************************************** Copyright (c)* All rights reserved.				            ** 文件名称:cs8900.c* 文件标识:* 摘    要:本文件是对cs8900网络处理芯片的测试程序。* 当前版本:1.0* 作    者:刘征* 完成日期:2005.4.3** 取代版本:* 作    者:* 完成日期:**********************************************************//***********************************************************   					 头文件**********************************************************/#include "cs8900.h"#include "Def.h"#include "option.h"#include "2410addr.h"#include "2410lib.h"#define DEBUGstatic unsigned short NetRxPackets[2*1024];static unsigned short dummy=0;/***********************************************************   					 函数原型**********************************************************/static void Int_cs8900_init(void);static void __irq cs8000Int_Net(void);int eth_init (void);void eth_halt (void);int eth_rx (void);int eth_send (volatile void *packet, int length);/*********************************************************** 函数介绍:本函数是packet page register access functions。			* 输入参数:regno---register number* 输出参数:无* 返回值  :无**********************************************************/static unsigned short get_reg_init_bus (int regno){	/* force 16 bit busmode */	volatile unsigned char c=0;    volatile unsigned short c1=0,c2=0;    //init	dummy = CS8900_BUS16_0;	dummy = CS8900_BUS16_1;	dummy = CS8900_BUS16_0;	dummy = CS8900_BUS16_1;	dummy = CS8900_BUS16_0;    // TODO: check if this is correct and/or necessary//	dummy = *(U8 *)(CS8900_BASE + 0x00) ;	/* Dummy read, put chip in 16bit-mode *///	dummy = *(U16 *)(CS8900_BASE + 0x00) ;	CS8900_PPTR = regno;//	c1 = (unsigned short) CS8900_PDATA;	//	CS8900_PPTR = regno+2;//	c2 = (unsigned short) CS8900_PDATA;	//	return ((c2<<8) | c1);	return (unsigned short) CS8900_PDATA;}/*********************************************************** 函数介绍:本函数是得到page register 的值。			* 输入参数:regno---register number* 输出参数:无* 返回值  :page register 的值**********************************************************/static unsigned short get_reg (int regno){	CS8900_PPTR = regno;	return (unsigned short) CS8900_PDATA;}/*********************************************************** 函数介绍:本函数是设置page register 的值。			* 输入参数:regno---register number*           val--- value* 输出参数:无* 返回值  :无**********************************************************/static void put_reg (int regno, unsigned short val){	CS8900_PPTR = regno;	CS8900_PDATA = val;}/*********************************************************** 函数介绍:本函数是eth复位函数。			* 输入参数:无* 输出参数:无* 返回值  :无**********************************************************/static void eth_reset (void){	// set RESET bit	CS8900_PPTR = PP_SelfCTL;		// { the RESET bit will be cleared by the cs8900a	//   as a result of the reset }		// RESET bit cleared?	while((CS8900_PDATA & 0x0040) != 0); // TODO: add timeout		// { after full initialization of the cs8900a	//   the INITD bit will be set }		CS8900_PPTR = PP_SelfSTAT;	// INITD bit still clear?	while ((CS8900_PDATA & 0x0080) == 0); // TODO: add timeout	// { INITD bit is set }	}/*********************************************************** 函数介绍:本函数是eth register 复位函数。			* 输入参数:无* 输出参数:无* 返回值  :无**********************************************************/static void eth_reginit (void){	/* receive only error free packets addressed to this card */	put_reg (PP_RxCTL, PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);	/* enable receive interrupt on receive operations */	put_reg (PP_RxCFG, 0x0003 | 0x0100/*RXIRQ*/);	/* do not generate any interrupts on transmit operations */	put_reg (PP_TxCFG, 0x0007 | 0);	/* use interrupt number 0*/	put_reg (PP_IntReg, PP_IntReg_IRQ0);	/* interrupt before counter overflow on buffer operations */	put_reg (PP_BufCFG, 0x2000 | 0x1000);		/* enable interrupt generation */	put_reg (PP_BusCTL, 0x0017 | 0x8000/*EnableIRQ*/);	/* enable transmitter/receiver mode */	put_reg (PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);}/*********************************************************** 函数介绍:本函数是eth halt函数。			* 输入参数:无* 输出参数:无* 返回值  :无**********************************************************/void eth_halt (void){	/* disable transmitter/receiver mode */	put_reg (PP_LineCTL, 0);	/* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */	get_reg_init_bus (PP_ChipID);}/*********************************************************** 函数介绍:本函数是eth init函数。			* 输入参数:无* 输出参数:无* 返回值  :1--success*           0--failure**********************************************************/int eth_init (void){	U8 mac_addr[6];	volatile unsigned short uuuu = 0,uuuu1 = 0;		//保证唯一的MAC地址	mac_addr[0] = 0x00;	mac_addr[1] = 0x00;	mac_addr[2] = 0x21;	mac_addr[3] = 0xe1;	mac_addr[4] = 0xc8;	mac_addr[5] = 0xc2;		uuuu = get_reg_init_bus (PP_ChipID);	uuuu1 = get_reg_init_bus (PP_ChipID+2);	uuuu1 = uuuu1 + uuuu;	//uuuu = get_reg (PP_ChipID);	/* verify chip id */	if (uuuu != 0x630e) 	{		#ifdef DEBUG			Uart_Printf ("CS8900 Ethernet chip not found?!\n");		#endif		return 0;	}	else	{		#ifdef DEBUG			Uart_Printf ("CS8900 Ethernet chip is 0x%6x!\n",get_reg_init_bus (PP_ChipID));		#endif	}		eth_reset ();	/* set the ethernet address */	put_reg (PP_IA + 0, mac_addr[0] | (mac_addr[1] << 8));	put_reg (PP_IA + 2, mac_addr[2] | (mac_addr[3] << 8));	put_reg (PP_IA + 4, mac_addr[4] | (mac_addr[5] << 8));	eth_reginit ();	return 1;}/*********************************************************** 函数介绍:本函数是Get a data block via Ethernet。			* 输入参数:无* 输出参数:无* 返回值  :rxlen--接收数据长度**********************************************************/int eth_rx (void){	int i;	unsigned short rxlen;	unsigned short *addr;	unsigned short status;	status = get_reg (PP_RER);	if ((status & PP_RER_RxOK) == 0)		return 0;	status = CS8900_RTDATA;		/* stat */	rxlen = CS8900_RTDATA;		/* len */#ifdef DEBUG	if (rxlen > PKTSIZE_ALIGN + PKTALIGN)		Uart_Printf ("packet too big!\n");#endif    /*NetRxPackets--接收数据的缓存区*/	for (addr = (unsigned short *) NetRxPackets[0], i = rxlen >> 1; i > 0;i--)	{		*addr++ = CS8900_RTDATA;	}	if (rxlen & 1)	{		*addr++ = CS8900_RTDATA;	}	/* Pass the packet up to the protocol layers. *///	NetReceive (NetRxPackets[0], rxlen);	return rxlen;}/*********************************************************** 函数介绍:本函数是Send a data block via Ethernet。			* 输入参数:packet--待发送数据包地址*           length--长度* 输出参数:无* 返回值  :0**********************************************************/int eth_send (volatile void *packet, int length){	volatile unsigned short *addr;	unsigned short s;retry:	/* initiate a transmit sequence */	CS8900_TxCMD = PP_TxCmd_TxStart_Full;	CS8900_TxLEN = length;	/* Test to see if the chip has allocated memory for the packet */	if ((get_reg (PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) 	{		/* Oops... this should not happen! */		#ifdef DEBUG				Uart_Printf("cs: unable to send packet; retrying...\n");		#endif		eth_reset ();		eth_reginit ();		goto retry;	}	/* Write the contents of the packet */	/* assume even number of bytes */	for (addr = packet; length > 0; length -= 2)	{		CS8900_RTDATA = *addr++;	}	/* wait for transfer to succeed */	while ((s = get_reg (PP_TER) & ~0x1F) == 0);//?	/* nothing */ ;	if ((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) 	{		#ifdef DEBUG				Uart_Printf("\ntransmission error %#x\n", s);		#endif	}	return 0;}/*********************************************************** 函数介绍:本函数是以太网接收、发送的中断处理函数。			* 输入参数:无* 输出参数:无* 返回值  :无**********************************************************/void cs8900_Isr(void){	// amount of ISQ's to handle (> 0) in one cs8900_service() call	unsigned char events2service = 1;	static unsigned short irq_status = 0x0000;		// no unhandled irq_status left?	if (irq_status == 0x0000)	{		// read ISQ register		irq_status = get_reg (PP_ISQ);	}	// ISQ interrupt event, and allowed to service in this loop?	while ((irq_status != 0x0000) && (events2service-- > 0))	{		// investigate event		if ((irq_status & 0x003f) == 0x0004/*Receiver Event*/)		{			// correctly received frame, either broadcast or individual address			// TODO: think where these checks should appear: here or in cs8900_input()			if ((irq_status & 0x0100/*RxOK*/) && (irq_status & 0x0c00/*Broadcast | Individual*/))			{				// read the frame from the cs8900a				eth_rx();			}			else			{				// skip this frame				put_reg (PP_RxCFG, 0x0040/*Skip_1*/);			}		}		// read ISQ register		irq_status = get_reg (PP_ISQ);	}}/*********************************************************** 函数介绍:本函数被使用来做网络初始化,因为网络芯片中断*           触发脚接到2410的外部中断脚9,所以初始化时设置*           2410的外部中断9。而网络芯片产生高有效中断,因此*           要设置2410的外部中断9高有效。 				* 输入参数:无* 输出参数:无* 返回值  :无**********************************************************/static void Int_cs8900_init(void){	rGPGCON = rGPGCON |(1<<3);//PG1 = EINT9		rEXTINT1 = rEXTINT1 | 0x1<<4; //EINT9 = high level triggered		//设置中断入口函数    pISR_EINT8_23 = (U32)cs8000Int_Net;        rEINTPEND = 0xffffff;    ClearPending(BIT_EINT8_23);    rINTMSK=~(BIT_EINT8_23);//开中断}/*********************************************************** 函数介绍:本函数是网络中断处理函数		* 输入参数:无* 输出参数:无* 返回值  :无**********************************************************/static void __irq cs8000Int_Net(void){	if(rEINTPEND==(1<<9))	{		cs8900_Isr();		rEINTPEND=(1<<9);	}    ClearPending(BIT_EINT8_23);}/*********************************************************** 函数介绍:本函数是cs8900 init函数。			* 输入参数:无* 输出参数:无* 返回值  :无**********************************************************/void cs8900_Init(void){	unsigned char ru;	ru = eth_init();	if (ru == 1)//init正确	{		Uart_Printf("eth_init is ok!\n");	}	else//init失败	{		Uart_Printf("eth_init is not ok!\n");		return;	}    //网卡中断处理初始化函数    Int_cs8900_init();	}/*********************************************************** 函数介绍:本函数是cs8900 init函数。			* 输入参数:无* 输出参数:无* 返回值  :无**********************************************************/void Test_cs8900(void){	cs8900_Init();	while(1);}

⌨️ 快捷键说明

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