#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会高低跳变了.