/*********************************************************************
?* @fn? ? ? USB2HostTransact
?*
?* @brief? ?傳輸事務(wù),輸入目的端點(diǎn)地址/PID令牌,同步標(biāo)志,以20uS為單位的NAK重試總時(shí)間(0則不重試,0xFFFF無(wú)限重試),返回0成功,超時(shí)/出錯(cuò)重試
?*? ? ? ? ? 本子程序著重于易理解,而在實(shí)際應(yīng)用中,為了提供運(yùn)行速度,應(yīng)該對(duì)本子程序代碼進(jìn)行優(yōu)化
?*
?* @param? ?endp_pid? ? - 令牌和地址, 高4位是token_pid令牌, 低4位是端點(diǎn)地址
?* @param? ?tog? ? ? ? ?- 同步標(biāo)志
?* @param? ?timeout? ? ?- 超時(shí)時(shí)間
?*
?* @return? ERR_USB_UNKNOWN 超時(shí),可能硬件異常
?*? ? ? ? ? ERR_USB_DISCON? 設(shè)備斷開
?*? ? ? ? ? ERR_USB_CONNECT 設(shè)備連接
?*? ? ? ? ? ERR_SUCCESS? ? ?傳輸完成
?*/
uint8_t USB2HostTransact(uint8_t endp_pid, uint8_t tog, uint32_t timeout)
{
? ? uint8_t TransRetry;
? ? uint8_t? s, r;
? ? uint16_t i;
? ? R8_U2H_RX_CTRL = R8_U2H_TX_CTRL = tog;
? ? TransRetry = 0;
? ? do
? ? {
? ? ? ? R8_U2H_EP_PID = endp_pid; // 指定令牌PID和目的端點(diǎn)號(hào)
? ? ? ? R8_USB2_INT_FG = RB_UIF_TRANSFER;
? ? ? ? for(i = WAIT_USB_TOUT_200US; i != 0 && (R8_USB2_INT_FG & RB_UIF_TRANSFER) == 0; i--)
? ? ? ? ? ? ;
? ? ? ? R8_U2H_EP_PID = 0x00; // 停止USB傳輸
? ? ? ? if((R8_USB2_INT_FG & RB_UIF_TRANSFER) == 0)
? ? ? ? {
? ? ? ? ? ? return (ERR_USB_UNKNOWN);
? ? ? ? }
? ? ? ? if(R8_USB2_INT_FG & RB_UIF_DETECT)
? ? ? ? { // USB設(shè)備插拔事件
? ? ? ? ? ? //? ? ? mDelayuS( 200 );? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 等待傳輸完成
? ? ? ? ? ? R8_USB2_INT_FG = RB_UIF_DETECT;
? ? ? ? ? ? s = AnalyzeRootU2Hub(); // 分析ROOT-U2HUB狀態(tài)
? ? ? ? ? ? if(s == ERR_USB_CONNECT)
? ? ? ? ? ? ? ? FoundNewU2Dev = 1;
#ifdef DISK_BASE_BUF_LEN
? ? ? ? ? ? if(CHRV3DiskStatus == DISK_DISCONNECT)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return (ERR_USB_DISCON);
? ? ? ? ? ? } // USB設(shè)備斷開事件
? ? ? ? ? ? if(CHRV3DiskStatus == DISK_CONNECT)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return (ERR_USB_CONNECT);
? ? ? ? ? ? } // USB設(shè)備連接事件
#else
? ? ? ? ? ? if(ThisUsb2Dev.DeviceStatus == ROOT_DEV_DISCONNECT)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return (ERR_USB_DISCON);
? ? ? ? ? ? } // USB設(shè)備斷開事件
? ? ? ? ? ? if(ThisUsb2Dev.DeviceStatus == ROOT_DEV_CONNECTED)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return (ERR_USB_CONNECT);
? ? ? ? ? ? } // USB設(shè)備連接事件
#endif
? ? ? ? ? ? mDelayuS(200); // 等待傳輸完成
? ? ? ? }
? ? ? ? if(R8_USB2_INT_FG & RB_UIF_TRANSFER) // 傳輸完成事件
? ? ? ? {
? ? ? ? ? ? if(R8_USB2_INT_ST & RB_UIS_TOG_OK)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return (ERR_SUCCESS);
? ? ? ? ? ? }
? ? ? ? ? ? r = R8_USB2_INT_ST & MASK_UIS_H_RES; // USB設(shè)備應(yīng)答狀態(tài)
? ? ? ? ? ? if(r == USB_PID_STALL)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return (r | ERR_USB_TRANSFER);
? ? ? ? ? ? }
? ? ? ? ? ? if(r == USB_PID_NAK)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(timeout == 0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? return (r | ERR_USB_TRANSFER);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if(timeout < 0xFFFFFFFF)
? ? ? ? ? ? ? ? ? ? timeout--;
? ? ? ? ? ? ? ? --TransRetry;
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? ? ? switch(endp_pid >> 4)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? case USB_PID_SETUP:
? ? ? ? ? ? ? ? ? ? case USB_PID_OUT:
? ? ? ? ? ? ? ? ? ? ? ? if(r)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? return (r | ERR_USB_TRANSFER);
? ? ? ? ? ? ? ? ? ? ? ? }? ? ? // 不是超時(shí)/出錯(cuò),意外應(yīng)答
? ? ? ? ? ? ? ? ? ? ? ? break; // 超時(shí)重試
? ? ? ? ? ? ? ? ? ? case USB_PID_IN:
? ? ? ? ? ? ? ? ? ? ? ? if(r == USB_PID_DATA0 || r == USB_PID_DATA1)
? ? ? ? ? ? ? ? ? ? ? ? { // 不同步則需丟棄后重試
? ? ? ? ? ? ? ? ? ? ? ? } // 不同步重試
? ? ? ? ? ? ? ? ? ? ? ? else if(r)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? return (r | ERR_USB_TRANSFER);
? ? ? ? ? ? ? ? ? ? ? ? }? ? ? // 不是超時(shí)/出錯(cuò),意外應(yīng)答
? ? ? ? ? ? ? ? ? ? ? ? break; // 超時(shí)重試
? ? ? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? ? ? return (ERR_USB_UNKNOWN); // 不可能的情況
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? }
? ? ? ? else
? ? ? ? {? ? ? ? ? ? ? ? ? ? ? ? ? // 其它中斷,不應(yīng)該發(fā)生的情況
? ? ? ? ? ? R8_USB2_INT_FG = 0xFF; /* 清中斷標(biāo)志 */
? ? ? ? }
? ? ? ? mDelayuS(15);
? ? } while(++TransRetry < 3);
? ? return (ERR_USB_TRANSFER); // 應(yīng)答超時(shí)
}