From c612d10440b19bb01777c409d6ed79e591ed5e6f Mon Sep 17 00:00:00 2001 From: cnlohr Date: Tue, 23 Apr 2024 14:45:15 -0400 Subject: [PATCH] Cleanup forgot to commit last night --- ch32v003fun/ch32v003fun.c | 27 +- ch32v003fun/ch32v003fun.h | 193 +------------- examples/blink/blink.bin | Bin 564 -> 560 bytes .../usbdevice.incomplete/usbdevice.c | 93 ------- .../Makefile | 3 +- .../fsusb.c | 251 ++++++++++++------ .../fsusb.h | 59 ++-- .../funconfig.h | 0 .../testtop.hidapi}/Makefile | 0 .../testtop.hidapi}/os_generic.h | 0 .../testtop.hidapi}/testtop.c | 2 +- .../testtop.hidapi}/winbuild.bat | 0 .../usb_config.h | 5 +- .../usb_defines.h | 185 +++++++++++++ examples_x035/usbdevice/usbdevice.c | 87 ++++++ 15 files changed, 508 insertions(+), 397 deletions(-) delete mode 100644 examples_x035/usbdevice.incomplete/usbdevice.c rename examples_x035/{usbdevice.incomplete => usbdevice}/Makefile (81%) rename examples_x035/{usbdevice.incomplete => usbdevice}/fsusb.c (71%) rename examples_x035/{usbdevice.incomplete => usbdevice}/fsusb.h (52%) rename examples_x035/{usbdevice.incomplete => usbdevice}/funconfig.h (100%) rename examples_x035/{usbdevice.incomplete/testtop => usbdevice/testtop.hidapi}/Makefile (100%) rename examples_x035/{usbdevice.incomplete/testtop => usbdevice/testtop.hidapi}/os_generic.h (100%) rename examples_x035/{usbdevice.incomplete/testtop => usbdevice/testtop.hidapi}/testtop.c (98%) rename examples_x035/{usbdevice.incomplete/testtop => usbdevice/testtop.hidapi}/winbuild.bat (100%) rename examples_x035/{usbdevice.incomplete => usbdevice}/usb_config.h (98%) rename examples_x035/{usbdevice.incomplete => usbdevice}/usb_defines.h (91%) create mode 100644 examples_x035/usbdevice/usbdevice.c diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c index 5e59a986..c7a75ecc 100644 --- a/ch32v003fun/ch32v003fun.c +++ b/ch32v003fun/ch32v003fun.c @@ -896,7 +896,7 @@ void InterruptVectorDefault() .word NMI_Handler /* NMI Handler */ \n\ .word HardFault_Handler /* Hard Fault Handler */ \n\ .word 0\n" -#if !defined(CH32X03x) +#if defined(CH32X03x) " .word Ecall_M_Mode_Handler /* Ecall M Mode */ \n\ .word 0 \n\ .word 0 \n\ @@ -975,9 +975,17 @@ void handle_reset() ".option arch, +zicsr\n" #endif // Setup the interrupt vector, processor status and INTSYSCR. + +#if FUNCONF_ENABLE_HPE // Enabled nested and hardware (HPE) stack, since it's really good on the x035. +" li t0, 0x88\n\ + csrs mstatus, t0\n" +" li t0, 0x0b\n\ + csrw 0x804, t0\n" +#else " li a0, 0x80\n\ - csrw mstatus, a0\n\ - li a3, 0x3\n\ + csrw mstatus, a0\n" +#endif +" li a3, 0x3\n\ la a0, InterruptVector\n\ or a0, a0, a3\n\ csrw mtvec, a0\n" @@ -1255,14 +1263,19 @@ void handle_reset( void ) asm volatile( " li t0, 0x1f\n\ csrw 0xbc0, t0\n" -#if defined(CH32V20x) || defined(CH32X03x) - // Enabled nested and hardware stack + +//XXX TODO: CHECKME - TEST ON 203!!! +#if FUNCONF_ENABLE_HPE // Enabled nested and hardware (HPE) stack, since it's really good on the x035. " li t0, 0x88\n\ csrs mstatus, t0\n" -#elif defined(CH32V30x) - // Enable nested and hardware stack " li t0, 0x0b\n\ csrw 0x804, t0\n" +#else +" li a0, 0x80\n\ + csrw mstatus, a0\n" +#endif + +#if defined(CH32V30x) // Enable floating point and interrupt " li t0, 0x688\n\ csrs mstatus, t0\n" diff --git a/ch32v003fun/ch32v003fun.h b/ch32v003fun/ch32v003fun.h index 28dd5e5e..6146f89b 100644 --- a/ch32v003fun/ch32v003fun.h +++ b/ch32v003fun/ch32v003fun.h @@ -55,6 +55,7 @@ #define FUNCONF_TINYVECTOR 0 // If enabled, Does not allow normal interrupts. #define FUNCONF_UART_PRINTF_BAUD 115200 // Only used if FUNCONF_USE_UARTPRINTF is set. #define FUNCONF_DEBUGPRINTF_TIMEOUT 160000 // Arbitrary time units +#define FUNCONF_ENABLE_HPE 1 // Enable hardware interrupt stack. Very good on QingKeV4, i.e. x035, v10x, v20x, v30x, but questionable on 003. */ // Sanity check for when porting old code. @@ -101,6 +102,14 @@ #error No PLL on the X03x #endif +#ifndef FUNCONF_ENABLE_HPE + #if defined( CH32V003 ) + #define FUNCONF_ENABLE_HPE 0 + #else + #define FUNCONF_ENABLE_HPE 1 + #endif +#endif + #if !defined( FUNCONF_USE_CLK_SEC ) #define FUNCONF_USE_CLK_SEC 1// use clock security system by default @@ -11548,190 +11557,6 @@ typedef volatile unsigned long *PUINT32V; #define R16_UEP7_T_LEN (*((PUINT16V)(0x4002344c))) // endpoint 7 transmittal length(16-bits for ch32v10x) #define R8_UEP7_CTRL (*((PUINT8V)(0x4002344e))) // endpoint 7 control -/* USB constant and structure define */ - -/* USB PID */ -#ifndef USB_PID_SETUP - #define USB_PID_NULL 0x00 /* reserved PID */ - #define USB_PID_SOF 0x05 - #define USB_PID_SETUP 0x0D - #define USB_PID_IN 0x09 - #define USB_PID_OUT 0x01 - #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_PRE 0x0C -#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 - -/* 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 - -/* USB CDC Class request code */ -#ifndef CDC_GET_LINE_CODING -#define CDC_GET_LINE_CODING 0X21 /* This request allows the host to find out the currently configured line coding */ -#define CDC_SET_LINE_CODING 0x20 /* Configures DTE rate, stop-bits, parity, and number-of-character */ -#define CDC_SET_LINE_CTLSTE 0X22 /* This request generates RS-232/V.24 style control signals */ -#define CDC_SEND_BREAK 0X23 /* Sends special carrier modulation used to specify RS-232 style break */ -#endif - -/* Bit define for USB request type */ -#ifndef USB_REQ_TYP_MASK - #define USB_REQ_TYP_IN 0x80 /* control IN, device to host */ - #define USB_REQ_TYP_OUT 0x00 /* control OUT, host to device */ - #define USB_REQ_TYP_READ 0x80 /* control read, device to host */ - #define USB_REQ_TYP_WRITE 0x00 /* control write, host to device */ - #define USB_REQ_TYP_MASK 0x60 /* bit mask of request type */ - #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 /* bit mask of request recipient */ - #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 request type for 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 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_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_IMAGE 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 endpoint type and attributes */ -#ifndef USB_ENDP_TYPE_MASK - #define USB_ENDP_DIR_MASK 0x80 - #define USB_ENDP_ADDR_MASK 0x0F - #define USB_ENDP_TYPE_MASK 0x03 - #define USB_ENDP_TYPE_CTRL 0x00 - #define USB_ENDP_TYPE_ISOCH 0x01 - #define USB_ENDP_TYPE_BULK 0x02 - #define USB_ENDP_TYPE_INTER 0x03 -#endif - -#ifndef USB_DEVICE_ADDR - #define USB_DEVICE_ADDR 0x02 -#endif -#ifndef DEFAULT_ENDP0_SIZE - #define DEFAULT_ENDP0_SIZE 8 /* default maximum packet size for endpoint 0 */ -#endif -#ifndef MAX_PACKET_SIZE - #define MAX_PACKET_SIZE 64 /* maximum packet size */ -#endif -#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 - -#define DEF_STRING_DESC_LANG 0x00 -#define DEF_STRING_DESC_MANU 0x01 -#define DEF_STRING_DESC_PROD 0x02 -#define DEF_STRING_DESC_SERN 0x03 - /* ch32v10x_usb_host.h -----------------------------------------------------------*/ #define ERR_SUCCESS 0x00 diff --git a/examples/blink/blink.bin b/examples/blink/blink.bin index c4ae5e0476d01db8c9adede2e3af224eff6ec4c4..23614187313a10492587efeb0091524a302f18e1 100755 GIT binary patch delta 257 zcmdnOvVmp76Gn!KPqi5pCJQo3>8dk1u)5DUyj`5h!JM6gQF#$NgD|@|$Be_~?DH9B z9N*5yz+?`TlX3pq|MmXl2u7KDKq5UvE(2|dT#Y+2uG$TZG zhV%AkVhoep*vue0XB?i)&gNkLo#BD9?TT~;B6Gn%LPqi5jOcrF6(iLZNFlXmrR9?i+Aj~e#G2?Kno4GoZgUDfX_W2Am zj++DJWt=BZOJ{g|m+jx=2u7Lu$?fg@$_v;TwzD%lnB4BpFU-yW)YjAxD9Cms(;lqB z-<<8^|5~xh&%>Ez&TkiIbeP=E?l8l7yBMQ`xhSK9<80w{afTU(XE?JuA9O10cT5ZH z2l33=7(UjD74`#ZMzDwzROO-V&%_wazXR=SV{ -#include -#include "fsusb.h" - -uint32_t count; - -int last = 0; -void handle_debug_input( int numbytes, uint8_t * data ) -{ - last = data[0]; - count += numbytes; -} - -int HandleHidUserReportSetup( struct _USBState * ctx, tusb_control_request_t * req ) -{ - -/* - int USBFS_SetupReqType = FSUSBCTX.USBFS_SetupReqType = pUSBFS_SetupReqPak->bmRequestType; - int USBFS_SetupReqCode = FSUSBCTX.USBFS_SetupReqCode = pUSBFS_SetupReqPak->bRequest; - int USBFS_SetupReqLen = FSUSBCTX.USBFS_SetupReqLen = pUSBFS_SetupReqPak->wLength; - int USBFS_SetupReqIndex = pUSBFS_SetupReqPak->wIndex; - int USBFS_IndexValue = FSUSBCTX.USBFS_IndexValue = ( pUSBFS_SetupReqPak->wIndex << 16 ) | pUSBFS_SetupReqPak->wValue; - len = 0; - USBDEBUG1++; -*/ - int id = req->wValue & 0xff; - if( id == 0xaa ) - { - if( req->bRequest == HID_REQ_CONTROL_SET_REPORT ) - { - //int i; - //for( i = 0; i < 64; i++ ) - //{ - // printf( "%02x ", CTRL0BUFF[i] ); - //} - //printf( "\n" ); - } - else - { - } - } - return 0; -} - -int HandleHidUserReportDataOut( struct _USBState * ctx, uint8_t * data, int len ) -{ - int i; - for( i = 0; i < len; i++ ) - { -// printf( "%02x ", data[i] ); - } -// printf( "\n" ); - printf( "OUT\n" ); - return 0; -} - -void HandleHidUserReportDataIn( struct _USBState * ctx, uint8_t * data, int len ) -{ - memset( data, 0xcc, len ); -} - - -int main() -{ - SystemInit(); - - funGpioInitAll(); - - funPinMode( PA0, GPIO_CFGLR_OUT_10Mhz_PP ); - - FSUSBSetup(); - - while(1) - { - printf( "%lu %08lx %lu %d %d\n", USBDEBUG0, USBDEBUG1, USBDEBUG2, 0, 0 ); - int i; - for( i = 1; i < 3; i++ ) - { - - uint32_t * buffer = (uint32_t*)USBFS_GetEPBufferIfAvailable( i ); - if( buffer ) - { - buffer[0] = 0x000000aa; - USBFS_SendEndpoint( i, (i==1)?8:4 ); - } - } - } -} - diff --git a/examples_x035/usbdevice.incomplete/Makefile b/examples_x035/usbdevice/Makefile similarity index 81% rename from examples_x035/usbdevice.incomplete/Makefile rename to examples_x035/usbdevice/Makefile index e28de11d..27b389bc 100644 --- a/examples_x035/usbdevice.incomplete/Makefile +++ b/examples_x035/usbdevice/Makefile @@ -2,8 +2,7 @@ all : flash TARGET:=usbdevice TARGET_MCU:=CH32X035 -ADDITIONAL_C_FILES:=fsusb.c - +ADDITIONAL_C_FILES:= include ../../ch32v003fun/ch32v003fun.mk flash : cv_flash diff --git a/examples_x035/usbdevice.incomplete/fsusb.c b/examples_x035/usbdevice/fsusb.c similarity index 71% rename from examples_x035/usbdevice.incomplete/fsusb.c rename to examples_x035/usbdevice/fsusb.c index 4c43708b..c67dfb4a 100644 --- a/examples_x035/usbdevice.incomplete/fsusb.c +++ b/examples_x035/usbdevice/fsusb.c @@ -30,29 +30,9 @@ struct _USBState FSUSBCTX; #define CUIS_TOKEN_IN 0x2 #define CUIS_TOKEN_SETUP 0x3 -#if 0 -static inline void fastcopy( uint8_t * dest, const uint8_t * src, int len ) -{ - src = ((intptr_t)src) & ~3; - asm volatile( "\ - add a3, %[src], %[len]\n\ -1:\n\ - lw a4, 0(%[src])\n\ - lw a5, 4(%[src])\n\ - lw s1, 8(%[src])\n\ - lw s2, 12(%[src])\n\ - addi %[src],%[src],16\n\ - sw a4, 0(%[dest])\n\ - sw a5, 4(%[dest])\n\ - sw s1, 8(%[dest])\n\ - sw s2, 12(%[dest])\n\ - addi %[dest],%[dest],16\n\ - bgtu a3,%[src],1b\n\ - " : [dest]"+r"(dest), [src]"+r"(src) : [len]"r"(len) : "memory", "a3", "a4", "a5", "s1", "s2" ); -} -#else -static inline void fastcopy( uint8_t * dest, const uint8_t * src, int len ) +static inline void DMA7FastCopy( uint8_t * dest, const uint8_t * src, int len ) { + while( DMA1_Channel7->CNTR ); DMA1_Channel7->CFGR = 0; DMA1_Channel7->MADDR = (uintptr_t)src; DMA1_Channel7->PADDR = (uintptr_t)dest; @@ -66,26 +46,35 @@ static inline void fastcopy( uint8_t * dest, const uint8_t * src, int len ) DMA_MemoryInc_Enable | DMA_PeripheralInc_Enable | DMA_Mode_Normal | DMA_CFGR1_EN; - //XXX TODO: Somehow, it seems to work (unsafely) without this. #if !( FUSB_CURSED_TURBO_DMA == 1 ) + // Somehow, it seems to work (unsafely) without this. + // Really, though, it's probably fine. while( DMA1_Channel7->CNTR ); #endif - } -#endif -void USBFS_IRQHandler() __attribute__((section(".text.vector_handler"))) __attribute__((interrupt)); +static inline void DMA7FastCopyComplete() { while( DMA1_Channel7->CNTR ); } + +#if FUSB_USE_HPE +void USBFS_IRQHandler() __attribute__((section(".text.vector_handler"))) __attribute((naked)); +#else +void USBFS_IRQHandler() __attribute__((section(".text.vector_handler"))) __attribute((interrupt)); +#endif void USBFS_InternalFinishSetup(); void USBFS_IRQHandler() { +#if FUSB_IO_PROFILE + GPIOA->BSHR = 1; +#endif + // Based on https://github.com/openwch/ch32x035/blob/main/EVT/EXAM/USB/USBFS/DEVICE/CompositeKM/User/ch32x035_usbfs_device.c // Combined FG + ST flag. uint16_t intfgst = *(uint16_t*)(&USBFS->INT_FG); int len = 0; struct _USBState * ctx = &FSUSBCTX; - GPIOA->BSHR = 1; + uint8_t * ctrl0buff = CTRL0BUFF; // TODO: Check if needs to be do-while to re-check. if( intfgst & CRB_UIF_TRANSFER ) @@ -113,22 +102,40 @@ void USBFS_IRQHandler() USBFS->UEP0_CTRL_H = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_ACK; } - if ( ( ctx->USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) + if( ctx->pCtrlPayloadPtr ) + { + // Shortcut mechanism, for descriptors or if the user wants it. + len = ctx->USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : ctx->USBFS_SetupReqLen; + DMA7FastCopy( ctrl0buff, ctx->pCtrlPayloadPtr, len ); // FYI -> Would need to do this if using DMA + ctx->USBFS_SetupReqLen -= len; + if( ctx->USBFS_SetupReqLen > 0 ) + ctx->pCtrlPayloadPtr += len; + else + ctx->pCtrlPayloadPtr = 0; + + USBFS->UEP0_TX_LEN = len; + USBFS->UEP0_CTRL_H ^= USBFS_UEP_T_TOG; + } + else if ( ( ctx->USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { - // Handle other control requests here. + +#if FUSB_HID_USER_REPORTS + len = ctx->USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : ctx->USBFS_SetupReqLen; + if( len && FSUSBCTX.USBFS_SetupReqCode == HID_GET_REPORT ) + { + len = HandleHidUserReportDataIn( ctx, ctrl0buff, len ); + USBFS->UEP0_TX_LEN = len; + USBFS->UEP0_CTRL_H ^= USBFS_UEP_T_TOG; + ctx->USBFS_SetupReqLen -= len; + ctx->pCtrlPayloadPtr += len; + } +#endif } else { switch( FSUSBCTX.USBFS_SetupReqCode ) { case USB_GET_DESCRIPTOR: - len = ctx->USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : ctx->USBFS_SetupReqLen; - //memcpy( CTRL0BUFF, ctx->pUSBFS_Descr, len ); // FYI -> IS IT POSSIBLE TO DO THIS WITH DMA???? - fastcopy( CTRL0BUFF, ctx->pUSBFS_Descr, len ); // FYI -> Would need to do this if using DMA - USBFS->UEP0_TX_LEN = len; - USBFS->UEP0_CTRL_H ^= USBFS_UEP_T_TOG; - ctx->USBFS_SetupReqLen -= len; - ctx->pUSBFS_Descr += len; break; case USB_SET_ADDRESS: @@ -136,17 +143,6 @@ void USBFS_IRQHandler() break; default: -#if FUSB_HID_USER_REPORTS - len = ctx->USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : ctx->USBFS_SetupReqLen; - if( len ) - { - HandleHidUserReportDataIn( ctx, CTRL0BUFF, len ); - USBFS->UEP0_TX_LEN = len; - USBFS->UEP0_CTRL_H ^= USBFS_UEP_T_TOG; - ctx->USBFS_SetupReqLen -= len; - ctx->pUSBFS_Descr += len; - } -#endif break; } } @@ -161,20 +157,42 @@ void USBFS_IRQHandler() case DEF_UEP0: if( intfgst & CRB_UIS_TOG_OK ) { - #if FUSB_HID_USER_REPORTS - int r = HandleHidUserReportDataOut( ctx, CTRL0BUFF, USBFS->RX_LEN ); - if( r >= 0 ) + int len = USBFS->RX_LEN; + uint8_t * cptr = ctx->pCtrlPayloadPtr; + if( !cptr ) { - USBFS->UEP0_TX_LEN = r; - USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; + HandleHidUserReportDataOut( ctx, ctrl0buff, len ); } else + { + int remain = ctx->USBFS_SetupReqLen - len; + if( remain < 0 ) + { + len += remain; + remain = 0; + } + DMA7FastCopy( cptr, ctrl0buff, len ); + ctx->USBFS_SetupReqLen = remain; + if( remain > 0 ) + ctx->pCtrlPayloadPtr = cptr + len; + else + ctx->pCtrlPayloadPtr = 0; + } #endif - if( FSUSBCTX.USBFS_SetupReqLen == 0 ) + + if( ctx->USBFS_SetupReqLen == 0 ) { - USBFS->UEP0_TX_LEN = 0; + USBFS->UEP0_TX_LEN = 0; USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; +#if FUSB_HID_USER_REPORTS + DMA7FastCopyComplete(); + HandleHidUserReportOutComplete( ctx ); +#endif + } + else + { + USBFS->UEP0_CTRL_H ^= USBFS_UEP_R_TOG; } } break; @@ -186,22 +204,19 @@ void USBFS_IRQHandler() /* Setup stage processing */ case CUIS_TOKEN_SETUP: + USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_NAK|USBFS_UEP_R_TOG|USBFS_UEP_R_RES_NAK; /* Store All Setup Values */ int USBFS_SetupReqType = FSUSBCTX.USBFS_SetupReqType = pUSBFS_SetupReqPak->bmRequestType; int USBFS_SetupReqCode = FSUSBCTX.USBFS_SetupReqCode = pUSBFS_SetupReqPak->bRequest; - int USBFS_SetupReqLen = FSUSBCTX.USBFS_SetupReqLen = pUSBFS_SetupReqPak->wLength; + int USBFS_SetupReqLen = FSUSBCTX.USBFS_SetupReqLen = pUSBFS_SetupReqPak->wLength; int USBFS_SetupReqIndex = pUSBFS_SetupReqPak->wIndex; int USBFS_IndexValue = FSUSBCTX.USBFS_IndexValue = ( pUSBFS_SetupReqPak->wIndex << 16 ) | pUSBFS_SetupReqPak->wValue; len = 0; if( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { -#if FUSB_HID_USER_REPORTS - len = HandleHidUserReportSetup( ctx, pUSBFS_SetupReqPak ); - if( len < 0 ) goto sendstall; -#endif #if FUSB_HID_INTERFACES > 0 if( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) == USB_REQ_TYP_CLASS ) { @@ -209,8 +224,36 @@ void USBFS_IRQHandler() switch( USBFS_SetupReqCode ) { case HID_SET_REPORT: +#if FUSB_HID_USER_REPORTS + len = HandleHidUserSetReportSetup( ctx, pUSBFS_SetupReqPak ); + if( len < 0 ) goto sendstall; + ctx->USBFS_SetupReqLen = len; + USBFS->UEP0_TX_LEN = 0; + USBFS->UEP0_CTRL_H = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_ACK | USBFS_UEP_T_TOG; + goto replycomplete; + case HID_GET_REPORT: + len = HandleHidUserGetReportSetup( ctx, pUSBFS_SetupReqPak ); + len = 255; + if( len < 0 ) goto sendstall; + ctx->USBFS_SetupReqLen = len; + len = len >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : len; + if( !ctx->pCtrlPayloadPtr ) + { + len = HandleHidUserReportDataIn( ctx, ctrl0buff, len ); + } + else + { + DMA7FastCopy( ctrl0buff, ctx->pCtrlPayloadPtr, len ); + ctx->pCtrlPayloadPtr += len; + } + USBFS->UEP0_TX_LEN = len; + USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; + ctx->USBFS_SetupReqLen -= len; + goto replycomplete; +#endif break; + case HID_SET_IDLE: if( USBFS_SetupReqIndex < FUSB_HID_INTERFACES ) FSUSBCTX.USBFS_HidIdle[ USBFS_SetupReqIndex ] = (uint8_t)( USBFS_IndexValue >> 8 ); @@ -223,7 +266,7 @@ void USBFS_IRQHandler() case HID_GET_IDLE: if( USBFS_SetupReqIndex < FUSB_HID_INTERFACES ) { - CTRL0BUFF[0] = FSUSBCTX.USBFS_HidIdle[ USBFS_SetupReqIndex ]; + ctrl0buff[0] = FSUSBCTX.USBFS_HidIdle[ USBFS_SetupReqIndex ]; len = 1; } break; @@ -231,7 +274,7 @@ void USBFS_IRQHandler() case HID_GET_PROTOCOL: if( USBFS_SetupReqIndex < FUSB_HID_INTERFACES ) { - CTRL0BUFF[0] = FSUSBCTX.USBFS_HidProtocol[ USBFS_SetupReqIndex ]; + ctrl0buff[0] = FSUSBCTX.USBFS_HidProtocol[ USBFS_SetupReqIndex ]; len = 1; } break; @@ -241,6 +284,8 @@ void USBFS_IRQHandler() break; } } +#else + ; #endif } else @@ -257,7 +302,7 @@ void USBFS_IRQHandler() { if( e->lIndexValue == USBFS_IndexValue ) { - ctx->pUSBFS_Descr = e->addr; + ctx->pCtrlPayloadPtr = (uint8_t*)e->addr; len = e->length; break; } @@ -267,18 +312,20 @@ void USBFS_IRQHandler() goto sendstall; } + /* Copy Descriptors to Endp0 DMA buffer */ - if( USBFS_SetupReqLen > len ) + int totalLen = USBFS_SetupReqLen; + if( totalLen > len ) { - USBFS_SetupReqLen = len; + totalLen = len; } - len = ( USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ) ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; - fastcopy( CTRL0BUFF, ctx->pUSBFS_Descr, len ); //memcpy( CTRL0BUFF, ctx->pUSBFS_Descr, len ); + len = ( totalLen >= DEF_USBD_UEP0_SIZE ) ? DEF_USBD_UEP0_SIZE : totalLen; + DMA7FastCopy( ctrl0buff, ctx->pCtrlPayloadPtr, len ); //memcpy( CTRL0BUFF, ctx->pCtrlPayloadPtr, len ); + ctx->USBFS_SetupReqLen = totalLen - len; + ctx->pCtrlPayloadPtr += len; USBFS->UEP0_TX_LEN = len; USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; - ctx->pUSBFS_Descr += len; goto replycomplete; - break; } /* Set usb address */ @@ -288,7 +335,7 @@ void USBFS_IRQHandler() /* Get usb configuration now set */ case USB_GET_CONFIGURATION: - CTRL0BUFF[0] = ctx->USBFS_DevConfig; + ctrl0buff[0] = ctx->USBFS_DevConfig; if( ctx->USBFS_SetupReqLen > 1 ) ctx->USBFS_SetupReqLen = 1; break; @@ -376,7 +423,7 @@ void USBFS_IRQHandler() /* This request allows the host to select another setting for the specified interface */ case USB_GET_INTERFACE: - CTRL0BUFF[0] = 0x00; + ctrl0buff[0] = 0x00; if( USBFS_SetupReqLen > 1 ) USBFS_SetupReqLen = 1; break; @@ -385,20 +432,20 @@ void USBFS_IRQHandler() /* host get status of specified device/interface/end-points */ case USB_GET_STATUS: - CTRL0BUFF[0] = 0x00; - CTRL0BUFF[1] = 0x00; + ctrl0buff[0] = 0x00; + ctrl0buff[1] = 0x00; if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) { #if FUSB_SUPPORTS_SLEEP - CTRL0BUFF[0] = (ctx->USBFS_DevSleepStatus & 0x01)<<1; + ctrl0buff[0] = (ctx->USBFS_DevSleepStatus & 0x01)<<1; #else - CTRL0BUFF[0] = 0x00; + ctrl0buff[0] = 0x00; #endif } else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { if( ( USBFS_SetupReqIndex & DEF_UEP_IN ) && ep < FUSB_CONFIG_EPS ) - CTRL0BUFF[0] = ( UEP_CTRL_H(ep) & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL; + ctrl0buff[0] = ( UEP_CTRL_H(ep) & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL; else goto sendstall; } @@ -489,19 +536,51 @@ void USBFS_IRQHandler() // Handle any other interrupts and just clear them out. *(uint16_t*)(&USBFS->INT_FG) = intfgst; - //intfgst = *(uint16_t*)(&USBFS->INT_FG); +#if FUSB_IO_PROFILE GPIOA->BSHR = 1<<16; +#endif + +#if FUSB_USE_HPE + asm volatile( "mret" ); +#endif } void USBFS_InternalFinishSetup() { - USBFS->UEP4_1_MOD = RB_UEP1_TX_EN; +#if FUSB_CONFIG_EPS > 4 + USBFS->UEP4_1_MOD = RB_UEP1_TX_EN | RB_UEP4_TX_EN; +#elif FUSB_CONFIG_EPS > 1 + USBFS->UEP4_1_MOD = RB_UEP1_TX_EN | RB_UEP4_TX_EN; +#endif + +#if FUSB_CONFIG_EPS > 3 + USBFS->UEP2_3_MOD = RB_UEP2_TX_EN | RB_UEP3_TX_EN; +#elif FUSB_CONFIG_EPS > 2 USBFS->UEP2_3_MOD = RB_UEP2_TX_EN; +#endif + USBFS->UEP567_MOD = 0; // This is really cursed. Somehow it doesn't explode. // But, normally the USB wants a separate buffer here. - USBFS->UEP0_DMA = (uintptr_t)CTRL0BUFF; + +#if FUSB_CONFIG_EPS > 4 + USBFS->UEP4_DMA = (uintptr_t)FSUSBCTX.ENDPOINTS[4]; +#endif +#if FUSB_CONFIG_EPS > 3 + USBFS->UEP3_DMA = (uintptr_t)FSUSBCTX.ENDPOINTS[3]; +#endif +#if FUSB_CONFIG_EPS > 2 + USBFS->UEP2_DMA = (uintptr_t)FSUSBCTX.ENDPOINTS[2]; +#endif +#if FUSB_CONFIG_EPS > 1 + USBFS->UEP1_DMA = (uintptr_t)FSUSBCTX.ENDPOINTS[1]; +#endif +#if FUSB_CONFIG_EPS > 0 + USBFS->UEP0_DMA = (uintptr_t)FSUSBCTX.ENDPOINTS[0]; +#else +#error You must have at least EP0! +#endif UEP_CTRL_H(0) = USBFS_UEP_R_RES_ACK | USBFS_UEP_T_RES_NAK; int i; @@ -572,5 +651,21 @@ int FSUSBSetup() return 0; } +// To TX, you can use USBFS_GetEPBufferIfAvailable or USBFSD_UEP_DMA( endp ) + +static inline uint8_t * USBFS_GetEPBufferIfAvailable( int endp ) +{ + if( FSUSBCTX.USBFS_Endp_Busy[ endp ] ) return 0; + return USBFSD_UEP_BUF( endp ); +} + +static inline void USBFS_SendEndpoint( int endp, int len ) +{ + USBFSD_UEP_TLEN( endp ) = len; + USBFSD_UEP_TX_CTRL( endp ) = ( USBFSD_UEP_TX_CTRL( endp ) & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_ACK; + FSUSBCTX.USBFS_Endp_Busy[ endp ] = 0x01; +} + + diff --git a/examples_x035/usbdevice.incomplete/fsusb.h b/examples_x035/usbdevice/fsusb.h similarity index 52% rename from examples_x035/usbdevice.incomplete/fsusb.h rename to examples_x035/usbdevice/fsusb.h index 3eb4f21f..8533b836 100644 --- a/examples_x035/usbdevice.incomplete/fsusb.h +++ b/examples_x035/usbdevice/fsusb.h @@ -27,18 +27,27 @@ extern uint32_t USBDEBUG0, USBDEBUG1, USBDEBUG2; struct _USBState; +// Provided functions: int FSUSBSetup(); 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 void USBFS_SendEndpoint( int endp, int len ); +static inline uint8_t * USBFS_GetEPBufferIfAvailable( int endp ); +static inline void USBFS_SendEndpoint( int endp, int len ); + +static inline void DMA7FastCopy( uint8_t * dest, const uint8_t * src, int len ); +static inline void DMA7FastCopyComplete(); + + // Implement the following: -#if FUSB_HID_NONSTANDARD -int HandleHidUserReportSetup( struct _USBState * ctx, tusb_control_request_t * req ); -int HandleHidUserReportOut( struct _USBState * ctx, uint8_t * data, int len ); -void HandleHidUserReportIn( struct _USBState * ctx, uint8_t * data, int len ); +#if FUSB_HID_USER_REPORTS +int HandleHidUserGetReportSetup( struct _USBState * ctx, tusb_control_request_t * req ); +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 @@ -47,45 +56,35 @@ void HandleHidUserReportIn( struct _USBState * ctx, uint8_t * data, int len ); struct _USBState { // Setup Request - volatile uint8_t USBFS_SetupReqCode; - volatile uint8_t USBFS_SetupReqType; - volatile uint16_t USBFS_SetupReqLen; - volatile uint32_t USBFS_IndexValue; + 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 - volatile uint8_t USBFS_DevConfig; - volatile uint8_t USBFS_DevAddr; - volatile uint8_t USBFS_DevSleepStatus; - volatile uint8_t USBFS_DevEnumStatus; + uint8_t USBFS_DevConfig; + uint8_t USBFS_DevAddr; + uint8_t USBFS_DevSleepStatus; + uint8_t USBFS_DevEnumStatus; - #define pUSBFS_SetupReqPak ((tusb_control_request_t*)USBFSD_UEP_BUF(0)) - #define CTRL0BUFF USBFSD_UEP_BUF(0) + uint8_t * pCtrlPayloadPtr; + + uint8_t ENDPOINTS[FUSB_CONFIG_EPS][64]; + + #define CTRL0BUFF (FSUSBCTX.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]; - const uint8_t *pUSBFS_Descr; }; extern struct _USBState FSUSBCTX; -// To TX, you can use USBFS_GetEPBufferIfAvailable or USBFSD_UEP_DMA( endp ) -static inline uint8_t * USBFS_GetEPBufferIfAvailable( int endp ) -{ - if( FSUSBCTX.USBFS_Endp_Busy[ endp ] ) return 0; - return USBFSD_UEP_BUF( endp ); -} - -static inline void USBFS_SendEndpoint( int endp, int len ) -{ - USBFSD_UEP_TLEN( endp ) = len; - USBFSD_UEP_TX_CTRL( endp ) = ( USBFSD_UEP_TX_CTRL( endp ) & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_ACK; - FSUSBCTX.USBFS_Endp_Busy[ endp ] = 0x01; -} +#include "fsusb.c" #endif diff --git a/examples_x035/usbdevice.incomplete/funconfig.h b/examples_x035/usbdevice/funconfig.h similarity index 100% rename from examples_x035/usbdevice.incomplete/funconfig.h rename to examples_x035/usbdevice/funconfig.h diff --git a/examples_x035/usbdevice.incomplete/testtop/Makefile b/examples_x035/usbdevice/testtop.hidapi/Makefile similarity index 100% rename from examples_x035/usbdevice.incomplete/testtop/Makefile rename to examples_x035/usbdevice/testtop.hidapi/Makefile diff --git a/examples_x035/usbdevice.incomplete/testtop/os_generic.h b/examples_x035/usbdevice/testtop.hidapi/os_generic.h similarity index 100% rename from examples_x035/usbdevice.incomplete/testtop/os_generic.h rename to examples_x035/usbdevice/testtop.hidapi/os_generic.h diff --git a/examples_x035/usbdevice.incomplete/testtop/testtop.c b/examples_x035/usbdevice/testtop.hidapi/testtop.c similarity index 98% rename from examples_x035/usbdevice.incomplete/testtop/testtop.c rename to examples_x035/usbdevice/testtop.hidapi/testtop.c index 87f8ef8b..3ceb7ec1 100644 --- a/examples_x035/usbdevice.incomplete/testtop/testtop.c +++ b/examples_x035/usbdevice/testtop.hidapi/testtop.c @@ -38,7 +38,7 @@ int main() // But we can fill in random for the rest. for( i = 1; i < sizeof( buffer0 ); i ++ ) - buffer0[i] = 0xbb;//rand(); + buffer0[i] = i;//rand(); if( buffer0[1] == 0xa4 ) buffer0[1]++; diff --git a/examples_x035/usbdevice.incomplete/testtop/winbuild.bat b/examples_x035/usbdevice/testtop.hidapi/winbuild.bat similarity index 100% rename from examples_x035/usbdevice.incomplete/testtop/winbuild.bat rename to examples_x035/usbdevice/testtop.hidapi/winbuild.bat diff --git a/examples_x035/usbdevice.incomplete/usb_config.h b/examples_x035/usbdevice/usb_config.h similarity index 98% rename from examples_x035/usbdevice.incomplete/usb_config.h rename to examples_x035/usbdevice/usb_config.h index 5ed6ce3f..82800e46 100644 --- a/examples_x035/usbdevice.incomplete/usb_config.h +++ b/examples_x035/usbdevice/usb_config.h @@ -5,9 +5,10 @@ #define FUSB_CONFIG_EPS 3 // Include EP0 in this count #define FUSB_SUPPORTS_SLEEP 0 #define FUSB_HID_INTERFACES 2 -#define FUSB_CURSED_TURBO_DMA 1 +#define FUSB_CURSED_TURBO_DMA 0 // Hacky, but seems fine, shaves 2.5us off filling 64-byte buffers. #define FUSB_HID_USER_REPORTS 1 - +#define FUSB_USE_HPE 1 // Use hardware stack. +#define FUSB_IO_PROFILE 1 #include "usb_defines.h" diff --git a/examples_x035/usbdevice.incomplete/usb_defines.h b/examples_x035/usbdevice/usb_defines.h similarity index 91% rename from examples_x035/usbdevice.incomplete/usb_defines.h rename to examples_x035/usbdevice/usb_defines.h index 3abf670c..02d8f456 100644 --- a/examples_x035/usbdevice.incomplete/usb_defines.h +++ b/examples_x035/usbdevice/usb_defines.h @@ -557,6 +557,191 @@ static inline uint8_t tu_desc_len(void const* desc) #define TU_BIT( x ) (1<<(x)) #endif +/* USB constant and structure define */ + +/* USB PID */ +#ifndef USB_PID_SETUP + #define USB_PID_NULL 0x00 /* reserved PID */ + #define USB_PID_SOF 0x05 + #define USB_PID_SETUP 0x0D + #define USB_PID_IN 0x09 + #define USB_PID_OUT 0x01 + #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_PRE 0x0C +#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 + +/* 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 + +/* USB CDC Class request code */ +#ifndef CDC_GET_LINE_CODING +#define CDC_GET_LINE_CODING 0X21 /* This request allows the host to find out the currently configured line coding */ +#define CDC_SET_LINE_CODING 0x20 /* Configures DTE rate, stop-bits, parity, and number-of-character */ +#define CDC_SET_LINE_CTLSTE 0X22 /* This request generates RS-232/V.24 style control signals */ +#define CDC_SEND_BREAK 0X23 /* Sends special carrier modulation used to specify RS-232 style break */ +#endif + +/* Bit define for USB request type */ +#ifndef USB_REQ_TYP_MASK + #define USB_REQ_TYP_IN 0x80 /* control IN, device to host */ + #define USB_REQ_TYP_OUT 0x00 /* control OUT, host to device */ + #define USB_REQ_TYP_READ 0x80 /* control read, device to host */ + #define USB_REQ_TYP_WRITE 0x00 /* control write, host to device */ + #define USB_REQ_TYP_MASK 0x60 /* bit mask of request type */ + #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 /* bit mask of request recipient */ + #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 request type for 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 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_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_IMAGE 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 endpoint type and attributes */ +#ifndef USB_ENDP_TYPE_MASK + #define USB_ENDP_DIR_MASK 0x80 + #define USB_ENDP_ADDR_MASK 0x0F + #define USB_ENDP_TYPE_MASK 0x03 + #define USB_ENDP_TYPE_CTRL 0x00 + #define USB_ENDP_TYPE_ISOCH 0x01 + #define USB_ENDP_TYPE_BULK 0x02 + #define USB_ENDP_TYPE_INTER 0x03 +#endif + +#ifndef USB_DEVICE_ADDR + #define USB_DEVICE_ADDR 0x02 +#endif +#ifndef DEFAULT_ENDP0_SIZE + #define DEFAULT_ENDP0_SIZE 8 /* default maximum packet size for endpoint 0 */ +#endif +#ifndef MAX_PACKET_SIZE + #define MAX_PACKET_SIZE 64 /* maximum packet size */ +#endif +#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 + +#define DEF_STRING_DESC_LANG 0x00 +#define DEF_STRING_DESC_MANU 0x01 +#define DEF_STRING_DESC_PROD 0x02 +#define DEF_STRING_DESC_SERN 0x03 + + //--------------------------------------------------------------------+ // Common Definitions //--------------------------------------------------------------------+ diff --git a/examples_x035/usbdevice/usbdevice.c b/examples_x035/usbdevice/usbdevice.c new file mode 100644 index 00000000..c3280a38 --- /dev/null +++ b/examples_x035/usbdevice/usbdevice.c @@ -0,0 +1,87 @@ +/* Small example showing how to use the SWIO programming pin to + do printf through the debug interface */ + +#include "ch32v003fun.h" +#include +#include +#include "fsusb.h" + +uint32_t count; + +int last = 0; +void handle_debug_input( int numbytes, uint8_t * data ) +{ + last = data[0]; + count += numbytes; +} + +uint8_t scratchpad[256]; + +int HandleHidUserSetReportSetup( struct _USBState * ctx, tusb_control_request_t * req ) +{ + int id = req->wValue & 0xff; + if( id == 0xaa ) + { + // memset( scratchpad, 0x55, sizeof(scratchpad) ); + // printf( "SET REPORT! %d [%02x]\n", req->wLength, scratchpad[200] ); + ctx->pCtrlPayloadPtr = scratchpad; + return req->wLength; + } + return 0; +} + +int HandleHidUserGetReportSetup( struct _USBState * ctx, tusb_control_request_t * req ) +{ + int id = req->wValue & 0xff; + if( id == 0xaa ) + { + //printf( "GET REPORT! %d\n", req->wLength ); + ctx->pCtrlPayloadPtr = scratchpad; + return 255; + } + return 0; +} + +void HandleHidUserReportDataOut( struct _USBState * ctx, uint8_t * data, int len ) +{ +} + +int HandleHidUserReportDataIn( struct _USBState * ctx, uint8_t * data, int len ) +{ +// printf( "IN %d %d %08x %08x\n", len, ctx->USBFS_SetupReqLen, data, FSUSBCTX.ENDPOINTS[0] ); +// memset( data, 0xcc, len ); + return len; +} + +void HandleHidUserReportOutComplete( struct _USBState * ctx ) +{ + return; +} + +int main() +{ + SystemInit(); + + funGpioInitAll(); + + funPinMode( PA0, GPIO_CFGLR_OUT_10Mhz_PP ); + + FSUSBSetup(); + + while(1) + { + //printf( "%lu %08lx %lu %d %d\n", USBDEBUG0, USBDEBUG1, USBDEBUG2, 0, 0 ); + int i; + for( i = 1; i < 3; i++ ) + { + + uint32_t * buffer = (uint32_t*)USBFS_GetEPBufferIfAvailable( i ); + if( buffer ) + { + buffer[0] = 0x000000aa; + USBFS_SendEndpoint( i, (i==1)?8:4 ); + } + } + } +} +