📄 dm9000x.c
字号:
/* 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 + -