314 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			314 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /********************************** (C) COPYRIGHT *******************************
 | ||
|  * File Name          : CH59x_usbhost.h
 | ||
|  * Author             : WCH
 | ||
|  * Version            : V1.2
 | ||
|  * Date               : 2021/11/17
 | ||
|  * Description
 | ||
|  *********************************************************************************
 | ||
|  * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 | ||
|  * Attention: This software (modified or not) and binary are used for 
 | ||
|  * microcontroller manufactured by Nanjing Qinheng Microelectronics.
 | ||
|  *******************************************************************************/
 | ||
| 
 | ||
| #ifndef __CH59x_USBHOST_H__
 | ||
| #define __CH59x_USBHOST_H__
 | ||
| 
 | ||
| #ifdef __cplusplus
 | ||
| extern "C" {
 | ||
| #endif
 | ||
| 
 | ||
| #if DISK_LIB_ENABLE
 | ||
|   #if DISK_WITHOUT_USB_HUB
 | ||
|   /* 不使用U盘文件系统库或者U盘挂载USBhub下面,需要关闭下面定义 */
 | ||
|     #define FOR_ROOT_UDISK_ONLY
 | ||
|   #endif
 | ||
|   /* 使用U盘文件系统库,需要开启下面定义, 不使用请关闭 */
 | ||
|   #define DISK_BASE_BUF_LEN    512  /* 默认的磁盘数据缓冲区大小为512字节,建议选择为2048甚至4096以支持某些大扇区的U盘,为0则禁止在.H文件中定义缓冲区并由应用程序在pDISK_BASE_BUF中指定 */
 | ||
| #endif
 | ||
| 
 | ||
| // 各子程序返回状态码
 | ||
| #define ERR_SUCCESS            0x00  // 操作成功
 | ||
| #define ERR_USB_CONNECT        0x15  /* 检测到USB设备连接事件,已经连接 */
 | ||
| #define ERR_USB_DISCON         0x16  /* 检测到USB设备断开事件,已经断开 */
 | ||
| #define ERR_USB_BUF_OVER       0x17  /* USB传输的数据有误或者数据太多缓冲区溢出 */
 | ||
| #define ERR_USB_DISK_ERR       0x1F  /* USB存储器操作失败,在初始化时可能是USB存储器不支持,在读写操作中可能是磁盘损坏或者已经断开 */
 | ||
| #define ERR_USB_TRANSFER       0x20  /* NAK/STALL等更多错误码在0x20~0x2F */
 | ||
| #define ERR_USB_UNSUPPORT      0xFB  /* 不支持的USB设备*/
 | ||
| #define ERR_USB_UNKNOWN        0xFE  /* 设备操作出错*/
 | ||
| #define ERR_AOA_PROTOCOL       0x41  /* 协议版本出错 */
 | ||
| 
 | ||
| /*USB设备相关信息表,最多支持1个设备*/
 | ||
| #define ROOT_DEV_DISCONNECT    0
 | ||
| #define ROOT_DEV_CONNECTED     1
 | ||
| #define ROOT_DEV_FAILED        2
 | ||
| #define ROOT_DEV_SUCCESS       3
 | ||
| #define DEV_TYPE_KEYBOARD      (USB_DEV_CLASS_HID | 0x20)
 | ||
| #define DEV_TYPE_MOUSE         (USB_DEV_CLASS_HID | 0x30)
 | ||
| #define DEF_AOA_DEVICE         0xF0
 | ||
| #define DEV_TYPE_UNKNOW        0xFF
 | ||
| 
 | ||
| /*
 | ||
| 约定: USB设备地址分配规则(参考USB_DEVICE_ADDR)
 | ||
| 地址值  设备位置
 | ||
| 0x02    内置Root-HUB下的USB设备或外部HUB
 | ||
| 0x1x    内置Root-HUB下的外部HUB的端口x下的USB设备,x为1~n
 | ||
| */
 | ||
| #define HUB_MAX_PORTS          4
 | ||
| #define WAIT_USB_TOUT_200US    800   // 等待USB中断超时时间
 | ||
| 
 | ||
| typedef struct
 | ||
| {
 | ||
|     uint8_t  DeviceStatus;  // 设备状态,0-无设备,1-有设备但尚未初始化,2-有设备但初始化枚举失败,3-有设备且初始化枚举成功
 | ||
|     uint8_t  DeviceAddress; // 设备被分配的USB地址
 | ||
|     uint8_t  DeviceSpeed;   // 0为低速,非0为全速
 | ||
|     uint8_t  DeviceType;    // 设备类型
 | ||
|     uint16_t DeviceVID;
 | ||
|     uint16_t DevicePID;
 | ||
|     uint8_t  GpVar[4];     // 通用变量,存放端点
 | ||
|     uint8_t  GpHUBPortNum; // 通用变量,如果是HUB,表示HUB端口数
 | ||
| } _RootHubDev;
 | ||
| 
 | ||
| typedef struct
 | ||
| {
 | ||
|     UINT8  DeviceStatus;  // 设备状态,0-无设备,1-有设备但尚未初始化,2-有设备但初始化枚举失败,3-有设备且初始化枚举成功
 | ||
|     UINT8  DeviceAddress; // 设备被分配的USB地址
 | ||
|     UINT8  DeviceSpeed;   // 0为低速,非0为全速
 | ||
|     UINT8  DeviceType;    // 设备类型
 | ||
|     UINT16 DeviceVID;
 | ||
|     UINT16 DevicePID;
 | ||
|     UINT8  GpVar[4]; // 通用变量
 | ||
| } _DevOnHubPort;     // 假定:不超过1个外部HUB,每个外部HUB不超过HUB_MAX_PORTS个端口(多了不管)
 | ||
| 
 | ||
| extern _RootHubDev   ThisUsbDev;
 | ||
| extern _DevOnHubPort DevOnHubPort[HUB_MAX_PORTS]; // 假定:不超过1个外部HUB,每个外部HUB不超过HUB_MAX_PORTS个端口(多了不管)
 | ||
| extern uint8_t       UsbDevEndp0Size;             // USB设备的端点0的最大包尺寸 */
 | ||
| extern uint8_t       FoundNewDev;
 | ||
| 
 | ||
| extern uint8_t *pHOST_RX_RAM_Addr;
 | ||
| extern uint8_t *pHOST_TX_RAM_Addr;
 | ||
| 
 | ||
| extern _RootHubDev   ThisUsb2Dev;
 | ||
| extern _DevOnHubPort DevOnU2HubPort[HUB_MAX_PORTS]; // 假定:不超过1个外部HUB,每个外部HUB不超过HUB_MAX_PORTS个端口(多了不管)
 | ||
| extern uint8_t       Usb2DevEndp0Size;              // USB设备的端点0的最大包尺寸 */
 | ||
| extern uint8_t       FoundNewU2Dev;
 | ||
| 
 | ||
| extern uint8_t *pU2HOST_RX_RAM_Addr;
 | ||
| extern uint8_t *pU2HOST_TX_RAM_Addr;
 | ||
| 
 | ||
| #define pSetupReq      ((PUSB_SETUP_REQ)pHOST_TX_RAM_Addr)
 | ||
| #define pU2SetupReq    ((PUSB_SETUP_REQ)pU2HOST_TX_RAM_Addr)
 | ||
| extern uint8_t Com_Buffer[];
 | ||
| extern uint8_t U2Com_Buffer[];
 | ||
| 
 | ||
| /* 以下为USB主机请求包 */
 | ||
| extern const uint8_t SetupGetDevDescr[];     // 获取设备描述符*/
 | ||
| extern const uint8_t SetupGetCfgDescr[];     // 获取配置描述符*/
 | ||
| extern const uint8_t SetupSetUsbAddr[];      // 设置USB地址*/
 | ||
| extern const uint8_t SetupSetUsbConfig[];    // 设置USB配置*/
 | ||
| extern const uint8_t SetupSetUsbInterface[]; // 设置USB接口配置*/
 | ||
| extern const uint8_t SetupClrEndpStall[];    // 清除端点STALL*/
 | ||
| 
 | ||
| extern const uint8_t SetupGetU2DevDescr[];    // 获取设备描述符*/
 | ||
| extern const uint8_t SetupGetU2CfgDescr[];    // 获取配置描述符*/
 | ||
| extern const uint8_t SetupSetUsb2Addr[];      // 设置USB地址*/
 | ||
| extern const uint8_t SetupSetUsb2Config[];    // 设置USB配置*/
 | ||
| extern const uint8_t SetupSetUsb2Interface[]; // 设置USB接口配置*/
 | ||
| extern const uint8_t SetupClrU2EndpStall[];   // 清除端点STALL*/
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   关闭ROOT-HUB端口,实际上硬件已经自动关闭,此处只是清除一些结构状态
 | ||
|  */
 | ||
| void DisableRootHubPort(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   分析ROOT-HUB状态,处理ROOT-HUB端口的设备插拔事件
 | ||
|  *          如果设备拔出,函数中调用DisableRootHubPort()函数,将端口关闭,插入事件,置相应端口的状态位
 | ||
|  *
 | ||
|  * @return  返回ERR_SUCCESS为没有情况,返回ERR_USB_CONNECT为检测到新连接,返回ERR_USB_DISCON为检测到断开
 | ||
|  */
 | ||
| uint8_t AnalyzeRootHub(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   设置USB主机当前操作的USB设备地址
 | ||
|  *
 | ||
|  * @param   addr    - USB设备地址
 | ||
|  */
 | ||
| void SetHostUsbAddr(uint8_t addr);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   设置当前USB速度
 | ||
|  *
 | ||
|  * @param   FullSpeed   - USB速度
 | ||
|  */
 | ||
| void SetUsbSpeed(uint8_t FullSpeed);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   检测到设备后,复位总线,为枚举设备准备,设置为默认为全速
 | ||
|  */
 | ||
| void ResetRootHubPort(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   使能ROOT-HUB端口,相应的bUH_PORT_EN置1开启端口,设备断开可能导致返回失败
 | ||
|  *
 | ||
|  * @return  返回ERR_SUCCESS为检测到新连接,返回ERR_USB_DISCON为无连接
 | ||
|  */
 | ||
| uint8_t EnableRootHubPort(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   等待USB中断
 | ||
|  *
 | ||
|  * @return  返回ERR_SUCCESS 数据接收或者发送成功,返回ERR_USB_UNKNOWN 数据接收或者发送失败
 | ||
|  */
 | ||
| uint8_t WaitUSB_Interrupt(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   传输事务,输入目的端点地址/PID令牌,同步标志,以20uS为单位的NAK重试总时间(0则不重试,0xFFFF无限重试),返回0成功,超时/出错重试
 | ||
|  *          本子程序着重于易理解,而在实际应用中,为了提供运行速度,应该对本子程序代码进行优化
 | ||
|  *
 | ||
|  * @param   endp_pid    - 令牌和地址, 高4位是token_pid令牌, 低4位是端点地址
 | ||
|  * @param   tog         - 同步标志
 | ||
|  * @param   timeout     - 超时时间
 | ||
|  *
 | ||
|  * @return  ERR_USB_UNKNOWN 超时,可能硬件异常
 | ||
|  *          ERR_USB_DISCON  设备断开
 | ||
|  *          ERR_USB_CONNECT 设备连接
 | ||
|  *          ERR_SUCCESS     传输完成
 | ||
|  */
 | ||
| uint8_t USBHostTransact(uint8_t endp_pid, uint8_t tog, uint32_t timeout);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   执行控制传输,8字节请求码在pSetupReq中,DataBuf为可选的收发缓冲区
 | ||
|  *
 | ||
|  * @param   DataBuf     - 如果需要接收和发送数据,那么DataBuf需指向有效缓冲区用于存放后续数据
 | ||
|  * @param   RetLen      - 实际成功收发的总长度保存在RetLen指向的字节变量中
 | ||
|  *
 | ||
|  * @return  ERR_USB_BUF_OVER    IN状态阶段出错
 | ||
|  *          ERR_SUCCESS         数据交换成功
 | ||
|  */
 | ||
| uint8_t HostCtrlTransfer(uint8_t *DataBuf, uint8_t *RetLen);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   复制控制传输的请求包
 | ||
|  *
 | ||
|  * @param   pReqPkt     - 控制请求包地址
 | ||
|  */
 | ||
| void CopySetupReqPkg(const uint8_t *pReqPkt);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   获取设备描述符,返回在 pHOST_TX_RAM_Addr 中
 | ||
|  *
 | ||
|  * @return  ERR_USB_BUF_OVER    描述符长度错误
 | ||
|  *          ERR_SUCCESS         成功
 | ||
|  */
 | ||
| uint8_t CtrlGetDeviceDescr(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   获取配置描述符,返回在 pHOST_TX_RAM_Addr 中
 | ||
|  *
 | ||
|  * @return  ERR_USB_BUF_OVER    描述符长度错误
 | ||
|  *          ERR_SUCCESS         成功
 | ||
|  */
 | ||
| uint8_t CtrlGetConfigDescr(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   设置USB设备地址
 | ||
|  *
 | ||
|  * @param   addr    - 设备地址
 | ||
|  *
 | ||
|  * @return  ERR_SUCCESS     成功
 | ||
|  */
 | ||
| uint8_t CtrlSetUsbAddress(uint8_t addr);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   设置USB设备配置
 | ||
|  *
 | ||
|  * @param   cfg     - 配置值
 | ||
|  *
 | ||
|  * @return  ERR_SUCCESS     成功
 | ||
|  */
 | ||
| uint8_t CtrlSetUsbConfig(uint8_t cfg);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   清除端点STALL
 | ||
|  *
 | ||
|  * @param   endp    - 端点地址
 | ||
|  *
 | ||
|  * @return  ERR_SUCCESS     成功
 | ||
|  */
 | ||
| uint8_t CtrlClearEndpStall(uint8_t endp);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   设置USB设备接口
 | ||
|  *
 | ||
|  * @param   cfg     - 配置值
 | ||
|  *
 | ||
|  * @return  ERR_SUCCESS     成功
 | ||
|  */
 | ||
| uint8_t CtrlSetUsbIntercace(uint8_t cfg);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   USB主机功能初始化
 | ||
|  */
 | ||
| void USB_HostInit(void);
 | ||
| uint8_t EnumAllHubPort(void);// 枚举所有ROOT-HUB端口下外部HUB后的二级USB设备
 | ||
| void SelectHubPort(uint8_t HubPortIndex); // HubPortIndex=0选择操作指定的ROOT-HUB端口,否则选择操作指定的ROOT-HUB端口的外部HUB的指定端口
 | ||
| uint16_t SearchTypeDevice(uint8_t type); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号,输出端口号为0xFFFF则未搜索到.
 | ||
| uint8_t SETorOFFNumLock(uint8_t *buf); // NumLock的点灯判断
 | ||
| 
 | ||
| /*************************************************************/
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   初始化指定ROOT-HUB端口的USB设备
 | ||
|  *
 | ||
|  * @return  错误码
 | ||
|  */
 | ||
| uint8_t InitRootDevice(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   获取HID设备报表描述符,返回在TxBuffer中
 | ||
|  *
 | ||
|  * @return  错误码
 | ||
|  */
 | ||
| uint8_t CtrlGetHIDDeviceReport(uint8_t infc);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   获取HUB描述符,返回在Com_Buffer中
 | ||
|  *
 | ||
|  * @return  错误码
 | ||
|  */
 | ||
| uint8_t CtrlGetHubDescr(void);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   查询HUB端口状态,返回在Com_Buffer中
 | ||
|  *
 | ||
|  * @param   HubPortIndex    - 端口号
 | ||
|  *
 | ||
|  * @return  错误码
 | ||
|  */
 | ||
| uint8_t HubGetPortStatus(uint8_t HubPortIndex);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   设置HUB端口特性
 | ||
|  *
 | ||
|  * @param   HubPortIndex    - 端口号
 | ||
|  * @param   FeatureSelt     - 端口特性
 | ||
|  *
 | ||
|  * @return  错误码
 | ||
|  */
 | ||
| uint8_t HubSetPortFeature(uint8_t HubPortIndex, uint8_t FeatureSelt);
 | ||
| 
 | ||
| /**
 | ||
|  * @brief   清除HUB端口特性
 | ||
|  *
 | ||
|  * @param   HubPortIndex    - 端口号
 | ||
|  * @param   FeatureSelt     - 端口特性
 | ||
|  *
 | ||
|  * @return  错误码
 | ||
|  */
 | ||
| uint8_t HubClearPortFeature(uint8_t HubPortIndex, uint8_t FeatureSelt);
 | ||
| 
 | ||
| #ifdef __cplusplus
 | ||
| }
 | ||
| #endif
 | ||
| 
 | ||
| #endif // __CH59x_USBHOST_H__
 |