pikapython/bsp/ch582/StdPeriphDriver/CH58x_usb2hostBase.c
2022-03-26 20:51:40 +08:00

651 lines
21 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************** (C) COPYRIGHT *******************************
* File Name : CH58x_usbhost.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* Description
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "CH58x_common.h"
#if DISK_LIB_ENABLE
#include "CHRV3UFI.H"
#endif
uint8_t Usb2DevEndp0Size; // USB2<42><EFBFBD>Ķ˵<C4B6>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD>
uint8_t FoundNewU2Dev;
_RootHubDev ThisUsb2Dev; //ROOT<4F><54>
_DevOnHubPort DevOnU2HubPort[HUB_MAX_PORTS]; // <20>ٶ<EFBFBD>:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD>ⲿHUB,ÿ<><C3BF><EFBFBD>ⲿHUB<55><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>HUB_MAX_PORTS<54><53><EFBFBD>˿<EFBFBD>(<28><><EFBFBD>˲<EFBFBD><CBB2><EFBFBD>)
uint8_t *pU2HOST_RX_RAM_Addr;
uint8_t *pU2HOST_TX_RAM_Addr;
/*<2A><>ȡ<EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
__attribute__((aligned(4))) const uint8_t SetupGetU2DevDescr[] = {USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00,
USB_DESCR_TYP_DEVICE, 0x00, 0x00, sizeof(USB_DEV_DESCR), 0x00};
/*<2A><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
__attribute__((aligned(4))) const uint8_t SetupGetU2CfgDescr[] = {USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00,
USB_DESCR_TYP_CONFIG, 0x00, 0x00, 0x04, 0x00};
/*<2A><><EFBFBD><EFBFBD>USB<53><42>ַ*/
__attribute__((aligned(4))) const uint8_t SetupSetUsb2Addr[] = {USB_REQ_TYP_OUT, USB_SET_ADDRESS, USB_DEVICE_ADDR,
0x00, 0x00, 0x00, 0x00, 0x00};
/*<2A><><EFBFBD><EFBFBD>USB<53><42><EFBFBD><EFBFBD>*/
__attribute__((aligned(4))) const uint8_t SetupSetUsb2Config[] = {USB_REQ_TYP_OUT, USB_SET_CONFIGURATION,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/*<2A><><EFBFBD><EFBFBD>USB<53>ӿ<EFBFBD><D3BF><EFBFBD><EFBFBD><EFBFBD>*/
__attribute__((aligned(4))) const uint8_t SetupSetUsb2Interface[] = {USB_REQ_RECIP_INTERF, USB_SET_INTERFACE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/*<2A><><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD>STALL*/
__attribute__((aligned(4))) const uint8_t SetupClrU2EndpStall[] = {USB_REQ_TYP_OUT | USB_REQ_RECIP_ENDP, USB_CLEAR_FEATURE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/*********************************************************************
* @fn DisableRootU2HubPort
*
* @brief <20>ر<EFBFBD>ROOT-HUB<55>˿<EFBFBD><><CAB5><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>Ѿ<EFBFBD><D1BE>Զ<EFBFBD><D4B6>ر<EFBFBD>,<2C>˴<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩ<D2BB>ṹ״̬
*
* @param none
*
* @return none
*/
void DisableRootU2HubPort(void)
{
#ifdef FOR_ROOT_UDISK_ONLY
CHRV3DiskStatus = DISK_DISCONNECT;
#endif
#ifndef DISK_BASE_BUF_LEN
ThisUsb2Dev.DeviceStatus = ROOT_DEV_DISCONNECT;
ThisUsb2Dev.DeviceAddress = 0x00;
#endif
}
/*********************************************************************
* @fn AnalyzeRootU2Hub
*
* @brief <20><><EFBFBD><EFBFBD>ROOT-HUB״̬,<2C><><EFBFBD><EFBFBD>ROOT-HUB<55>˿ڵ<CBBF><DAB5><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>γ<EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>DisableRootHubPort()<29><><EFBFBD><EFBFBD>,<2C><><EFBFBD>˿ڹر<DAB9>,<2C><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>,<2C><><EFBFBD><EFBFBD>Ӧ<EFBFBD>˿ڵ<CBBF>״̬λ
*
* @param none
*
* @return <20><><EFBFBD><EFBFBD>ERR_SUCCESSΪû<CEAA><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>ERR_USB_CONNECTΪ<54><CEAA><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>ERR_USB_DISCONΪ<4E><CEAA><EFBFBD><EFBFBD>Ͽ<EFBFBD>
*/
uint8_t AnalyzeRootU2Hub(void)
{
uint8_t s;
s = ERR_SUCCESS;
if(R8_USB2_MIS_ST & RB_UMS_DEV_ATTACH)
{ // <20><EFBFBD><E8B1B8><EFBFBD><EFBFBD>
#ifdef DISK_BASE_BUF_LEN
if(CHRV3DiskStatus == DISK_DISCONNECT
#else
if(ThisUsb2Dev.DeviceStatus == ROOT_DEV_DISCONNECT // <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD>
#endif
|| (R8_U2HOST_CTRL & RB_UH_PORT_EN) == 0x00)
{ // <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><><CBB5><EFBFBD>Ǹղ<C7B8><D5B2><EFBFBD>
DisableRootU2HubPort(); // <20>رն˿<D5B6>
#ifdef DISK_BASE_BUF_LEN
CHRV3DiskStatus = DISK_CONNECT;
#else
ThisUsb2Dev.DeviceSpeed = R8_USB2_MIS_ST & RB_UMS_DM_LEVEL ? 0 : 1;
ThisUsb2Dev.DeviceStatus = ROOT_DEV_CONNECTED; //<2F><><EFBFBD><EFBFBD><EFBFBD>ӱ<EFBFBD>־
#endif
PRINT("USB2 dev in\n");
s = ERR_USB_CONNECT;
}
}
#ifdef DISK_BASE_BUF_LEN
else if(CHRV3DiskStatus >= DISK_CONNECT)
{
#else
else if(ThisUsb2Dev.DeviceStatus >= ROOT_DEV_CONNECTED)
{ //<2F><><EFBFBD><EFBFBD><EFBFBD>γ<EFBFBD>
#endif
DisableRootU2HubPort(); // <20>رն˿<D5B6>
PRINT("USB2 dev out\n");
if(s == ERR_SUCCESS)
s = ERR_USB_DISCON;
}
// R8_USB_INT_FG = RB_UIF_DETECT; // <20><><EFBFBD>жϱ<D0B6>־
return (s);
}
/*********************************************************************
* @fn SetHostUsb2Addr
*
* @brief <20><><EFBFBD><EFBFBD>USB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<53><EFBFBD><E8B1B8>ַ
*
* @param addr - USB<53><EFBFBD><E8B1B8>ַ
*
* @return none
*/
void SetHostUsb2Addr(uint8_t addr)
{
R8_USB2_DEV_AD = (R8_USB2_DEV_AD & RB_UDA_GP_BIT) | (addr & MASK_USB_ADDR);
}
/*********************************************************************
* @fn SetUsb2Speed
*
* @brief <20><><EFBFBD>õ<EFBFBD>ǰUSB<53>ٶ<EFBFBD>
*
* @param FullSpeed - USB<53>ٶ<EFBFBD>
*
* @return none
*/
void SetUsb2Speed(uint8_t FullSpeed)
{
#ifndef DISK_BASE_BUF_LEN
if(FullSpeed) // ȫ<><C8AB>
{
R8_USB2_CTRL &= ~RB_UC_LOW_SPEED; // ȫ<><C8AB>
R8_U2H_SETUP &= ~RB_UH_PRE_PID_EN; // <20><>ֹPRE PID
}
else
{
R8_USB2_CTRL |= RB_UC_LOW_SPEED; // <20><><EFBFBD><EFBFBD>
}
#endif
(void)FullSpeed;
}
/*********************************************************************
* @fn ResetRootU2HubPort
*
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><E8B1B8>,<2C><>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>,Ϊö<CEAA><C3B6><EFBFBD>豸׼<E8B1B8><D7BC>,<2C><><EFBFBD><EFBFBD>ΪĬ<CEAA><C4AC>Ϊȫ<CEAA><C8AB>
*
* @param none
*
* @return none
*/
void ResetRootU2HubPort(void)
{
Usb2DevEndp0Size = DEFAULT_ENDP0_SIZE; //USB2<42><EFBFBD>Ķ˵<C4B6>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD>
SetHostUsb2Addr(0x00);
R8_U2HOST_CTRL &= ~RB_UH_PORT_EN; // <20>ص<EFBFBD><D8B5>˿<EFBFBD>
SetUsb2Speed(1); // Ĭ<><C4AC>Ϊȫ<CEAA><C8AB>
R8_U2HOST_CTRL = (R8_U2HOST_CTRL & ~RB_UH_LOW_SPEED) | RB_UH_BUS_RESET; // Ĭ<><C4AC>Ϊȫ<CEAA><C8AB>,<2C><>ʼ<EFBFBD><CABC>λ
mDelaymS(15); // <20><>λʱ<CEBB><CAB1>10mS<6D><53>20mS
R8_U2HOST_CTRL = R8_U2HOST_CTRL & ~RB_UH_BUS_RESET; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
mDelayuS(250);
R8_USB2_INT_FG = RB_UIF_DETECT; // <20><><EFBFBD>жϱ<D0B6>־
}
/*********************************************************************
* @fn EnableRootU2HubPort
*
* @brief ʹ<><CAB9>ROOT-HUB<55>˿<EFBFBD>,<2C><>Ӧ<EFBFBD><D3A6>bUH_PORT_EN<45><4E>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>,<2C><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ܵ<EFBFBD><DCB5>·<EFBFBD><C2B7><EFBFBD>ʧ<EFBFBD><CAA7>
*
* @param none
*
* @return <20><><EFBFBD><EFBFBD>ERR_SUCCESSΪ<53><CEAA><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>ERR_USB_DISCONΪ<4E><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
uint8_t EnableRootU2HubPort(void)
{
#ifdef DISK_BASE_BUF_LEN
if(CHRV3DiskStatus < DISK_CONNECT)
CHRV3DiskStatus = DISK_CONNECT;
#else
if(ThisUsb2Dev.DeviceStatus < ROOT_DEV_CONNECTED)
ThisUsb2Dev.DeviceStatus = ROOT_DEV_CONNECTED;
#endif
if(R8_USB2_MIS_ST & RB_UMS_DEV_ATTACH)
{ // <20><><EFBFBD>
#ifndef DISK_BASE_BUF_LEN
if((R8_U2HOST_CTRL & RB_UH_PORT_EN) == 0x00)
{ // <20><>δʹ<CEB4><CAB9>
ThisUsb2Dev.DeviceSpeed = (R8_USB2_MIS_ST & RB_UMS_DM_LEVEL) ? 0 : 1;
if(ThisUsb2Dev.DeviceSpeed == 0)
R8_U2HOST_CTRL |= RB_UH_LOW_SPEED; // <20><><EFBFBD><EFBFBD>
}
#endif
R8_U2HOST_CTRL |= RB_UH_PORT_EN; //ʹ<><CAB9>HUB<55>˿<EFBFBD>
return (ERR_SUCCESS);
}
return (ERR_USB_DISCON);
}
#ifndef DISK_BASE_BUF_LEN
/*********************************************************************
* @fn SelectU2HubPort
*
* @brief ѡ<><D1A1><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>HUB<55><42>
*
* @param HubPortIndex - ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ROOT-HUB<55>˿ڵ<CBBF><DAB5>ⲿHUB<55><42>ָ<EFBFBD><D6B8><EFBFBD>˿<EFBFBD>
*
* @return None
*/
void SelectU2HubPort(uint8_t HubPortIndex)
{
if(HubPortIndex) // ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ROOT-HUB<55>˿ڵ<CBBF><DAB5>ⲿHUB<55><42>ָ<EFBFBD><D6B8><EFBFBD>˿<EFBFBD>
{
SetHostUsb2Addr(DevOnU2HubPort[HubPortIndex - 1].DeviceAddress); // <20><><EFBFBD><EFBFBD>USB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<53><EFBFBD><E8B1B8>ַ
SetUsb2Speed(DevOnU2HubPort[HubPortIndex - 1].DeviceSpeed); // <20><><EFBFBD>õ<EFBFBD>ǰUSB<53>ٶ<EFBFBD>
if(DevOnU2HubPort[HubPortIndex - 1].DeviceSpeed == 0) // ͨ<><CDA8><EFBFBD>ⲿHUB<55><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<53>豸ͨѶ<CDA8><D1B6>Ҫǰ<D2AA><C7B0>ID
{
R8_U2EP1_CTRL |= RB_UH_PRE_PID_EN; // <20><><EFBFBD><EFBFBD>PRE PID
mDelayuS(100);
}
}
else
{
SetHostUsb2Addr(ThisUsb2Dev.DeviceAddress); // <20><><EFBFBD><EFBFBD>USB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<53><EFBFBD><E8B1B8>ַ
SetUsb2Speed(ThisUsb2Dev.DeviceSpeed); // <20><><EFBFBD><EFBFBD>USB<53><EFBFBD><E8B1B8><EFBFBD>ٶ<EFBFBD>
}
}
#endif
/*********************************************************************
* @fn WaitUSB2_Interrupt
*
* @brief <20>ȴ<EFBFBD>USB<53>ж<EFBFBD>
*
* @param none
*
* @return <20><><EFBFBD><EFBFBD>ERR_SUCCESS <20><><EFBFBD>ݽ<EFBFBD><DDBD>ջ<EFBFBD><D5BB>߷<EFBFBD><DFB7>ͳɹ<CDB3>,<2C><><EFBFBD><EFBFBD>ERR_USB_UNKNOWN <20><><EFBFBD>ݽ<EFBFBD><DDBD>ջ<EFBFBD><D5BB>߷<EFBFBD><DFB7><EFBFBD>ʧ<EFBFBD><CAA7>
*/
uint8_t WaitUSB2_Interrupt(void)
{
uint16_t i;
for(i = WAIT_USB_TOUT_200US; i != 0 && (R8_USB2_INT_FG & RB_UIF_TRANSFER) == 0; i--)
{
;
}
return ((R8_USB2_INT_FG & RB_UIF_TRANSFER) ? ERR_SUCCESS : ERR_USB_UNKNOWN);
}
/*********************************************************************
* @fn USB2HostTransact
*
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ŀ<EFBFBD>Ķ˵<C4B6><CBB5><EFBFBD>ַ/PID<49><44><EFBFBD><EFBFBD><><CDAC><EFBFBD><EFBFBD>־,<2C><>20uSΪ<53><CEAA>λ<EFBFBD><CEBB>NAK<41><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>(0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,0xFFFF<46><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>),<2C><><EFBFBD><EFBFBD>0<EFBFBD>ɹ<EFBFBD>,<2C><>ʱ/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <20><><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><><CEAA><EFBFBD><EFBFBD><E1B9A9><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><>öԱ<C3B6><D4B1>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD>
*
* @param endp_pid - <20><><EFBFBD>ƺ͵<C6BA>ַ, <20><><34><CEBB>token_pid<69><64><EFBFBD><EFBFBD>, <20><><34>Ƕ˵<C7B6><CBB5><EFBFBD>ַ
* @param tog - ͬ<><CDAC><EFBFBD><EFBFBD>־
* @param timeout - <20><>ʱʱ<CAB1><CAB1>
*
* @return ERR_USB_UNKNOWN <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>
* ERR_USB_DISCON <20><EFBFBD>Ͽ<EFBFBD>
* ERR_USB_CONNECT <20><EFBFBD><E8B1B8><EFBFBD><EFBFBD>
* ERR_SUCCESS <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
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; // ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PID<49><44>Ŀ<EFBFBD>Ķ˵<C4B6><CBB5><EFBFBD>
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<53><42><EFBFBD><EFBFBD>
if((R8_USB2_INT_FG & RB_UIF_TRANSFER) == 0)
{
return (ERR_USB_UNKNOWN);
}
if(R8_USB2_INT_FG & RB_UIF_DETECT)
{ // USB<53><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
// mDelayuS( 200 ); // <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
R8_USB2_INT_FG = RB_UIF_DETECT;
s = AnalyzeRootU2Hub(); // <20><><EFBFBD><EFBFBD>ROOT-U2HUB״̬
if(s == ERR_USB_CONNECT)
FoundNewU2Dev = 1;
#ifdef DISK_BASE_BUF_LEN
if(CHRV3DiskStatus == DISK_DISCONNECT)
{
return (ERR_USB_DISCON);
} // USB<53><EFBFBD>Ͽ<EFBFBD><CFBF>¼<EFBFBD>
if(CHRV3DiskStatus == DISK_CONNECT)
{
return (ERR_USB_CONNECT);
} // USB<53><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
#else
if(ThisUsb2Dev.DeviceStatus == ROOT_DEV_DISCONNECT)
{
return (ERR_USB_DISCON);
} // USB<53><EFBFBD>Ͽ<EFBFBD><CFBF>¼<EFBFBD>
if(ThisUsb2Dev.DeviceStatus == ROOT_DEV_CONNECTED)
{
return (ERR_USB_CONNECT);
} // USB<53><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
#endif
mDelayuS(200); // <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
if(R8_USB2_INT_FG & RB_UIF_TRANSFER) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
{
if(R8_USB2_INT_ST & RB_UIS_TOG_OK)
{
return (ERR_SUCCESS);
}
r = R8_USB2_INT_ST & MASK_UIS_H_RES; // USB<53>豸Ӧ<E8B1B8><D3A6>״̬
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);
} // <20><><EFBFBD>dz<EFBFBD>ʱ/<2F><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
break; // <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
case USB_PID_IN:
if(r == USB_PID_DATA0 || r == USB_PID_DATA1)
{ // <20><>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8B6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
} // <20><>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else if(r)
{
return (r | ERR_USB_TRANSFER);
} // <20><><EFBFBD>dz<EFBFBD>ʱ/<2F><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
break; // <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
default:
return (ERR_USB_UNKNOWN); // <20><><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD>
break;
}
}
else
{ // <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>,<2C><>Ӧ<EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
R8_USB2_INT_FG = 0xFF; /* <20><><EFBFBD>жϱ<D0B6>־ */
}
mDelayuS(15);
} while(++TransRetry < 3);
return (ERR_USB_TRANSFER); // Ӧ<><D3A6><EFBFBD><EFBFBD>ʱ
}
/*********************************************************************
* @fn U2HostCtrlTransfer
*
* @brief ִ<>п<EFBFBD><D0BF>ƴ<EFBFBD><C6B4><EFBFBD>,8<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pSetupReq<65><71>,DataBufΪ<66><CEAA>ѡ<EFBFBD><D1A1><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param DataBuf - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>պͷ<D5BA><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>ôDataBuf<75><66>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4>ź<EFBFBD><C5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param RetLen - ʵ<>ʳɹ<CAB3><C9B9>շ<EFBFBD><D5B7><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>RetLenָ<6E><D6B8><EFBFBD><EFBFBD><EFBFBD>ֽڱ<D6BD><DAB1><EFBFBD><EFBFBD><EFBFBD>
*
* @return ERR_USB_BUF_OVER IN״̬<D7B4>׶γ<D7B6><CEB3><EFBFBD>
* ERR_SUCCESS <20><><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
*/
uint8_t U2HostCtrlTransfer(uint8_t *DataBuf, uint8_t *RetLen)
{
uint16_t RemLen = 0;
uint8_t s, RxLen, RxCnt, TxCnt;
uint8_t *pBuf;
uint8_t *pLen;
pBuf = DataBuf;
pLen = RetLen;
mDelayuS(200);
if(pLen)
*pLen = 0; // ʵ<>ʳɹ<CAB3><C9B9>շ<EFBFBD><D5B7><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
R8_U2H_TX_LEN = sizeof(USB_SETUP_REQ);
s = USB2HostTransact(USB_PID_SETUP << 4 | 0x00, 0x00, 200000 / 20); // SETUP<55>׶<EFBFBD>,200mS<6D><53>ʱ
if(s != ERR_SUCCESS)
return (s);
R8_U2H_RX_CTRL = R8_U2H_TX_CTRL = RB_UH_R_TOG | RB_UH_R_AUTO_TOG | RB_UH_T_TOG | RB_UH_T_AUTO_TOG; // Ĭ<><C4AC>DATA1
R8_U2H_TX_LEN = 0x01; // Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݹ<EFBFBD>״̬<D7B4>׶<EFBFBD>ΪIN
RemLen = pU2SetupReq->wLength;
if(RemLen && pBuf) // <20><>Ҫ<EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD>
{
if(pU2SetupReq->bRequestType & USB_REQ_TYP_IN) // <20><>
{
while(RemLen)
{
mDelayuS(200);
s = USB2HostTransact(USB_PID_IN << 4 | 0x00, R8_U2H_RX_CTRL, 200000 / 20); // IN<49><4E><EFBFBD><EFBFBD>
if(s != ERR_SUCCESS)
return (s);
RxLen = R8_USB2_RX_LEN < RemLen ? R8_USB2_RX_LEN : RemLen;
RemLen -= RxLen;
if(pLen)
*pLen += RxLen; // ʵ<>ʳɹ<CAB3><C9B9>շ<EFBFBD><D5B7><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
for(RxCnt = 0; RxCnt != RxLen; RxCnt++)
{
*pBuf = pU2HOST_RX_RAM_Addr[RxCnt];
pBuf++;
}
if(R8_USB2_RX_LEN == 0 || (R8_USB2_RX_LEN & (Usb2DevEndp0Size - 1)))
break; // <20>̰<EFBFBD>
}
R8_U2H_TX_LEN = 0x00; // ״̬<D7B4>׶<EFBFBD>ΪOUT
}
else // <20><>
{
while(RemLen)
{
mDelayuS(200);
R8_U2H_TX_LEN = RemLen >= Usb2DevEndp0Size ? Usb2DevEndp0Size : RemLen;
for(TxCnt = 0; TxCnt != R8_U2H_TX_LEN; TxCnt++)
{
pU2HOST_TX_RAM_Addr[TxCnt] = *pBuf;
pBuf++;
}
s = USB2HostTransact(USB_PID_OUT << 4 | 0x00, R8_U2H_TX_CTRL, 200000 / 20); // OUT<55><54><EFBFBD><EFBFBD>
if(s != ERR_SUCCESS)
return (s);
RemLen -= R8_U2H_TX_LEN;
if(pLen)
*pLen += R8_U2H_TX_LEN; // ʵ<>ʳɹ<CAB3><C9B9>շ<EFBFBD><D5B7><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
}
// R8_U2H_TX_LEN = 0x01; // ״̬<D7B4>׶<EFBFBD>ΪIN
}
}
mDelayuS(200);
s = USB2HostTransact((R8_U2H_TX_LEN ? USB_PID_IN << 4 | 0x00 : USB_PID_OUT << 4 | 0x00), RB_UH_R_TOG | RB_UH_T_TOG, 200000 / 20); // STATUS<55>׶<EFBFBD>
if(s != ERR_SUCCESS)
return (s);
if(R8_U2H_TX_LEN == 0)
return (ERR_SUCCESS); // ״̬OUT
if(R8_USB2_RX_LEN == 0)
return (ERR_SUCCESS); // ״̬IN,<2C><><EFBFBD><EFBFBD>IN״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
return (ERR_USB_BUF_OVER); // IN״̬<D7B4>׶δ<D7B6><CEB4><EFBFBD>
}
/*********************************************************************
* @fn CopyU2SetupReqPkg
*
* @brief <20><><EFBFBD>ƿ<EFBFBD><C6BF>ƴ<EFBFBD><C6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param pReqPkt - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
*
* @return none
*/
void CopyU2SetupReqPkg(const uint8_t *pReqPkt) // <20><><EFBFBD>ƿ<EFBFBD><C6BF>ƴ<EFBFBD><C6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
uint8_t i;
for(i = 0; i != sizeof(USB_SETUP_REQ); i++)
{
((uint8_t *)pU2SetupReq)[i] = *pReqPkt;
pReqPkt++;
}
}
/*********************************************************************
* @fn CtrlGetU2DeviceDescr
*
* @brief <20><>ȡ<EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pHOST_TX_RAM_Addr <20><>
*
* @param none
*
* @return ERR_USB_BUF_OVER <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>
* ERR_SUCCESS <20>ɹ<EFBFBD>
*/
uint8_t CtrlGetU2DeviceDescr(void)
{
uint8_t s;
uint8_t len;
Usb2DevEndp0Size = DEFAULT_ENDP0_SIZE;
CopyU2SetupReqPkg((uint8_t *)SetupGetU2DevDescr);
s = U2HostCtrlTransfer(U2Com_Buffer, &len); // ִ<>п<EFBFBD><D0BF>ƴ<EFBFBD><C6B4><EFBFBD>
if(s != ERR_SUCCESS)
return (s);
Usb2DevEndp0Size = ((PUSB_DEV_DESCR)U2Com_Buffer)->bMaxPacketSize0; // <20>˵<EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>Ǽ򻯴<C7BC><F2BBAFB4><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>Ȼ<EFBFBD>ȡǰ8<C7B0>ֽں<D6BD><DABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UsbDevEndp0Size<7A>ټ<EFBFBD><D9BC><EFBFBD>
if(len < ((PUSB_SETUP_REQ)SetupGetU2DevDescr)->wLength)
return (ERR_USB_BUF_OVER); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn CtrlGetU2ConfigDescr
*
* @brief <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pHOST_TX_RAM_Addr <20><>
*
* @param none
*
* @return ERR_USB_BUF_OVER <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>
* ERR_SUCCESS <20>ɹ<EFBFBD>
*/
uint8_t CtrlGetU2ConfigDescr(void)
{
uint8_t s;
uint8_t len;
CopyU2SetupReqPkg((uint8_t *)SetupGetU2CfgDescr);
s = U2HostCtrlTransfer(U2Com_Buffer, &len); // ִ<>п<EFBFBD><D0BF>ƴ<EFBFBD><C6B4><EFBFBD>
if(s != ERR_SUCCESS)
return (s);
if(len < ((PUSB_SETUP_REQ)SetupGetU2CfgDescr)->wLength)
return (ERR_USB_BUF_OVER); // <20><><EFBFBD>س<EFBFBD><D8B3>ȴ<EFBFBD><C8B4><EFBFBD>
len = ((PUSB_CFG_DESCR)U2Com_Buffer)->wTotalLength;
CopyU2SetupReqPkg((uint8_t *)SetupGetU2CfgDescr);
pU2SetupReq->wLength = len; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
s = U2HostCtrlTransfer(U2Com_Buffer, &len); // ִ<>п<EFBFBD><D0BF>ƴ<EFBFBD><C6B4><EFBFBD>
if(s != ERR_SUCCESS)
return (s);
#ifdef DISK_BASE_BUF_LEN
if(len > 64)
len = 64;
memcpy(TxBuffer, U2Com_Buffer, len); //U<>̲<EFBFBD><CCB2><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TxBuffer
#endif
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn CtrlSetUsb2Address
*
* @brief <20><><EFBFBD><EFBFBD>USB<53><EFBFBD><E8B1B8>ַ
*
* @param addr - <20><EFBFBD><E8B1B8>ַ
*
* @return ERR_SUCCESS <20>ɹ<EFBFBD>
*/
uint8_t CtrlSetUsb2Address(uint8_t addr)
{
uint8_t s;
CopyU2SetupReqPkg((uint8_t *)SetupSetUsb2Addr);
pU2SetupReq->wValue = addr; // USB<53><EFBFBD><E8B1B8>ַ
s = U2HostCtrlTransfer(NULL, NULL); // ִ<>п<EFBFBD><D0BF>ƴ<EFBFBD><C6B4><EFBFBD>
if(s != ERR_SUCCESS)
return (s);
SetHostUsb2Addr(addr); // <20><><EFBFBD><EFBFBD>USB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<53><EFBFBD><E8B1B8>ַ
mDelaymS(10); // <20>ȴ<EFBFBD>USB<53><EFBFBD><E8B1B8><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn CtrlSetUsb2Config
*
* @brief <20><><EFBFBD><EFBFBD>USB<53><EFBFBD><E8B1B8><EFBFBD><EFBFBD>
*
* @param cfg - <20><><EFBFBD><EFBFBD>ֵ
*
* @return ERR_SUCCESS <20>ɹ<EFBFBD>
*/
uint8_t CtrlSetUsb2Config(uint8_t cfg)
{
CopyU2SetupReqPkg((uint8_t *)SetupSetUsb2Config);
pU2SetupReq->wValue = cfg; // USB<53><EFBFBD><E8B1B8><EFBFBD><EFBFBD>
return (U2HostCtrlTransfer(NULL, NULL)); // ִ<>п<EFBFBD><D0BF>ƴ<EFBFBD><C6B4><EFBFBD>
}
/*********************************************************************
* @fn CtrlClearU2EndpStall
*
* @brief <20><><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD>STALL
*
* @param endp - <20>˵<EFBFBD><CBB5><EFBFBD>ַ
*
* @return ERR_SUCCESS <20>ɹ<EFBFBD>
*/
uint8_t CtrlClearU2EndpStall(uint8_t endp)
{
CopyU2SetupReqPkg((uint8_t *)SetupClrU2EndpStall); // <20><><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>Ĵ<EFBFBD><C4B4><EFBFBD>
pU2SetupReq->wIndex = endp; // <20>˵<EFBFBD><CBB5><EFBFBD>ַ
return (U2HostCtrlTransfer(NULL, NULL)); // ִ<>п<EFBFBD><D0BF>ƴ<EFBFBD><C6B4><EFBFBD>
}
/*********************************************************************
* @fn CtrlSetUsb2Intercace
*
* @brief <20><><EFBFBD><EFBFBD>USB<53><EFBFBD>ӿ<EFBFBD>
*
* @param cfg - <20><><EFBFBD><EFBFBD>ֵ
*
* @return ERR_SUCCESS <20>ɹ<EFBFBD>
*/
uint8_t CtrlSetUsb2Intercace(uint8_t cfg)
{
CopyU2SetupReqPkg((uint8_t *)SetupSetUsb2Interface);
pU2SetupReq->wValue = cfg; // USB<53><EFBFBD><E8B1B8><EFBFBD><EFBFBD>
return (U2HostCtrlTransfer(NULL, NULL)); // ִ<>п<EFBFBD><D0BF>ƴ<EFBFBD><C6B4><EFBFBD>
}
/*********************************************************************
* @fn USB2_HostInit
*
* @brief USB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD>ʼ<EFBFBD><CABC>
*
* @param none
*
* @return none
*/
void USB2_HostInit(void)
{
R8_USB2_CTRL = RB_UC_HOST_MODE;
R8_U2HOST_CTRL = 0;
R8_USB2_DEV_AD = 0x00;
R8_U2H_EP_MOD = RB_UH_EP_TX_EN | RB_UH_EP_RX_EN;
R16_U2H_RX_DMA = (uint16_t)(uint32_t)pU2HOST_RX_RAM_Addr;
R16_U2H_TX_DMA = (uint16_t)(uint32_t)pU2HOST_TX_RAM_Addr;
R8_U2H_RX_CTRL = 0x00;
R8_U2H_TX_CTRL = 0x00;
R8_USB2_CTRL = RB_UC_HOST_MODE | RB_UC_INT_BUSY | RB_UC_DMA_EN;
R8_U2H_SETUP = RB_UH_SOF_EN;
R8_USB2_INT_FG = 0xFF;
DisableRootU2HubPort();
R8_USB2_INT_EN = RB_UIE_TRANSFER | RB_UIE_DETECT;
FoundNewU2Dev = 0;
}