enc28j60网卡驱动移植到tcc8900上

段时间研究网卡移植到开发板,小有成果。

开发板类型: tcc-8900

网卡型号: enc28j60 (28个针脚)

操作系统:Linux 2.6.28

 

 

网卡是通过spi总线与mcu 进行数据与命令的传输,即网卡是挂载到spi总线下的设备,在驱动网卡之前要先驱动起spi总线。很佩服做linux的一些前辈,在kenerl 中已经把大部分的程序给我写好了只需要做一些改动即可。

我做的具体过程:

 

刚开始的终端输入 :make menuconfig

进行内核的一些配置

 

即选中device  driver 下的spi support 下的 spi master controller (如果全选也可以)

还有device driver 下 network  support 下 (10 M/100 M )ether 下的enc28j60 选项

另外就是要注意你的芯片的内存是128 m 还是256M 的设置

 

下面是过程

 

(1)/../linux-2.6.28/arch/arm/mach-tcc8900目录下找到board-tcc8900.c文件找到结构体tcc8900_spi0_board_info

把该结构体中的变量  .modalias = spidev ,改为 .modalias = enc28j60 ,这样网卡enc28j60就挂载到spi0 总线下了,tcc8900 下默认开启两个spi总线 spi0 和spi1,你可以任选一个,如果选spi1 就在tcc8900_spi1_board_info下改

 .modalias = enc28j60 即可。一般说来一个spi总线下可以挂载的设备数目可达127个,相同总线下每个设备的名称不一样。

 

(2)/../linux-2.6.28/drivers/net 目录下找到enc28j60.c这个文件,基本上不要修改什么东东,添加一些初始化设置。

该文件中最主要的函数就是enc28j60_probe,这个是网卡的探测函数,在内核中会有个设备列表,当注册进去的硬件名称与列表中名称相同的话,就会执行probe函数。步骤1中的修改就是为了,可以在设备列表里添加硬件的名称。所以你会在board-tcc8900.c中看到spi_register_board_info函数,这个应该相当于设备资源注册吧,在enc28j60.c中看到spi_register_driver函数。这个就是设备驱动注册,两个注册函数的设备名称相同,就可以执行探测probe函数。

 

 

(3)还是在enc28j60.c文件下添加初始化设置。这个可能要根据不同的硬件电路图配置。我的情况是用到了tcc8900芯片的GPIOF[11 :17] 分别接enc28j60 芯片的针脚如下;

GPIOF[11]   : wol  (中断唤醒)貌似没什么用

        [12]   :   rst    (复位脚)

        [13]   :   int    (中断脚)

        [14]   : si     (spi 接口数据输入引脚)

         [15]   :  so   (spi接口数据输出引脚)

        [16]   :   sck(spi 接口时钟输入引脚)

         [17]  :    cs(spi 接口的片选引脚)

然后就是对这些引脚进行初始化设置(参照tcc8900 的datasheet)

volatile PPIC pic_regs = (volatile PPIC)tcc_p2v(HwPIC_BASE);

 volatile PGPIO gpio_regs = (volatile PGPIO)tcc_p2v(HwGPIO_BASE);

volatile PGPSBPORTCFG gpsb_pcf_regs = (volatile PGPSBPORTCFG)tcc_p2v(HwGPSBPORTCFG_BASE);

 

 

BITCSET(gpsb_pcf_regs->PCFG0, Hw8-Hw0, Hw3); 设置选择spi0 的通道 为8

注:如果你用的是spi1 设备,就要改为

BITCSET(gpsb_pcf_regs->PCFG0, Hw16-Hw8, Hw3);

 

 

/gpiof [14 :16]/  si so sck 等针脚设置为功能2 。

BITCSET(gpio_regs->GPFFN1, Hw32-Hw24, Hw29|Hw25);

BITCSET(gpio_regs->GPFFN2, Hw4-1, Hw1);  

 

/gpiof 17/  片选这个脚设置

BITCSET(gpio_regs->GPFFN2 , Hw8 - Hw4 ,0);作为功能0 即为i/o口

BITSET(gpio_regs->GPFEN , Hw17);作为输出模式

BITCLR(gpio_regs->GPFDAT,Hw17); gpiof[17] 输出为低电平

 

 

以上的初始化可以放在专门一个函数中,就暂且叫enc28j60_hard_init吧  区别于enc28j60.c中原来的函数 enc28j60_hw_init

 

下面是写另一个函数enc28j60_hard_reset

/gpio12 / 复位这个脚

BITCSET(gpio_regs->GPFFN1 , Hw20 - Hw16 ,0);作为功能0 ,i/o口

BITSET(gpio_regs->GPFEN , Hw12);作为输出模式

BITCLR(gpio_regs->GPFDAT,Hw12); gpiof[12] 输出低电平

udelay(2000) ;要延迟至少1ms

 

BITSET(gpio_regs->GPFDAT,Hw12); 输出高电平

udelay(200000);这个也要延迟很长时间

 

到现在为止初试化的一些工作就完成的差不多了,把两个函数放在probe函数中靠前的位置。要记住顺序,先复位enc28j60_hard_reset,在enc28j60_hard_init。

然后就可以编译啦,这样的结果还是会错的。错在什么地方呢。

在移植过程中出现的一些错误,和解决方法会在另一篇文章《enc28j60网卡移植的总结续》给出。

 

不是在卖关子,是太饿啦,先去吃饭。回来再写

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

/ gpiof 13  中断引脚/这个配置可能要多一些

BITCSET(gpio_regs->GPFFN1 , Hw24 - Hw20 ,0);作为功能0 ,i/o口

BITCLR(gpio->GPFEN ,Hw13);作为输入模式

BITCSET(pic_regs-> EINTSEL2 , Hw22 - Hw16 ,Hw21 | Hw28 | Hw16);我们用了外部中断号INT_EI10

BITSET(pic->POL , Hw13);设置为低电平有效

BITCLR(pic->MODE0 ,Hw13),设置为边缘触发

BITCLR(pic->MODEA0 ,Hw13);设置为单边缘触发

BITSET(pic->IEN0 ,Hw13);是外部中断10有效

 

 

 /gpiof 11 /   中断唤醒引脚

 

BITCSET(gpio_regs->GPFFN1 , Hw16 - Hw12 ,0);作为功能0 ,i/o口

 

 

 

BITCLR(gpio_regs->GPFEN , Hw11);作为输入模式

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值