UBOOT DM9000驱动完全注释.docx

上传人:b****5 文档编号:12088075 上传时间:2023-04-17 格式:DOCX 页数:19 大小:20.93KB
下载 相关 举报
UBOOT DM9000驱动完全注释.docx_第1页
第1页 / 共19页
UBOOT DM9000驱动完全注释.docx_第2页
第2页 / 共19页
UBOOT DM9000驱动完全注释.docx_第3页
第3页 / 共19页
UBOOT DM9000驱动完全注释.docx_第4页
第4页 / 共19页
UBOOT DM9000驱动完全注释.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

UBOOT DM9000驱动完全注释.docx

《UBOOT DM9000驱动完全注释.docx》由会员分享,可在线阅读,更多相关《UBOOT DM9000驱动完全注释.docx(19页珍藏版)》请在冰豆网上搜索。

UBOOT DM9000驱动完全注释.docx

UBOOTDM9000驱动完全注释

U-BOOTDM9000驱动完全注释

U-BOOTDM9000驱动完全注释

#include"../include/dm9000x.h"

/*Board/System/Debuginformation/definition----------------*/

#defineDM9801_NOISE_FLOOR   0x08

#defineDM9802_NOISE_FLOOR   0x05

/*#defineCONFIG_DM9000_DEBUG*/

#defineDM9000_DBG(fmt,args...)

//*================================================================

//DM9000芯片的PHY层模式

//*================================================================

enumDM9000_PHY_mode{DM9000_10MHD=0,DM9000_100MHD=

      1,DM9000_10MFD=4,DM9000_100MFD=5,DM9000_AUTO=

      8,DM9000_1M_HPNA=0x10

};

//*================================================================

//DM9000芯片的网卡类型。

NIC=networkinterfacecard

//*================================================================

enumDM9000_NIC_TYPE{FASTETHER_NIC=0,HOMERUN_NIC=1,LONGRUN_NIC=2

};

//*================================================================

//DM9000芯片的数据结构

//*================================================================

typedefstructboard_info{

   u32runt_length_counter;      //接收报文长度小于64byte的计数器

   u32long_length_counter;      //接收报文长度大于1514byte的计数器

   u32reset_counter;            //复位计数

   u32reset_tx_timeout;         //由发送超时引起的复位

   u32reset_rx_status;         //由接收状态引起的复位

   u16tx_pkt_cnt;                 //接收包计数

   u16queue_start_addr;          //序列起始地址

   u16dbug_cnt;

   u8phy_addr;                  //MAC地址

   u8device_wait_reset;         //设备状态

   u8nic_type;               //网卡类型

   unsignedcharsrom[128];

}board_info_t;

board_info_tdmfe_info;

//*================================================================

//DM9000芯片的设置参数

//*================================================================

staticintmedia_mode=DM9000_AUTO;

staticu8nfloor=0;

//*================================================================

//DM9000芯片的函数声明

//*================================================================

inteth_init(bd_t*bd);                  //DM9000网卡初始化

inteth_send(volatilevoid*,int);            //将来自上层的数据包发送到媒介上

inteth_rx(void);                        //接收数据包并且发送到上层去

voideth_halt(void);                     //关闭网卡

staticintdm9000_probe(void);               //探测网卡芯片

staticu16phy_read(int);                   //从物理层上读取一个字(16位)

staticvoidphy_write(int,u16);               //往物理层上写一个字(16位)

staticu16read_srom_word(int);               //读取SROM中的一个字

staticu8DM9000_ior(int);                  //从IO口上读取一个字节

staticvoidDM9000_iow(intreg,u8value);      //写一个字节到IO口上

//*================================================================

//DM9000芯片的的寄存器操作宏,分为byte,word,Dword三种

//*================================================================

#defineDM9000_outb(d,r)(*(volatileu8*)r=d)

#defineDM9000_outw(d,r)(*(volatileu16*)r=d)

#defineDM9000_outl(d,r)(*(volatileu32*)r=d)

#defineDM9000_inb(r)(*(volatileu8*)r)

#defineDM9000_inw(r)(*(volatileu16*)r)

#defineDM9000_inl(r)(*(volatileu32*)r)

//*================================================================

//函数名称:

dm9000_probe

//函数功能:

