📄 dm9000.c
字号:
#define __DM9000
#include "dm9000.h"
#undef __DM9000
//********************** Global Variable **********************
// 网络数据缓冲区
volatile uchar * NetTxPacket; // 发送包 /* THE transmit packet */
volatile uchar * NetRxPackets[PKTBUFSRX]; // 接收包 /* Receive packets */
// 网卡参数
char MACAddr[] = {8, 1, 62, 38, 10, 91}; // MAC地址
IPaddr_t IPAddr = 0x0A0A0A76; // 自身IP地址: 10.10.10.118
IPaddr_t GateAddr = 0x0a0a0afe; // 网关: 10.10.10.254
IPaddr_t MaskAddr = 0xffffff00; // 子网掩码: 255.255.255.0
IPaddr_t ServerAddr = 0x0A0A0A1A; // 服务器地址: 10.10.10.26
//*************************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 取DM9000ID.
// 描述: packet page register access functions.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
u32 GetDM9000ID (void)
{
u32 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;
}//GetDM9000ID()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网卡I/O写.
//
// [参数表]
// reg: 寄存器号.
// value: 写入值.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static void iow(int reg, u8 value)
{
DM9000_PPTR = reg;
DM9000_PDATA = value & 0xff;
}//iow()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网卡I/O读.
//
// [参数表]
// reg: 寄存器号.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static unsigned char ior(int reg)
{
DM9000_PPTR = reg;
return DM9000_PDATA & 0xff;
}//ior()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网卡复位.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static void eth_reset (void)
{
int IoMode,i;
iow(0, 1); /* register 0 set 1 in order to reset, auto clean after 10us*/
for( i=0; i<1000; i++ ); // 延时
IoMode = ior(0xfe) >> 6; /* ISR bit7:6 keeps I/O mode */
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(0x05, 0x33); /* enable rx fuction, note: must set promiscuous mode */
ior(0x06);
iow(0x02, 1); /* enable tx fuction */
IoMode = ior(0x01);
}//eth_reset()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 初始化网卡.
// 描述: 初始化DM9000.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void DM9000_init (void)
{
int i, oft;
u32 ID;
ID = GetDM9000ID(); // 取网卡ID号
if ( ID != DM9000_ID) // 若ID验证失败, 则跳出
return;
eth_reset (); // 网卡重置
for( i=0, oft=0x10; i<6; i++, oft++) // 写入MAC地址
iow(oft, MACAddr[i]);
}//DM9000_init()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网络接收一个数据包.
// 描述: Get a data block via Ethernet.
//
// 返回: 数据包长度.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int eth_rx (void)
{
int i;
unsigned short rxlen;
unsigned short *addr;
unsigned short status;
u8 RxRead;
RxRead = ior(0xf1);
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 status */
rxlen = DM9000_PDATA; /* get len */
// 数据包长度溢出, 返回
if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
return 0;
// 接收数据包
for( addr=(unsigned short *)NetRxPackets[0], i=rxlen>>1; i>0; i--)
*addr++ = DM9000_PDATA;
if (rxlen & 1)
*addr = DM9000_PDATA;
NetReceiveProcess (NetRxPackets[0], rxlen); // 网络接收数据包处理
return rxlen; // 返回数据包长度
}//eth_rx()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网络发送一个数据包.
// 描述: Send a data block via Ethernet.
//
// [参数表]
// packet: 数据包地址.
// length: 数据包长度.
//
// 返回: 数据包长度.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int eth_send (volatile void *packet, int length)
{
volatile unsigned short *addr;
int tmo;
u8 TxStatus;
int length1 = length;
int IoMode, TryTimes=0, TryTimes1=0;
while(1)
{
TryTimes++;
if( TryTimes > 5 ) // 试5次
break;
TxStatus = ior( 0x01);
TxStatus = TxStatus & 0xc;
if(!TxStatus) // 发送完成置零,要判是否连接OK
{
TryTimes1 = 0;
for( tmo = get_timer(0)+CFG_HZ; get_timer(0)< tmo; )
{
TryTimes1++;
if( TryTimes1>5000 )
{
eth_reset ();
return 1;
}
}
IoMode = ior( 0x01);
if(IoMode & 0x40) // 没有连接, 重新复位再试
eth_reset ();
}
else
break;
}
DM9000_PPTR = 0xf8; /* data copy ready set */
/* copy data */
for (addr = packet; length > 0; length -= 2)
DM9000_PDATA = *addr++;
iow(0xfd, (length1 >> 8) & 0xff); /*set transmit leng */
iow(0xfc, length1 & 0xff);
/* start transmit */
iow(0x02, 1);
return 0;
}//eth_send()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -