返回该小组首页 回复主题
koner

koner

小组等级:     E币:298  (E币换礼)

#1楼主:CS8900A在uboot1.1.6下的adsp-bf533移植

文章发表于:2008-01-24 12:09

首先解释一下U-BOOT的硬件驱动模型。
U-BOOT中没有使用中断资源,所有的与中断相关的硬件操作均是基于轮询操作完成。
例如:网络芯片发送数据包结束,是通过循环查询网络芯片的相关寄存器位来判断的。
因此无需在U-BOOT中配置中断。

准备知识:
1、搞清楚CS8900A映射在blackfin533中的地址,例如我移植的板子上CS8900A的基地址为0x203D4000。注意CS8900A自身还有一定的偏移地址,具体请查看CS8900A的datasheet中的I/O BASE ADDRESS寄存器,我所用的芯片默认的片内偏移值为0x300。所以实际的寄存器地址应该为0x203D4000 + 0x300*2 = 0x203D4600。(为什么要乘以2:因为bf533是16位总线,bf的A1接在CS8900的a0上)
2、修改板子的主要配置文件(include/configs/bf533-xxx.h)
我选择的模板配置文件为bf533-stamp.h,其默认的网卡芯片为SMC91111。
A:修改驱动配置    
        CONFIG_DRIVER_SMC91111 -> CONFIG_DRIVER_CS8900
B:修改基地址    
        CONFIG_SMC91111_BASE   0x20300300 -> CS8900_BASE 0x203d4600
C:定义总线宽度  
        #define CS8900_BUS16
D:配置IP地址    
        找到Network settings段,将
        #if (CONFIG_DRIVER_SMC91111)
        改为
        #if (CONFIG_DRIVER_CS8900)
E:如果没有为CS8900A配置EEPROM的话
        还需要将
        #define CONFIG_ETHADDR
        的注释去掉
F:开放网络相关命令
        找到
        #define CONFIG_COMMANDS1
        将其前的
        #if (CONFIG_DRIVER_SMC91111)
        修改为
        #if (CONFIG_DRIVER_CS8900)

3、修改board.c(lib_blackfin/board.c)
A:去掉smc91111.h的头文件的包含,即注释掉
    #include "../drivers/smc91111.h"
B:初始化CS8900的MAC地址
    在board_init_r函数中
    #ifdef CONFIG_DRIVER_SMC91111
    之前增加以下程序
    #ifdef CONFIG_DRIVER_CS8900
        cs8900_get_enetaddr (gd->bd);
    #endif

4、修改驱动(drivers/cs8900.c和cs8900.h)
A:修改cs00.h
    将
    #ifdef CS8900_BUS16
          /* 16 bit aligned registers, 16 bit wide */
          #define CS8900_REG u16
          #define CS8900_OFF 0x02    
    段的#define CS8900_OFF 0x02 修改为
    #define CS8900_OFF 0x04
    原因:还是因为blackfin的地址总线有偏移,没有A0这根地址线。
B:修改get_reg_init_bus()函数
    在调试的过程中,发现加上CS8900后,系统上电运行后即异常,并且很难用仿真器进入到硬件仿真环境下。经跟踪发现cs8900.c文件中的get_reg_init_bus()函数有问题。将
    /* force 16 bit busmode */
    volatile unsigned char c;

    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
    注释掉后就不会再导致以上问题了。
C:修改 eth_send()函数
    调试过程中,发现尽管编译通过,但仍不能发送数据包。经跟踪发现eth_send函数中,if ((get_reg (PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0)的判断始终失败,导致一直在retry。
    进一步的跟踪却发现,在此if语句内再次读PP_BusSTAT寄存器时,可满足通过条件。遂更改为:
    在此if语句内,再次判断,若满足要求,则跳出此if语句,继续执行后面的程序
    具体修改的程序为:
    在此if语句体中第一行增加以下程序
    if ((get_reg (PP_BusSTAT) & PP_BusSTAT_TxRDY) != 0)
        goto resumeSend;
    注:resumeSend为此if语句后的行号。放置在for (addr = packet; length > 0; length -= 2)之前。

至此全部移植工作完成,编译后下载到板子后,可完成ping命令,并能ping到活动主机。    

更多相关的资料大家可以到我的blog中翻阅。
http://topone.blog.xdnice.com/

 

 关于初始化

1、搞清楚CS8900A映射在blackfin533中的地址,例如我移植的板子上CS8900A的基地址为0x203D4000。注意CS8900A自身还有一定的偏移地址,具体请查看CS8900A的datasheet中的I/O BASE ADDRESS寄存器,我所用的芯片默认的片内偏移值为0x300。所以实际的寄存器地址应该为0x203D4000 + 0x300*2 = 0x203D4600。(为什么要乘以2:因为bf533是16位总线,bf的A1接在CS8900的a0上)


B:修改get_reg_init_bus()函数
    在调试的过程中,发现加上CS8900后,系统上电运行后即异常,并且很难用仿真器进入到硬件仿真环境下。经跟踪发现cs8900.c文件中的get_reg_init_bus()函数有问题。将
    /* force 16 bit busmode */
    volatile unsigned char c;

    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
    注释掉后就不会再导致以上问题了。
-----------------------------------------------------------
我不知道你的CS8900的SBHE是否是接在CS8900的SA0位,
CS8900-SA0 <==> BF533-A1,而且是16位地址模式.
如果是的话那么上面的:
    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
就是初始化CS8900到16位模式的代码.具体可以看CS8900 SBHE信号定义段.
而在CS8900.h文件中对CS8900_BUS16模式下定义如下:
#define    CS8900_BUS16_0    *(volatile u8 *)(CS8900_BASE+0x00)
#define    CS8900_BUS16_1    *(volatile u8 *)(CS8900_BASE+0x01)
所以需要修改成
#define    CS8900_BUS16_0    *(volatile u16 *)(CS8900_BASE+0x00)
#define    CS8900_BUS16_1    *(volatile u16 *)(CS8900_BASE+0x01)

原因还是因为BF533没有A0位!!!

不知道分析是否正确,等板子打好了就调试!

 

 关于CS8900在U-BOOT上的修改.

首先感谢topone的贡献,我也是在看了你总结修改的U-BOOT.
现在可以在上面TFTP linux kernel了.

看了你的代码,和硬件连接 CS8900-SA0 <--> BF533-SA1

而我的板子是 CS8900-SA1 <--> BF533-SA1, CS8900-SA0接地.
CS8900-SBHE <--> BF533-SA19.

所以把你上面说明需要*2的地方全部没有*;

修改get_reg_init_bus()

原来的
#define    CS8900_BUS16_0    *(volatile u8 *)(CS8900_BASE+0x00)
#define    CS8900_BUS16_1    *(volatile u8 *)(CS8900_BASE+0x01)
    volatile unsigned char c;

    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;

其实上一段程序主要是初始化CS8900A为16位模式.
SBHE需要有01010的跳变,才会成为16位模式.
且在16位模式访问时SBHE必须为0.

所以在其一些MCU有A0的情况下, 通常是MCU的SA0和CS8900的SBHE线连在一起的.这样在16位模式下SA0永远都是为0的.

根据我的BF533和CS8900的连接修改了
CS8900_BUS16_0 和 CS8900_BUS16_1
的定义:
#define    CS8900_BUS16_0    *(volatile u16 *)(0xzzzzzzzz)
#define    CS8900_BUS16_1    *(volatile u16 *)(0xyyyyyyyy)
其中0xzzzzzzzz和0xyyyyyyyy的地址只要让BF533-SA19为0和1就可以了.
这样就在执行
    volatile unsigned int c;   //这里修改了类型为int

    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
    c = CS8900_BUS16_1;
    c = CS8900_BUS16_0;
时SA19会高低跳变了.

快速回复主题--如果想加入编辑器功能,建议使用 [高级回复]

您目前还不是小组成员,请先加入

回复贴子区

用户名:    您没有注册?

密码:    忘记了密码?

内容:

  • DesignDesign
  • HTMLHTML

浏览该小组的用户还看过...

所有小组精华文章