Created
April 14, 2023 14:29
-
-
Save SelvinPL/68637937286e4d530a0f6a58807850a3 to your computer and use it in GitHub Desktop.
tinyusb proof of concept IRQ host implementation for CH20X (prolly can be ported to 58x)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************** (C) COPYRIGHT ******************************* | |
* File Name : ch32v20x_usb.h | |
* Author : WCH | |
* Version : V1.0.0 | |
* Date : 2021/06/06 | |
* Description : CH32V20x Device Peripheral Access Layer System Header File. | |
********************************************************************************* | |
* 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 __CH32V20x_USB_H | |
#define __CH32V20x_USB_H | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/*******************************************************************************/ | |
/* Header Files */ | |
#include "stdint.h" | |
/*******************************************************************************/ | |
/* USB Communication Related Macro Definition */ | |
/* USB Endpoint0 Size */ | |
#ifndef DEFAULT_ENDP0_SIZE | |
#define DEFAULT_ENDP0_SIZE 8 | |
#endif | |
/* USB PID */ | |
#ifndef USB_PID_SETUP | |
#define USB_PID_NULL 0x00 | |
#define USB_PID_SOF 0x05 | |
#define USB_PID_SETUP 0x0D | |
#define USB_PID_IN 0x09 | |
#define USB_PID_OUT 0x01 | |
#define USB_PID_NYET 0x06 | |
#define USB_PID_ACK 0x02 | |
#define USB_PID_NAK 0x0A | |
#define USB_PID_STALL 0x0E | |
#define USB_PID_DATA0 0x03 | |
#define USB_PID_DATA1 0x0B | |
#define USB_PID_DATA2 0x07 | |
#define USB_PID_MDATA 0x0F | |
#define USB_PID_PRE 0x0C | |
#define USB_PID_SPLIT 0x08 | |
#define USB_PID_PING 0x04 | |
#endif | |
/* USB standard device request code */ | |
#ifndef USB_GET_DESCRIPTOR | |
#define USB_GET_STATUS 0x00 | |
#define USB_CLEAR_FEATURE 0x01 | |
#define USB_SET_FEATURE 0x03 | |
#define USB_SET_ADDRESS 0x05 | |
#define USB_GET_DESCRIPTOR 0x06 | |
#define USB_SET_DESCRIPTOR 0x07 | |
#define USB_GET_CONFIGURATION 0x08 | |
#define USB_SET_CONFIGURATION 0x09 | |
#define USB_GET_INTERFACE 0x0A | |
#define USB_SET_INTERFACE 0x0B | |
#define USB_SYNCH_FRAME 0x0C | |
#endif | |
#define DEF_STRING_DESC_LANG 0x00 | |
#define DEF_STRING_DESC_MANU 0x01 | |
#define DEF_STRING_DESC_PROD 0x02 | |
#define DEF_STRING_DESC_SERN 0x03 | |
/* USB hub class request code */ | |
#ifndef HUB_GET_DESCRIPTOR | |
#define HUB_GET_STATUS 0x00 | |
#define HUB_CLEAR_FEATURE 0x01 | |
#define HUB_GET_STATE 0x02 | |
#define HUB_SET_FEATURE 0x03 | |
#define HUB_GET_DESCRIPTOR 0x06 | |
#define HUB_SET_DESCRIPTOR 0x07 | |
#endif | |
/* USB HID class request code */ | |
#ifndef HID_GET_REPORT | |
#define HID_GET_REPORT 0x01 | |
#define HID_GET_IDLE 0x02 | |
#define HID_GET_PROTOCOL 0x03 | |
#define HID_SET_REPORT 0x09 | |
#define HID_SET_IDLE 0x0A | |
#define HID_SET_PROTOCOL 0x0B | |
#endif | |
/* Bit Define for USB Request Type */ | |
#ifndef USB_REQ_TYP_MASK | |
#define USB_REQ_TYP_IN 0x80 | |
#define USB_REQ_TYP_OUT 0x00 | |
#define USB_REQ_TYP_READ 0x80 | |
#define USB_REQ_TYP_WRITE 0x00 | |
#define USB_REQ_TYP_MASK 0x60 | |
#define USB_REQ_TYP_STANDARD 0x00 | |
#define USB_REQ_TYP_CLASS 0x20 | |
#define USB_REQ_TYP_VENDOR 0x40 | |
#define USB_REQ_TYP_RESERVED 0x60 | |
#define USB_REQ_RECIP_MASK 0x1F | |
#define USB_REQ_RECIP_DEVICE 0x00 | |
#define USB_REQ_RECIP_INTERF 0x01 | |
#define USB_REQ_RECIP_ENDP 0x02 | |
#define USB_REQ_RECIP_OTHER 0x03 | |
#define USB_REQ_FEAT_REMOTE_WAKEUP 0x01 | |
#define USB_REQ_FEAT_ENDP_HALT 0x00 | |
#endif | |
/* USB Descriptor Type */ | |
#ifndef USB_DESCR_TYP_DEVICE | |
#define USB_DESCR_TYP_DEVICE 0x01 | |
#define USB_DESCR_TYP_CONFIG 0x02 | |
#define USB_DESCR_TYP_STRING 0x03 | |
#define USB_DESCR_TYP_INTERF 0x04 | |
#define USB_DESCR_TYP_ENDP 0x05 | |
#define USB_DESCR_TYP_QUALIF 0x06 | |
#define USB_DESCR_TYP_SPEED 0x07 | |
#define USB_DESCR_TYP_OTG 0x09 | |
#define USB_DESCR_TYP_BOS 0X0F | |
#define USB_DESCR_TYP_HID 0x21 | |
#define USB_DESCR_TYP_REPORT 0x22 | |
#define USB_DESCR_TYP_PHYSIC 0x23 | |
#define USB_DESCR_TYP_CS_INTF 0x24 | |
#define USB_DESCR_TYP_CS_ENDP 0x25 | |
#define USB_DESCR_TYP_HUB 0x29 | |
#endif | |
/* USB Device Class */ | |
#ifndef USB_DEV_CLASS_HUB | |
#define USB_DEV_CLASS_RESERVED 0x00 | |
#define USB_DEV_CLASS_AUDIO 0x01 | |
#define USB_DEV_CLASS_COMMUNIC 0x02 | |
#define USB_DEV_CLASS_HID 0x03 | |
#define USB_DEV_CLASS_MONITOR 0x04 | |
#define USB_DEV_CLASS_PHYSIC_IF 0x05 | |
#define USB_DEV_CLASS_POWER 0x06 | |
#define USB_DEV_CLASS_PRINTER 0x07 | |
#define USB_DEV_CLASS_STORAGE 0x08 | |
#define USB_DEV_CLASS_HUB 0x09 | |
#define USB_DEV_CLASS_VEN_SPEC 0xFF | |
#endif | |
/* USB Hub Class Request */ | |
#ifndef HUB_GET_HUB_DESCRIPTOR | |
#define HUB_CLEAR_HUB_FEATURE 0x20 | |
#define HUB_CLEAR_PORT_FEATURE 0x23 | |
#define HUB_GET_BUS_STATE 0xA3 | |
#define HUB_GET_HUB_DESCRIPTOR 0xA0 | |
#define HUB_GET_HUB_STATUS 0xA0 | |
#define HUB_GET_PORT_STATUS 0xA3 | |
#define HUB_SET_HUB_DESCRIPTOR 0x20 | |
#define HUB_SET_HUB_FEATURE 0x20 | |
#define HUB_SET_PORT_FEATURE 0x23 | |
#endif | |
/* Hub Class Feature Selectors */ | |
#ifndef HUB_PORT_RESET | |
#define HUB_C_HUB_LOCAL_POWER 0 | |
#define HUB_C_HUB_OVER_CURRENT 1 | |
#define HUB_PORT_CONNECTION 0 | |
#define HUB_PORT_ENABLE 1 | |
#define HUB_PORT_SUSPEND 2 | |
#define HUB_PORT_OVER_CURRENT 3 | |
#define HUB_PORT_RESET 4 | |
#define HUB_PORT_POWER 8 | |
#define HUB_PORT_LOW_SPEED 9 | |
#define HUB_C_PORT_CONNECTION 16 | |
#define HUB_C_PORT_ENABLE 17 | |
#define HUB_C_PORT_SUSPEND 18 | |
#define HUB_C_PORT_OVER_CURRENT 19 | |
#define HUB_C_PORT_RESET 20 | |
#endif | |
/* USB HID Class Request Code */ | |
#ifndef HID_GET_REPORT | |
#define HID_GET_REPORT 0x01 | |
#define HID_GET_IDLE 0x02 | |
#define HID_GET_PROTOCOL 0x03 | |
#define HID_SET_REPORT 0x09 | |
#define HID_SET_IDLE 0x0A | |
#define HID_SET_PROTOCOL 0x0B | |
#endif | |
/* USB UDisk */ | |
#ifndef USB_BO_CBW_SIZE | |
#define USB_BO_CBW_SIZE 0x1F | |
#define USB_BO_CSW_SIZE 0x0D | |
#endif | |
#ifndef USB_BO_CBW_SIG0 | |
#define USB_BO_CBW_SIG0 0x55 | |
#define USB_BO_CBW_SIG1 0x53 | |
#define USB_BO_CBW_SIG2 0x42 | |
#define USB_BO_CBW_SIG3 0x43 | |
#define USB_BO_CSW_SIG0 0x55 | |
#define USB_BO_CSW_SIG1 0x53 | |
#define USB_BO_CSW_SIG2 0x42 | |
#define USB_BO_CSW_SIG3 0x53 | |
#endif | |
/*******************************************************************************/ | |
/* USBFS Related Register Macro Definition */ | |
/* R8_USB_CTRL */ | |
#define USBFS_UC_HOST_MODE 0x80 | |
#define USBFS_UC_LOW_SPEED 0x40 | |
#define USBFS_UC_DEV_PU_EN 0x20 | |
#define USBFS_UC_SYS_CTRL_MASK 0x30 | |
#define USBFS_UC_SYS_CTRL0 0x00 | |
#define USBFS_UC_SYS_CTRL1 0x10 | |
#define USBFS_UC_SYS_CTRL2 0x20 | |
#define USBFS_UC_SYS_CTRL3 0x30 | |
#define USBFS_UC_INT_BUSY 0x08 | |
#define USBFS_UC_RESET_SIE 0x04 | |
#define USBFS_UC_CLR_ALL 0x02 | |
#define USBFS_UC_DMA_EN 0x01 | |
/* R8_USB_INT_EN */ | |
#define USBFS_UIE_DEV_SOF 0x80 | |
#define USBFS_UIE_DEV_NAK 0x40 | |
#define USBFS_UIE_FIFO_OV 0x10 | |
#define USBFS_UIE_HST_SOF 0x08 | |
#define USBFS_UIE_SUSPEND 0x04 | |
#define USBFS_UIE_TRANSFER 0x02 | |
#define USBFS_UIE_DETECT 0x01 | |
#define USBFS_UIE_BUS_RST 0x01 | |
/* R8_USB_DEV_AD */ | |
#define USBFS_UDA_GP_BIT 0x80 | |
#define USBFS_USB_ADDR_MASK 0x7F | |
/* R8_USB_MIS_ST */ | |
#define USBFS_UMS_SOF_PRES 0x80 | |
#define USBFS_UMS_SOF_ACT 0x40 | |
#define USBFS_UMS_SIE_FREE 0x20 | |
#define USBFS_UMS_R_FIFO_RDY 0x10 | |
#define USBFS_UMS_BUS_RESET 0x08 | |
#define USBFS_UMS_SUSPEND 0x04 | |
#define USBFS_UMS_DM_LEVEL 0x02 | |
#define USBFS_UMS_DEV_ATTACH 0x01 | |
/* R8_USB_INT_FG */ | |
#define USBFS_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received | |
#define USBFS_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK | |
#define USBFS_U_SIE_FREE 0x20 // RO, indicate USB SIE free status | |
#define USBFS_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear | |
#define USBFS_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear | |
#define USBFS_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear | |
#define USBFS_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear | |
#define USBFS_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear | |
#define USBFS_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear | |
/* R8_USB_INT_ST */ | |
#define USBFS_UIS_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received for USB device mode | |
#define USBFS_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK | |
#define USBFS_UIS_TOKEN_MASK 0x30 // RO, bit mask of current token PID code received for USB device mode | |
#define USBFS_UIS_TOKEN_OUT 0x00 | |
#define USBFS_UIS_TOKEN_SOF 0x10 | |
#define USBFS_UIS_TOKEN_IN 0x20 | |
#define USBFS_UIS_TOKEN_SETUP 0x30 | |
// bUIS_TOKEN1 & bUIS_TOKEN0: current token PID code received for USB device mode | |
// 00: OUT token PID received | |
// 01: SOF token PID received | |
// 10: IN token PID received | |
// 11: SETUP token PID received | |
#define USBFS_UIS_ENDP_MASK 0x0F // RO, bit mask of current transfer endpoint number for USB device mode | |
#define USBFS_UIS_H_RES_MASK 0x0F // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received | |
/* R32_USB_OTG_CR */ | |
#define USBFS_CR_SESS_VTH 0x20 | |
#define USBFS_CR_VBUS_VTH 0x10 | |
#define USBFS_CR_OTG_EN 0x08 | |
#define USBFS_CR_IDPU 0x04 | |
#define USBFS_CR_CHARGE_VBUS 0x02 | |
#define USBFS_CR_DISCHAR_VBUS 0x01 | |
/* R32_USB_OTG_SR */ | |
#define USBFS_SR_ID_DIG 0x08 | |
#define USBFS_SR_SESS_END 0x04 | |
#define USBFS_SR_SESS_VLD 0x02 | |
#define USBFS_SR_VBUS_VLD 0x01 | |
/* R8_UDEV_CTRL */ | |
#define USBFS_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable | |
#define USBFS_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level | |
#define USBFS_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level | |
#define USBFS_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed | |
#define USBFS_UD_GP_BIT 0x02 // general purpose bit | |
#define USBFS_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable | |
/* R8_UEP4_1_MOD */ | |
#define USBFS_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT) | |
#define USBFS_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN) | |
#define USBFS_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1 | |
// bUEPn_RX_EN & bUEPn_TX_EN & bUEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA | |
// 0 0 x: disable endpoint and disable buffer | |
// 1 0 0: 64 bytes buffer for receiving (OUT endpoint) | |
// 1 0 1: dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes | |
// 0 1 0: 64 bytes buffer for transmittal (IN endpoint) | |
// 0 1 1: dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes | |
// 1 1 0: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes | |
// 1 1 1: dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes | |
#define USBFS_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT) | |
#define USBFS_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN) | |
// bUEP4_RX_EN & bUEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA | |
// 0 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) | |
// 1 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes | |
// 0 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes | |
// 1 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) | |
// + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes | |
#define USBFS_UEP4_BUF_MOD 0x01 | |
/* R8_UEP2_3_MOD */ | |
#define USBFS_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT) | |
#define USBFS_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN) | |
#define USBFS_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3 | |
#define USBFS_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT) | |
#define USBFS_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN) | |
#define USBFS_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2 | |
/* R8_UEP5_6_MOD */ | |
#define USBFS_UEP6_RX_EN 0x80 // enable USB endpoint 6 receiving (OUT) | |
#define USBFS_UEP6_TX_EN 0x40 // enable USB endpoint 6 transmittal (IN) | |
#define USBFS_UEP6_BUF_MOD 0x10 // buffer mode of USB endpoint 6 | |
#define USBFS_UEP5_RX_EN 0x08 // enable USB endpoint 5 receiving (OUT) | |
#define USBFS_UEP5_TX_EN 0x04 // enable USB endpoint 5 transmittal (IN) | |
#define USBFS_UEP5_BUF_MOD 0x01 // buffer mode of USB endpoint 5 | |
/* R8_UEP7_MOD */ | |
#define USBFS_UEP7_RX_EN 0x08 // enable USB endpoint 7 receiving (OUT) | |
#define USBFS_UEP7_TX_EN 0x04 // enable USB endpoint 7 transmittal (IN) | |
#define USBFS_UEP7_BUF_MOD 0x01 // buffer mode of USB endpoint 7 | |
/* R8_UEPn_TX_CTRL */ | |
#define USBFS_UEP_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle | |
#define USBFS_UEP_T_TOG 0x04 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1 | |
#define USBFS_UEP_T_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN) | |
#define USBFS_UEP_T_RES_ACK 0x00 | |
#define USBFS_UEP_T_RES_NONE 0x01 | |
#define USBFS_UEP_T_RES_NAK 0x02 | |
#define USBFS_UEP_T_RES_STALL 0x03 | |
// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN) | |
// 00: DATA0 or DATA1 then expecting ACK (ready) | |
// 01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions | |
// 10: NAK (busy) | |
// 11: STALL (error) | |
// host aux setup | |
/* R8_UEPn_RX_CTRL, n=0-7 */ | |
#define USBFS_UEP_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle | |
#define USBFS_UEP_R_TOG 0x04 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1 | |
#define USBFS_UEP_R_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X receiving (OUT) | |
#define USBFS_UEP_R_RES_ACK 0x00 | |
#define USBFS_UEP_R_RES_NONE 0x01 | |
#define USBFS_UEP_R_RES_NAK 0x02 | |
#define USBFS_UEP_R_RES_STALL 0x03 | |
// RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT) | |
// 00: ACK (ready) | |
// 01: no response, time out to host, for non-zero endpoint isochronous transactions | |
// 10: NAK (busy) | |
// 11: STALL (error) | |
/* R8_UHOST_CTRL */ | |
#define USBFS_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable | |
#define USBFS_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level | |
#define USBFS_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level | |
#define USBFS_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed | |
#define USBFS_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset | |
#define USBFS_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached | |
/* R32_UH_EP_MOD */ | |
#define USBFS_UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal | |
#define USBFS_UH_EP_TBUF_MOD 0x10 // buffer mode of USB host OUT endpoint | |
// bUH_EP_TX_EN & bUH_EP_TBUF_MOD: USB host OUT endpoint buffer mode, buffer start address is UH_TX_DMA | |
// 0 x: disable endpoint and disable buffer | |
// 1 0: 64 bytes buffer for transmittal (OUT endpoint) | |
// 1 1: dual 64 bytes buffer by toggle bit bUH_T_TOG selection for transmittal (OUT endpoint), total=128bytes | |
#define USBFS_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving | |
#define USBFS_UH_EP_RBUF_MOD 0x01 // buffer mode of USB host IN endpoint | |
// bUH_EP_RX_EN & bUH_EP_RBUF_MOD: USB host IN endpoint buffer mode, buffer start address is UH_RX_DMA | |
// 0 x: disable endpoint and disable buffer | |
// 1 0: 64 bytes buffer for receiving (IN endpoint) | |
// 1 1: dual 64 bytes buffer by toggle bit bUH_R_TOG selection for receiving (IN endpoint), total=128bytes | |
/* R16_UH_SETUP */ | |
#define USBFS_UH_PRE_PID_EN 0x0400 // USB host PRE PID enable for low speed device via hub | |
#define USBFS_UH_SOF_EN 0x0004 // USB host automatic SOF enable | |
/* R8_UH_EP_PID */ | |
#define USBFS_UH_TOKEN_MASK 0xF0 // bit mask of token PID for USB host transfer | |
#define USBFS_UH_ENDP_MASK 0x0F // bit mask of endpoint number for USB host transfer | |
/* R8_UH_RX_CTRL */ | |
#define USBFS_UH_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle | |
#define USBFS_UH_R_TOG 0x04 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1 | |
#define USBFS_UH_R_RES 0x01 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions | |
/* R8_UH_TX_CTRL */ | |
#define USBFS_UH_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle | |
#define USBFS_UH_T_TOG 0x04 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1 | |
#define USBFS_UH_T_RES 0x01 // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions | |
/*******************************************************************************/ | |
/* Struct Definition */ | |
/* USB Setup Request */ | |
typedef struct __attribute__((packed)) _USB_SETUP_REQ | |
{ | |
uint8_t bRequestType; | |
uint8_t bRequest; | |
uint16_t wValue; | |
uint16_t wIndex; | |
uint16_t wLength; | |
} USB_SETUP_REQ, *PUSB_SETUP_REQ; | |
/* USB Device Descriptor */ | |
typedef struct __attribute__((packed)) _USB_DEVICE_DESCR | |
{ | |
uint8_t bLength; | |
uint8_t bDescriptorType; | |
uint16_t bcdUSB; | |
uint8_t bDeviceClass; | |
uint8_t bDeviceSubClass; | |
uint8_t bDeviceProtocol; | |
uint8_t bMaxPacketSize0; | |
uint16_t idVendor; | |
uint16_t idProduct; | |
uint16_t bcdDevice; | |
uint8_t iManufacturer; | |
uint8_t iProduct; | |
uint8_t iSerialNumber; | |
uint8_t bNumConfigurations; | |
} USB_DEV_DESCR, *PUSB_DEV_DESCR; | |
/* USB Configuration Descriptor */ | |
typedef struct __attribute__((packed)) _USB_CONFIG_DESCR | |
{ | |
uint8_t bLength; | |
uint8_t bDescriptorType; | |
uint16_t wTotalLength; | |
uint8_t bNumInterfaces; | |
uint8_t bConfigurationValue; | |
uint8_t iConfiguration; | |
uint8_t bmAttributes; | |
uint8_t MaxPower; | |
} USB_CFG_DESCR, *PUSB_CFG_DESCR; | |
/* USB Interface Descriptor */ | |
typedef struct __attribute__((packed)) _USB_INTERF_DESCR | |
{ | |
uint8_t bLength; | |
uint8_t bDescriptorType; | |
uint8_t bInterfaceNumber; | |
uint8_t bAlternateSetting; | |
uint8_t bNumEndpoints; | |
uint8_t bInterfaceClass; | |
uint8_t bInterfaceSubClass; | |
uint8_t bInterfaceProtocol; | |
uint8_t iInterface; | |
} USB_ITF_DESCR, *PUSB_ITF_DESCR; | |
/* USB Endpoint Descriptor */ | |
typedef struct __attribute__((packed)) _USB_ENDPOINT_DESCR | |
{ | |
uint8_t bLength; | |
uint8_t bDescriptorType; | |
uint8_t bEndpointAddress; | |
uint8_t bmAttributes; | |
uint8_t wMaxPacketSizeL; | |
uint8_t wMaxPacketSizeH; | |
uint8_t bInterval; | |
} USB_ENDP_DESCR, *PUSB_ENDP_DESCR; | |
/* USB Configuration Descriptor Set */ | |
typedef struct __attribute__((packed)) _USB_CONFIG_DESCR_LONG | |
{ | |
USB_CFG_DESCR cfg_descr; | |
USB_ITF_DESCR itf_descr; | |
USB_ENDP_DESCR endp_descr[ 1 ]; | |
} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG; | |
/* USB HUB Descriptor */ | |
typedef struct __attribute__((packed)) _USB_HUB_DESCR | |
{ | |
uint8_t bDescLength; | |
uint8_t bDescriptorType; | |
uint8_t bNbrPorts; | |
uint8_t wHubCharacteristicsL; | |
uint8_t wHubCharacteristicsH; | |
uint8_t bPwrOn2PwrGood; | |
uint8_t bHubContrCurrent; | |
uint8_t DeviceRemovable; | |
uint8_t PortPwrCtrlMask; | |
} USB_HUB_DESCR, *PUSB_HUB_DESCR; | |
/* USB HID Descriptor */ | |
typedef struct __attribute__((packed)) _USB_HID_DESCR | |
{ | |
uint8_t bLength; | |
uint8_t bDescriptorType; | |
uint16_t bcdHID; | |
uint8_t bCountryCode; | |
uint8_t bNumDescriptors; | |
uint8_t bDescriptorTypeX; | |
uint8_t wDescriptorLengthL; | |
uint8_t wDescriptorLengthH; | |
} USB_HID_DESCR, *PUSB_HID_DESCR; | |
/* USB UDisk */ | |
typedef struct __attribute__((packed)) _UDISK_BOC_CBW | |
{ | |
uint32_t mCBW_Sig; | |
uint32_t mCBW_Tag; | |
uint32_t mCBW_DataLen; | |
uint8_t mCBW_Flag; | |
uint8_t mCBW_LUN; | |
uint8_t mCBW_CB_Len; | |
uint8_t mCBW_CB_Buf[ 16 ]; | |
} UDISK_BOC_CBW, *PXUDISK_BOC_CBW; | |
/* USB UDisk */ | |
typedef struct __attribute__((packed)) _UDISK_BOC_CSW | |
{ | |
uint32_t mCBW_Sig; | |
uint32_t mCBW_Tag; | |
uint32_t mCSW_Residue; | |
uint8_t mCSW_Status; | |
} UDISK_BOC_CSW, *PXUDISK_BOC_CSW; | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif /* __CH32V20x_USB_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ch32v20x_usb.h" | |
#include "ch32v20x.h" //from SDK | |
#include "common/tusb_common.h" | |
#include "common/tusb_types.h" | |
#include "common/tusb_debug.h" | |
#include "hcd.h" | |
#include <assert.h> | |
typedef struct | |
{ | |
uint8_t *buffer; | |
uint16_t buffer_len; | |
uint16_t buffer_transfered; | |
uint8_t ep_addr; | |
uint8_t dev_addr; | |
} pipe; | |
pipe pipes[5][10] = {0}; | |
#define WCHX_DEBUG(...) TU_LOG(2, __VA_ARGS__) | |
#define WCHX_TRACE(...) TU_LOG(3, __VA_ARGS__) | |
const uint8_t USB_INTERRUPTS = USBFS_UIE_DETECT | USBFS_UIE_TRANSFER; | |
bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) | |
{ | |
WCHX_TRACE("hcd_configure\n"); | |
(void) rhport; | |
return true; | |
} | |
bool hcd_init(uint8_t rhport) | |
{ | |
WCHX_TRACE("hcd_init\n"); | |
(void) rhport; | |
if( SystemCoreClock == 144000000 ) | |
{ | |
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div3 ); | |
} | |
else if( SystemCoreClock == 96000000 ) | |
{ | |
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div2 ); | |
} | |
else if( SystemCoreClock == 48000000 ) | |
{ | |
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div1 ); | |
} | |
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_OTG_FS, ENABLE ); | |
USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL; | |
Delay_Us( 10 ); | |
USBOTG_H_FS->BASE_CTRL = 0; | |
USBOTG_H_FS->BASE_CTRL = USBFS_UC_HOST_MODE | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN; | |
USBOTG_H_FS->HOST_EP_MOD = USBFS_UH_EP_TX_EN | USBFS_UH_EP_RX_EN; | |
USBOTG_H_FS->HOST_RX_DMA = (uint32_t)0; | |
USBOTG_H_FS->HOST_TX_DMA = (uint32_t)0; | |
USBOTG_H_FS->INT_EN |= USB_INTERRUPTS; | |
NVIC_EnableIRQ(USBHD_IRQn); | |
return true; | |
} | |
void hcd_port_reset(uint8_t rhport) | |
{ | |
USBOTG_H_FS->DEV_ADDR = USBOTG_H_FS->DEV_ADDR & USBFS_UD_GP_BIT; | |
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_BUS_RESET; | |
Delay_Ms(15); | |
USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_BUS_RESET; | |
Delay_Ms(2); | |
if((USBOTG_H_FS->HOST_CTRL & USBFS_UH_PORT_EN) == 0) | |
{ | |
if(USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL) | |
{ | |
USBOTG_H_FS->BASE_CTRL |= USBFS_UC_LOW_SPEED; | |
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_LOW_SPEED; | |
USBOTG_H_FS->HOST_SETUP |= USBFS_UH_PRE_PID_EN; | |
} | |
} | |
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN; | |
USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN; | |
} | |
void hcd_port_reset_end(uint8_t rhport) | |
{ | |
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT; | |
USBOTG_H_FS->INT_EN |= USB_INTERRUPTS; | |
} | |
tusb_speed_t hcd_port_speed_get(uint8_t rhport) | |
{ | |
WCHX_TRACE("hcd_port_speed_get\n"); | |
return (USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; | |
} | |
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) | |
{ | |
WCHX_TRACE("hcd_edpt_open dev_addr %d, ep_addr %d\n", dev_addr, desc_ep->bEndpointAddress); | |
USBOTG_H_FS->DEV_ADDR = (USBOTG_H_FS->DEV_ADDR & USBFS_UD_GP_BIT) | (dev_addr & USBFS_USB_ADDR_MASK); | |
return true; | |
} | |
void osal_task_delay(uint32_t msec) | |
{ | |
Delay_Ms(msec); | |
} | |
bool hcd_port_connect_status(uint8_t rhport) | |
{ | |
bool status = USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH; | |
WCHX_TRACE("hcd_port_connect_status: %d\n", status); | |
return status; | |
} | |
void hcd_device_close(uint8_t rhport, uint8_t dev_addr) | |
{ | |
WCHX_TRACE("hcd_device_close %d\n", dev_addr); | |
(void) rhport; | |
} | |
void hcd_int_enable(uint8_t rhport) | |
{ | |
(void) rhport; | |
} | |
void hcd_int_disable(uint8_t rhport) | |
{ | |
(void) rhport; | |
} | |
void wch_usb_start_transact( uint8_t endp_pid, uint8_t endp_tog) | |
{ | |
USBOTG_H_FS->HOST_TX_CTRL = USBOTG_H_FS->HOST_RX_CTRL = endp_tog; | |
USBOTG_H_FS->HOST_EP_PID = endp_pid; // Specify token PID and endpoint number | |
USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER; // Allow transfer | |
} | |
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) | |
{ | |
(void) rhport; | |
WCHX_TRACE("hcd_setup_send dev_addr %d\n", dev_addr); | |
pipe* pipe_current = &pipes[USBOTG_H_FS->DEV_ADDR & USBFS_USB_ADDR_MASK][0]; | |
pipe_current->buffer = NULL; | |
pipe_current->buffer_len = 8; | |
pipe_current->buffer_transfered = 0; | |
pipe_current->dev_addr = dev_addr; | |
pipe_current->ep_addr = 0; | |
USBOTG_H_FS->HOST_TX_LEN = sizeof( USB_SETUP_REQ ); | |
USBOTG_H_FS->HOST_TX_DMA = (uint32_t)setup_packet; | |
wch_usb_start_transact( ( USB_PID_SETUP << 4 ) | 0x0, 0); | |
return true; | |
} | |
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) | |
{ | |
WCHX_TRACE("hcd_edpt_xfer dev_addr %d, ep_addr 0x%x, len %d\n", dev_addr, ep_addr, buflen); | |
if(tu_edpt_dir(ep_addr) == TUSB_DIR_IN) | |
{ | |
pipe* pipe_current = &pipes[USBOTG_H_FS->DEV_ADDR & USBFS_USB_ADDR_MASK][ep_addr & USBFS_USB_ADDR_MASK]; | |
pipe_current->buffer = buffer; | |
pipe_current->buffer_len = buflen; | |
pipe_current->buffer_transfered = 0; | |
pipe_current->dev_addr = dev_addr; | |
pipe_current->ep_addr = ep_addr; | |
USBOTG_H_FS->HOST_RX_DMA = (uint32_t)buffer; | |
if(!(ep_addr & USBFS_USB_ADDR_MASK)) | |
{ | |
USBOTG_H_FS->HOST_TX_CTRL = USBOTG_H_FS->HOST_RX_CTRL = USBFS_UH_T_TOG; | |
} | |
wch_usb_start_transact( ( USB_PID_IN << 4 ) | (ep_addr & USBFS_USB_ADDR_MASK), USBOTG_H_FS->HOST_RX_CTRL); | |
} | |
else | |
{ | |
USBOTG_H_FS->HOST_TX_DMA = (uint32_t)buffer; | |
USBOTG_H_FS->HOST_TX_LEN = buflen; | |
wch_usb_start_transact( ( USB_PID_OUT << 4 ) | (ep_addr & 0x7F), USBOTG_H_FS->HOST_TX_CTRL); | |
} | |
return true; | |
} | |
__INTERRUPT | |
void USBHD_IRQHandler() | |
{ | |
if(USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT) | |
{ | |
if(USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH) | |
{ | |
USBOTG_H_FS->INT_EN = USBOTG_H_FS->INT_EN & ~USBFS_UIE_DETECT; | |
hcd_event_device_attach(0, true); | |
} | |
else | |
{ | |
hcd_event_device_remove(0, true); | |
} | |
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT; | |
} | |
if(USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER) | |
{ | |
if(USBOTG_H_FS->INT_ST & USBFS_UIS_TOG_OK) | |
{ | |
USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER; | |
uint8_t epPID = USBOTG_H_FS->HOST_EP_PID; | |
USBOTG_H_FS->HOST_EP_PID = 0x00; | |
uint8_t ep_addr = epPID & 0xf; | |
pipe* pipe_current = &pipes[USBOTG_H_FS->DEV_ADDR][ep_addr]; | |
switch(epPID >> 4) | |
{ | |
case USB_PID_SETUP: | |
case USB_PID_OUT: | |
hcd_event_xfer_complete(pipe_current->dev_addr, pipe_current->ep_addr, pipe_current->buffer_len, XFER_RESULT_SUCCESS, true); | |
break; | |
case USB_PID_IN: | |
USBOTG_H_FS->HOST_RX_CTRL ^= USBFS_UH_T_TOG; | |
pipe_current->buffer_transfered += USBOTG_H_FS->RX_LEN; | |
if(pipe_current->buffer_transfered >= pipe_current->buffer_len) | |
{ | |
hcd_event_xfer_complete(pipe_current->dev_addr, pipe_current->ep_addr, pipe_current->buffer_len, XFER_RESULT_SUCCESS, true); | |
} | |
else | |
{ | |
USBOTG_H_FS->HOST_RX_DMA = (uint32_t)(pipe_current->buffer + pipe_current->buffer_transfered); | |
wch_usb_start_transact(epPID, USBOTG_H_FS->HOST_RX_CTRL); | |
} | |
break; | |
default: | |
WCHX_TRACE("--USB_PID_WHAT: %02x\n", epPID >> 4); | |
break; | |
} | |
} | |
else | |
{ | |
USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER; | |
uint8_t epPID = USBOTG_H_FS->HOST_EP_PID; | |
USBOTG_H_FS->HOST_EP_PID = 0x00; | |
uint8_t ep_addr = epPID & 0xf; | |
pipe* pipe_current = &pipes[USBOTG_H_FS->DEV_ADDR][ep_addr]; | |
hcd_event_xfer_complete(pipe_current->dev_addr, pipe_current->ep_addr, pipe_current->buffer_len, XFER_RESULT_FAILED, true); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The MIT License (MIT) | |
* | |
* Copyright (c) 2019 Ha Thach (tinyusb.org) | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy | |
* of this software and associated documentation files (the "Software"), to deal | |
* in the Software without restriction, including without limitation the rights | |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the Software is | |
* furnished to do so, subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in | |
* all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
* THE SOFTWARE. | |
* | |
*/ | |
#pragma once | |
#define OPT_MCU_CH20x 2298 | |
#define OPT_MCU_CH58x 2299 | |
#define CFG_TUSB_MCU OPT_MCU_CH20x | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
// RHPort number used for host can be defined by board.mk, default to port 0 | |
#ifndef BOARD_TUH_RHPORT | |
#define BOARD_TUH_RHPORT 0 | |
#endif | |
// RHPort max operational speed can defined by board.mk | |
#ifndef BOARD_TUH_MAX_SPEED | |
#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED | |
#endif | |
//-------------------------------------------------------------------- | |
// COMMON CONFIGURATION | |
//-------------------------------------------------------------------- | |
// defined by compiler flags for flexibility | |
#ifndef CFG_TUSB_MCU | |
#error CFG_TUSB_MCU must be defined | |
#endif | |
#ifndef CFG_TUSB_OS | |
#define CFG_TUSB_OS OPT_OS_NONE | |
#endif | |
#ifndef CFG_TUSB_DEBUG | |
#define CFG_TUSB_DEBUG 5 | |
#endif | |
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST | |
// Default is max speed that hardware controller could support with on-chip PHY | |
#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED | |
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. | |
* Tinyusb use follows macros to declare transferring memory so that they can be put | |
* into those specific section. | |
* e.g | |
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) | |
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) | |
*/ | |
#ifndef CFG_TUSB_MEM_SECTION | |
#define CFG_TUSB_MEM_SECTION | |
#endif | |
#ifndef CFG_TUSB_MEM_ALIGN | |
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) | |
#endif | |
//-------------------------------------------------------------------- | |
// CONFIGURATION | |
//-------------------------------------------------------------------- | |
// Size of buffer to hold descriptors and other data used for enumeration | |
#define CFG_TUH_ENUMERATION_BUFSIZE 512 | |
#define CFG_TUH_HUB 0 | |
#define CFG_TUH_CDC 0 | |
#define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces | |
#define CFG_TUH_MSC 0 | |
#define CFG_TUH_VENDOR 0 | |
#define TUP_DCD_ENDPOINT_MAX 8 | |
// max device support (excluding hub device) | |
// 1 hub typically has 4 ports | |
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) | |
//------------- HID -------------// | |
#define CFG_TUH_HID_EP_BUFSIZE 64 | |
#ifdef __cplusplus | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment