您的位置:首页 > 其它

[国嵌攻略][065][DM9000驱动程序设计]

2015-11-26 15:04 288 查看
移植代码:通过已有的可用的代码修改到新环境下运行。

代码编写:

初始化网卡

1.选中网卡

nLAN_CS BWSCON(0x48000000) DW4:01 16bit

BANKCON4(0x48000014)

(0x0<<13)|(0x0<<11)|(0x7<<8)|(0x1<<6)|(0x0<<4)|(0x0<<2)|(0x0<<0)

2.初始化中断

中断源EIN7

GPFCON GPF7:10

设置触发方式(高电平触发)

EXTINT0 0x1<<28

设置中断掩码寄存器

INTMSK ~(1<<4)

EINTMASK ~(1<<7)

3.复位网卡

4.捕获网卡

5.初始化MAC

6.初始化MAC地址

7.启动网卡

发送数据

1.禁止中断

2.写入待发送的数据

3.写入发送数据的长度

4.启动发送

5.等待发送结束

6.清除发送转态

7.恢复中断

接收数据

1.判断是否产生中断,并清除

2.空读

3.读取状态

4.读取包长度

5.读取数据

/********************************************************************
*名称:dm9000.c
*作者:D
*时间:2015.11.24
*功能:网卡驱动
*********************************************************************/

/********************************************************************
*宏定义
*********************************************************************/
#define BWSCON ( *((volatile unsigned long *)0x48000000) )     //总线宽度与等待状态寄存器
#define BANKCON4 ( *((volatile unsigned long *)0x48000014) )   //Bank4控制寄存器

#define GPFCON ( *((volatile unsigned long *)0x56000050) )     //GPF组控制寄存器,注意该寄存器只有16位
#define SRCPND ( (*(volatile unsigned long *)0X4A000000) )     //中断源请求寄存器
#define INTMSK ( (*(volatile unsigned long *)0x4A000008) )     //中断掩码寄存器
#define INTPND ( (*(volatile unsigned long *)0X4A000010) )     //中断请求寄存器
#define EXTINT0 ( *((volatile unsigned long *)0x56000088) )    //外部中断0控制寄存器
#define EINTMASK ( (*(volatile unsigned long *)0x560000A4) )   //外部中断掩码寄存器
#define EINTPEND ( (*(volatile unsigned long *)0x560000A8) )   //外部中断掩码寄存器

#define DM9000_IO ( (*(volatile unsigned short *)0x20000300) )     //DM9000索引端口
#define DM9000_DATA ( (*(volatile unsigned short *)0x20000304) )   //DM9000数据端口

//DM9000寄存器
#define DM9000_NCR 0x00    //网络控制寄存器
#define DM9000_NSR 0x01    //网络状态寄存器
#define DM9000_TCR 0x02    //发送控制寄存器
#define DM9000_RCR 0x05    //接收控制寄存器
#define DM9000_BPTR 0x08   //背压门限寄存器
#define DM9000_FCTR 0x09   //流量控制门限寄存器
#define DM9000_FCR 0x0A    //接收流量门限寄存器

#define DM9000_PAR 0x10    //物理地址寄存器
#define DM9000_GPCR 0x1E   //GPIO控制寄存器
#define DM9000_GPR 0x1F    //GPIO状态寄存器
#define DM9000_SMCR 0x2F   //特殊模式寄存器

#define DM9000_MRCMDX 0xF0   //地址固定的存储数据读寄存器
#define DM9000_MRCMD 0xF2    //地址递增的存储数据读寄存器
#define DM9000_MWCMD 0xF8    //地址递增的存储数据写寄存器

#define DM9000_TXPLL 0xFC   //传输帧长度低8位
#define DM9000_TXPLH 0xFD   //传输帧长度高8位

#define DM9000_ISR 0xFE    //中断状态寄存器
#define DM9000_IMR 0xFF    //中断掩码寄存器

//DM9000 NCR配置
#define NCR_LBK (0x1<<1)   //MAC internal loopback
#define NCR_RST (1<<0)     //Software reset

