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

📄 cs89x.c

📁 这是TFTP 协议的最新源代码 很辛苦的
💻 C
字号:
/*	Copyright 2001-2004 Georges Menie (www.menie.org)	This file is part of Tftpnaive.    Tftpnaive is free software; you can redistribute it and/or modify    it under the terms of the GNU Lesser General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    Tftpnaive is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public License    along with Tftpnaive; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include "tftpnaive.h"#include "68vz328.h"#include "io.h"#include "net.h"#include "cs89x.h"#include "baselib.h"#include "timer.h"#ifdef CS89_HW_SWAP#define writew_reg(w,r) writew(swapw(w),r)#define readw_reg(r) swapw(readw(r))#define writew_data(w,r) writew(w,r)#define readw_data(r) readw(r)#else#define writew_reg(w,r) writew(w,r)#define readw_reg(r) readw(r)#define writew_data(w,r) writew(swapw(w),r)#define readw_data(r) swapw(readw(r))#endifinline static unsigned short swapw (unsigned short x){	return ((x << 8) | (x >> 8));}int cs89xSend (void *pkt, unsigned short length){	register unsigned short *p = pkt;	register int i;	writew_reg (CS89xTxCMDStartAll, CS89xIOTransmitCommand);	writew_reg (length, CS89xIOTransmitLength);	writew_reg (CS89xBusStatus, CS89xIOPacketPagePointer);	for (i = 10; i >= 0; --i) {		if ((readw_reg (CS89xIOPacketpageDataPort0) & CS89xBusSTRdy4TxNOW))			break;		usleep (30);	}	if (i < 0)		return ERR_TIMEOUT;	for (i = 0; i < (length + 1) >> 1; ++i, ++p) {		writew_data (*p, CS89xIOReceiveTransmitDataPort0);	}	writew_reg (CS89xTransmitterEvent, CS89xIOPacketPagePointer);	for (i = 100; i >= 0; --i) {		if ((readw_reg (CS89xIOPacketpageDataPort0) & CS89xTxEventTxOK))			break;		usleep (30);	}	if (i < 0)		return ERR_TIMEOUT;	return 0;}static void RxEvent (short isq){	int idxi, idxo;	unsigned short i, length;	idxi = idxiPBuf;	idxo = idxoPBuf;	idxi = (++idxi) % MAXPACKETBUF;	writew_reg (CS89xReceiveLength, CS89xIOPacketPagePointer);	length = readw_reg (CS89xIOPacketpageDataPort0);	if (idxi != idxo && length < MAXPACKETLEN) {		unsigned short *p = (unsigned short *) &packetBuf[idxi][0];		for (i = (length + 1) >> 1; i > 0; --i) {			*p++ = readw_data (CS89xIOReceiveTransmitDataPort0);		}		packetBufLen[idxi] = length;		idxiPBuf = idxi;	}	else {		/* no more buffers or packet too big, discard new packet */		for (i = (length + 1) >> 1; i > 0; --i) {			(void) readw (CS89xIOReceiveTransmitDataPort0);		}		++netif.RxQFull;	}}/* * CS89x Interrupt Service Routine * */void __attribute__ ((interrupt)) cs89xISR (void){	register unsigned short isq;	++netif.TotalIRQ;	if (readl (ISR) & (1 << IRQ_NUM)) {		for (;;) {			isq = readw_reg (CS89xIOInterruptStatusQueue);			if (isq == 0)				break;			++netif.TotalEvent;			switch (isq & 0x3f) {			case 0x4:			// RxEvent				RxEvent (isq >> 6);				++netif.RxEvent;				break;			case 0x8:			// TxEvent				++netif.TxEvent;				break;			case 0xC:			// BufEvent				++netif.BufEvent;				break;			case 0x10:			// RxMiss				netif.RxMiss += isq >> 6;				break;			case 0x12:			// TxColl				netif.TxColl += isq >> 6;				break;			default:				++netif.UnknownEvent;				break;			}		}		orl (1 << IRQ_NUM, ISR);	}}int cs89xReset (void){	unsigned short pic1, pic2;	int t;	/* software reset */	writew_reg (CS89xSelfControl, CS89xIOPacketPagePointer);	writew_reg (CS89xSelfCTLRESET, CS89xIOPacketpageDataPort0);	for (t = 20; t >= 0; --t) {		if (!(readw_reg (CS89xIOPacketpageDataPort0) & CS89xSelfCTLRESET))			break;		usleep (100);	}	if (t < 0)		return ERR_TIMEOUT;#if 0	/* dummy reads to go 16 bits */	readb (CS89xIOReceiveTransmitDataPort0);	readb (CS89xIOReceiveTransmitDataPort0 + 1);	readb (CS89xIOReceiveTransmitDataPort0);	readb (CS89xIOReceiveTransmitDataPort0 + 1);#endif	/* signature check */	if (readw_reg (CS89xIOPacketPagePointer) != 0x3000)		return ERR_CHIPID;	/* wait on eeprom busy */	writew_reg (CS89xSelfStatus, CS89xIOPacketPagePointer);	for (t = 150; t >= 0; --t) {		if (!(readw_reg (CS89xIOPacketpageDataPort0) & CS89xSelfSTSIBUSY))			break;		usleep (100);	}	if (t < 0)		return ERR_TIMEOUT;	/* wait on init */	writew_reg (CS89xSelfStatus, CS89xIOPacketPagePointer);	for (t = 400; t >= 0; --t) {		if ((readw_reg (CS89xIOPacketpageDataPort0) & CS89xSelfSTINITD))			break;		usleep (100);	}	if (t < 0)		return ERR_TIMEOUT;	/* EISA code check */	writew_reg (CS89xProductIdentificationCode, CS89xIOPacketPagePointer);	pic1 = readw_reg (CS89xIOPacketpageDataPort0);	pic2 = readw_reg (CS89xIOPacketpageDataPort1);	if (pic1 != CS89xEISACODE)		return ERR_CHIPID;	/* Bus control, disable interrupts */	writew_reg (CS89xBusControl, CS89xIOPacketPagePointer);	writew_reg (0, CS89xIOPacketpageDataPort0);	/* Line control, disable Tx and Rx */	writew_reg (CS89xLineControl, CS89xIOPacketPagePointer);	writew_reg (0, CS89xIOPacketpageDataPort0);	/* Disable Receive interrupts */	writew_reg (CS89xReceiverConfiguration, CS89xIOPacketPagePointer);	writew_reg (0, CS89xIOPacketpageDataPort0);	/* Disable Transmit interrupts */	writew_reg (CS89xTransmitConfiguration, CS89xIOPacketPagePointer);	writew_reg (0, CS89xIOPacketpageDataPort0);	/* force the LEDs off */	writew_reg (CS89xSelfControl, CS89xIOPacketPagePointer);	writew_reg (CS89xSelfCTLHC0E | CS89xSelfCTLHC1E,				CS89xIOPacketpageDataPort0);	return 0;}#define STATUSLOOPCOUNT 20int cs89xStatus (void){	int i;	unsigned short lst;	for (i = 0; i < STATUSLOOPCOUNT; ++i) {		writew_reg (CS89xLineStatus, CS89xIOPacketPagePointer);		if ((lst =			 readw_reg (CS89xIOPacketpageDataPort0)) & CS89xLineSTLinkOK)			break;		usleep (100000);	}	if (i >= STATUSLOOPCOUNT)		return ERR_LINK;	if (lst & CS89xLineSTAUI)		printf ("AUI port, ");	if (lst & CS89xLineST10BT)		printf ("10BT port, ");	if (lst & CS89xLineSTPolarityOK)		printf ("normal polarity, ");	else		printf ("reverse polarity, ");	printf ("IEEEIA ");	for (i = 0; i < 6; i += 2) {		unsigned short w;		writew_reg (CS89xIndividualAddress + i, CS89xIOPacketPagePointer);		w = readw_data (CS89xIOPacketpageDataPort0);		printf ("%s%02x:%02x", i ? ":" : "", (w >> 8) & 0xff, w & 0xff);	}	printf ("\n");	return 0;}int cs89xSetup (void){	int i;	/* IEEE Individual Address */	for (i = 0; i < 6; i += 2) {		unsigned short w = (netif.IEEEIA[i] << 8) | netif.IEEEIA[i + 1];		writew_reg (CS89xIndividualAddress + i, CS89xIOPacketPagePointer);		writew_data (w, CS89xIOPacketpageDataPort0);	}	/* Receive Frame selection */	writew_reg (CS89xReceiverControl, CS89xIOPacketPagePointer);	writew_reg (CS89xRxCTLRxOKA | CS89xRxCTLIndividualA |				CS89xRxCTLBroadcastA, CS89xIOPacketpageDataPort0);	/* Enable Receive interrupts */	writew_reg (CS89xReceiverConfiguration, CS89xIOPacketPagePointer);	writew_reg (CS89xRxCFGRxOKiE, CS89xIOPacketpageDataPort0);	/* Enable Transmit interrupts */	writew_reg (CS89xTransmitConfiguration, CS89xIOPacketPagePointer);	writew_reg (CS89xTxCFGJaberiE | CS89xTxCFG16ColliE,				CS89xIOPacketpageDataPort0);	/* IRQ selection (INTRQ0) */	writew_reg (CS89xInterruptNumber, CS89xIOPacketPagePointer);	writew_reg (0, CS89xIOPacketpageDataPort0);	/* Line control, enable Tx and Rx */	writew_reg (CS89xLineControl, CS89xIOPacketPagePointer);	writew_reg (CS89xLineCTLSerRxOn | CS89xLineCTLSerTxOn,				CS89xIOPacketpageDataPort0);	/* allow status LEDs, disable sleep/standby mode */	writew_reg (CS89xSelfControl, CS89xIOPacketPagePointer);	writew_reg (0, CS89xIOPacketpageDataPort0);	/* Enable interrupts */	writew_reg (CS89xBusControl, CS89xIOPacketPagePointer);	writew_reg (CS89xBusCTLEnableIRQ, CS89xIOPacketpageDataPort0);	return cs89xStatus ();}

⌨️ 快捷键说明

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