pikapython/bsp/ch582/StdPeriphDriver/CH58x_usb2hostBase.c

651 lines
21 KiB
C
Raw Normal View History

2022-03-26 20:51:40 +08:00
/********************************** (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 <EFBFBD>ر<EFBFBD>ROOT-HUB<EFBFBD>˿<EFBFBD>,ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD>ر<EFBFBD>,<EFBFBD>˴<EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩ<EFBFBD>״̬
*
* @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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ROOT-HUB״̬,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ROOT-HUB<EFBFBD>˿ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>γ<EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD>DisableRootHubPort()<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD>˿ڹر<EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>˿ڵ<EFBFBD>״̬λ
*
* @param none
*
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ERR_SUCCESSΪû<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ERR_USB_CONNECTΪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ERR_USB_DISCONΪ<EFBFBD><EFBFBD><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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<EFBFBD><EFBFBD><EFBFBD>ַ
*
* @param addr - USB<EFBFBD><EFBFBD><EFBFBD>ַ
*
* @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 <EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ǰUSB<EFBFBD>ٶ<EFBFBD>
*
* @param FullSpeed - USB<EFBFBD>ٶ<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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,Ϊö<EFBFBD><EFBFBD><EFBFBD>׼<EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪĬ<EFBFBD><EFBFBD>Ϊȫ<EFBFBD><EFBFBD>
*
* @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 ʹ<EFBFBD><EFBFBD>ROOT-HUB<EFBFBD>˿<EFBFBD>,<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>bUH_PORT_EN<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>,<EFBFBD><EFBFBD>Ͽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
*
* @param none
*
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ERR_SUCCESSΪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ERR_USB_DISCONΪ<EFBFBD><EFBFBD><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 ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>HUB<EFBFBD><EFBFBD>
*
* @param HubPortIndex - ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ROOT-HUB<EFBFBD>˿ڵ<EFBFBD><EFBFBD>ⲿHUB<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><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 <EFBFBD>ȴ<EFBFBD>USB<EFBFBD>ж<EFBFBD>
*
* @param none
*
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ERR_SUCCESS <EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>߷<EFBFBD><EFBFBD>ͳɹ<EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ERR_USB_UNKNOWN <EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>߷<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
*/
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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>Ķ˵<EFBFBD><EFBFBD><EFBFBD>ַ/PID<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>־,<EFBFBD><EFBFBD>20u<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>NAK<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>(0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,0xFFFF<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>),<EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>ɹ<EFBFBD>,<EFBFBD><EFBFBD>ʱ/<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>,Ӧ<EFBFBD>öԱ<EFBFBD><EFBFBD>ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD>
*
* @param endp_pid - <EFBFBD><EFBFBD><EFBFBD>ƺ͵<EFBFBD>ַ, <EFBFBD><EFBFBD>4λ<EFBFBD><EFBFBD>token_pid<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>4λ<EFBFBD>Ƕ˵<EFBFBD><EFBFBD><EFBFBD>ַ
* @param tog - ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
* @param timeout - <EFBFBD><EFBFBD>ʱʱ<EFBFBD><EFBFBD>
*
* @return ERR_USB_UNKNOWN <EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><EFBFBD><EFBFBD>
* ERR_USB_DISCON <EFBFBD><EFBFBD>Ͽ<EFBFBD>
* ERR_USB_CONNECT <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* ERR_SUCCESS <EFBFBD><EFBFBD><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>п<EFBFBD><EFBFBD>ƴ<EFBFBD><EFBFBD><EFBFBD>,8<EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pSetupReq<EFBFBD><EFBFBD>,DataBufΪ<EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param DataBuf - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>պͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD>ôDataBuf<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>ź<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param RetLen - ʵ<EFBFBD>ʳɹ<EFBFBD><EFBFBD>շ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD>ȱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>RetLenָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @return ERR_USB_BUF_OVER IN״̬<EFBFBD>׶γ<EFBFBD><EFBFBD><EFBFBD>
* ERR_SUCCESS <EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><EFBFBD><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 <EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><EFBFBD>ƴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param pReqPkt - <EFBFBD><EFBFBD><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 <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pHOST_TX_RAM_Addr <EFBFBD><EFBFBD>
*
* @param none
*
* @return ERR_USB_BUF_OVER <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>
* ERR_SUCCESS <EFBFBD>ɹ<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 <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pHOST_TX_RAM_Addr <EFBFBD><EFBFBD>
*
* @param none
*
* @return ERR_USB_BUF_OVER <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>
* ERR_SUCCESS <EFBFBD>ɹ<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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<EFBFBD><EFBFBD><EFBFBD>ַ
*
* @param addr - <EFBFBD><EFBFBD><EFBFBD>ַ
*
* @return ERR_SUCCESS <EFBFBD>ɹ<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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param cfg - <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
*
* @return ERR_SUCCESS <EFBFBD>ɹ<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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD>STALL
*
* @param endp - <EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD>ַ
*
* @return ERR_SUCCESS <EFBFBD>ɹ<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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<EFBFBD><EFBFBD>ӿ<EFBFBD>
*
* @param cfg - <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
*
* @return ERR_SUCCESS <EFBFBD>ɹ<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<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD>ʼ<EFBFBD><EFBFBD>
*
* @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;
}