//DM9000 NSR配置
#define NSR_WAKEST (1<<5)   //Clear
#define NSR_TX2END (1<<3)   //Clear
#define NSR_TX1END (1<<2)   //Clear

//DM9000 TCR配置
#define TCR_TXREQ (1<<0)   //Tx request

//DM9000 BPTR配置
#define BPTR_BPHW (0x3<<4)   //3KB
#define BPTR_JPT (0xF<<0)    //600us

//DM9000 FCTR配置
#define FCTR_HWOT (0x3<<4)   //3KB
#define FCTR_LWOT (0x8<<0)   //3KB

//DM9000 GPCR配置
#define GPCR_GPIO0 (1<<0)   //GPIO0:output

//DM9000 ISR配置
#define ISR_ROOS (1<<3)   //Clear
#define ISR_ROS (1<<2)    //Clear
#define ISR_PTS (1<<1)    //Clear
#define ISR_PRS (1<<0)    //Clear

//DM9000 RCR配置
#define RCR_DIS_LONG (1<<5)   //1522Byte
#define RCR_DIS_CRC (1<<4)    //CRC
#define RCR_RXEN (1<<0)       //Enable

//DM9000 IMR配置
#define IMR_PAR (1<<7)   //Enable
#define IMR_PRM (1<<0)   //Enable

//DM9000 网卡ID
#define DM9000_ID 0x90000A46   //DM9000 网卡ID
#define DM9000_VIDL 0x28       //DM9000 Vender ID低8位控制寄存器
#define DM9000_VIDH 0x29       //DM9000 Vender ID高8位控制寄存器
#define DM9000_PIDL 0x2A       //DM9000 Product ID低8位控制寄存器
#define DM9000_PIDH 0x2B       //DM9000 Product ID高8位控制寄存器

#define DM9000_PKT_MAX 1536   //接收数据包最大长度

/********************************************************************
*全局变量声明
*********************************************************************/
unsigned char mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};   //MAC地址

unsigned char buffur[1024];   //接收数据缓存

/********************************************************************
*函数原型声明
*********************************************************************/
void init_dm9000();
void init_cs();
void init_int();
void reset_dm9000();
void probe_dm9000();
void launch_dm9000();

int tx_dm9000(unsigned char *buffur, int length);
int rx_dm9000(unsigned char *buffur);

unsigned char ior8_dm9000(int reg);
void iow8_dm9000(int reg, unsigned char value);
unsigned short ior16_dm9000(int reg);
void iow16_dm9000(int reg, unsigned short value);

void rx_dm9000_irq();

/********************************************************************
*名称:init_dm9000
*参数:
*	none
*返回:
*	none
*功能:初始化网卡
*********************************************************************/
void init_dm9000(){
//设置片选
init_cs();

//设置中断
init_int();

//重置网卡
reset_dm9000();

//捕获网卡
probe_dm9000();

//启动网卡
launch_dm9000();
}

/********************************************************************
*名称:init_cs
*参数:
*	none
*返回:
*	none
*功能:设置片选
*********************************************************************/
void init_cs(){
//设置数据宽度
BWSCON &= ~(0x3<<16);
BWSCON |= (0x1<<16);   //DW4:16bit

//设置片选控制
//Tacs:0clk, Tcos:0clk, Tacc:14clk, Tcoh:1clk, Tcah:0clk, Tacp:2clk, PMC:normal
BANKCON4 = (0x0<<13)|(0x0<<11)|(0x7<<8)|(0x1<<6)|(0x0<<4)|(0x0<<2)|(0x0<<0);
}

/********************************************************************
*名称:init_int
*参数:
*	none
*返回:
*	none
*功能:设置中断
*********************************************************************/
void init_int(){
//配置中断引脚
GPFCON &= ~(0x3<<14);
GPFCON |= 0x2<<14;   //GPF7:EINT[7]

//设置触发方式
EXTINT0 &= ~(0x7<<28);
EXTINT0 |= 0x1<<28;   //EINT7:High level

// 设置外部中断掩码
EINTMASK &= ~(1<<7);   //EINT7:enable interrupt

// 设置中断掩码
INTMSK &= ~(1<<4);   //EINT4_7:Service available
}

