[国嵌攻略][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 ...
随机推荐
- g4e基础篇#1 什么是版本控制系统
g4e 是 Git for Enterprise Developer的简写,这个系列文章会统一使用g4e作为标识,便于大家查看和搜索. 章节目录 前言 1. 基础篇: 为什么要使用版本控制系统 Git ...
- Java NIO (五) 管道 (Pipe)
Java NIO 管道是2个线程之间的单向数据连接.Pipe有一个source通道和一个sink通道.数据会被写到sink通道,从source通道读取. 如下图: 向管道写数据: 从管道读数据: 1. ...
- Linux的编码及编码转换
如果你需要在Linux中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linux一般都是UTF-8.下面介绍一下,在Li ...
- Python第二十四天 binascii模块
Python第二十四天 binascii模块 binascii用来进行进制和字符串之间的转换 import binascii s = 'abcde' h = binascii.b2a_hex(s) # ...
- 测试库的接收到的数据是否完整(jrtplib为列)
最近使用jrtplib来接收RTP包,然后解码播放 发现解码出来的是绿屏,马赛克 于是开始排查 首先直接用wireshark抓进来的包,转为可以被vlc播放的文件 操作如下 http://blog.c ...
- MySQL ALTER TABLE: ALTER vs CHANGE vs MODIFY COLUMN
ALTER COLUMN 语法: ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} 作用: 设置或删除列的默认值.该操作会直接修 ...
- Go 语言编写单元测试
吾尝终日而思矣,不如须臾之所学也:吾尝跂而望矣,不如登高之博见也.登高而招,臂非加长也,而见者远:顺风而呼,声非加疾也,而闻者彰.假舆马者,非利足也,而致千里:假舟楫者,非能水也,而绝江河.君子生非异 ...
- sqlalchemy 踩过的坑
记录下Sqlalchemy遇到的问题,不定时更新. 设置主键为非自增 sqlalchemy 在sql server中默认主键是自增的,如果在数据库设置的主键不是自增的,这个时候插入就会出现异常: 提示 ...
- JQuery 网页瞄点
$("html,body").animate({ scrollTop: $("#Content1").offset().top }, 3000); 代码说明:h ...
- 解决打开png图片黑屏问题(批量还原Xcode优化后的png)
window 打开Xcode 里面的png图片会黑屏,但是在mac 打开就显示正常, 这是因为Xocde里面的png图片被 pngcrush 优化过了,需要还原它的优化,window 平台才可以打开. ...