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

419 lines
12 KiB
C

#ifndef _FSUSB_H
#define _FSUSB_H
#include <stdint.h>
#include "ch32fun.h"
#include "usb_defines.h"
#include "usb_config.h"
#if defined(FUSB_FROM_RAM) && (FUSB_FROM_RAM)
#if defined(CH5xx)
#define __USBFS_FUN_ATTRIBUTE __attribute__((section(".srodata"), used))
#else
#define __USBFS_FUN_ATTRIBUTE
#endif
#else
#define __USBFS_FUN_ATTRIBUTE
#endif
#if defined(CH5xx) || defined(CH32X03x) || defined(CH32V10x)
#if !defined (CH32X03x) && !defined(CH32V10x)
#define USBFS_BASE USB_BASE_ADDR
typedef struct
{
__IO uint8_t BASE_CTRL;
__IO uint8_t UDEV_CTRL;
__IO uint8_t INT_EN;
__IO uint8_t DEV_ADDR;
__IO uint8_t USB_STATUS;
__IO uint8_t MIS_ST;
__IO uint8_t INT_FG; // "Combined" register in some situations. (ST_FG)
__IO uint8_t INT_ST;
__IO uint8_t RX_LEN;
__IO uint8_t Reserved0;
__IO uint16_t Reserved1;
__IO uint8_t UEP4_1_MOD;
__IO uint8_t UEP2_3_MOD;
__IO uint8_t UEP567_MOD;
__IO uint8_t Reserved2;
__IO uint16_t UEP0_DMA;
__IO uint16_t Reserved3;
__IO uint16_t UEP1_DMA;
__IO uint16_t Reserved4;
__IO uint16_t UEP2_DMA;
__IO uint16_t Reserved5;
__IO uint16_t UEP3_DMA;
__IO uint16_t Reserved6;
__IO uint8_t UEP0_TX_LEN;
__IO uint8_t Reserved7;
__IO uint8_t UEP0_TX_CTRL;
__IO uint8_t Reserved8;
__IO uint8_t UEP1_TX_LEN;
__IO uint8_t Reserved9;
__IO uint8_t UEP1_TX_CTRL;
__IO uint8_t Reserved10;
__IO uint8_t UEP2_TX_LEN;
__IO uint8_t Reserved11;
__IO uint8_t UEP2_TX_CTRL;
__IO uint8_t Reserved12;
__IO uint8_t UEP3_TX_LEN;
__IO uint8_t Reserved13;
__IO uint8_t UEP3_TX_CTRL;
__IO uint8_t Reserved14;
__IO uint8_t UEP4_TX_LEN;
__IO uint8_t Reserved15;
__IO uint8_t UEP4_TX_CTRL;
__IO uint8_t Reserved16;
__IO uint32_t Reserved17;
__IO uint32_t Reserved18;
__IO uint32_t Reserved19;
__IO uint32_t Reserved20;
__IO uint32_t Reserved21;
__IO uint32_t Reserved22;
__IO uint32_t Reserved23;
__IO uint32_t Reserved24;
__IO uint16_t UEP5_DMA;
__IO uint16_t UEP6_DMA;
__IO uint16_t UEP7_DMA;
__IO uint32_t Reserved25;
__IO uint8_t UEP5_TX_LEN;
__IO uint8_t Reserved26;
__IO uint8_t UEP5_TX_CTRL;
__IO uint8_t Reserved27;
__IO uint8_t UEP6_TX_LEN;
__IO uint8_t Reserved28;
__IO uint8_t UEP6_TX_CTRL;
__IO uint8_t Reserved29;
__IO uint8_t UEP7_TX_LEN;
__IO uint8_t UEP7_TX_CTRL;
__IO uint8_t Reserved30;
__IO uint32_t EPX_MODE;
} USBFS_TypeDef;
#define UEP_CTRL_LEN(n) (((uint8_t*)&USBFS->UEP0_TX_LEN)[n*4])
#define UEP_CTRL_TX(n) (((uint8_t*)&USBFS->UEP0_TX_CTRL)[n*4])
#define UEP_CTRL_RX(n) (((uint8_t*)&USBFS->UEP0_TX_CTRL)[n*4])
#define UEP_DMA(n) (((uint16_t*)&USBFS->UEP0_DMA)[n*2])
#endif
#if defined(CH32V10x)
#define USBFS_BASE 0x40023400
#define USB_IRQn USBFS_IRQn
typedef struct
{
__IO uint8_t BASE_CTRL;
__IO uint8_t UDEV_CTRL;
__IO uint8_t INT_EN;
__IO uint8_t DEV_ADDR;
__IO uint8_t USB_STATUS;
__IO uint8_t MIS_ST;
__IO uint8_t INT_FG; // "Combined" register in some situations. (ST_FG)
__IO uint8_t INT_ST;
__IO uint8_t RX_LEN;
__IO uint8_t Reserved0;
__IO uint16_t Reserved1;
__IO uint8_t UEP4_1_MOD;
__IO uint8_t UEP2_3_MOD;
__IO uint8_t UEP5_6_MOD;
__IO uint8_t UEP7_MOD;
__IO uint16_t UEP0_DMA;
__IO uint16_t Reserved3;
__IO uint16_t UEP1_DMA;
__IO uint16_t Reserved4;
__IO uint16_t UEP2_DMA;
__IO uint16_t Reserved5;
__IO uint16_t UEP3_DMA;
__IO uint16_t Reserved6;
__IO uint16_t UEP4_DMA;
__IO uint16_t Reserved7;
__IO uint16_t UEP5_DMA;
__IO uint16_t Reserved8;
__IO uint16_t UEP6_DMA;
__IO uint16_t Reserved9;
__IO uint16_t UEP7_DMA;
__IO uint16_t Reserved10;
__IO uint16_t UEP0_TX_LEN;
__IO uint8_t UEP0_TX_CTRL;
__IO uint8_t Reserved11;
__IO uint16_t UEP1_TX_LEN;
__IO uint8_t UEP1_TX_CTRL;
__IO uint8_t Reserved12;
__IO uint16_t UEP2_TX_LEN;
__IO uint8_t UEP2_TX_CTRL;
__IO uint8_t Reserved13;
__IO uint16_t UEP3_TX_LEN;
__IO uint8_t UEP3_TX_CTRL;
__IO uint8_t Reserved14;
__IO uint16_t UEP4_TX_LEN;
__IO uint8_t UEP4_TX_CTRL;
__IO uint8_t Reserved15;
__IO uint16_t UEP5_TX_LEN;
__IO uint8_t UEP5_TX_CTRL;
__IO uint8_t Reserved16;
__IO uint16_t UEP6_TX_LEN;
__IO uint8_t UEP6_TX_CTRL;
__IO uint8_t Reserved17;
__IO uint16_t UEP7_TX_LEN;
__IO uint8_t UEP7_TX_CTRL;
__IO uint8_t Reserved18;
} USBFS_TypeDef;
#define UEP_CTRL_LEN(n) (((volatile uint16_t*)&USBFS->UEP0_TX_LEN)[n*2])
#define UEP_CTRL_TX(n) (((volatile uint8_t*)&USBFS->UEP0_TX_CTRL)[n*4])
#define UEP_CTRL_RX(n) (((volatile uint8_t*)&USBFS->UEP0_TX_CTRL)[n*4])
#define UEP_DMA(n) (((volatile uint16_t*)&USBFS->UEP0_DMA)[n*2])
#endif
#if !defined (CH32X03x)
#define DEBUG_PIN PA8
#define DEF_USBD_UEP0_SIZE 64 /* usb hs/fs device end-point 0 size */
#define UEP_SIZE 64
#define DEF_UEP_IN 0x80
#define DEF_UEP_OUT 0x00
#define DEF_UEP_BUSY 0x01
#define DEF_UEP_FREE 0x00
#define DEF_UEP0 0
#define DEF_UEP1 1
#define DEF_UEP2 2
#define DEF_UEP3 3
#define DEF_UEP4 4
#define DEF_UEP5 5
#define DEF_UEP6 6
#define DEF_UEP7 7
#define UNUM_EP 8
#define USBFS_UEP_T_RES_MASK MASK_UEP_T_RES
#define USBFS_UEP_T_RES_ACK UEP_T_RES_ACK
#define USBFS_UEP_T_RES_NAK UEP_T_RES_NAK
#define USBFS_UEP_T_TOG RB_UEP_T_TOG
#define USBFS_UEP_T_RES_STALL UEP_T_RES_STALL
#define USBFS_UEP_R_RES_MASK MASK_UEP_R_RES
#define USBFS_UEP_R_RES_ACK UEP_R_RES_ACK
#define USBFS_UEP_R_RES_NAK UEP_R_RES_NAK
#define USBFS_UEP_R_TOG RB_UEP_R_TOG
#define USBFS_UEP_R_RES_STALL UEP_R_RES_STALL
#define USBFS_UDA_GP_BIT RB_UDA_GP_BIT
#define USBFS_UMS_SUSPEND RB_UMS_SUSPEND
#define USBFS_UC_RESET_SIE RB_UC_RESET_SIE
#define USBFS_UC_CLR_ALL RB_UC_CLR_ALL
#define USBFS_UIE_SUSPEND RB_UIE_SUSPEND
#define USBFS_UIE_TRANSFER RB_UIE_TRANSFER
#define USBFS_UIE_BUS_RST RB_UIE_BUS_RST
#define USBFS_UC_INT_BUSY RB_UC_INT_BUSY
#define USBFS_UC_DMA_EN RB_UC_DMA_EN
#define USBFS_UC_DEV_PU_EN RB_UC_DEV_PU_EN
#endif
#define USBFS_UD_PORT_EN RB_UD_PORT_EN
#define USBFS_UD_PD_DIS RB_UD_PD_DIS
#define USBFS_UEP1_RX_EN RB_UEP1_RX_EN
#define USBFS_UEP2_RX_EN RB_UEP2_RX_EN
#define USBFS_UEP3_RX_EN RB_UEP3_RX_EN
#define USBFS_UEP4_RX_EN RB_UEP4_RX_EN
#define USBFS_UEP1_TX_EN RB_UEP1_TX_EN
#define USBFS_UEP2_TX_EN RB_UEP2_TX_EN
#define USBFS_UEP3_TX_EN RB_UEP3_TX_EN
#define USBFS_UEP4_TX_EN RB_UEP4_TX_EN
#define CHECK_USBFS_UEP_AUTO_TOG RB_UEP_AUTO_TOG
#define CHECK_USBFS_UEP_T_AUTO_TOG RB_UEP_AUTO_TOG
// #define CHECK_USBFS_UEP_R_AUTO_TOG USBOTG_UEP_R_AUTO_TOG
#define USBFS ((USBFS_TypeDef *)USBFS_BASE)
#ifdef CH32X03x
#define UEP_CTRL_LEN(n) (((volatile uint16_t*)&USBFS->UEP0_TX_LEN)[n*2])
#define UEP_CTRL_TX(n) (((volatile uint16_t*)&USBFS->UEP0_CTRL_H)[n*2])
#define UEP_CTRL_RX(n) (((volatile uint16_t*)&USBFS->UEP0_CTRL_H)[n*2])
#define UEP_DMA(n) (((volatile uint32_t*)&USBFS->UEP0_DMA)[n])
#define DEBUG_PIN PB12
#define USB_IRQn USBFS_IRQn
#endif
#else
#define DEBUG_PIN PB0
#define USBFS ((USBOTG_FS_TypeDef *)USBFS_BASE)
#define UEP_CTRL_LEN(n) (((volatile uint16_t*)&USBFS->UEP0_TX_LEN)[n*2])
#define UEP_CTRL_TX(n) (((volatile uint8_t*)&USBFS->UEP0_TX_CTRL)[n*4])
#define UEP_CTRL_RX(n) (((volatile uint8_t*)&USBFS->UEP0_RX_CTRL)[n*4])
#define UEP_DMA(n) (((volatile uint32_t*)&USBFS->UEP0_DMA)[n])
#define CHECK_USBFS_UEP_T_AUTO_TOG USBOTG_UEP_T_AUTO_TOG
#define CHECK_USBFS_UEP_R_AUTO_TOG USBOTG_UEP_R_AUTO_TOG
#define USBFS_UEP_T_RES_MASK USBOTG_UEP_T_RES_MASK
#define USBFS_UEP_T_RES_ACK USBOTG_UEP_T_RES_ACK
#define USBFS_UEP_T_RES_NAK USBOTG_UEP_T_RES_NAK
#define USBFS_UEP_T_TOG USBOTG_UEP_T_TOG
#define USBFS_UEP_T_RES_STALL USBOTG_UEP_T_RES_STALL
#define USBFS_UEP_R_RES_MASK USBOTG_UEP_R_RES_MASK
#define USBFS_UEP_R_RES_ACK USBOTG_UEP_R_RES_ACK
#define USBFS_UEP_R_RES_NAK USBOTG_UEP_R_RES_NAK
#define USBFS_UEP_R_TOG USBOTG_UEP_R_TOG
#define USBFS_UEP_R_RES_STALL USBOTG_UEP_R_RES_STALL
// #define USBFS_UDA_GP_BIT USBOTG_UDA_GP_BIT
#define USBFS_UMS_SUSPEND USBOTG_UMS_SUSPEND
#define USBFS_UEP1_RX_EN USBOTG_UEP1_RX_EN
#define USBFS_UEP2_RX_EN USBOTG_UEP2_RX_EN
#define USBFS_UEP3_RX_EN USBOTG_UEP3_RX_EN
#define USBFS_UEP4_RX_EN USBOTG_UEP4_RX_EN
#define USBFS_UEP1_TX_EN USBOTG_UEP1_TX_EN
#define USBFS_UEP2_TX_EN USBOTG_UEP2_TX_EN
#define USBFS_UEP3_TX_EN USBOTG_UEP3_TX_EN
#define USBFS_UEP4_TX_EN USBOTG_UEP4_TX_EN
#define USBFS_UC_RESET_SIE USBOTG_UC_RESET_SIE
#define USBFS_UC_CLR_ALL USBOTG_UC_CLR_ALL
#define USBFS_UIE_SUSPEND USBOTG_UIE_SUSPEND
#define USBFS_UIE_TRANSFER USBOTG_UIE_TRANSFER
#define USBFS_UIE_BUS_RST USBOTG_UIE_BUS_RST
#define USBFS_UC_INT_BUSY USBOTG_UC_INT_BUSY
#define USBFS_UC_DMA_EN USBOTG_UC_DMA_EN
#define USBFS_UC_DEV_PU_EN USBOTG_UC_DEV_PU_EN
#define USBFS_UD_PD_DIS USBOTG_UD_PD_DIS
#define USBFS_UD_PORT_EN USBOTG_UD_PORT_EN
#ifdef CH32V30x_D8C
#define USB_IRQn OTG_FS_IRQn
#else
#define USB_IRQn USBHD_IRQn
#endif
#endif
// Mask for the combined USBFS->INT_FG + USBFS->INT_ST
#define CRB_UIS_IS_NAK (1<<7)
#define CRB_U_TOG_OK (1<<6)
#define CRB_U_SIE_FREE (1<<5)
#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)
#if defined(CH5xx) || defined(CH32X03x) || defined(CH32V10x)
#define CRB_UIF_SETUP_ACT (1<<15)
#endif
#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 USBFS_PACKET_SIZE 64
extern uint32_t USBDEBUG0, USBDEBUG1, USBDEBUG2;
struct _USBState;
// Provided functions:
int USBFSSetup();
uint8_t USBFS_Endp_DataUp(uint8_t endp, const uint8_t *pbuf, uint16_t len, uint8_t mod);
static inline uint8_t * USBFS_GetEPBufferIfAvailable( int endp );
static inline int USBFS_SendEndpoint( int endp, int len );
static inline int USBFS_SendACK( int endp, int tx );
static inline int USBFS_SendNAK( int endp, int tx );
#if FUSB_USE_DMA7_COPY
static inline void copyBuffer( uint8_t * dest, const uint8_t * src, int len );
static inline void copyBufferComplete();
#endif
// Implement the following:
#if FUSB_HID_USER_REPORTS
__USBFS_FUN_ATTRIBUTE int HandleHidUserGetReportSetup( struct _USBState * ctx, tusb_control_request_t * req );
__USBFS_FUN_ATTRIBUTE 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
__USBFS_FUN_ATTRIBUTE int HandleInRequest( struct _USBState * ctx, int endp, uint8_t * data, int len );
__USBFS_FUN_ATTRIBUTE void HandleDataOut( struct _USBState * ctx, int endp, uint8_t * data, int len );
__USBFS_FUN_ATTRIBUTE int HandleSetupCustom( struct _USBState * ctx, int setup_code);
#endif
typedef enum
{
USBFS_EP_OFF = 0,
USBFS_EP_RX = -1,
USBFS_EP_TX = 1,
} USBFS_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
{
// Setup Request
uint8_t USBFS_SetupReqCode;
uint8_t USBFS_SetupReqType;
uint16_t USBFS_SetupReqLen; // Used for tracking place along send.
uint32_t USBFS_IndexValue;
// USB Device Status
uint8_t USBFS_DevConfig;
uint8_t USBFS_DevAddr;
uint8_t USBFS_DevSleepStatus;
uint8_t USBFS_DevEnumStatus;
uint8_t* pCtrlPayloadPtr;
uint8_t ENDPOINTS[FUSB_CONFIG_EPS][64];
USBFS_EP_mode endpoint_mode[FUSB_CONFIG_EPS+1]; // IN -1, OUT 1, OFF 0
#define CTRL0BUFF (USBFSCTX.ENDPOINTS[0])
#define pUSBFS_SetupReqPak ((tusb_control_request_t*)CTRL0BUFF)
#if FUSB_HID_INTERFACES > 0
uint8_t USBFS_HidIdle[FUSB_HID_INTERFACES];
uint8_t USBFS_HidProtocol[FUSB_HID_INTERFACES];
#endif
volatile uint8_t USBFS_Endp_Busy[FUSB_CONFIG_EPS];
volatile uint8_t USBFS_errata_dont_send_endpoint_in_window;
};
extern struct _USBState USBFSCTX;
#include "fsusb.c"
#endif