/********************************************************************
*名称:reset_dm9000
*参数:
*	none
*返回:
*	none
*功能:重置网卡
*********************************************************************/
void reset_dm9000(){
//打开PHY电源
iow8_dm9000(DM9000_GPCR, GPCR_GPIO0);
iow8_dm9000(DM9000_GPR, 0);

//第一次重置
iow8_dm9000(DM9000_NCR, (NCR_LBK|NCR_RST));
iow8_dm9000(DM9000_NCR, 0);

//第二次重置
iow8_dm9000(DM9000_NCR, (NCR_LBK|NCR_RST));
iow8_dm9000(DM9000_NCR, 0);
}

/********************************************************************
*名称:probe_dm9000
*参数:
*	none
*返回:
*	none
*功能:捕获网卡
*********************************************************************/
void probe_dm9000(){
unsigned long id = 0;   //网卡ID

//获取网卡ID
id |= ior8_dm9000(DM9000_VIDL)<<0;
id |= ior8_dm9000(DM9000_VIDH)<<8;
id |= ior8_dm9000(DM9000_PIDL)<<16;
id |= ior8_dm9000(DM9000_PIDH)<<24;

//判断网卡ID
if(id == DM9000_ID){
printf("DM9000 is found!");
}else{
printf("DM9000 is not foun!");
}
}

/********************************************************************
*名称:launch_dm9000
*参数:
*	none
*返回:
*	none
*功能:启动网卡
*********************************************************************/
void launch_dm9000(){
int i;
unsigned char temp_addr;   //以太网地址临时变量

//配置网卡
iow8_dm9000(DM9000_NCR, 0);                                  //Program operating register, only internal phy supported
iow8_dm9000(DM9000_TCR, 0);                                  //TX Polling clear
iow8_dm9000(DM9000_BPTR, BPTR_BPHW|BPTR_JPT);                //Less 3Kb, 600us
iow8_dm9000(DM9000_FCTR, FCTR_HWOT|FCTR_LWOT);               //Flow Control : High/Low Water
iow8_dm9000(DM9000_FCR, 0);                                  //SH FIXME: This looks strange! Flow Control
iow8_dm9000(DM9000_SMCR, 0);                                 //Special Mode
iow8_dm9000(DM9000_NSR, NSR_WAKEST|NSR_TX2END|NSR_TX1END);   //clear TX status
iow8_dm9000(DM9000_ISR, ISR_ROOS|ISR_ROS|ISR_PTS|ISR_PRS);   //IOMODE:16bit, Clear interrupt status

//配置MAC地址
for(i = 0; i < 6; i++){
iow8_dm9000(DM9000_PAR+i, mac_addr[i]);
}

//回读MAC地址
printf("MAC address is ");
for(i = 0; i < 6; i++){
temp_addr = ior8_dm9000(DM9000_PAR+i);
printf("%02X:",temp_addr);
}
printf("\b!\n");

//启动网卡
iow8_dm9000(DM9000_RCR, RCR_DIS_LONG|RCR_DIS_CRC|RCR_RXEN);   //RX enable
iow8_dm9000(DM9000_IMR, IMR_PAR);   	                      //Disable all interrupt
}

/*----------------------------------------分割线----------------------------------------*/

