11_DM9000C移植

11_DM9000C移植

1、介绍

DM9000C网卡原理图:
在这里插入图片描述
问:怎样才能选中网卡芯片呢?
答:只要CPU发出的物理基地址为0x20000000 到 0x28000000之间nGCS4就会变为低电平即访问到网卡芯片。
在这里插入图片描述
移植DM9000C网卡驱动:
这个DM9000是内存接口的芯片,假设有两个开发板,它们最小的差别就是基地址、位宽、中断引脚;
找出相异性并修改:基地址、中断引脚、位宽。
在这里插入图片描述
移植DM9000c驱动程序到2440需要设置相关的时序:
在这里插入图片描述
设置s3c2440的memory controller:
1、BWSCON
在这里插入图片描述
MD9000芯片使用16条数据线,位宽为8
在这里插入图片描述

/* DW4[17:16]: 01 -16bit
* WS4[18]   :  0 -WAIT disable
* ST4[19]   :  0 = Not using UB/LB (The pins are dedicated nWBE[3:0])
*/
val = *bwscon;
val &= ~(0xf<<16);
val |= (1<<16);
*bwscon = val;

2、设置时间参数:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
操作DM9000芯片:先把地址写到索引寄存器中去,再去读数据寄存器
在这里插入图片描述

	/ *
	 * Tacs[14:13]: 发出片选信号之前,多长时间内要先发出地址信号
	 *              DM9000C的片选信号和CMD信号可以同时发出,
	 *              所以它设为0
	 * Tcos[12:11]: 发出片选信号之后,多长时间才能发出读信号nOE
	 *              DM9000C的T1>=0ns, 
	 *              所以它设为0
	 * Tacc[10:8] : 读写信号的脉冲长度, 
	 *              DM9000C的T2>=10ns, 
	 *              所以它设为1, 表示2个hclk周期,hclk=100MHz,就是20ns
	 * Tcoh[7:6]  : 当读信号nOE变为高电平后,片选信号还要维持多长时间
	 *              DM9000C进行写操作时, nWE变为高电平之后, 数据线上的数据还要维持最少3ns
	 *              DM9000C进行读操作时, nOE变为高电平之后, 数据线上的数据在6ns之内会消失
	 *              我们取一个宽松值: 让片选信号在nOE放为高电平后,再维持10ns, 
	 *              所以设为01
	 * Tcah[5:4]  : 当片选信号变为高电平后, 地址信号还要维持多长时间
	 *              DM9000C的片选信号和CMD信号可以同时出现,同时消失
	 *              所以设为0
	 * PMC[1:0]   : 00-正常模式
	 */
	*bankcon4 = (1<<8)|(1<<6);	/* 对DM9000C可以设Tacc为1, 对于DM9000E,Tacc要设大一点,如最大值7 */

2、修改dm9000c驱动程序来移植

2.0、包含头文件

。。。
。。。
/* 1845294728@qq.com zdy */
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch-s3c2410/regs-mem.h>

/* Board/System/Debug information/definition ---------------- */
。。。
。。。

2.1、去掉一些信息

在这里插入图片描述
在这里插入图片描述

2.2、函数dmfe_probe1中

int __init dmfe_probe1(struct net_device *dev)
{
	。。。	
	outb(DM9KS_VID_L, iobase);	/* DM9000C的索引寄存器,cmd引脚为0 */
	id_val = inb(iobase + 4);			/* 读DM9000C的数据寄存器,cmd引脚为1 */
	。。。
	。。。
/* 1845294728@qq.com zdy 
 * 注释掉,发现版本号不对不用返回
 */
//if((db->chip_revision!=0x1A) || ((chip_info&(1<<5))!=0) || ((chip_info&(1<<2))!=1)) return -ENODEV;
。。。
。。。
}

2.3、在dmf_open函数中

static int dmfe_open(struct net_device *dev)
{
	。。。
	。。。
	/* 1845294728@qq.com zdy 
	 * 参数3:中断触发方式为上升沿
	 */
	if (request_irq(dev->irq,&dmfe_interrupt,IRQF_TRIGGER_RISING,dev->name,dev)) 
		return -EAGAIN;
	。。。
	。。。
}

2.4、修改入口函数

