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

📄 dm9000x.c

📁 uCOS-II下实现的lwip协议栈实现Ping功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    dm9000.c: Version 1.0 12/15/2003	A Davicom DM9000 ISA NIC fast Ethernet driver for uCOS-II	Copyright (C) 2012 SunnyV1.0  02/13/2012	created by Sunny		TODO: external MII is not functional, only internal at the moment.*/#include "config.h"#include "/LwIP/include/lwip/opt.h"#include "uCOS_II/SOURCE/API/os_api.h"#include "uCOS_II/include/ucos_ii.h"#include "uCOS_II/include/OS_CPU.h"#include "dm9000x.h"/* function declaration */static int dm9000_probe(void);static u8 DM9000_ior(int);static void DM9000_iow(int reg, u8 value);int timer_load_val = 0;static u_long timer_clk;static u_long timestamp;static u_long lastdec;static struct 	buffer_pool		r_pool[RWIDE];static struct	buffer_pool	* head_free=NULL;static struct	buffer_pool	* head_used=NULL;char MACAddr[] = {8, 1, 62, 38, 10, 91};// MACchar IPAddr[]  = {192, 168, 192, 231}; 	// IP//static u8 LastIsrState = 0;/* */static void OpenDM9kIntr(void){	rEINTPEND |= 1<<9;	ClearPending(BIT_EINT8_23);	rEINTMASK = rEINTMASK & (~(0x01<<9));	rINTMSK   = rINTMSK & (~(BIT_EINT8_23));}/* */static void CloseDM9kIntr(void){	rINTMSK   |= BIT_EINT8_23;	rEINTMASK |= (0x01<<9);	rEINTPEND |= 1<<9;	ClearPending(BIT_EINT8_23);}/* * Function: irqEMACISR */static void irqEMACISR(void){	extern HANDLER hEthernetInput;	#if OS_CRITICAL_METHOD == 3		OS_CPU_SR  cpu_sr;	#endif		//u8  ulIntStatus;	OS_ENTER_CRITICAL()	{		CloseDM9kIntr();		LastIsrState = DM9000_ior(0xfe) ; //获取中断状态		//OSPrintf("dm9000 interrupt status is : 0x%x\n", LastIsrState);				if (LastIsrState & 0x01)	{			OSAPISemSend(hEthernetInput);			Uart_Printf("Interrupt is from receive,state=0x%x\n", LastIsrState);			dm9000_rx();		}				if (LastIsrState & 0x02)	{			//Uart_SendString("Interrupt is from Transmit\n");		}		//OSIntExit();		DM9000_iow(DM9000_ISR, 0x3f); //清除所有中断标志位		DM9000_iow(DM9000_IMR, 0x81);			OpenDM9kIntr();	//OpenInt9();	}	OS_EXIT_CRITICAL()}//*------------------------------------------------------------------------------------------------//* 函数名称 : buffer_pool_init//* 功能描述 : 接收数据缓冲池初始化,在EMAC初始化中被调用//* 入口参数 : 无//* 出口参数 : 无//*------------------------------------------------------------------------------------------------static void buffer_pool_init(void){	INT8U i=0;	head_free=r_pool;	head_used=NULL;	for(;i<RWIDE-1;i++)	{		r_pool[i].next=&r_pool[i+1];		r_pool[i].leng=0;	}	r_pool[i].next=NULL;	r_pool[i].leng=0;}//*---------------------------------------------------------------------------------------------//* 函数名称 : SetDM9000Intr//* 功能描述 : 为DM9000中断初始化INT9引脚的中断//* 入口参数 : 无//* 出口参数 : 无//*--------------------------------------------------------------------------------------------void SetDM9000Intr(void){	//GPG1设置为EINT9,DM9000的INT连接EINIT9 [3:2]=10	rGPGCON = (rGPGCON & (~(0x03<<2))) | (0x02<<2);	       	rEXTINT1 = (rEXTINT1 & (~(0x07<<4))) | (0x01<<4);	rEINTMASK = rEINTMASK & (~(0x01<<9));  //EINIT9中断使能    	//rINTMOD |= 0x01<<5;	//ChearPending()清除SCRPND和INTPND对应的位,rSRCPND = bit;rINTPND = bit;rINTPND;	//清除中断源	/*rGPFCON = (rGPFCON & (~(0x03<<14))) | (0x02<<14);	//GPF7设置为EINT7	rEXTINT0 = (rEXTINT0 & (~(0x07<<28))) | (0x01<<28);	//开外部中断屏蔽寄存器,小门	rEINTMASK = rEINTMASK & (~(0x01<<7));*/ 	rEINTPEND |= 1<<9;	ClearPending(BIT_EINT8_23);	//rSRCPND |= 0x1<<5;rINTPND |= 0x1<<5 ;	pISR_EINT8_23 = (U32)irqEMACISR;                	rINTMSK = rINTMSK & (~(BIT_EINT8_23));	}/* */int get_ticks(void){	int now = readl(rTCNTO4) & 0xffff;//READ_TIMER();	if (lastdec >= now) {		/* normal mode */		timestamp += lastdec - now;	} else {		/* we have an overflow ... */		timestamp += lastdec + timer_load_val - now;	}	lastdec = now;	return timestamp;}/* * NOP for a while/unit usec */void udelay(unsigned long usec){	u_long tmo;	u_long start = get_ticks();	tmo = usec / 1000;	tmo *= (timer_load_val * 100);	tmo /= 1000;	while ((u_long) (get_ticks() - start) < tmo) ;/*NOP*/}/* */u_long get_timer_masked(void){	u_long tmr = get_ticks();	return tmr / (timer_clk / CONFIG_SYS_HZ);}/* */u_long get_timer(u_long base){	return get_timer_masked() - base;}/******************************************************************  * basic operation about reading and writing dm9000 registers. *****************************************************************//* * Read a byte from I/O port */static u8 DM9000_ior(int reg){	DM9000_outb(reg, DM9000_IO);	return DM9000_inb(DM9000_DATA);}/* * Write a byte to I/O port */static void DM9000_iow(int reg, u8 value){	DM9000_outb(reg, DM9000_IO);	DM9000_outb(value, DM9000_DATA);}/****************************************************************** * Confusion about sending data of dm9000,  * the bus width is 8 or 16 or 32 bit mode ? *****************************************************************//* 8 bit data to send */static void dm9000_outblk_8bit(volatile void *data_ptr, int count){	int i;	for (i = 0; i < count; i++)		DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA);}/* 16 bit */static void dm9000_outblk_16bit(volatile void *data_ptr, int count){	int i;	u32 tmplen = (count + 1) / 2;	for (i = 0; i < tmplen; i++)		DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);}/* 32 bit */static void dm9000_outblk_32bit(volatile void *data_ptr, int count){	int i;	u32 tmplen = (count + 3) / 4;	for (i = 0; i < tmplen; i++)		DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);}/*-----------------------------------------------------------------*/static void dm9000_inblk_8bit(void *data_ptr, int count){	int i;	for (i = 0; i < count; i++) {		((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA);	}}static void dm9000_inblk_16bit(void *data_ptr, int count){	int i;	u32 tmplen = (count + 1) / 2;	for (i = 0; i < tmplen; i++) {		((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA);	}}static void dm9000_inblk_32bit(void *data_ptr, int count){	int i;	u32 tmplen = (count + 3) / 4;	for (i = 0; i < tmplen; i++) {		((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA);	}}/*-------------------------------------------------------------------*/static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen){	u32 tmpdata;	DM9000_outb(DM9000_MRCMD, DM9000_IO);	tmpdata = DM9000_inl(DM9000_DATA);	*RxStatus = __le16_to_cpu(tmpdata);	*RxLen = __le16_to_cpu(tmpdata >> 16);}static void dm9000_rx_status_16bit(u16 *RxStatus, u16 *RxLen){	DM9000_outb(DM9000_MRCMD, DM9000_IO);	*RxStatus = __le16_to_cpu(DM9000_inw(DM9000_DATA));	*RxLen = __le16_to_cpu(DM9000_inw(DM9000_DATA));}static void dm9000_rx_status_8bit(u16 *RxStatus, u16 *RxLen){	DM9000_outb(DM9000_MRCMD, DM9000_IO);	*RxStatus = __le16_to_cpu(DM9000_inb(DM9000_DATA) +			  (DM9000_inb(DM9000_DATA) << 8));	*RxLen    = __le16_to_cpu(DM9000_inb(DM9000_DATA) +			  (DM9000_inb(DM9000_DATA) << 8));}/*-----------------------------------------------------------------*//* * Reset DM9000 */static void dm9000_reset(void){	DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT);//DM9000_GPCR?	/* Step 1: Power internal PHY by writing 0 to GPIO0 pin */	DM9000_iow(DM9000_GPR, 0);//DM9000_GPR?	/* Step 2: Software reset */	DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));//DM9000_NCR?	do {		Uart_SendString("resetting the DM9000, 1st reset\n");		udelay(25); /* Wait at least 20 us */	} while (DM9000_ior(DM9000_NCR) & 1);	DM9000_iow(DM9000_NCR, 0);	DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */

⌨️ 快捷键说明

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