📄 dm9000_255.c
字号:
/* * DM9000 dm9000ernet * writen by kavin, mail:kavin@citiz.net * * This program is loaded into SRAM in bootstrap mode, where it waits * for commands on UART1 to read and write memory, jump to code etc. * A design goal for this program is to be entirely independent of the * target board. Anything with a CL-PS7111 or EP7211 should be able to run * this code in bootstrap mode. All the board specifics can be handled on * the host. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <windows.h>#include <halether.h>#define MAX_COUNT 0x100000//#define DM9000_BASE (0xa4000000)#define DM9000_BASE (0xB6700000)#define DM9000_VID_L 0x28#define DM9000_VID_H 0x29#define DM9000_PID_L 0x2A#define DM9000_PID_H 0x2B#define DM9000_ID 0x90000A46#define PKTALIGN 32#define DM9000_INT_MII 0x00#define PKTSIZE_ALIGN 1536#define IOWRITED(o,d) *((volatile USHORT *)(0x0 + (o))) = (USHORT)(d)#define DBGMSG EdbgOutputDebugString#define DM9000_PPTR (*(volatile USHORT *)(DM9000_BASE))#define DM9000_PDATA (*(volatile USHORT *)(DM9000_BASE + 2))static unsigned char ior(int reg);/* packet page register access functions */static UINT GetDM9000ID(void){ UINT id_val; DM9000_PPTR = DM9000_PID_H; id_val = (DM9000_PDATA & 0xff) << 8; DM9000_PPTR = DM9000_PID_L; id_val+= (DM9000_PDATA & 0xff); id_val = id_val << 16; DM9000_PPTR = DM9000_VID_H; id_val += (DM9000_PDATA & 0xff) << 8; DM9000_PPTR = DM9000_VID_L; id_val += (DM9000_PDATA & 0xff); return id_val;}static unsigned short get_reg (int regno){ DM9000_PPTR = regno; return (unsigned short) DM9000_PDATA;}static void put_reg (int regno, unsigned short val){ DM9000_PPTR = regno; DM9000_PDATA = val;}static void ioww(int reg,USHORT value){DM9000_PPTR=reg;DM9000_PDATA=(value & 0XFFFF);}static void iow(int reg, UCHAR value){ DM9000_PPTR = reg; DM9000_PDATA = value & 0xff;}static unsigned char ior(int reg){ DM9000_PPTR = reg; return DM9000_PDATA & 0xff;}static void dm9000_reset (void){ int IoMode; int i; iow(0, 1); /* register 0 set 1 in order to reset, auto clean after 10us*/ for (i = 0; i < MAX_COUNT; i++) { } /* delay 100us */ IoMode = ior(0xfe) >> 6; /* ISR bit7:6 keeps I/O mode */ if(!IoMode) DBGMSG("DM9000 work in 16 bus width\n"); else if(IoMode == 2) DBGMSG("DM9000 work in 8 bus width\n"); else if(IoMode == 1) DBGMSG("DM9000 work in 32 bus width\n"); else DBGMSG("DM9000 work in wrong bus width, error\n"); iow(0x1e, 0x01); /* Let GPIO0 output */ iow(0x1f, 0x00); /* Enable PHY , Let GPIO0 output value = 0*/ iow(0xff, 0x80); /* disable interrupt and sram read/write point auto return*/ iow(0x01, 0xc); /* clear TX status */ iow(0x5, 0x33); /* enable rx fuction, note: must set promiscuous mode */ ior(0x6); iow(0x2, 1); /* enable tx fuction */ IoMode = ior(0x01); if(IoMode & 0x40) DBGMSG("Link on ethernet at:%d Mbps\n", (IoMode & 0x80) ? 10:100); else DBGMSG("Not link of ethernet\n");}void DM9000_get_enetaddr (USHORT *MacAddr){ int i, oft; UINT ID; ID = GetDM9000ID(); DBGMSG("DM9000 ID=0x%x\r\n ", ID); if ( ID != DM9000_ID) return; DBGMSG("Found DM9000 ID:%x at address %x", ID, DM9000_BASE); dm9000_reset (); iow(0x10 , (UCHAR)(MacAddr[0] & 0x00FF)); DBGMSG("DM9000 Mac : %B\n",ior(0x10)); iow(0x11, (UCHAR)(MacAddr[0] >> 8)); DBGMSG("DM9000 Mac : %B\n",ior(0x11)); iow(0x12, (UCHAR)(MacAddr[1] & 0x00FF) ); DBGMSG("DM9000 Mac : %B\n",ior(0x12)); iow(0x13, (UCHAR)(MacAddr[1] >> 8)); DBGMSG("DM9000 Mac : %B\n",ior(0x13)); iow(0x14, (UCHAR)(MacAddr[2] & 0x00FF)); DBGMSG("DM9000 Mac : %B\n",ior(0x14)); iow(0x15, (UCHAR)( MacAddr[2] >> 8) ); DBGMSG("DM9000 Mac : %B\n",ior(0x15)); DBGMSG("DM9000_Init OK.\n"); return;}void dm9000_halt (void){ GetDM9000ID();}int dm9000_init (DWORD iobase, DWORD membase, USHORT MacAddr[3])//int SMCInit (DWORD iobase, DWORD membase, USHORT MacAddr[3]){ BYTE version ; int tmp ; IOWRITED(0xb080000c, 0x1f7c); DBGMSG("DM9000_base=0x%x\r\n",iobase) ; version = ior(0x2C) ; DBGMSG("version=0x%x\r\n",version) ; DBGMSG("DM9000 Mac Address: %B:%B:%B:%B:%B:%B\r\n", MacAddr[0] & 0x00FF, MacAddr[0] >> 8, MacAddr[1] & 0x00FF, MacAddr[1] >> 8, MacAddr[2] & 0x00FF, MacAddr[2] >> 8); DM9000_get_enetaddr(MacAddr); iow(0x5, (UCHAR)0x23);DBGMSG("----------------------\r\n") ;tmp = ior(0x5); DBGMSG("0x5=0x%x\r\n",tmp) ;tmp = ior(0xfe); DBGMSG("0xfe=0x%x\r\n",tmp) ;tmp = ior(0xff); DBGMSG("0xff=0x%x\r\n",tmp) ;tmp = ior(0x10); DBGMSG("0x10=0x%x\r\n",tmp) ;tmp = ior(0x11); DBGMSG("0x11=0x%x\r\n",tmp) ;tmp = ior(0x12); DBGMSG("0x12=0x%x\r\n",tmp) ;tmp = ior(0x13); DBGMSG("0x13=0x%x\r\n",tmp) ;tmp = ior(0x14); DBGMSG("0x14=0x%x\r\n",tmp) ;tmp = ior(0x15); DBGMSG("0x15=0x%x\r\n",tmp) ;tmp = ior(0x16); DBGMSG("0x16=0x%x\r\n",tmp) ;tmp = ior(0x17); DBGMSG("0x17=0x%x\r\n",tmp) ;tmp = ior(0x18); DBGMSG("0x18=0x%x\r\n",tmp) ;tmp = ior(0x19); DBGMSG("0x19=0x%x\r\n",tmp) ;tmp = ior(0x1A); DBGMSG("0x1A=0x%x\r\n",tmp) ;tmp = ior(0x1B); DBGMSG("0x1B=0x%x\r\n",tmp) ;tmp = ior(0x1C); DBGMSG("0x1C=0x%x\r\n",tmp) ;tmp = ior(0x1D); DBGMSG("0x1D=0x%x\r\n",tmp) ; return TRUE;}/* Get a data block via Ethernet */extern int dm9000_rx (BYTE *pbData, DWORD dwLength){ int i; unsigned short rxlen; unsigned short *addr; unsigned short status; UCHAR RxRead; UCHAR *tmp; RxRead = ior(0xf0); RxRead = (DM9000_PDATA) & 0xff; RxRead = (DM9000_PDATA) & 0xff; if (RxRead != 1) /* no data */ return 0; DM9000_PPTR = 0xf2; /* set read ptr ++ */ status = DM9000_PDATA; /* get stat */ rxlen = DM9000_PDATA; /* get len */// //// if (rxlen> dwLength) rxlen = 0;// if (rxlen > PKTSIZE_ALIGN + PKTALIGN) rxlen=0;// while(rxlen){ for (addr = (unsigned short *) pbData, i = rxlen >> 1; i > 0; i--) *addr++ = DM9000_PDATA; if (rxlen & 1) *addr = DM9000_PDATA;// } return rxlen;}/* Send a data block via Ethernet. */extern int dm9000_send (volatile void*pbData, int length){ volatile unsigned short *addr; int tmo; UCHAR TxStatus; int IoMode,i; int length1 = length;retry: TxStatus = ior(0x01); TxStatus = TxStatus & 0xc; /* Test to see if the chip has allocated memory for the packet */ if (!TxStatus) { DBGMSG("unable to send packet; retrying... %d\n", TxStatus); /*NOP*/; IoMode = ior(0x01); if(IoMode & 0x40) dm9000_reset (); goto retry; } DM9000_PPTR = 0xf8; /* data copy ready set */ /* copy data */ //DBGMSG("length=0x%x",length) ; for (addr = pbData; length > 0; length -= 2) { //DBGMSG("[%d][%d]", *(USHORT *)addr, *((USHORT*)addr + 1)); DM9000_PDATA = *addr++; } iow(0xfd, (length1 >> 8) & 0xff); /*set transmit leng */ iow(0xfc, length1 & 0xff); /* start transmit */ iow(0x02, 1); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -