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

📄 lib_emac.c

📁 uCOS-II下实现的lwip协议栈实现Ping功能
💻 C
📖 第 1 页 / 共 2 页
字号:
    OSAPISemSend(hEthernetInput);
//    OSSchedUnlock();
    }
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : EMACSendPacket
//* 功能描述 : 由__low_level_output()函数调用,完成实际的数据发送。
//* 入口参数 :         <pbFrom>[in] 指向pbuf中数据的指针
//*			 :       <ulLength>[in] pbuf中的数据长度
//*			 : <blIsEndOfFrame>[in] 是否是pbuf链中的最后一个,也就是帧尾
//* 出口参数 : 如果无法申请下内存则返回ERR_MEM,成功则返回ERR_OK
//*------------------------------------------------------------------------------------------------
BOOLEAN EMACSendPacket(char *pbFrom, INT32U ulLength, BOOLEAN blIsEndOfFrame)
{

	INT32U i=0;
	INT8U	err=0;
	
	if(pbFrom==NULL)
		return	ERR_MEM;
	OSSemPend(hEthernetInput,0,&err);
//	dm9000_reg_write(DM9000_IMR,0x80);    //先禁止网卡中断,防止在发送数据时被中断干扰
	
	///*写数据到发送缓冲寄存器中等待发送
	//Printf("\nEMACSendPacket\n");
	
	DM_ADD = DM9000_MWCMD;
	
	for(i=0; i<ulLength; i+=2)                   //16 bit mode
    {
       // udelay(2);
        DM_CMD = pbFrom[i] | (pbFrom[i+1]<<8);
    }
    
	if(blIsEndOfFrame)////*说明是末尾的pbuf了
	{
		sendlengh+=ulLength;
		
		//*将这个最终的长度写入发送长度寄存器中
		dm9000_reg_write(DM9000_TXPLH, (sendlengh>>8) & 0x0ff);
    	dm9000_reg_write(DM9000_TXPLL, sendlengh & 0x0ff);
    	sendlengh=0;
    	dm9000_reg_write(DM9000_TCR, 0x01);     //发送数据到以太网上
	}
	OSAPISemSend(hEthernetInput);
//	dm9000_reg_write(DM9000_IMR,0x81);////开启网卡中断
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : EMACReadPacket
//* 入口参数 :  
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
void EMACReadPacket(struct buffer_pool * temp,char *pbTo, INT16S uwSegmentLen, BOOLEAN blIsLastPbuf)
{		
	//*首先是接着上次的检查开始,或者是上次的传送开始的。也就是说这里的指针值
	//*是没有什么变化的	
	INT16U i=0;
	static unsigned int countt=0;
	if(uwSegmentLen<=0||uwSegmentLen>=1600) return;
	if(temp==NULL) return ;
	//countt++;
	//if(countt%200==0)
	//{
//	if(!blIsLastPbuf) Printf("bug in the EMACReadPacket\n");
	//Printf("\nEMACReadPacket	length %d  packet is %d\n",uwSegmentLen,countt);
	//}
	for(;i<uwSegmentLen;i++)
	{
		pbTo[i]=temp->data[i];
//		Printf(" %x ",temp->data[i]);
//		if((i+1)%10==0) Printf("\n");
	}
//	Printf(" \n***********\n");
	//*将表加入到空闲表中
	OSSchedLock();
	if(head_free==NULL)
	head_free=temp;
	else
	{
		temp->next=head_free;
		head_free=temp;
	}
	OSSchedUnlock();
}

//*------------------------------------------------------------------------------------------------
//* 函数名称 : DM9000_init
//* 功能描述 : 初始化EMAC:不会打开网卡中断寄存器
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------

static void DM9000_init(void)
{
	INT32U i;
	extern OS_EVENT * hEthernetInput;
	//opera_timer(0);
    __CheckPHYID();
    
    //初始化设置步骤: 1
    dm9000_reg_write(DM9000_GPCR, 0x01);    //设置 GPCR(1EH) bit[0]=1,使DM9000的GPIO3为输出。
    dm9000_reg_write(DM9000_GPR,  0x00);    //GPR bit[0]=0 使DM9000的GPIO3输出为低以激活内部PHY。
    udelay(2000);                           //延时2ms以上等待PHY上电。
    //初始化设置步骤: 2
    dm9000_reg_write(DM9000_NCR,  0x03);    //软件复位
    udelay(500);                               //延时20us以上等待软件复位完成
    dm9000_reg_write(DM9000_NCR,  0x00);    //复位完成,设置正常工作模式。
    dm9000_reg_write(DM9000_NCR,  0x03);    //第二次软件复位,为了确保软件复位完全成功。此步骤是必要的。
    udelay(500);
    dm9000_reg_write(DM9000_NCR,  0x00);
    //初始化设置步骤: 3
    dm9000_reg_write(DM9000_IMR,  0x80);     //中断禁止
    //初始化设置步骤: 4

    dm9000_reg_write(DM9000_TCR,  0x00);    //发送控制
    dm9000_reg_write(DM9000_BPTR, 0x3f);
    dm9000_reg_write(DM9000_FCTR, 0x38);    //接收FIFO门限3k 8k
    dm9000_reg_write(DM9000_FCR,  0xff);
    dm9000_reg_write(DM9000_SMCR, 0x00);    
    //初始化设置步骤: 5
    for(i=0; i<6; i++)
        dm9000_reg_write(DM9000_PAR + i, mac_addr[i]);
    
    //初始化设置步骤: 6
    dm9000_reg_write(DM9000_NSR,  0x2c);    //清除各种状态标志位
    dm9000_reg_write(DM9000_ISR,  0x3f);    //清除所有中断标志位
    dm9000_reg_write(DM9000_RCR,  0x39);    //接收控制
    dm9000_reg_write(DM9000_IMR,  0x81);     //中断使能
	Printf("DM9000 config OK\n");
  // opera_timer(1);
}


static void OpenDM9000Isr(void)
{
	 //初始化设置步骤: 6
    dm9000_reg_write(DM9000_ISR,  0x3f);    //清除所有中断标志位
    dm9000_reg_write(DM9000_IMR, 0x81);     //中断使能
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : EMACInit
//* 功能描述 : 初始化EMAC:对PHY、MII口线、EMAC操作模式进行配置,设置接收和发送缓冲区描述符。设置
//*			 : EMAC接收和发送中断
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------


void EMACInit(void)
{
	//* 就是一个时间控制结构体的指针	
	extern OS_EVENT * hEthernetInput;

	buffer_pool_init();
	//* 建立接收任务使用的信号量,对uCOS的配置保证信号量在软件逻辑上能够百分百建立成功
	hEthernetInput = OSAPISemNew(1);
	
	hEMACInput= OSAPISemNew(0);
	
	EthernetInput= OSAPISemNew(0);
	
	//*为了减少包的丢失,专门用一个底层函数处理得到的数据包,其中使用自己的缓冲区,这个底层函数优先级很高
	OSTaskCreate(MACPackets,(void *)0, &MACPACKETS_STK[MACPACKETS_STK_LENGH - 1], 4);
	
	//*设置外部中断开启
	IOSetInit();
	
	//*初始化网卡,主要是为下一步检查网卡连接状态做准备
	DM9000_init();

}



//*------------------------------------------------------------------------------------------------
//* 函数名称 : GetInputPacketLen
//* 功能描述 : 获取到达的信息包的长度
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
struct buffer_pool * GetInputPacketLen( void)
{
	struct buffer_pool * pp;
	if(head_used==NULL)
		return	NULL;
	else
	{
		OSSchedLock();
		
		pp=head_used;
		head_used=head_used->next;
		pp->next=NULL;
		
		OSSchedUnlock();
		return pp;	
	}
	return pp;
}


char DATA[1500]={
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10
};
INT8S pacg[2000];
void testmac(void * pada)
{
	INT16S	leng=0,i=0;
	struct buffer_pool * tk=NULL;
	pada=pada;
	
	EMACInit();
	
	while(1)
	{
	/*	等待网卡端送来数据	*/
		OSAPISemWait(hEthernetInput, 0);
		tk=GetInputPacketLen();
		if(tk)
		{
			i++;
			leng=tk->leng;
//			Printf("\nThe packet is %d   the lengh=%d \n",i,leng);
			EMACReadPacket(tk,pacg,leng,1);
//			EMACSendPacket(DATA,1500,1);		
		}
	}
}

//static mun=0;
void MACPackets(void *pada)
{
	pada=pada;
	while(1)
	{
		//*	首先获取信号量,如果有信号量 那么获取,这样当多个事件的时候就能不丢失
		OSAPISemWait(hEMACInput, 0);
		
		//*然后去DM9000的RAM中取数据块,取到的数据块首先放置在缓冲区中。这个区的大小要依据自己的需要定义,要能保证不溢出
//		mun++;
//		Printf("\nThe packet is %d\n",mun);
		readthemacbuffer();			
		//*给上层协议栈的buf发送信号,使它过来搬取数据
		
	}
}

//*------------------------------------------------------------------------------------------------
//* 函数名称 : PrintfDM9000Reg
//* 功能描述 : 供调试用
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------

static void PrintfDM9000Reg(void)
{
	uint16 data,i;
	Printf("------Print the reg of dm9000\n");
	for(i=0x0;i<0x10;i++)
	{
		data = dm9000_reg_read(i);
		Printf("RET_0x%02x = %x\n",i,data);
	}
	for(i=0x10;i<0x16;i++)
	{
		data = dm9000_reg_read(i);
		Printf("RET_0x%02x = %02x\n",i,data);
	}
	
	i=0x16;
	data = dm9000_reg_read(i);
	Printf("RET_0x%2x = %x\n",i,data);
	
	for(i=0x1e;i<0x26;i++)
	{
		data = dm9000_reg_read(i);
		Printf("RET_0x%2x = %x\n",i,data);
	}
	
	for(i=0x28;i<0x2c;i++)
	{
		data = dm9000_reg_read(i);
		Printf("RET_0x%2x = 0x%x\n",i,data);
	}
	
	i=0x2f;
	data = dm9000_reg_read(i);
	Printf("RET_0x%2x = %x\n",i,data);
	
	for(i=0xf0;i<0xff;i++)
	{
		data = dm9000_reg_read(i);
		Printf("RET_0x%2x = %x\n",i,data);
	}
	data = dm9000_reg_read(i);
	Printf("RET_0x%2x = %x\r\n",i,data);
	
	data = dm9000_reg_read(0xfe);
	Printf("dm9000 IO mode:%x\r\n",((uint8)data)>>6);
	
	data = dm9000_reg_read(0x01);
	if(((uint8)data)>>1)
		Printf("10M mode\r\n");				
	else
		Printf("100M mode\r\n");
	
}



















⌨️ 快捷键说明

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