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

📄 dm9000.c

📁 基于S3C2410和SM501的彩屏控制器程序
💻 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 + -