/********************************************************************
*名称:rx_dm9000
*参数:
*	buffur   数据缓存
*返回:
*	return  0 成功
*	        1 失败
*功能:接收数据
*********************************************************************/
int rx_dm9000(unsigned char *buffur){
int i;
unsigned short temp;     //临时数据
unsigned short status;   //数据状态
unsigned short length;   //数据长度

//判断接收中断
if( !(ior8_dm9000(DM9000_ISR)&ISR_PRS) ){   //如果没有产生中断,那么返回
return 1;
}

//清除接收中断
iow8_dm9000(DM9000_ISR, ISR_PRS);

//空读接收数据
ior16_dm9000(DM9000_MRCMDX);

//读取接收状态
status = ior16_dm9000(DM9000_MRCMD);

//读取接收长度
length = ior16_dm9000(DM9000_MRCMD);
if(length > DM9000_PKT_MAX){
printf("rx length too big!\n");
return 1;
}

//读取接收数据
for(i = 0; i < length; i = i+2){
temp = ior16_dm9000(DM9000_MRCMD);
buffur[i] = (temp>>0)&0xFF;
buffur[i+1] = (temp>>8)&0xFF;
}

return 0;
}

/********************************************************************
*名称:tx_dm9000
*参数:
*	buffur   数据缓存
*	length   数据长度
*返回:
*	return   0 成功
*	         1 失败
*功能:发送数据
*********************************************************************/
int tx_dm9000(unsigned char *buffur, int length){
int i;
unsigned short temp;   //临时数据

//关闭接收中断
iow8_dm9000(DM9000_IMR, IMR_PAR);

//写入发送长度
iow8_dm9000(DM9000_TXPLL, (length>>0)&0xff);
iow8_dm9000(DM9000_TXPLH, (length>>8)&0xff);

//写入发送数据
for(i = 0; i < length; i = i+2){
temp = (buffur[i+1]<<8)|(buffur[i]<<0);
iow16_dm9000(DM9000_MWCMD, temp);
}

//打开发送请求
iow8_dm9000(DM9000_TCR, TCR_TXREQ);

//等待发送结束
while( (ior8_dm9000(DM9000_TCR)&TCR_TXREQ) );   //如果发送请求为1,那么等待

//清除发送状态
iow8_dm9000(DM9000_NSR, NSR_WAKEST|NSR_TX2END|NSR_TX1END);

//打开接收中断
iow8_dm9000(DM9000_IMR, IMR_PAR|IMR_PRM);

return 0;
}

/*----------------------------------------分割线----------------------------------------*/

/********************************************************************
*名称:ior8_dm9000
*参数:
*	reg     索引端口
*返回:
*	value   读取数据
*功能:从网卡IO端口读取一个字节
*********************************************************************/
unsigned char ior8_dm9000(int reg){
unsigned char value;

DM9000_IO = reg;
value = DM9000_DATA;

return value;
}

/********************************************************************
*名称:iow8_dm9000
*参数:
*	reg     索引端口
*	value   写入数据
*返回:
*	none
*功能:写一个字节到网卡IO端口中
*********************************************************************/
void iow8_dm9000(int reg, unsigned char value){
DM9000_IO = reg;
DM9000_DATA = value;
}

/********************************************************************
*名称:ior16_dm9000
*参数:
*	reg     索引端口
*返回:
*	value   读取数据
*功能:从网卡IO端口读取两个字节
*********************************************************************/
unsigned short ior16_dm9000(int reg){
unsigned short value;

DM9000_IO = reg;
value = DM9000_DATA;

return value;
}

/********************************************************************
*名称:iow16_dm9000
*参数:
*	reg     索引端口
*	value   写入数据
*返回:
*	none
*功能:写两个字节到网卡IO端口中
*********************************************************************/
void iow16_dm9000(int reg, unsigned short value){
DM9000_IO = reg;
DM9000_DATA = value;
}

/*----------------------------------------分割线----------------------------------------*/

/********************************************************************
*名称:rx_dm9000_irq
*参数:
*	none
*返回:
*	none
*功能:接收数据中断服务
*********************************************************************/
void rx_dm9000_irq(){
//接收数据
rx_dm9000(buffur);

//清除外部中断请求
EINTPEND |= (1<<7);   //EINT8:cleard

//清除中断源请求
SRCPND |= (1<<4);   //EINT4_7:cleard

//清除中断请求
INTPND |= (1<<4);   //EINT4_7:cleard
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: