cmake_cpputest_template/inc/extralibs/hsusb.h
2025-12-23 14:33:54 -08:00

475 lines
13 KiB
C

#ifndef _HSUSB_H
#define _HSUSB_H
#include <stdint.h>
#include "ch32fun.h"
#include "usb_defines.h"
#include "usb_config.h"
#if !defined(CH584_CH585) && !defined(CH32V205) && !defined(CH32H4xx) && !defined(CH32V30x) && !defined(CH565_CH569)
#error "This lib doesn't work on this MCU"
#endif
#if defined(CH32V30x) || defined(CH565_CH569)
#define USBHS_IMPL 1
// #elif defined(CH584_CH585) || defined(CH32V205) || defined(CH32H4xx)
#else
#define USBHS_IMPL 2
#endif
#ifndef __HIGH_CODE
#define __HIGH_CODE
#endif
#ifndef USBHS_BASE
#if defined(CH32V30x) || defined(CH32V205)
#define USBHS_BASE (0x40023400)
#elif defined(CH32H4xx)
#define USBHS_BASE (0x40030000)
#else
#define USBHS_BASE (0x40009000)
#endif
#endif
#if (USBHS_IMPL==1)
#if (FUNCONF_USE_HSI) && !defined(FUSB_SOF_HSITRIM)
#define FUSB_SOF_HSITRIM 1
#endif
#define TICKS_PER_HSITRIM (FUNCONF_PLL_MULTIPLIER * 20000 * 125) / 1000000 // SOF is sent every 125uS, each HSITRIM changes HSI by 20kHz
typedef struct
{
__IO uint8_t BASE_CTRL;
__IO uint8_t HOST_CTRL;
__IO uint8_t INT_EN;
__IO uint8_t DEV_AD;
__IO uint16_t FRAME_NO;
__IO uint8_t SUSPEND;
__IO uint8_t RESERVED0;
__IO uint8_t SPEED_TYPE;
__IO uint8_t MIS_ST;
__IO uint8_t INT_FG;
__IO uint8_t INT_ST;
__IO uint16_t RX_LEN;
__IO uint16_t RESERVED1;
__IO uint32_t UEP_CONFIG;
__IO uint32_t UEP_TYPE;
__IO uint32_t UEP_BUF_MODE;
__IO uint32_t UEP0_DMA;
__IO uint32_t UEP1_RX_DMA;
__IO uint32_t UEP2_RX_DMA;
__IO uint32_t UEP3_RX_DMA;
__IO uint32_t UEP4_RX_DMA;
__IO uint32_t UEP5_RX_DMA;
__IO uint32_t UEP6_RX_DMA;
__IO uint32_t UEP7_RX_DMA;
__IO uint32_t UEP8_RX_DMA;
__IO uint32_t UEP9_RX_DMA;
__IO uint32_t UEP10_RX_DMA;
__IO uint32_t UEP11_RX_DMA;
__IO uint32_t UEP12_RX_DMA;
__IO uint32_t UEP13_RX_DMA;
__IO uint32_t UEP14_RX_DMA;
__IO uint32_t UEP15_RX_DMA;
__IO uint32_t UEP1_TX_DMA;
__IO uint32_t UEP2_TX_DMA;
__IO uint32_t UEP3_TX_DMA;
__IO uint32_t UEP4_TX_DMA;
__IO uint32_t UEP5_TX_DMA;
__IO uint32_t UEP6_TX_DMA;
__IO uint32_t UEP7_TX_DMA;
__IO uint32_t UEP8_TX_DMA;
__IO uint32_t UEP9_TX_DMA;
__IO uint32_t UEP10_TX_DMA;
__IO uint32_t UEP11_TX_DMA;
__IO uint32_t UEP12_TX_DMA;
__IO uint32_t UEP13_TX_DMA;
__IO uint32_t UEP14_TX_DMA;
__IO uint32_t UEP15_TX_DMA;
__IO uint16_t UEP0_MAX_LEN;
__IO uint16_t RESERVED2;
__IO uint16_t UEP1_MAX_LEN;
__IO uint16_t RESERVED3;
__IO uint16_t UEP2_MAX_LEN;
__IO uint16_t RESERVED4;
__IO uint16_t UEP3_MAX_LEN;
__IO uint16_t RESERVED5;
__IO uint16_t UEP4_MAX_LEN;
__IO uint16_t RESERVED6;
__IO uint16_t UEP5_MAX_LEN;
__IO uint16_t RESERVED7;
__IO uint16_t UEP6_MAX_LEN;
__IO uint16_t RESERVED8;
__IO uint16_t UEP7_MAX_LEN;
__IO uint16_t RESERVED9;
__IO uint16_t UEP8_MAX_LEN;
__IO uint16_t RESERVED10;
__IO uint16_t UEP9_MAX_LEN;
__IO uint16_t RESERVED11;
__IO uint16_t UEP10_MAX_LEN;
__IO uint16_t RESERVED12;
__IO uint16_t UEP11_MAX_LEN;
__IO uint16_t RESERVED13;
__IO uint16_t UEP12_MAX_LEN;
__IO uint16_t RESERVED14;
__IO uint16_t UEP13_MAX_LEN;
__IO uint16_t RESERVED15;
__IO uint16_t UEP14_MAX_LEN;
__IO uint16_t RESERVED16;
__IO uint16_t UEP15_MAX_LEN;
__IO uint16_t RESERVED17;
__IO uint16_t UEP0_T_LEN;
__IO uint8_t UEP0_TX_CTRL;
__IO uint8_t UEP0_RX_CTRL;
__IO uint16_t UEP1_T_LEN;
__IO uint8_t UEP1_TX_CTRL;
__IO uint8_t UEP1_RX_CTRL;
__IO uint16_t UEP2_T_LEN;
__IO uint8_t UEP2_TX_CTRL;
__IO uint8_t UEP2_RX_CTRL;
__IO uint16_t UEP3_T_LEN;
__IO uint8_t UEP3_TX_CTRL;
__IO uint8_t UEP3_RX_CTRL;
__IO uint16_t UEP4_T_LEN;
__IO uint8_t UEP4_TX_CTRL;
__IO uint8_t UEP4_RX_CTRL;
__IO uint16_t UEP5_T_LEN;
__IO uint8_t UEP5_TX_CTRL;
__IO uint8_t UEP5_RX_CTRL;
__IO uint16_t UEP6_T_LEN;
__IO uint8_t UEP6_TX_CTRL;
__IO uint8_t UEP6_RX_CTRL;
__IO uint16_t UEP7_T_LEN;
__IO uint8_t UEP7_TX_CTRL;
__IO uint8_t UEP7_RX_CTRL;
__IO uint16_t UEP8_T_LEN;
__IO uint8_t UEP8_TX_CTRL;
__IO uint8_t UEP8_RX_CTRL;
__IO uint16_t UEP9_T_LEN;
__IO uint8_t UEP9_TX_CTRL;
__IO uint8_t UEP9_RX_CTRL;
__IO uint16_t UEP10_T_LEN;
__IO uint8_t UEP10_TX_CTRL;
__IO uint8_t UEP10_RX_CTRL;
__IO uint16_t UEP11_T_LEN;
__IO uint8_t UEP11_TX_CTRL;
__IO uint8_t UEP11_RX_CTRL;
__IO uint16_t UEP12_T_LEN;
__IO uint8_t UEP12_TX_CTRL;
__IO uint8_t UEP12_RX_CTRL;
__IO uint16_t UEP13_T_LEN;
__IO uint8_t UEP13_TX_CTRL;
__IO uint8_t UEP13_RX_CTRL;
__IO uint16_t UEP14_T_LEN;
__IO uint8_t UEP14_TX_CTRL;
__IO uint8_t UEP14_RX_CTRL;
__IO uint16_t UEP15_T_LEN;
__IO uint8_t UEP15_TX_CTRL;
__IO uint8_t UEP15_RX_CTRL;
} USBHS_TypeDef;
#define USBHS_CHECK_NAK_RX (USBHS->INT_ST & 0x80)
#define CRB_U_IS_NAK (1<<7)
#define CTOG_MATCH_SYNC (1<<6)
#define CRB_UIF_SETUP_ACT (1<<5) // CRB_U_SIE_FREE on USBFS
#define CRB_UIF_FIFO_OV (1<<4)
#define CRB_UIF_HST_SOF (1<<3)
#define CRB_UIF_SUSPEND (1<<2)
#define CRB_UIF_TRANSFER (1<<1)
#define CRB_UIF_BUS_RST (1<<0)
#define CSETUP_ACT (1<<15)
#define CRB_UIS_TOG_OK (1<<14)
#define CMASK_UIS_TOKEN (3<<12)
#define CMASK_UIS_ENDP (0xf<<8)
#define CUIS_TOKEN_OUT 0x0
#define CUIS_TOKEN_SOF 0x1
#define CUIS_TOKEN_IN 0x2
#define CUIS_TOKEN_SETUP 0x3
#define UEP_TX_EN(n) USBHS->UEP_CONFIG |= ((uint32_t)(1<<n))
#define UEP_RX_EN(n) USBHS->UEP_CONFIG |= ((uint32_t)(1<<(n+16)))
#define USBHS_DONE_TX(n)
#define USBHS_DONE_RX(n)
#elif (USBHS_IMPL==2)
typedef struct
{
__IO uint8_t BASE_CTRL;
__IO uint8_t BASE_MODE;
__IO uint8_t INT_EN;
__IO uint8_t DEV_AD;
__IO uint8_t WAKE_CTRL;
__IO uint8_t TEST_MODE;
__IO uint16_t LPM_DATA;
__IO uint8_t INT_FG; // "Combined" register in some situations. (ST_FG)
__IO uint8_t INT_ST;
__IO uint8_t MIS_ST;
__IO uint16_t FRAME_NO;
__IO uint16_t BUS;
__IO uint16_t UEP_TX_EN;
__IO uint16_t UEP_RX_EN;
__IO uint16_t UEP_T_TOG_AUTO;
__IO uint16_t UEP_R_TOG_AUTO;
__IO uint8_t UEP_T_BURST;
__IO uint8_t UEP_T_BURST_MODE;
__IO uint8_t UEP_R_BURST;
__IO uint8_t UEP_R_RES_MODE;
__IO uint32_t UEP_AF_MODE;
__IO uint32_t UEP0_DMA;
__IO uint32_t UEP1_RX_DMA;
__IO uint32_t UEP2_RX_DMA;
__IO uint32_t UEP3_RX_DMA;
__IO uint32_t UEP4_RX_DMA;
__IO uint32_t UEP5_RX_DMA;
__IO uint32_t UEP6_RX_DMA;
__IO uint32_t UEP7_RX_DMA;
__IO uint32_t UEP1_TX_DMA;
__IO uint32_t UEP2_TX_DMA;
__IO uint32_t UEP3_TX_DMA;
__IO uint32_t UEP4_TX_DMA;
__IO uint32_t UEP5_TX_DMA;
__IO uint32_t UEP6_TX_DMA;
__IO uint32_t UEP7_TX_DMA;
__IO uint32_t UEP0_MAX_LEN;
__IO uint32_t UEP1_MAX_LEN;
__IO uint32_t UEP2_MAX_LEN;
__IO uint32_t UEP3_MAX_LEN;
__IO uint32_t UEP4_MAX_LEN;
__IO uint32_t UEP5_MAX_LEN;
__IO uint32_t UEP6_MAX_LEN;
__IO uint32_t UEP7_MAX_LEN;
__IO uint16_t UEP0_RX_LEN;
__IO uint16_t reserved;
__IO uint16_t UEP1_RX_LEN;
__IO uint16_t UEP1_R_SIZE;
__IO uint16_t UEP2_RX_LEN;
__IO uint16_t UEP2_R_SIZE;
__IO uint16_t UEP3_RX_LEN;
__IO uint16_t UEP3_R_SIZE;
__IO uint16_t UEP4_RX_LEN;
__IO uint16_t UEP4_R_SIZE;
__IO uint16_t UEP5_RX_LEN;
__IO uint16_t UEP5_R_SIZE;
__IO uint16_t UEP6_RX_LEN;
__IO uint16_t UEP6_R_SIZE;
__IO uint16_t UEP7_RX_LEN;
__IO uint16_t UEP7_R_SIZE;
__IO uint16_t UEP0_T_LEN;
__IO uint8_t UEP0_TX_CTRL;
__IO uint8_t UEP0_RX_CTRL;
__IO uint16_t UEP1_T_LEN;
__IO uint8_t UEP1_TX_CTRL;
__IO uint8_t UEP1_RX_CTRL;
__IO uint16_t UEP2_T_LEN;
__IO uint8_t UEP2_TX_CTRL;
__IO uint8_t UEP2_RX_CTRL;
__IO uint16_t UEP3_T_LEN;
__IO uint8_t UEP3_TX_CTRL;
__IO uint8_t UEP3_RX_CTRL;
__IO uint16_t UEP4_T_LEN;
__IO uint8_t UEP4_TX_CTRL;
__IO uint8_t UEP4_RX_CTRL;
__IO uint16_t UEP5_T_LEN;
__IO uint8_t UEP5_TX_CTRL;
__IO uint8_t UEP5_RX_CTRL;
__IO uint16_t UEP6_T_LEN;
__IO uint8_t UEP6_TX_CTRL;
__IO uint8_t UEP6_RX_CTRL;
__IO uint16_t UEP7_T_LEN;
__IO uint8_t UEP7_TX_CTRL;
__IO uint8_t UEP7_RX_CTRL;
__IO uint16_t UEP_T_ISO;
__IO uint16_t UEP_R_ISO;
} USBHS_TypeDef;
#define USBHS_CHECK_NAK_RX (USBHS->UEP0_RX_CTRL & (1<<6))
#define UEP_RX_LEN(n) (((volatile uint16_t*)&USBHS->UEP1_RX_LEN)[(n-1)*2])
#define UEP_TX_EN(n) USBHS->UEP_TX_EN |= ((uint16_t)(1<<n))
#define UEP_RX_EN(n) USBHS->UEP_RX_EN |= ((uint16_t)(1<<n))
#define DEBUG_PIN PB17
#define TEST_ENABLE 0x01
#define TEST_MASK 0x0F
#define USBHS_UMS_SUSPEND (1<<1)
#define USBHS_UC_RESET_SIE (1<<1)
#define USBHS_UC_CLR_ALL (1<<2)
#define USBHS_UC_DMA_EN (1<<4)
#define USBHS_UC_PORT_EN (1<<5)
#define USBHS_UIE_SUSPEND (1<<1)
#define USBHS_UIE_TRANSFER (1<<4)
#define USBHS_UIE_BUS_RST (1<<0)
// Mask for the combined USBHS->INT_FG + USBHS->INT_ST
#define CRB_UIF_FIFO_OV (1<<7)
#define CRB_UIF_LINK_RDY (1<<6)
#define CRB_UIF_RX_SOF (1<<5)
#define CRB_UIF_TRANSFER (1<<4)
#define CRB_UIF_LPM_ACT (1<<3)
#define CRB_UIF_BUS_SLEEP (1<<2)
#define CRB_UIF_SUSPEND (1<<1)
#define CRB_UIF_BUS_RST (1<<0)
#define CMASK_UIS_TOKEN (1<<12)
#define CMASK_UIS_ENDP (7<<8)
#define CUIS_TOKEN_OUT 0x0
#define CUIS_TOKEN_IN 0x1
#define USBHS_DONE_TX(n) UEP_CTRL_TX(n) &= ~(USBHS_UEP_T_DONE)
#define USBHS_DONE_RX(n) UEP_CTRL_RX(n) &= ~(USBHS_UEP_R_DONE)
#endif
#define USBHS_SPEED_TYPE_MASK ((uint8_t)(0x03))
#define USBHS_DEF_UEP_IN 0x80
#define USBHS_DEF_UEP_OUT 0x00
#define USBHS_DEF_UEP_BUSY 0x01
#define USBHS_DEF_UEP_FREE 0x00
#define USBHS_NUM_EP 8
#define USBHS_DEF_UEP0 0
#define USBHS_DEF_UEP1 1
#define USBHS_DEF_UEP2 2
#define USBHS_DEF_UEP3 3
#define USBHS_DEF_UEP4 4
#define USBHS_DEF_UEP5 5
#define USBHS_DEF_UEP6 6
#define USBHS_DEF_UEP7 7
#define USBHS_DEF_UEP8 8
#define USBHS_DEF_UEP9 9
#define USBHS_DEF_UEP10 10
#define USBHS_DEF_UEP11 11
#define USBHS_DEF_UEP12 12
#define USBHS_DEF_UEP13 13
#define USBHS_DEF_UEP14 14
#define USBHS_DEF_UEP15 15
#define USBHS_DEF_UEP0_SIZE 64
#ifndef FUSB_EP_SIZE
#define USBHS_UEP_SIZE 64
#else
#define USBHS_UEP_SIZE FUSB_EP_SIZE
#endif
#define UEP_CTRL_LEN(n) (((volatile uint16_t*)&USBHS->UEP0_T_LEN)[n*2])
#define UEP_CTRL_TX(n) (((volatile uint8_t*)&USBHS->UEP0_TX_CTRL)[n*4])
#define UEP_CTRL_RX(n) (((volatile uint8_t*)&USBHS->UEP0_RX_CTRL)[n*4])
#define UEP_DMA_RX(n) (((volatile uint32_t*)&USBHS->UEP0_DMA)[n])
#define UEP_DMA_TX(n) (((volatile uint32_t*)&USBHS->UEP1_TX_DMA)[n-1])
#define USBHS ((USBHS_TypeDef *)USBHS_BASE)
extern uint32_t USBDEBUG0, USBDEBUG1, USBDEBUG2;
struct _USBState;
// Provided functions:
int USBHSSetup();
static inline int USBHS_SendEndpointNEW( int endp, const uint8_t* data, int len, int copy);
static inline uint8_t * USBHS_GetEPBufferIfAvailable( int endp );
static inline int USBHS_SendEndpoint( int endp, int len );
static inline int USBHS_SendACK( int endp, int tx );
static inline int USBHS_SendNAK( int endp, int tx );
// Implement the following:
#if FUSB_HID_USER_REPORTS
__HIGH_CODE int HandleHidUserGetReportSetup( struct _USBState * ctx, tusb_control_request_t * req );
__HIGH_CODE int HandleHidUserSetReportSetup( struct _USBState * ctx, tusb_control_request_t * req );
void HandleHidUserReportDataOut( struct _USBState * ctx, uint8_t * data, int len );
int HandleHidUserReportDataIn( struct _USBState * ctx, uint8_t * data, int len );
void HandleHidUserReportOutComplete( struct _USBState * ctx );
#endif
#if FUSB_USER_HANDLERS
__HIGH_CODE int HandleInRequest( struct _USBState * ctx, int endp, uint8_t * data, int len );
__HIGH_CODE void HandleDataOut( struct _USBState * ctx, int endp, uint8_t * data, int len );
__HIGH_CODE int HandleSetupCustom( struct _USBState * ctx, int setup_code);
#endif
#if FUSB_OUT_FLOW_CONTROL > 0
void USBHS_RxReady(int endp);
#endif
typedef enum
{
USB_SPEED_FULL = 0,
USB_SPEED_HIGH = 1,
USB_SPEED_LOW = 2,
} USB_SPEED_t;
typedef enum
{
USBHS_EP_OFF = 0,
USBHS_EP_RX = -1,
USBHS_EP_TX = 1,
} USBHS_EP_mode;
#ifndef FUSB_EP1_MODE
#define FUSB_EP1_MODE 0
#endif
#ifndef FUSB_EP2_MODE
#define FUSB_EP2_MODE 0
#endif
#ifndef FUSB_EP3_MODE
#define FUSB_EP3_MODE 0
#endif
#ifndef FUSB_EP4_MODE
#define FUSB_EP4_MODE 0
#endif
#ifndef FUSB_EP5_MODE
#define FUSB_EP5_MODE 0
#endif
#ifndef FUSB_EP6_MODE
#define FUSB_EP6_MODE 0
#endif
#ifndef FUSB_EP7_MODE
#define FUSB_EP7_MODE 0
#endif
struct _USBState
{
__attribute__ ((aligned(4))) uint8_t CTRL0BUFF[64];
__attribute__ ((aligned(4))) uint8_t ENDPOINTS[FUSB_CONFIG_EPS-1][FUSB_EP_SIZE];
// Setup Request
uint8_t USBHS_SetupReqCode;
uint8_t USBHS_SetupReqType;
uint16_t USBHS_SetupReqLen; // Used for tracking place along send.
uint32_t USBHS_IndexValue;
// USB Device Status
uint8_t USBHS_DevConfig;
uint8_t USBHS_DevAddr;
uint8_t USBHS_DevSleepStatus;
uint8_t USBHS_DevEnumStatus;
uint8_t* pCtrlPayloadPtr;
USBHS_EP_mode endpoint_mode[FUSB_CONFIG_EPS+1]; // IN -1, OUT 1, OFF 0
#define pUSBHS_SetupReqPak ((tusb_control_request_t*)USBHSCTX.CTRL0BUFF)
#if FUSB_HID_INTERFACES > 0
uint8_t USBHS_HidIdle[FUSB_HID_INTERFACES];
uint8_t USBHS_HidProtocol[FUSB_HID_INTERFACES];
#endif
volatile uint8_t USBHS_Endp_Busy[FUSB_CONFIG_EPS];
volatile uint8_t USBHS_errata_dont_send_endpoint_in_window;
volatile uint64_t USBHS_sof_timestamp;
};
extern struct _USBState USBHSCTX;
#include "hsusb.c"
#endif