/*********************************************************************

?* @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í)

}