打印

转:EZ-USB FX2(68013)固件研究(3)——FW.C文件【1】

[复制链接]
3049|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
相见欢喜|  楼主 | 2011-9-21 00:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
FW.C文件,是比较难看懂的了,这个要逐字逐句研读,我当初整整看了一个星期,边理解,边一行一行的注释,可以说,看懂了,USB协议部分也就差不多了。
    从main()函数开始看:
DWORD i;
WORD   offset;
DWORD DevDescrLen;
WORD   IntDescrAddr;
WORD   ExtDescrAddr;

Sleep = FALSE;         //初始化用户变量 休眠使能--禁止
Rwuen = FALSE;         //远程唤醒--禁止
Selfpwr = FALSE;       //
GotSUD = FALSE;        //SetUp令牌包到来标志

   定义了一些变量,具体用途在后面;第二段同时对变量进行初始化,从名字可以看出其用途。
TD_Init();
   紧接着调用TD_Init()函数,是一些我们自己的初始化配置。
沙发
相见欢喜|  楼主 | 2011-9-21 00:14 | 只看该作者
//定向USB描述符
pDeviceDscr = (WORD)&DeviceDscr;     
pDeviceQualDscr = (WORD)&DeviceQualDscr;
pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr;
pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr;
pStringDscr = (WORD)&StringDscr;
    这段代码用来获取USB的各个描述符在68013内存中的地址,准确说是在RAM中的地址,在dscrpt.a51文件中有定义,所有的描述符组成了整个的描述符表,后面会用到。
if ((WORD)&DeviceDscr & 0xC000)
    这段代码及以后的,在固件中解释是:
    Is the descriptor table in external RAM (> 16Kbytes)? If yes,
    then relocate.
    Note that this code only checks if the descriptors START in
    external RAM. It will not work if the descriptor table spans
    internal and external RAM.

使用特权

评论回复
板凳
相见欢喜|  楼主 | 2011-9-21 00:15 | 只看该作者
意思是说,这段代码用来判断描述符表首址,也就是前面的DeviceDscr、DeviceQualDscr等是否位于68013的外部RAM区,如果是,则移除,然后将描述符表移到内部RAM区,为什么要移到内部RAM区,因为当描述符表位于外部RAM时,USB是不工作的。那么如何判断描述符地址是否超出内部RAM的地址呢?首先,&DeviceDscr取得整个描述符表的首地址(它也是DeviceDscr设备描述的首址),然后和0XC000相与,为什么要和0XC000相与?这就牵涉到68013 FX2LP(注意是LP)的内部结构图:

       上图针对的是128pin的FX2LP,如果是56或100pin的,那么没有外部RAM,只有内部RAM。可以看到,FX2LP内部RAM从0000-FFFF,其他为外部RAM。而内部RAM中,只有从0000-3FFF和从E000-FFFF的区域可用,其他为系统保留。从0000-3FFF这16K bytes的内部RAM空间,叫做主RAM,对56,100,128pin来说,都可以同时作为程序或数据存储器(对128pin来说,EA=0)。再看&DeviceDscr & 0xC000的结果,要为“真”的话,显然,必须&DeviceDscr>=0X4000,也就是说判断的是描述表首址&DeviceDsc是否大于3FFF,刚好是主RAM区的大小,这就是为什么要用&DeviceDscr 0xC000相与就来判断实现了描述符表首地址的原因了(外部 or 内部 ram?)。

使用特权

评论回复
地板
相见欢喜|  楼主 | 2011-9-21 00:15 | 只看该作者
// 重定向描述符
IntDescrAddr = INTERNAL_DSCR_ADDR;
ExtDescrAddr = (WORD)&DeviceDscr;
DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2;
for (i = 0; i < DevDescrLen; i++)
*((BYTE xdata *)IntDescrAddr+i) = *((BYTE xdata *)ExtDescrAddr+i);

   判断发现描述符表首址位于外部RAM的后,紧接着就将外部RAM的描述符移到内部RAM。这里就用到了前面定义的变量,IntDescrAddr保存内部RAM首址0X80,ExtDescrAddr保存我们获得的当前描述符表外部RAM的首址 ,DevDescrLen是整个描述表的长度,从DeviceDscr段到UserDscr段,在dscrptr中有定义。然后for循环,将从ExtDescrAddr地址开始的外部RAM中的数据逐个copy到从IntDescrAddr地址开始的内部RAM区。
// 更新描述符指针
pDeviceDscr = IntDescrAddr;
offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;
pDeviceQualDscr -= offset;
pConfigDscr -= offset;
pOtherConfigDscr -= offset;
pHighSpeedConfigDscr -= offset;
pFullSpeedConfigDscr -= offset;
pStringDscr -= offset;

   完毕后更新描述符指针,指向内部RAM区,通过原指针减去一个偏移量得到。

使用特权

评论回复
5
相见欢喜|  楼主 | 2011-9-21 00:15 | 只看该作者
然后是USB的一些初始状态设置:

EZUSB_IRQ_ENABLE();                                                                                // EZUSB中断使能
EZUSB_ENABLE_RSMIRQ();                                                                      // 使能远程唤醒中断
INTSETUP |= (bmAV2EN | bmAV4EN);                                                    //使能INT2,4自动向量跳转
USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT;     // 使能所选择中断
EA = 1;                                                                                                   // 开8051中断

   EZUSB_IRQ_ENABLE();预定义是EZUSB=1,查TRM得知,ezusb是EIE寄存器的第0位,EIE.0=1,使能USB中断;EZUSB_ENABLE_RSMIRQ();EICON |= 0x20,EICON.5=1,使能远程唤醒中断;INTSETUP |= (bmAV2EN | bmAV4EN);使能INT2,4自动向量跳转; USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT;使能所选择中断,相关的中断意义,我也一知半解,后面慢慢学习补充;   EA = 1;    开8051中断。

               写到这里,未完待续。。。

使用特权

评论回复
6
Go_PSoC| | 2011-9-21 22:58 | 只看该作者
帮你顶

使用特权

评论回复
7
langgq| | 2011-9-22 19:13 | 只看该作者
好**

使用特权

评论回复
8
liangziusb| | 2011-9-26 14:09 | 只看该作者
把USB2.0研究通了,再研究USB3.0看来还是可以的呀!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

517

帖子

1

粉丝