对于U盘来说,进行U盘的数据传输时需要通过批量传输端口收发数据,所使用的协议为Mass Storage协议,参见《Universal Serial Bus Mass Storage Class Bulk-Only Transport》 。该协议是批量端口数据传输的底层协议,为了完成U盘扇区读写,还需要在该协议上面实现UFI协议,参见《Universal Serial Bus Mass Storage Class UFI Command Specification》 。
在本函数内只处理Mass Storage协议,不理会UFI协议:
/**
* 从批量端点读取数据
* @param *pCbw CBW数据区指针
* @param *pData 存放读取结果的数据区指针
* @param *pCsw CSW数据区指针
*/
short bulkRead(unsigned char *pCbw, unsigned char *pData, unsigned char *pCsw)
{
BYTE toggle;
//得到批量出端点的下一次发送数据区编号
toggle = usbGetEdToggle(bulkEd[0]);
//初始化批量出端点ED
AT91F_CreateEd(
(unsigned int) &bulkEd[0], // ED Address
64 , // Max packet
0,
// TD format
0,
// Skip
0,
// Speed
ED_OUT, // Direction
usbDevInfo.bulkOutPort, // Endpoint
usbDevInfo.addr, // Func Address
(unsigned int) &genTd[1], // TDQTailPointer
(unsigned int) &genTd[0], // TDQHeadPointer
toggle, // ToggleCarry
(unsigned int) &bulkEd[1]); // NextED
//设置批量出端点的TD,用于发送CBW命令
AT91F_CreateGenTd(
(unsigned int) &genTd[0], // TD Address
0,
// Data Toggle
TD_DELAY_INT, // DelayInterrupt
TD_OUT, // Direction
1,
// Buffer Rounding
(unsigned int) pCbw, // Current Buffer Pointer
(unsigned int) &genTd[1], // Next TD
31);
// Buffer Length
AT91F_CreateGenTd(
(unsigned int) &genTd[1], // TD Address
0,
// Data Toggle
TD_DELAY_INT, // DelayInterrupt
TD_OUT, // Direction
1,
// Buffer Rounding
0x0,
// Current Buffer Pointer
(unsigned int) 0,
// Next TD
0x0);
// Buffer Length
//得到批量入端点的下一次发送数据区编号
toggle = usbGetEdToggle(bulkEd[1]);
//初始化批量入端点ED
AT91F_CreateEd(
(unsigned int) &bulkEd[1], // ED Address
64 , // Max packet
0,
// TD format
0,
// Skip
0,
// Speed
ED_IN, // Direction
usbDevInfo.bulkInPort, // Endpoint
usbDevInfo.addr, // Func Address
(unsigned int) &genTd[4], // TDQTailPointer
(unsigned int) &genTd[2], // TDQHeadPointer
toggle, // ToggleCarry
(unsigned int) 0);
// NextED
//设置批量入端点的TD
//用于接收数据的TD
AT91F_CreateGenTd(
(unsigned int) &genTd[2], // TD Address
0,
// Data Toggle
TD_DELAY_INT, // DelayInterrupt
TD_IN, // Direction
1,
// Buffer Rounding
(unsigned int) pData, // Current Buffer Pointer
(unsigned int) &genTd[3], // Next TD
512);
// Buffer Length
//用于接收CSW的TD
AT91F_CreateGenTd(
(unsigned int) &genTd[3], // TD Address
0, // Data Toggle
TD_DELAY_INT, // DelayInterrupt
TD_IN,
// Direction
1,
// Buffer Rounding
(unsigned int) pCsw, // Current Buffer Pointer
(unsigned int) &genTd[4], // Next TD
64);
// Buffer Length
AT91F_CreateGenTd(
(unsigned int) &genTd[4], // TD Address
0,
// Data Toggle
TD_DELAY_INT, // DelayInterrupt
TD_IN, //
Direction
1,
// Buffer Rounding
0x0,
// Current Buffer Pointer
(unsigned int) 0,
// Next TD
0x0);
// Buffer Length
//调用底层接口把数据发送出去
ohciBulkXfer(&bulkEd[0]);
usbRunCmd(USB_CMD_TYPE_BULK_READ, 3);
return 0;
}
|