cmake_cpputest_template/inc/extralibs/fsusb.h

490 lines
15 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 EP_JMPR; // Nothing here, but used for UEP 5,6,7 jump in UEP_(n) macros
__IO uint32_t Reserved21;
__IO uint32_t Reserved22;
__IO uint32_t Reserved23;
__IO uint32_t Reserved24; // 0x50
__IO uint16_t UEP5_DMA; // 0x54
__IO uint16_t Reserved25; // 0x56
__IO uint16_t UEP6_DMA; // 0x58
__IO uint16_t Reserved26; // 0x5A
__IO uint16_t UEP7_DMA; // 0x5C
__IO uint16_t Reserved27; // 0x5E
__IO uint32_t Reserved28; // 0x60
__IO uint8_t UEP5_TX_LEN; // 0x64
__IO uint8_t Reserved29; // 0x65
__IO uint8_t UEP5_TX_CTRL; // 0x66
__IO uint8_t Reserved30; // 0x67
__IO uint8_t UEP6_TX_LEN; // 0x68
__IO uint8_t Reserved31; // 0x69
__IO uint8_t UEP6_TX_CTRL; // 0x6A
__IO uint8_t Reserved32; // 0x6B
__IO uint8_t UEP7_TX_LEN; // 0x6C
__IO uint8_t Reserved33; // 0x6D
__IO uint8_t UEP7_TX_CTRL; // 0x6E
__IO uint8_t Reserved34; // 0x6F
__IO uint32_t EPX_MODE; // 0x70
} USBFS_TypeDef;
#define UEP_JMP ((void*)&(USBFS->EP_JMPR) - (void*)&(USBFS->UEP0_DMA))
#define UEP_CTRL_LEN(n) (((volatile uint8_t*)&USBFS->UEP0_TX_LEN)[n*4 +((n>4) ? UEP_JMP : 0)])
#define UEP_CTRL_TX(n) (((volatile uint8_t*)&USBFS->UEP0_TX_CTRL)[n*4 +((n>4) ? UEP_JMP : 0)])
#define UEP_CTRL_RX(n) (((volatile uint8_t*)&USBFS->UEP0_TX_CTRL)[n*4 +((n>4) ? UEP_JMP : 0)])
#define UEP_DMA(n) (((volatile uint16_t*)&USBFS->UEP0_DMA)[n*2 +((n>4) ? (UEP_JMP /2) : 0)]) // BREAKS FOR EP4!!!
#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 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_UEP5_RX_EN RB_UEP5_RX_EN
#define USBFS_UEP6_RX_EN RB_UEP6_RX_EN
#define USBFS_UEP7_RX_EN RB_UEP7_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 USBFS_UEP5_TX_EN RB_UEP5_TX_EN
#define USBFS_UEP6_TX_EN RB_UEP6_TX_EN
#define USBFS_UEP7_TX_EN RB_UEP7_TX_EN
#define CHECK_USBFS_UEP_R_AUTO_TOG RB_UEP_AUTO_TOG
#define CHECK_USBFS_UEP_T_AUTO_TOG RB_UEP_AUTO_TOG
#define USBFS ((USBFS_TypeDef *)USBFS_BASE)
#ifdef CH32X03x
#define EP_JMPR (USBFS_BASE + 64)
#define UEP_JMP ((void*)(EP_JMPR) - (void*)&(USBFS->UEP0_DMA))
#define UEP_CTRL_LEN(n) (((volatile uint8_t*)&USBFS->UEP0_TX_LEN)[n*4 +((n>4) ? UEP_JMP : 0)])
#define UEP_CTRL_TX(n) (((volatile uint8_t*)&USBFS->UEP0_CTRL_H)[n*4 +((n>4) ? UEP_JMP : 0)])
#define UEP_CTRL_RX(n) (((volatile uint8_t*)&USBFS->UEP0_CTRL_H)[n*4 +((n>4) ? UEP_JMP : 0)])
#define UEP_DMA(n) (((volatile uint16_t*)&USBFS->UEP0_DMA)[n*2 +((n>4) ? (UEP_JMP /2) : 0)]) // DMA for EP4 is tied to EP0 DMA on these chips, so this maceo won't work for it
#define DEBUG_PIN PB12
#define USB_IRQn USBFS_IRQn
#endif
#else
#define DEBUG_PIN PB0
#if defined(CH32L103)
#define USBFS ((USBFSD_TypeDef *)USBFS_BASE)
#define CHECK_USBFS_UEP_R_AUTO_TOG USBFS_UEP_T_AUTO_TOG
#define CHECK_USBFS_UEP_T_AUTO_TOG USBFS_UEP_T_AUTO_TOG
#else
#define USBFS ((USBOTG_FS_TypeDef *)USBFS_BASE)
#define CHECK_USBFS_UEP_T_AUTO_TOG USBOTG_UEP_T_AUTO_TOG
#define CHECK_USBFS_UEP_R_AUTO_TOG USBOTG_UEP_R_AUTO_TOG
#endif
#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])
#if defined(CH32V20x)
#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_UEP5_RX_EN USBOTG_UEP5_RX_EN
#define USBFS_UEP6_RX_EN USBOTG_UEP6_RX_EN
#define USBFS_UEP7_RX_EN USBOTG_UEP7_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_UEP5_TX_EN USBOTG_UEP5_TX_EN
#define USBFS_UEP6_TX_EN USBOTG_UEP6_TX_EN
#define USBFS_UEP7_TX_EN USBOTG_UEP7_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
#endif
#if defined(CH32L103)
#define USB_IRQn USBFS_IRQn
#elif defined(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();
void USBFSReset();
uint8_t USBFS_Endp_DataUp(uint8_t endp, const uint8_t *pbuf, uint16_t len, uint8_t mod);
uint8_t * USBFS_GetEPBufferIfAvailable( int endp );
int USBFS_SendEndpoint( int endp, int len );
int USBFS_SendACK( int endp, int tx );
int USBFS_SendNAK( int endp, int tx );
int USBFS_SendEndpointNEW( int endp, uint8_t* data, int len, int copy);
#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
#if FUNCONF_USE_USBPRINTF
void HandleUSBInput( int numbytes, uint8_t * data );
extern uint8_t usb_inputbuffer[USBFS_PACKET_SIZE];
extern int usb_inbuf_idx;
#endif
#ifndef FUSB_MAX_EP_CNT
#define FUSB_MAX_EP_CNT 8
#endif
#ifndef FUSB_BUFFERS_NUMBER
#define FUSB_BUFFERS_NUMBER 1
#undef FUSB_EP1_MODE
#define FUSB_EP1_MODE 0
#undef FUSB_EP2_MODE
#define FUSB_EP2_MODE 0
#undef FUSB_EP3_MODE
#define FUSB_EP3_MODE 0
#undef FUSB_EP4_MODE
#define FUSB_EP4_MODE 0
#undef FUSB_EP5_MODE
#define FUSB_EP5_MODE 0
#undef FUSB_EP6_MODE
#define FUSB_EP6_MODE 0
#undef FUSB_EP7_MODE
#define FUSB_EP7_MODE 0
#warning "You may have forgotten to properly define used EPs in usb_config.h"
#endif
// high-level-ish abstraction to help dealing with endpoints
typedef struct
{
union {
uint8_t * out;
uint8_t * rx;
};
union {
uint8_t * in;
uint8_t * tx;
};
uint8_t mode;
volatile uint8_t busy;
uint16_t reserved;
} USBFS_EP_TypeDef;
#define USBFS_EP_MODE_TX 4
#define USBFS_EP_MODE_TX_DOUBLE 5
#define USBFS_EP_MODE_RX 8
#define USBFS_EP_MODE_RX_DOUBLE 9
#define USBFS_EP_MODE_BDIR 12
#define USBFS_EP_MODE_BDIR_DOUBLE 13
#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 ep_buffers[FUSB_BUFFERS_NUMBER][64];
USBFS_EP_TypeDef endpoints[FUSB_MAX_EP_CNT];
#define CTRL0BUFF (USBFSCTX.ep_buffers[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_errata_dont_send_endpoint_in_window;
};
extern struct _USBState USBFSCTX;
#endif