寻找DM9000芯片,分配内存空间,注册。

//           复位结束后到网卡的vendorID寄存器和productID寄存器读取id,

//           检测此网卡是否是dm9000。

//出口参数:

//入口参数:

//*================================================================

int

dm9000_probe(void)

{

   u32id_val; //32bit变量

   id_val=DM9000_ior(DM9000_VIDL);//首先读VIDLvendorIDlowbyte

   id_val|=DM9000_ior(DM9000_VIDH)<<8;//然后读VIDHvendorIDhighbyte

   id_val|=DM9000_ior(DM9000_PIDL)<<16;//再读PIDLProductIDlowbyte

   id_val|=DM9000_ior(DM9000_PIDH)<<24;//最后读PIDHProductIDhighbyte

   if(id_val==DM9000_ID){

      printf("dm9000i/o:

0x%x,id:

0x%x\n",CONFIG_DM9000_BASE,

            id_val);

      return0;

   }else{

      printf("dm9000notfoundat0x%08xid:

0x%08x\n",

            CONFIG_DM9000_BASE,id_val);

      return-1;

   }

}

//*================================================================

//函数名称:

set_PHY_mode

//函数功能:

设置PHY芯片的操作模式。

若设置的是自动选择,则直接配置,若不是则可以选择

//           设置四种模式:

10Mbps(半双工,全双工),100Mbps(半双工,全双工)。

//出口参数:

//入口参数:

//*================================================================

staticvoid

set_PHY_mode(void)

{

   u16phy_reg4=0x01e1,phy_reg0=0x1000;

   if(!

(media_mode&DM9000_AUTO)){

      switch(media_mode){

      caseDM9000_10MHD:

              //10M半双工

         phy_reg4=0x21;      //设置双工、半双工

         phy_reg0=0x0000; //设置速度模式

         break;

      caseDM9000_10MFD:

            //10M全双工

         phy_reg4=0x41;

         phy_reg0=0x1100;

         break;

      caseDM9000_100MHD:

           //100M半双工

         phy_reg4=0x81;

         phy_reg0=0x2000;

         break;

      caseDM9000_100MFD:

            //100M全双工

         phy_reg4=0x101;

         phy_reg0=0x3100;

         break;

      }

      phy_write(4,phy_reg4);         //设置为自动选择,通过写寄存器4设置该网卡支持IEEE802.3CSMA/CD和其他一些工作模式

      phy_write(0,phy_reg0);         //phy寄存器0是设置速度模式,采取的是自动协商

   }

   DM9000_iow(DM9000_GPCR,0x01);      //定义GPIO的输入输出方向。

1为输出,0为输入。

GPIO0默认为输出做POWER_DOWN功能。

                              //其它默认为输入。

因此默认值为0001。

   DM9000_iow(DM9000_GPR,0x00);      //使能DM9000,写DM9000的GPIO寄存器,若希望启用PHY,则驱动程序需要通过写“0”将PWER_DOWN信号清零

}

//*================================================================

//函数名称:

program_dm9801

//函数功能:

设置DM9801的HOMERUN模式

//出口参数:

//入口参数:

HPNA_rev

//*================================================================

staticvoid

program_dm9801(u16HPNA_rev)

{

   __u16reg16,reg17,reg24,reg25;

   if(!

nfloor)

      nfloor=DM9801_NOISE_FLOOR;

   reg16=phy_read(16);

   reg17=phy_read(17);

   reg24=phy_read(24);

   reg25=phy_read(25);

   switch(HPNA_rev){

   case0xb900:

      /*DM9801E3*/

      reg16|=0x1000;

      reg25=((reg24+nfloor)&0x00ff)|0xf000;

      break;

   case0xb901:

      /*DM9801E4*/

      reg25=((reg24+nfloor)&0x00ff)|0xc200;

      reg17=(reg17&0xfff0)+nfloor+3;

      break;

   case0xb902:

      /*DM9801E5*/

   case0xb903:

      /*DM9801E6*/

   default:

      reg16|=0x1000;

      reg25=((reg24+nfloor-3)&0x00ff)|0xc200;

      reg17=(reg17&0xfff0)+nfloor;

   }

   phy_write(16,reg16);

   phy_write(17,reg17);

   phy_write(25,reg25);

}

