本文PDF文档下载
此外,CBWCB的第一个字节是接收到的命令的操作码。它会用来解码命令并作相应的处理(通过MSDCommandHandler)。有可能有命令不需要作任何数据传输。在这种情况下,Direction位被置为‘<?xml:namespace prefix = st1 />0’,MSD_State被设为MSD_DATA_OUT。如果给定的命令不需要数据传输,命令被执行并且通过sendCSW()函数来设置状态。根据命令执行的结构,来设置dDataResidue和bCSWStauts的值。
图11显示了MSDDataIn()函数的流程。此函数被用来发送在MSDCommandHandler()处理的命令获得的数据。数据方向是从设备到主机,使用MSD_BD_IN。在命令执行后,dCSWDataResidue体现了被发送到主机的命令执行的结果包含的数据的字节数。一旦出现了错误(bCSWStatus!=0x00),会将主机期望的数据大小(dCBWDataTransferLength)置为0发送出去。如果发送数据的大小大于MSD_IN_EP_SIZE(64字节,端点1 IN的缓冲区大小),则发送数量等于MSD_IN_EP_SIZE的数据;否则,利用MSD_BD_IN缓冲区发送数量等于dCSWDataResidue大小的数据。
注意,只有WRITE(10)命令的数据需要从主机读出。在MSD_WAIT态,MSD_BD_OUT指向msd_cbw结构体以便于读下一个命令块(command block)。但是当收到了一个WRITE(10)命令后,设备边为MSD_DATA_OUT态。在此状态中,设备必须从主机读取更多的数据并将数据写入SD卡。这些数据写入SD卡都是通过512字节的msd_buffer。因此,在MSD_DATA_OUT态中,MSD_BD_OUT(端点1 OUT)缓冲指向msd_buffer。为了读取完整的512数据块,在每次读操作后,MSD_BD_OUT指针在msd_buffer中的增加是根据MSD_OUT_EP_SIZE的(端点1 OUT缓冲大小)。一旦msd_buffer被填满(8次读取64字节),数据通过SECTORwrite(…)函数(在sdcard.c中定义)被写入SD卡的特定位置。如果多个数据块要写入SD卡就重复上述的过程。WRITE(10) CBWCB的LBA域给出了LBA的起始地址;WRITE(10) CBWCB 的TRANSFER LENGTH域表示LBA被连续写入的长度的。
Out端点的大小被配置为64字节。Msd_buffer的大小在USB双口RAM区中被定义为512字节。SD卡的block大小为512字节。通过多次的从MSD_BD_OUT读取64字节数据,Msd_buffer可从主机读取512字节。一旦从主机读取了512字节后(msd_buffer被填满),就通过SETCTORWrite()函数将整块的数据写入SD卡。对于TRANSFER LENGTH>1的WRITE(10)命令,多个512字节的数据块被写入根据LBA描述起始地址的连续的扇区。LBA和物理地址的转换是根据:因为每个扇区有2^9=512字节,物理地址是通过将LBA左移9位获得。同样,对于READ(10)命令,先通过SECTORread()函数从SD卡读取512字节,然后通过64字节的MSD_BD_IN缓冲发送到主机。
每次从MSD_BD_OUT或MSD_BD_IN进行读和写后,都要调用mUSBDriverService()函数来清除TRNIF位。mUSBBufferReady(MSD_BD_IN)或mUSBBufferReady(MSD_BD_OUT)宏被用来读写BD寄存器中的数据。
FW仅支持固定格式来响应INQUIRY命令。根据规范,在对应的INQUIRY命令发生时不能产生媒介访问延迟。标准INQUIRY命令的数据最少为36字节,最多可达96字节。
READ CAPACITY命令的8字节响应表示了LBA的数量和Block的字节长度。为了获得这些信息,我们通过调用CSDread(…)函数从SD卡读取Card Specific Data(CSD)。CSDread函数向SD卡发送SPI命令CSD_READ, 并且将反馈的数据存入全局变量gblCSDReg。卡容量可以通过CSD寄存器的C_SIZE,C_SIZE_MULT和READ_BL_LEN计算获得。
Memory容量=BLOCKNR*BLOCK_LEN,
BLOCKNR=(C_SIZE+1)*MULT,MULT=2^(C_SIZE_MULT+2)。
Block length(BLOCK_LEN)通过下式计算:
<!--[if !supportLists]-->● <!--[endif]-->READ_BL_LEN=WRTIE_BL_LEN
<!--[if !supportLists]-->● <!--[endif]-->BLOCK_LEN=2^READ_BL_LEN
<?xml:namespace prefix = o />
(frm 注:这篇AN的基本章节就学习到这里了。通过这个AN我们了解了单片机实现USB Mass Storage设备时用到的基本概念和软件的基本流程。后面要通过分析和移植Cypress的例程,真正实现一个类似DFU的USB Mass Storage的设备。)
大家要更加系统的学习USB Mass Storage的知识,可以参考以下的经典书目:
USB Complete: Everything You need to Develop Custom USB Peripherals By Jan Axelson
USB Mass Storage:Designing and Programming Devices and Embedded Hosts By Jan Axelson
大家要是希望得到以上的书籍(PDF)可以给我留言或短消息。
用户393536 2008-10-17 14:30
用户59663 2008-10-8 09:17
用户1632415 2008-9-4 12:24
zigbee_904218839 2007-8-13 20:14
我是一个学习电子的学生,觉得这个东西很好,但不知道对我一个新手有用没?
我的EMAIL是lbj_01@163.com
请多指教。