int _init init_module(void) 改为 int _init dm9000c_init(void)
int __init dm9000c_init(void)
{
	volatile unsigned int long *bwscon;		//0x48000000
	volatile unsigned int long *bankcon4;	//0x48000014
	unsigned long val;

	/* 设置网卡的基地址 
	 * 参数1:基地址 参数2:大小1024(1M)
	 */
	iobase = (int)ioremap(0x20000000, 1024);	/* 1845294728@qq.com zdy */

	/* 网卡芯片里有内存,芯片收到数据存入内存中
	 * 网卡芯片收到数据后产生中断,在中断服务程序中把数据拿出来构造一个sk_buff然后提交
	 * 网卡芯片在发送数据后(上层传来的sk_buff),芯片硬件就会把数据发送出去
	 * 中断引脚接到2440的EINT7
	 */
	irq	   = IRQ_EINT7;					/* 1845294728@qq.com zdy */

	/* 设置s3c2440的memory controller */
	bwscon 	 = ioremap(0x48000000, 4);
	bankcon4 = ioremap(0x48000014, 4);

	/* DW4[17:16]: 01-16bit
	 * WS4[18]   : 0-WAIT disable
	 * ST4[19]   : 0 = Not using UB/LB (The pins are dedicated nWBE[3:0])
	 */
	val = *bwscon;
	val &= ~(0xf<<16);
	val |= (1<<16);
	*bwscon = val;

	/ *
	 * Tacs[14:13]: 发出片选信号之前,多长时间内要先发出地址信号
	 *              DM9000C的片选信号和CMD信号可以同时发出,
	 *              所以它设为0
	 * Tcos[12:11]: 发出片选信号之后,多长时间才能发出读信号nOE
	 *              DM9000C的T1>=0ns, 
	 *              所以它设为0
	 * Tacc[10:8] : 读写信号的脉冲长度, 
	 *              DM9000C的T2>=10ns, 
	 *              所以它设为1, 表示2个hclk周期,hclk=100MHz,就是20ns
	 * Tcoh[7:6]  : 当读信号nOE变为高电平后,片选信号还要维持多长时间
	 *              DM9000C进行写操作时, nWE变为高电平之后, 数据线上的数据还要维持最少3ns
	 *              DM9000C进行读操作时, nOE变为高电平之后, 数据线上的数据在6ns之内会消失
	 *              我们取一个宽松值: 让片选信号在nOE放为高电平后,再维持10ns, 
	 *              所以设为01
	 * Tcah[5:4]  : 当片选信号变为高电平后, 地址信号还要维持多长时间
	 *              DM9000C的片选信号和CMD信号可以同时出现,同时消失
	 *              所以设为0
	 * PMC[1:0]   : 00-正常模式
	 *
	 */
	*bankcon4 = (1<<8)|(1<<6);	/* 对DM9000C设Tacc为1, 对于DM9000E,Tacc要设大一点,比如最大值7  */
	//*bankcon4 = (7<<8)|(1<<6);  /* MINI2440使用DM9000E,Tacc要设大一点 */

	iounmap(bwscon);
	iounmap(bankcon4);
	
	switch(mode) {
		case DM9KS_10MHD:
		case DM9KS_100MHD:
		case DM9KS_10MFD:
		case DM9KS_100MFD:
			media_mode = mode;
			break;
		default:
			media_mode = DM9KS_AUTO;
	}
	dmfe_dev = dmfe_probe();
	if(IS_ERR(dmfe_dev))
		return PTR_ERR(dmfe_dev);
	return 0;
}

2.5、修改出口函数

void _exit cleabup_module(void)改为Void _exit dm9000c_exit(void)
void __exit dm9000c_exit(void)
{
。。。
。。。
	iounmap((void *)iobase);
	。。。
}
//添加修饰
module_init(dm9000c_init);
module_exit(dm9000c_exit);

3、测试修改好的驱动

测试DM9000C驱动程序:
0、把原来的dm9dev9000c.c修改为dm9dev9000c_bak.c
1、把修改好的dm9dev9000c.c放到内核的drivers/net目录下
2、修改drivers/net/Makefile
注释后两行、添加第一行:
在这里插入图片描述
3、编译内核
make uImage
cp arch/arm/boot/uImage /work/nfs_root/uImage_dm9000c
使用新内核启动:
OpenJTAG> nfs 30000000 192.168.2.16:/work/nfs_root/uImage_dm9000c;bootm 30000000
4、测试驱动
4.1、使用NFS启动:
在这里插入图片描述
4.2、使用nand flash上的文件系统启动:
配置IP:ifconfig eth0 192.167.2.56
ping: ping 192.168.2.16

4、内存控制器

4.1、不同位宽设备之间的连接

CPU先连接到内存控制器,再由内存控制器连接到各个设备:
在这里插入图片描述
与各设备连接图:
其中与8bit、16bit、32bit设备连接不同:
在这里插入图片描述
例如:CPU到地址为3的地方读取1字节的数据:
在这里插入图片描述
例如:CPU到地址为4的地方读取4字节的数据:
在这里插入图片描述
确定芯片访问地址:
在这里插入图片描述

4.2、内存控制器操作

在这里插入图片描述
CPU在操作内存设备时需要设置位宽,因不同位宽的读写操作不相同,连接引脚时也不同
例1:
在这里插入图片描述
例2:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值