//*================================================================

//函数名称:

program_dm9802

//函数功能:

设置DM9802的LONGRUN模式

//出口参数:

//入口参数:

//*================================================================

staticvoid

program_dm9802(void)

{

   __u16reg25;

   if(!

nfloor)

      nfloor=DM9802_NOISE_FLOOR;

   reg25=phy_read(25);

   reg25=(reg25&0xff00)+nfloor;

   phy_write(25,reg25);

}

//*================================================================

//函数名称:

identify_nic

//函数功能:

识别网卡芯片.接着是检测网卡类型,是FASTETHER,HOMERUN或LONGRUN类型。

//            这里主要是通过phy_read(3)和phy_read(31)读取PHY寄存器的值并进行比较判断。

//            读PHY寄存器的方法将在后面介绍。

//出口参数:

//入口参数:

//*================================================================

staticvoid

identify_nic(void)

{

   structboard_info*db=&dmfe_info;   /*Pointaboardinformationstructure*/

   u16phy_reg3;

   DM9000_iow(DM9000_NCR,NCR_EXT_PHY);

   phy_reg3=phy_read(3);

   switch(phy_reg3&0xfff0){

   case0xb900:

      if(phy_read(31)==0x4404){

         db->nic_type=HOMERUN_NIC;

         program_dm9801(phy_reg3);

         DM9000_DBG("foundhomerunNIC\n");

      }else{

         db->nic_type=LONGRUN_NIC;

         DM9000_DBG("foundlongrunNIC\n");

         program_dm9802();

      }

      break;

   default:

      db->nic_type=FASTETHER_NIC;

      break;

   }

   DM9000_iow(DM9000_NCR,0);

}

//*================================================================

//函数名称:

dm9000_reset

//函数功能:

DM9000的复位。

//出口参数:

//入口参数:

//*================================================================

staticvoid

dm9000_reset(void)

{

   DM9000_iow(DM9000_NCR,NCR_RST);

   OSTimeDly

(1);      /*delay50ms*/

}

//*================================================================

//函数名称:

eth_init

//函数功能:

网卡的初始化

//出口参数:

//入口参数:

bd

//*================================================================

int

eth_init(bd_t*bd)

{

   inti,oft,lnk;

   /*RESETdevice*/

   dm9000_reset();

   dm9000_probe();

   /*NICType:

FASTETHER,HOMERUN,LONGRUN*/

   identify_nic();

   /*GPIO0onpre-activatePHY*/

   DM9000_iow(DM9000_GPR,0x00);   /*REG_1Fbit0activatephyxcer*/

   /*SetPHY*/

   set_PHY_mode();

   /*Programoperatingregister*/

   DM9000_iow(DM9000_NCR,0x0);   /*onlyinternphysupportedbynow*/

   DM9000_iow(DM9000_TCR,0);   /*TXPollingclear*/

   DM9000_iow(DM9000_BPTR,0x3f);   /*Less3Kb,200us*/

   DM9000_iow(DM9000_FCTR,FCTR_HWOT(3)|FCTR_LWOT(8));   /*FlowControl:

High/LowWater*/

   DM9000_iow(DM9000_FCR,0x0);   /*SHFIXME:

Thislooksstrange!

FlowControl*/

   DM9000_iow(DM9000_SMCR,0);   /*SpecialMode*/

   DM9000_iow(DM9000_NSR,NSR_WAKEST|NSR_TX2END|NSR_TX1END);   /*clearTXstatus*/

   DM9000_iow(DM9000_ISR,0x0f);   /*Clearinterruptstatus*/

   /*下面这段代码是设置dm9000的MAC地址,

   选是通过read_srom_word(i)到srom中读取MAC地址值,

   再分别写入板子信息数据结构bd和dm9000的MAC寄存器中,

   再将MulticastAddressRegister寄存器全部置1。

*/

   for(i=0;i<6;i++)

      ((u16*)bd->bi_enetaddr)[i]=read_srom_word(i);

   printf("MAC:

%02x:

%02x:

%02x:

%02x:

%02x:

%02x\n",bd->bi_enetaddr[0],

         bd->bi_enetaddr[1],bd->bi_enetaddr[2],bd->bi_enetadd

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1