[国嵌攻略][065][DM9000驱动程序设计]
移植代码:通过已有的可用的代码修改到新环境下运行。
代码编写:
初始化网卡
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
}
[国嵌攻略][065][DM9000驱动程序设计]的更多相关文章
- [国嵌攻略][117][LED驱动程序设计]
LED程序设计 1.编写内核模块 2.搭建字符驱动框架 3.实现设备方法 头文件 <linux/io.h> writel() 1.编译/安装驱动 make cp leddev.ko ... ...
- [国嵌攻略][164][USB驱动程序设计]
USB驱动模型 1.USB host controller driver(主控器驱动):为USB主控制器提供驱动程序 2.USB core(USB核心):连接USB主控制器驱动和USB设备驱动 3.U ...
- [国嵌攻略][160][SPI驱动程序设计]
SPI Flash驱动 1.打开/drivers/mtd/devices/m25p80.c驱动文件.找到初始化m25p80_init函数,其中通过spi_register_driver来注册spi设备 ...
- [国嵌攻略][151][nandflash驱动程序设计]
初始化 打开/drivers/mtd/nand/s3c2410.c找到nand flash驱动程序代码,找到模块初始化函数s3c_nand_init,找到platform_driver中的probe函 ...
- [国嵌攻略][136][DM9000网卡驱动深度分析]
网卡初始化 1.分配描述结构,alloc_etherdev 2.获取平台资源,platform_get_resource 2.1.在s3c_dm9k_resource中有相关的资源 2.2.add地址 ...
- [国嵌攻略][137][DM9000网卡驱动编程]
DM9000数据发送 DM9000数据发送函数是在/drivers/net/dm9000.c中的dm9000_start_xmit函数 static int dm9000_start_xmit(str ...
- [国嵌攻略][119][Linux中断处理程序设计]
裸机中断: 1.中断统一入口. 2.注册中断处理程序. 3.根据中断源编号,调用中断处理程序. Linux中断 1.在entry-armv.S中的_irq_svc是中断统一入口. 2.获取产生中断源的 ...
- [国嵌攻略][061][2440LCD驱动设计]
LCD初始化 1.引脚初始化 2.时序初始化 VBPD(vertical back porch):表示在一帧图像开始时,垂直同步信号以后的无效的行数 VFBD(vertical front porch ...
- [国嵌攻略][052][NandFlash驱动设计_读]
NandFlash读数据方式 1.页读,读出页中主数据区的所有数据,提供页地址(行地址) 2.随机读,读出页中指定的存储单元的数据,提供页地址(行地址)和页内偏移(行地址) 代码编写 1.根据Nand ...
随机推荐
- nova创建虚拟机源码分析系列之四 nova代码模拟
在前面的三篇博文中,介绍了restful和SWGI的实现.结合restful和WSGI配置就能够简单的实现nova服务模型的最简单的操作. 如下的内容是借鉴网上博文,因为写的很巧妙,将nova管理虚拟 ...
- lesson - 8 Linux文档的压缩和打包
内容概要:1. gzip工具语法: gzip [-d#] filename 其中#为1-9的数字,默认压缩级别为6 只能压缩文件gzip filename 生成filename.gz 源文件消失解压 ...
- vue的挖坑和爬坑之css背景图样式终极解决方法
原问题 #wrapper{ width:100%; height:100%; position:fixed; background-image:url(./img/open_bg.jpg) } 在.v ...
- SQL Server CPU
解决数据库系统的性能问题可能是一项艰巨的任务.了解如何找到问题很重要,但是了解系统对特定请求作出特定反应的原因更加重要.影响数据库服务器上的 CPU 利用率 的因素有很多:SQL 语句的编译和重新编译 ...
- idea创建Maven多模块项目
最近几天学习到了创建多模块项目,应为自己使用的是Idea,所以想用idea创建多模块,查阅了相关资料后,自己做一个记录. 一.首先创建一个maven项目 Parent Project,创建xxx-ro ...
- 动手搭建第一个小程序音视频Demo
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:小程序音视频产品经理 腾讯云提供了全套技术文档和源码来帮助您快速构建一个音视频小程序,但是再好的源码和文档也有学习成本,为了尽快的能调试起 ...
- 客户端 未登录页面 (clearfix 分割线)
做了一个手机客户端页面,未登录的状态页面 类似 如上图所示 这样 上面列表采取80%宽度,右侧浮动.ul li设置绝对定位.左边icon图标采取决定定位. 为了防止小屏幕手机左边空白缝隙过小,事先给外 ...
- 总结基础OOP(面向对象)
OOP其实也就是面向对象编程. 一:什么是对象: 我们最常见的理解方式无非是:对象(object)是任何看得见.摸得着.感觉得到,可以获得的东西,有自己的标识的任何东西.对象是某一类的事物的具体个 ...
- 局域网中间人:MITMf使用
系统环境:kali 安装流程参考github官方地址:https://github.com/byt3bl33d3r/MITMf/wiki/Installation 安装相关依赖: apt--dev l ...
- windows平台python 2.7环境编译安装zbarlight
类似于前一篇博文,http://www.cnblogs.com/zhongtang/p/7148082.html中描述的情况. 编译zbarlight同样出现问题,简要处理步骤如下: 1.到https ...