DM9000裸机驱动及ARP实现

本文详细介绍了DM9000网络芯片的物理结构、编程接口、初始化过程、发送与接收函数的实现,以及中断处理。同时,文章还探讨了ARP协议的功能、包格式,并给出了ARP请求包的构造与发送方法。
摘要由CSDN通过智能技术生成

一、DM9000物理结构
1、原理图
这里写图片描述
工作实质就是MAC通过MII控制PHY的过程。

2、网卡和网络模型的映射关系
这里写图片描述
MAC对应的是数据链路层,PHY对应的是物理层

3、MAC的工作原理
这里写图片描述
当网络协议栈的IP包送到网卡的时候,先要到达MAC,MAC就根据数据链路层的协议对接收到的数据进行封装,将IP包封装成以太网包,完成数据帧的构建。当然它还具备数据纠错以及传送控制等功能。

4、关于PHY
PHY是物理接口收发器。主要和实际的传输硬件打交道。他接收到来自MAC的以太网包,先加上校检码。然后按照物理层的规则进行数据编码,然后传输到物理介质,接受过程则与之相反。
这里写图片描述

5、MII即媒体独立接口。表明在MAC一定情况下,更换PHY是不会影响系统的工作的。因为他们最后都要遵循MII接口。故MII起到了MAC和PHY之间通信的桥梁作用。
这里写图片描述

二、DM9000的编程接口
1、DM9000的接口不是绝对开放的,不能像访问nand控制器那样直接按照地址去访问相关寄存器。
2、但是他提供了两个可以供CPU访问的接口,一个是index另一个是数据端口。
3、index的地址在mini2440上是0x20000300.原因是
(1)mini2440的原理图中
这里写图片描述
dm9000的片选信号AEN就是接到nLAN_CS片选。再看CPU原理图
这里写图片描述
我们可以看到nLAN_CS实质接在nGCS4上。再看datasheet
这里写图片描述
可以看到nGCS4对应的片选信号是0x20000000开头的,在0x20000000-0x28000000之间。所以index的地址开头是0x2********。即片选地址
(2)再看DM9000的datasheet
这里写图片描述
再看DM9000的TXD【2:0】的引脚接线情况
这里写图片描述
发现都是0,所以I/O base的地址是300H。即相对片选地址的位置。(相对地址,片选地址相当于基地址)。
(3)不管是index端口还是数据端口都是用SD0-SD15来传递数据。所以要区分具体某一时刻,这些数据到底是给那一个接口用。于是利用CMD引脚来区别。当CMD引脚是高电平的时候,SD上的数据是给数据接口用的,当CMD是低电平的时候,是给index接口用的。index接口是用来传递偏移量的。可以看到CMD接到CPU的ADDR2,当他为1的时候,就是为数据接口传送数据,即地址是0x20000304.当ADDR2为0的时候,SD是为index接口传送偏移量,即ADDR2为0,即地址是0x20000300.故我们找到了,片选地址,I/O base地址,以及数据接口地址。
这里写图片描述

三、DM9000初始化
1、片选信息设置
(1)数据宽度(BWSCON)
(2)时序信号填写(BANKCON4)

void cs_init()
{
    /*1.数据宽度设置*/
    BWSCON &= ~(3 << 16);
    BWSCON |= (1 <<16);
    /*2.时序信号设置*/
    BANKCON4 = (0 << 13) | (0 << 11) | (7 << 8) | (1 << 6) | (0 << 4) | (0 << 2) | (0 << 0);
}

2、中断初始化
(1)从原理图找到DM9000使用的中断源
(2)配置相应的中断引脚
(3)设置中断触发方式(高电平,EXTINT0)
(4)使能中断,设置中断屏蔽寄存器(INTMSK,EINTMSK)
(5)清除中断标志(SRCPND,INTPND,EINTPND)

void int_init()
{
    /*设置中断引脚工作模式*/
    GPFCON = GPFCON &(~(0x3<<14));
    GPFCON = GPFCON |(0x2<<14);
    /*设置中断触发方式*/
    EXTINT0 = EXTINT0 & (~(0x7<<28));
    EXTINT0 = EXTINT0 | (0x1<<28);
    /*使能中断*/
    INTMSK = INTMSK &(~(1<<4));
    EINTMASK = EINTMASK & (~(0x1<<7));
    /*清楚之前所有的中断标志*/
    EINTPEND |= (1<<7);
    SRCPND = (1<<4);
    INTPND = (1<<4);
}

3、复位设备
(1)实现往DM9000读写数据的函数
(2)设置I/O为输出模式
(3)通过对GPIO0写0为内部的PHY提供电源
(4)软件复位(自动清0),MAC内部回环模式
(5)对(4)中的寄存器全部写入0
(6)重复(4)(5)

void dm9000_write(u16 reg,u16 data)
{
    DM_ADD = reg;   
    DM_DAT = data;  
}
u8 dm9000_read(u16 reg)
{
    DM_ADD = reg;
    return DM_DAT;  
}
void dm9000_reset()
{
    /*1.设置I/O为输出模式*/
    dm9000_write(DM9000_GPCR, GPCR_GPIO0_OUT);
    /*2.通过对GPIO0写入0为内部的PHY提供电源*/
    dm9000_write(DM9000_GPR, 0);
    /*3.软件复位(自动清0),MAC内部回环模式*/
    dm9000_write(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
    /*4.对上一步的寄存器写入全0*/
    dm9000_write(DM9000_NCR, 0);
    /*5.重复(3)(4),用两次实现真正复位*/    
    dm9000_write(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
    dm9000_write(DM9000_NCR, 0);
}

4、捕获网卡
(1)读取厂家ID
(2)读取product的ID
(3)将两个ID组合与之前预定义的网卡ID进行对比

u8 dm9000_probe()
{
    u32 id_val;
    /*1.读取厂家ID*/
    id_val = dm9000_read(DM9000_VIDL);
    id_val |= dm9000_read(DM9000_VIDH) << 8;
    /*2.读取产品ID并将其和厂家ID组合*/
    id_val |= dm9000_read(DM9000_PIDL) << 16;
    id_val |= dm9000_read(DM9000_PIDH) << 24;

    if (id_val == DM9000_ID) {
        printf("dm9000 is found !\n\r");
        return 0;
    } else {
        printf("dm9000 is not found !\n\r");
        return -1;
    }   
}

5、MAC初始化
参照u-boot设置MAC


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值