diff --git a/examples_x035/usbdevice.incomplete/fsusb.c b/examples_x035/usbdevice.incomplete/fsusb.c index 8ebb3c7ea8081becbf319f6a3e9127e60d7c7492..4c43708b7d9ccc0fb78058f860da40c7398e2936 100644 --- a/examples_x035/usbdevice.incomplete/fsusb.c +++ b/examples_x035/usbdevice.incomplete/fsusb.c @@ -115,7 +115,7 @@ void USBFS_IRQHandler() if ( ( ctx->USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { - /* Non-standard request endpoint 0 Data upload, noted by official docs, but I don't think this would ever really be used. */ + // Handle other control requests here. } else { @@ -136,6 +136,17 @@ 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; } } @@ -150,32 +161,22 @@ void USBFS_IRQHandler() case DEF_UEP0: if( intfgst & CRB_UIS_TOG_OK ) { - if( ( FSUSBCTX.USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) + +#if FUSB_HID_USER_REPORTS + int r = HandleHidUserReportDataOut( ctx, CTRL0BUFF, USBFS->RX_LEN ); + if( r >= 0 ) { - if( ( FSUSBCTX.USBFS_SetupReqType & USB_REQ_TYP_MASK ) == USB_REQ_TYP_CLASS ) - { - switch( FSUSBCTX.USBFS_SetupReqCode ) - { - case HID_SET_REPORT: - //KB_LED_Cur_Status = USBFS_EP0_Buf[ 0 ]; - FSUSBCTX.USBFS_SetupReqLen = 0; - break; - default: - break; - } - } + USBFS->UEP0_TX_LEN = r; + USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; } else +#endif + if( FSUSBCTX.USBFS_SetupReqLen == 0 ) { - /* Standard request end-point 0 Data download */ - /* Add your code here */ + USBFS->UEP0_TX_LEN = 0; + USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; } } - if( FSUSBCTX.USBFS_SetupReqLen == 0 ) - { - USBFS->UEP0_TX_LEN = 0; - USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; - } break; default: @@ -197,6 +198,10 @@ void USBFS_IRQHandler() 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 ) { diff --git a/examples_x035/usbdevice.incomplete/fsusb.h b/examples_x035/usbdevice.incomplete/fsusb.h index beae51dcc74990237e32835812796fc96a2bbdfd..3eb4f21f84bb0e15804062f8f46bdaa93d100d7c 100644 --- a/examples_x035/usbdevice.incomplete/fsusb.h +++ b/examples_x035/usbdevice.incomplete/fsusb.h @@ -25,6 +25,8 @@ extern uint32_t USBDEBUG0, USBDEBUG1, USBDEBUG2; +struct _USBState; + int FSUSBSetup(); uint8_t USBFS_Endp_DataUp(uint8_t endp, const uint8_t *pbuf, uint16_t len, uint8_t mod); @@ -32,6 +34,16 @@ static inline uint8_t * USBFS_GetEPBufferIfAvailable( int endp ); static inline void USBFS_SendEndpoint( int endp, int len ); +// 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 ); +#endif + + + + struct _USBState { // Setup Request diff --git a/examples_x035/usbdevice.incomplete/testtop/Makefile b/examples_x035/usbdevice.incomplete/testtop/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7094e41d7f3699e326236fd17012bb2008508e6f --- /dev/null +++ b/examples_x035/usbdevice.incomplete/testtop/Makefile @@ -0,0 +1,8 @@ +all : testtop + +testtop : testtop.c + gcc -o $@ $^ -I../../../minichlink -ludev + +clean : + rm -rf *.o *~ testtop + diff --git a/examples_x035/usbdevice.incomplete/testtop/os_generic.h b/examples_x035/usbdevice.incomplete/testtop/os_generic.h new file mode 100644 index 0000000000000000000000000000000000000000..6bd7c1e882073b7a4bf0ab8fa226fee452ef771a --- /dev/null +++ b/examples_x035/usbdevice.incomplete/testtop/os_generic.h @@ -0,0 +1,521 @@ +#ifndef _OS_GENERIC_H +#define _OS_GENERIC_H +/* + "osgeneric" Generic, platform independent tool for threads and time. + Geared around Windows and Linux. Designed for operation on MSVC, + TCC, GCC and clang. Others may work. + + It offers the following operations: + + Delay functions: + void OGSleep( int is ); + void OGUSleep( int ius ); + + Getting current time (may be time from program start, boot, or epoc) + double OGGetAbsoluteTime(); + double OGGetFileTime( const char * file ); + + Thread functions + og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter ); + void * OGJoinThread( og_thread_t ot ); + void OGCancelThread( og_thread_t ot ); + + Mutex functions, used for protecting data structures. + (recursive on platforms where available.) + og_mutex_t OGCreateMutex(); + void OGLockMutex( og_mutex_t om ); + void OGUnlockMutex( og_mutex_t om ); + void OGDeleteMutex( og_mutex_t om ); + + Always a semaphore (not recursive) + og_sema_t OGCreateSema(); //Create a semaphore, comes locked initially. + NOTE: For platform compatibility, max count is 32767 + void OGLockSema( og_sema_t os ); + int OGGetSema( og_sema_t os ); //if <0 there was a failure. + void OGUnlockSema( og_sema_t os ); + void OGDeleteSema( og_sema_t os ); + + TLS (Thread-Local Storage) + og_tls_t OGCreateTLS(); + void OGDeleteTLS( og_tls_t tls ); + void OGSetTLS( og_tls_t tls, void * data ); + void * OGGetTLS( og_tls_t tls ); + + You can permute the operations of this file by the following means: + OSG_NO_IMPLEMENTATION + OSG_PREFIX + OSG_NOSTATIC + + The default behavior is to do static inline. + + Copyright (c) 2011-2012,2013,2016,2018,2019,2020 <>< Charles Lohr + + This file may be licensed under the MIT/x11 license, NewBSD or CC0 licenses + + 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 this file. + + 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. + + Date Stamp: 2019-09-05 CNL: Allow for noninstantiation and added TLS. + Date Stamp: 2018-03-25 CNL: Switched to header-only format. +*/ + + +#if defined( OSG_NOSTATIC ) && OSG_NOSTATIC != 0 +#ifndef OSG_PREFIX +#define OSG_PREFIX +#endif +#ifndef OSG_NO_IMPLEMENTATION +#define OSG_NO_IMPLEMENTATION +#endif +#endif + +#ifndef OSG_PREFIX +#ifdef __wasm__ +#define OSG_PREFIX +#else +#define OSG_PREFIX static inline +#endif +#endif + +//In case you want to hook the closure of a thread, i.e. if your system has thread-local storage. +#ifndef OSG_TERM_THREAD_CODE +#define OSG_TERM_THREAD_CODE +#endif + +typedef void* og_thread_t; +typedef void* og_mutex_t; +typedef void* og_sema_t; +typedef void* og_tls_t; + +#ifdef __cplusplus +extern "C" { +#endif + +OSG_PREFIX void OGSleep( int is ); +OSG_PREFIX void OGUSleep( int ius ); +OSG_PREFIX double OGGetAbsoluteTime(); +OSG_PREFIX double OGGetFileTime( const char * file ); +OSG_PREFIX og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter ); +OSG_PREFIX void * OGJoinThread( og_thread_t ot ); +OSG_PREFIX void OGCancelThread( og_thread_t ot ); +OSG_PREFIX og_mutex_t OGCreateMutex(); +OSG_PREFIX void OGLockMutex( og_mutex_t om ); +OSG_PREFIX void OGUnlockMutex( og_mutex_t om ); +OSG_PREFIX void OGDeleteMutex( og_mutex_t om ); +OSG_PREFIX og_sema_t OGCreateSema(); +OSG_PREFIX int OGGetSema( og_sema_t os ); +OSG_PREFIX void OGLockSema( og_sema_t os ); +OSG_PREFIX void OGUnlockSema( og_sema_t os ); +OSG_PREFIX void OGDeleteSema( og_sema_t os ); +OSG_PREFIX og_tls_t OGCreateTLS(); +OSG_PREFIX void OGDeleteTLS( og_tls_t key ); +OSG_PREFIX void * OGGetTLS( og_tls_t key ); +OSG_PREFIX void OGSetTLS( og_tls_t key, void * data ); + +#ifdef __cplusplus +}; +#endif + +#ifndef OSG_NO_IMPLEMENTATION + +#if defined( WIN32 ) || defined (WINDOWS) || defined( _WIN32) +#define USE_WINDOWS +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef USE_WINDOWS + +#include <windows.h> +#include <stdint.h> + +OSG_PREFIX void OGSleep( int is ) +{ + Sleep( is*1000 ); +} + +OSG_PREFIX void OGUSleep( int ius ) +{ + Sleep( ius/1000 ); +} + +OSG_PREFIX double OGGetAbsoluteTime() +{ + static LARGE_INTEGER lpf; + LARGE_INTEGER li; + + if( !lpf.QuadPart ) + { + QueryPerformanceFrequency( &lpf ); + } + + QueryPerformanceCounter( &li ); + return (double)li.QuadPart / (double)lpf.QuadPart; +} + + +OSG_PREFIX double OGGetFileTime( const char * file ) +{ + FILETIME ft; + + HANDLE h = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + + if( h==INVALID_HANDLE_VALUE ) + return -1; + + GetFileTime( h, 0, 0, &ft ); + + CloseHandle( h ); + + return ft.dwHighDateTime + ft.dwLowDateTime; +} + + +OSG_PREFIX og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter ) +{ + return (og_thread_t)CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)routine, parameter, 0, 0 ); +} + +OSG_PREFIX void * OGJoinThread( og_thread_t ot ) +{ + WaitForSingleObject( ot, INFINITE ); + OSG_TERM_THREAD_CODE + CloseHandle( ot ); + return 0; +} + +OSG_PREFIX void OGCancelThread( og_thread_t ot ) +{ + OSG_TERM_THREAD_CODE + TerminateThread( ot, 0); + CloseHandle( ot ); +} + +OSG_PREFIX og_mutex_t OGCreateMutex() +{ + return CreateMutex( 0, 0, 0 ); +} + +OSG_PREFIX void OGLockMutex( og_mutex_t om ) +{ + WaitForSingleObject(om, INFINITE); +} + +OSG_PREFIX void OGUnlockMutex( og_mutex_t om ) +{ + ReleaseMutex(om); +} + +OSG_PREFIX void OGDeleteMutex( og_mutex_t om ) +{ + CloseHandle( om ); +} + + + +OSG_PREFIX og_sema_t OGCreateSema() +{ + HANDLE sem = CreateSemaphore( 0, 0, 32767, 0 ); + return (og_sema_t)sem; +} + +OSG_PREFIX int OGGetSema( og_sema_t os ) +{ + typedef LONG NTSTATUS; + HANDLE sem = (HANDLE)os; + typedef NTSTATUS (NTAPI *_NtQuerySemaphore)( + HANDLE SemaphoreHandle, + DWORD SemaphoreInformationClass, /* Would be SEMAPHORE_INFORMATION_CLASS */ + PVOID SemaphoreInformation, /* but this is to much to dump here */ + ULONG SemaphoreInformationLength, + PULONG ReturnLength OPTIONAL + ); + + typedef struct _SEMAPHORE_BASIC_INFORMATION { + ULONG CurrentCount; + ULONG MaximumCount; + } SEMAPHORE_BASIC_INFORMATION; + + + static _NtQuerySemaphore NtQuerySemaphore; + SEMAPHORE_BASIC_INFORMATION BasicInfo; + NTSTATUS Status; + + if( !NtQuerySemaphore ) + { + NtQuerySemaphore = (_NtQuerySemaphore)GetProcAddress (GetModuleHandle ("ntdll.dll"), "NtQuerySemaphore"); + if( !NtQuerySemaphore ) + { + return -1; + } + } + + + Status = NtQuerySemaphore (sem, 0 /*SemaphoreBasicInformation*/, + &BasicInfo, sizeof (SEMAPHORE_BASIC_INFORMATION), NULL); + + if (Status == ERROR_SUCCESS) + { + return BasicInfo.CurrentCount; + } + + return -2; +} + +OSG_PREFIX void OGLockSema( og_sema_t os ) +{ + WaitForSingleObject( (HANDLE)os, INFINITE ); +} + +OSG_PREFIX void OGUnlockSema( og_sema_t os ) +{ + ReleaseSemaphore( (HANDLE)os, 1, 0 ); +} + +OSG_PREFIX void OGDeleteSema( og_sema_t os ) +{ + CloseHandle( os ); +} + +OSG_PREFIX og_tls_t OGCreateTLS() +{ + return (og_tls_t)(intptr_t)TlsAlloc(); +} + +OSG_PREFIX void OGDeleteTLS( og_tls_t key ) +{ + TlsFree( (DWORD)(intptr_t)key ); +} + +OSG_PREFIX void * OGGetTLS( og_tls_t key ) +{ + return TlsGetValue( (DWORD)(intptr_t)key ); +} + +OSG_PREFIX void OGSetTLS( og_tls_t key, void * data ) +{ + TlsSetValue( (DWORD)(intptr_t)key, data ); +} + +#elif defined( __wasm__ ) + +//We don't actually have any function defintions here. +//The outside system will handle it. + +#else + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <sys/stat.h> +#include <stdlib.h> +#include <pthread.h> +#include <sys/time.h> +#include <semaphore.h> +#include <unistd.h> + +OSG_PREFIX void OGSleep( int is ) +{ + sleep( is ); +} + +OSG_PREFIX void OGUSleep( int ius ) +{ + usleep( ius ); +} + +OSG_PREFIX double OGGetAbsoluteTime() +{ + struct timeval tv; + gettimeofday( &tv, 0 ); + return ((double)tv.tv_usec)/1000000. + (tv.tv_sec); +} + +OSG_PREFIX double OGGetFileTime( const char * file ) +{ + struct stat buff; + + int r = stat( file, &buff ); + + if( r < 0 ) + { + return -1; + } + + return buff.st_mtime; +} + + + +OSG_PREFIX og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter ) +{ + pthread_t * ret = (pthread_t *)malloc( sizeof( pthread_t ) ); + if( !ret ) return 0; + int r = pthread_create( ret, 0, routine, parameter ); + if( r ) + { + free( ret ); + return 0; + } + return (og_thread_t)ret; +} + +OSG_PREFIX void * OGJoinThread( og_thread_t ot ) +{ + void * retval; + if( !ot ) + { + return 0; + } + pthread_join( *(pthread_t*)ot, &retval ); + OSG_TERM_THREAD_CODE + free( ot ); + return retval; +} + +OSG_PREFIX void OGCancelThread( og_thread_t ot ) +{ + if( !ot ) + { + return; + } +#ifdef ANDROID + pthread_kill( *(pthread_t*)ot, SIGTERM ); +#else + pthread_cancel( *(pthread_t*)ot ); +#endif + OSG_TERM_THREAD_CODE + free( ot ); +} + +OSG_PREFIX og_mutex_t OGCreateMutex() +{ + pthread_mutexattr_t mta; + og_mutex_t r = malloc( sizeof( pthread_mutex_t ) ); + if( !r ) return 0; + + pthread_mutexattr_init(&mta); + pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE); + + pthread_mutex_init( (pthread_mutex_t *)r, &mta ); + + return r; +} + +OSG_PREFIX void OGLockMutex( og_mutex_t om ) +{ + if( !om ) + { + return; + } + pthread_mutex_lock( (pthread_mutex_t*)om ); +} + +OSG_PREFIX void OGUnlockMutex( og_mutex_t om ) +{ + if( !om ) + { + return; + } + pthread_mutex_unlock( (pthread_mutex_t*)om ); +} + +OSG_PREFIX void OGDeleteMutex( og_mutex_t om ) +{ + if( !om ) + { + return; + } + + pthread_mutex_destroy( (pthread_mutex_t*)om ); + free( om ); +} + + + + +OSG_PREFIX og_sema_t OGCreateSema() +{ + sem_t * sem = (sem_t *)malloc( sizeof( sem_t ) ); + if( !sem ) return 0; + sem_init( sem, 0, 0 ); + return (og_sema_t)sem; +} + +OSG_PREFIX int OGGetSema( og_sema_t os ) +{ + int valp; + sem_getvalue( (sem_t*)os, &valp ); + return valp; +} + + +OSG_PREFIX void OGLockSema( og_sema_t os ) +{ + sem_wait( (sem_t*)os ); +} + +OSG_PREFIX void OGUnlockSema( og_sema_t os ) +{ + sem_post( (sem_t*)os ); +} + +OSG_PREFIX void OGDeleteSema( og_sema_t os ) +{ + sem_destroy( (sem_t*)os ); + free(os); +} + +OSG_PREFIX og_tls_t OGCreateTLS() +{ + pthread_key_t ret = 0; + pthread_key_create(&ret, 0); + return (og_tls_t)(intptr_t)ret; +} + +OSG_PREFIX void OGDeleteTLS( og_tls_t key ) +{ + pthread_key_delete( (pthread_key_t)(intptr_t)key ); +} + +OSG_PREFIX void * OGGetTLS( og_tls_t key ) +{ + return pthread_getspecific( (pthread_key_t)(intptr_t)key ); +} + +OSG_PREFIX void OGSetTLS( og_tls_t key, void * data ) +{ + pthread_setspecific( (pthread_key_t)(intptr_t)key, data ); +} + +#endif + +#ifdef __cplusplus +}; +#endif + +#endif //OSG_NO_IMPLEMENTATION + +#endif //_OS_GENERIC_H + + diff --git a/examples_x035/usbdevice.incomplete/testtop/testtop.c b/examples_x035/usbdevice.incomplete/testtop/testtop.c new file mode 100644 index 0000000000000000000000000000000000000000..87f8ef8b28fa314b09c9a60785600f8c28398bbb --- /dev/null +++ b/examples_x035/usbdevice.incomplete/testtop/testtop.c @@ -0,0 +1,91 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +// We borrow the combined hidapi.c from minichlink. +// +// This is for total perf testing. + +#include "hidapi.c" + +#include "os_generic.h" + +int main() +{ + hid_device * hd = hid_open( 0xaaaa, 0xd004, L"CUSTOMDEVICE000"); // third parameter is "serial" + if( !hd ) + { + fprintf( stderr, "Error: Failed to open device.\n" ); + return -4; + } + + // Size of buffers must match the report descriptor size in the special_hid_desc + // NOTE: You are permitted to have multiple entries. + uint8_t buffer0[255] = { 0 }; // NOTE: This must be ONE MORE THAN what is in the hid descriptor. + uint8_t buffer1[255] = { 0 }; + int r; + int i; + int j; + int retries = 0; + double dStart = OGGetAbsoluteTime(); + double dSecond = dStart; + double dStartSend = 0.0; + double dSendTotal = 0; + double dRecvTotal = 0; + for( j = 0; ; j++ ) + { + buffer0[0] = 0xaa; // First byte must match the ID. + + // But we can fill in random for the rest. + for( i = 1; i < sizeof( buffer0 ); i ++ ) + buffer0[i] = 0xbb;//rand(); + + if( buffer0[1] == 0xa4 ) buffer0[1]++; + + retrysend: + + dStartSend = OGGetAbsoluteTime(); + r = hid_send_feature_report( hd, buffer0, sizeof(buffer0) ); + dSendTotal += OGGetAbsoluteTime() - dStartSend; + if( r != sizeof(buffer0) ) + { + fprintf( stderr, "Warning: HID Send fault (%d) Retrying\n", r ); + retries++; + if( retries > 10 ) break; + goto retrysend; + } + + retries = 0; + printf( "<" ); // Print this out meaning we sent the data. + + memset( buffer1, 0xff, sizeof( buffer1 ) ); + buffer1[0] = 0xaa; // First byte must be ID. + + double dStartRecv = OGGetAbsoluteTime(); + r = hid_get_feature_report( hd, buffer1, sizeof(buffer1) ); + dRecvTotal += OGGetAbsoluteTime() - dStartRecv; + + printf( ">" ); fflush( stdout); + + if( r != sizeof( buffer1 ) && r != sizeof( buffer1 ) + 1) { printf( "Got %d\n", r ); break; } + + // Validate the scratches matched. + if( memcmp( buffer0, buffer1, sizeof( buffer0 ) ) != 0 ) + { + printf( "%d: ", r ); + for( i = 0; i < r; i++ ) + printf( "[%d] %02x>%02x %s", i, buffer0[i], buffer1[i], (buffer1[i] != buffer0[i])?"MISMATCH ":"" ); + printf( "\n" ); + break; + } + + if( dStartRecv - dSecond > 1.0 ) + { + printf( "\n%2.3f KB/s PC->003 / %2.3f KB/s 003->PC\n", j * .249 / dSendTotal, j * .249 / dRecvTotal ); + dSecond++; + } + } + + hid_close( hd ); +} + diff --git a/examples_x035/usbdevice.incomplete/testtop/winbuild.bat b/examples_x035/usbdevice.incomplete/testtop/winbuild.bat new file mode 100644 index 0000000000000000000000000000000000000000..250ad79e51cb84f2972d04f35eb399186b5852e1 --- /dev/null +++ b/examples_x035/usbdevice.incomplete/testtop/winbuild.bat @@ -0,0 +1 @@ +tcc testtop.c -I../../ch32v003fun/minichlink -lsetupapi diff --git a/examples_x035/usbdevice.incomplete/usb_config.h b/examples_x035/usbdevice.incomplete/usb_config.h index fce35fdeb0d67a2d95d5dd282d60b1caf6782f09..310d52554cfafce1a24240a710c958795b8b480e 100644 --- a/examples_x035/usbdevice.incomplete/usb_config.h +++ b/examples_x035/usbdevice.incomplete/usb_config.h @@ -4,11 +4,12 @@ #define FUSB_5V_OPERATION 0 #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_HID_NONSTANDARD 1 -#define FUSB_CURSED_TURBO_DMA 1 +#include "usb_defines.h" //Taken from http://www.usbmadesimple.co.uk/ums_ms_desc_dev.htm static const uint8_t device_descriptor[] = { @@ -136,6 +137,22 @@ static const uint8_t KeyRepDesc[ ] = 0x29, 0x91, // Usage Maximum (145) 0x81, 0x00, // Input(Data,Array,Absolute) 0xC0 // End Collection +, + // TODO - Figure out how to work this in. + HID_USAGE_PAGE ( 0xff ), // Vendor-defined page. + HID_USAGE ( 0x00 ), + HID_REPORT_SIZE ( 8 ), + HID_COLLECTION ( HID_COLLECTION_LOGICAL ), + HID_REPORT_COUNT ( 254 ), + HID_REPORT_ID ( 0xaa ) + HID_USAGE ( 0x01 ), + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , + HID_REPORT_COUNT ( 63 ), // For use with `hidapitester --vidpid 1209/D003 --open --read-feature 171` + HID_REPORT_ID ( 0xab ) + HID_USAGE ( 0x01 ), + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , + HID_COLLECTION_END, + }; /* Mouse Report Descriptor */ @@ -171,8 +188,8 @@ static const uint8_t MouseRepDesc[ ] = }; -#define STR_MANUFACTURER u"WCH" -#define STR_PRODUCT u"CH32X035 Custom Device" +#define STR_MANUFACTURER u"WCH-TEST" +#define STR_PRODUCT u"ch32v003fun ch32x035 test" #define STR_SERIAL u"CUSTOMDEVICE000" struct usb_string_descriptor_struct { diff --git a/examples_x035/usbdevice.incomplete/usb_defines.h b/examples_x035/usbdevice.incomplete/usb_defines.h index 4fd18b68433d10408b992598c9fd3bb24b4657ea..3abf670cf5f8a205769de2160c23c345730f10f3 100644 --- a/examples_x035/usbdevice.incomplete/usb_defines.h +++ b/examples_x035/usbdevice.incomplete/usb_defines.h @@ -538,296 +538,1057 @@ static inline uint8_t tu_desc_len(void const* desc) } #endif -#endif /* _TUSB_TYPES_H_ */ - -/** @} */ +// from tinyusb_hid.h -#if 0 - -/* 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 Communication Related Macro Definition */ - -/* 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_PRE 0x0C +#ifdef __cplusplus + extern "C" { #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 TU_U16_HIGH(u16) ((uint8_t) (((u16) >> 8) & 0x00ff)) +#define TU_U16_LOW(u16) ((uint8_t) ((u16) & 0x00ff)) +#define U16_TO_U8S_BE(u16) TU_U16_HIGH(u16), TU_U16_LOW(u16) +#define U16_TO_U8S_LE(u16) TU_U16_LOW(u16), TU_U16_HIGH(u16) -#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 +#ifndef TU_ATTR_PACKED +#define TU_ATTR_PACKED __attribute__((packed)) #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 +#ifndef TU_BIT +#define TU_BIT( x ) (1<<(x)) #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 +//--------------------------------------------------------------------+ +// Common Definitions +//--------------------------------------------------------------------+ +/** \defgroup ClassDriver_HID_Common Common Definitions + * @{ */ -/* 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 HID Descriptor +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength; /**< Numeric expression that is the total size of the HID descriptor */ + uint8_t bDescriptorType; /**< Constant name specifying type of HID descriptor. */ -/* 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 + uint16_t bcdHID; /**< Numeric expression identifying the HID Class Specification release */ + uint8_t bCountryCode; /**< Numeric expression identifying country code of the localized hardware. */ + uint8_t bNumDescriptors; /**< Numeric expression specifying the number of class descriptors */ -/* 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 + uint8_t bReportType; /**< Type of HID class report. */ + uint16_t wReportLength; /**< the total size of the Report descriptor. */ +} tusb_hid_descriptor_hid_t; -/* 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 +/// HID Subclass +typedef enum +{ + HID_SUBCLASS_NONE = 0, ///< No Subclass + HID_SUBCLASS_BOOT = 1 ///< Boot Interface Subclass +}hid_subclass_type_t; -/* 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 +/// HID Protocol +typedef enum +{ + HID_PROTOCOL_NONE = 0, ///< None + HID_PROTOCOL_KEYBOARD = 1, ///< Keyboard + HID_PROTOCOL_MOUSE = 2 ///< Mouse +}hid_protocol_type_t; -/* 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 +/// HID Descriptor Type +typedef enum +{ + HID_DESC_TYPE_HID = 0x21, ///< HID Descriptor + HID_DESC_TYPE_REPORT = 0x22, ///< Report Descriptor + HID_DESC_TYPE_PHYSICAL = 0x23 ///< Physical Descriptor +}hid_descriptor_type_t; -/* 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 -/*******************************************************************************/ +/// HID Request Report Type +typedef enum +{ + HID_REPORT_TYPE_INVALID = 0, + HID_REPORT_TYPE_INPUT, ///< Input + HID_REPORT_TYPE_OUTPUT, ///< Output + HID_REPORT_TYPE_FEATURE ///< Feature +}hid_report_type_t; +/// HID Class Specific Control Request +typedef enum +{ + HID_REQ_CONTROL_GET_REPORT = 0x01, ///< Get Report + HID_REQ_CONTROL_GET_IDLE = 0x02, ///< Get Idle + HID_REQ_CONTROL_GET_PROTOCOL = 0x03, ///< Get Protocol + HID_REQ_CONTROL_SET_REPORT = 0x09, ///< Set Report + HID_REQ_CONTROL_SET_IDLE = 0x0a, ///< Set Idle + HID_REQ_CONTROL_SET_PROTOCOL = 0x0b ///< Set Protocol +}hid_request_type_t; + +/// HID Country Code +typedef enum +{ + HID_LOCAL_NotSupported = 0 , ///< NotSupported + HID_LOCAL_Arabic , ///< Arabic + HID_LOCAL_Belgian , ///< Belgian + HID_LOCAL_Canadian_Bilingual , ///< Canadian_Bilingual + HID_LOCAL_Canadian_French , ///< Canadian_French + HID_LOCAL_Czech_Republic , ///< Czech_Republic + HID_LOCAL_Danish , ///< Danish + HID_LOCAL_Finnish , ///< Finnish + HID_LOCAL_French , ///< French + HID_LOCAL_German , ///< German + HID_LOCAL_Greek , ///< Greek + HID_LOCAL_Hebrew , ///< Hebrew + HID_LOCAL_Hungary , ///< Hungary + HID_LOCAL_International , ///< International + HID_LOCAL_Italian , ///< Italian + HID_LOCAL_Japan_Katakana , ///< Japan_Katakana + HID_LOCAL_Korean , ///< Korean + HID_LOCAL_Latin_American , ///< Latin_American + HID_LOCAL_Netherlands_Dutch , ///< Netherlands/Dutch + HID_LOCAL_Norwegian , ///< Norwegian + HID_LOCAL_Persian_Farsi , ///< Persian (Farsi) + HID_LOCAL_Poland , ///< Poland + HID_LOCAL_Portuguese , ///< Portuguese + HID_LOCAL_Russia , ///< Russia + HID_LOCAL_Slovakia , ///< Slovakia + HID_LOCAL_Spanish , ///< Spanish + HID_LOCAL_Swedish , ///< Swedish + HID_LOCAL_Swiss_French , ///< Swiss/French + HID_LOCAL_Swiss_German , ///< Swiss/German + HID_LOCAL_Switzerland , ///< Switzerland + HID_LOCAL_Taiwan , ///< Taiwan + HID_LOCAL_Turkish_Q , ///< Turkish-Q + HID_LOCAL_UK , ///< UK + HID_LOCAL_US , ///< US + HID_LOCAL_Yugoslavia , ///< Yugoslavia + HID_LOCAL_Turkish_F ///< Turkish-F +} hid_country_code_t; + +/** @} */ +//--------------------------------------------------------------------+ +// GAMEPAD +//--------------------------------------------------------------------+ +/** \addtogroup ClassDriver_HID_Gamepad Gamepad + * @{ */ + +/* From https://www.kernel.org/doc/html/latest/input/gamepad.html + ____________________________ __ + / [__ZL__] [__ZR__] \ | + / [__ TL __] [__ TR __] \ | Front Triggers + __/________________________________\__ __| + / _ \ | + / /\ __ (N) \ | + / || __ |MO| __ _ _ \ | Main Pad + | <===DP===> |SE| |ST| (W) -|- (E) | | + \ || ___ ___ _ / | + /\ \/ / \ / \ (S) /\ __| + / \________ | LS | ____ | RS | ________/ \ | +| / \ \___/ / \ \___/ / \ | | Control Sticks +| / \_____/ \_____/ \ | __| +| / \ | + \_____/ \_____/ + + |________|______| |______|___________| + D-Pad Left Right Action Pad + Stick Stick + + |_____________| + Menu Pad + + Most gamepads have the following features: + - Action-Pad 4 buttons in diamonds-shape (on the right side) NORTH, SOUTH, WEST and EAST. + - D-Pad (Direction-pad) 4 buttons (on the left side) that point up, down, left and right. + - Menu-Pad Different constellations, but most-times 2 buttons: SELECT - START. + - Analog-Sticks provide freely moveable sticks to control directions, Analog-sticks may also + provide a digital button if you press them. + - Triggers are located on the upper-side of the pad in vertical direction. The upper buttons + are normally named Left- and Right-Triggers, the lower buttons Z-Left and Z-Right. + - Rumble Many devices provide force-feedback features. But are mostly just simple rumble motors. + */ + +/// HID Gamepad Protocol Report. +typedef struct TU_ATTR_PACKED +{ + int8_t x; ///< Delta x movement of left analog-stick + int8_t y; ///< Delta y movement of left analog-stick + int8_t z; ///< Delta z movement of right analog-joystick + int8_t rz; ///< Delta Rz movement of right analog-joystick + int8_t rx; ///< Delta Rx movement of analog left trigger + int8_t ry; ///< Delta Ry movement of analog right trigger + uint8_t hat; ///< Buttons mask for currently pressed buttons in the DPad/hat + uint16_t buttons; ///< Buttons mask for currently pressed buttons +}hid_gamepad_report_t; + +/// HID Switch Gamepad Protocol Report. +typedef struct TU_ATTR_PACKED +{ + uint16_t buttons; ///< Buttons mask for currently pressed buttons + uint8_t hat; ///< Buttons mask for currently pressed buttons in the DPad/hat + int8_t x; ///< Delta x movement of left analog-stick + int8_t y; ///< Delta y movement of left analog-stick + int8_t rx; ///< Delta Rx movement of analog left trigger + int8_t ry; ///< Delta Ry movement of analog right trigger + int8_t z; ///< Delta z movement of right analog-joystick + int8_t rz; ///< Delta Rz movement of right analog-joystick +}hid_gamepad_ns_report_t; + +/// Standard Gamepad Buttons Bitmap (from Linux input event codes) +typedef enum +{ + GAMEPAD_BUTTON_A = TU_BIT(0), ///< A/South button + GAMEPAD_BUTTON_B = TU_BIT(1), ///< B/East button + GAMEPAD_BUTTON_C = TU_BIT(2), ///< C button + GAMEPAD_BUTTON_X = TU_BIT(3), ///< X/North button + GAMEPAD_BUTTON_Y = TU_BIT(4), ///< Y/West button + GAMEPAD_BUTTON_Z = TU_BIT(5), ///< Z button + GAMEPAD_BUTTON_TL = TU_BIT(6), ///< L1 button + GAMEPAD_BUTTON_TR = TU_BIT(7), ///< R1 button + GAMEPAD_BUTTON_TL2 = TU_BIT(8), ///< L2 button + GAMEPAD_BUTTON_TR2 = TU_BIT(9), ///< R2 button + GAMEPAD_BUTTON_SELECT = TU_BIT(10), ///< Select button + GAMEPAD_BUTTON_START = TU_BIT(11), ///< Start button + GAMEPAD_BUTTON_MODE = TU_BIT(12), ///< Mode button + GAMEPAD_BUTTON_THUMBL = TU_BIT(13), ///< L3 button + GAMEPAD_BUTTON_THUMBR = TU_BIT(14), ///< R3 button +//GAMEPAD_BUTTON_ = TU_BIT(15), ///< Undefined button +}hid_gamepad_button_bm_t; + +/// Switch Gamepad Buttons Bitmap +typedef enum +{ + GAMEPAD_NS_BUTTON_Y = 0x01, + GAMEPAD_NS_BUTTON_B = 0x02, + GAMEPAD_NS_BUTTON_A = 0x04, + GAMEPAD_NS_BUTTON_X = 0x08, + GAMEPAD_NS_BUTTON_TL = 0x10, + GAMEPAD_NS_BUTTON_TR = 0x20, + GAMEPAD_NS_BUTTON_TL2 = 0x40, + GAMEPAD_NS_BUTTON_TR2 = 0x80, + GAMEPAD_NS_BUTTON_MINUS = 0x100, + GAMEPAD_NS_BUTTON_PLUS = 0x200, + GAMEPAD_NS_BUTTON_THUMBL = 0x400, + GAMEPAD_NS_BUTTON_THUMBR = 0x800, + GAMEPAD_NS_BUTTON_HOME = 0x1000, + GAMEPAD_NS_BUTTON_CAPTURE = 0x2000, + GAMEPAD_NS_BUTTON_Z = 0x4000, ///UNUSED? +}hid_gamepad_ns_button_bm_t; + +/// Standard Gamepad HAT/DPAD Buttons (from Linux input event codes) +typedef enum +{ + GAMEPAD_HAT_CENTERED = 0, ///< DPAD_CENTERED + GAMEPAD_HAT_UP = 1, ///< DPAD_UP + GAMEPAD_HAT_UP_RIGHT = 2, ///< DPAD_UP_RIGHT + GAMEPAD_HAT_RIGHT = 3, ///< DPAD_RIGHT + GAMEPAD_HAT_DOWN_RIGHT = 4, ///< DPAD_DOWN_RIGHT + GAMEPAD_HAT_DOWN = 5, ///< DPAD_DOWN + GAMEPAD_HAT_DOWN_LEFT = 6, ///< DPAD_DOWN_LEFT + GAMEPAD_HAT_LEFT = 7, ///< DPAD_LEFT + GAMEPAD_HAT_UP_LEFT = 8, ///< DPAD_UP_LEFT +}hid_gamepad_hat_t; + +/// Switch Gamepad HAT/DPAD Buttons (from Linux input event codes) +typedef enum +{ + GAMEPAD_NS_HAT_CENTERED = 8, ///< DPAD_CENTERED + GAMEPAD_NS_HAT_UP = 0, ///< DPAD_UP + GAMEPAD_NS_HAT_UP_RIGHT = 1, ///< DPAD_UP_RIGHT + GAMEPAD_NS_HAT_RIGHT = 2, ///< DPAD_RIGHT + GAMEPAD_NS_HAT_DOWN_RIGHT = 3, ///< DPAD_DOWN_RIGHT + GAMEPAD_NS_HAT_DOWN = 4, ///< DPAD_DOWN + GAMEPAD_NS_HAT_DOWN_LEFT = 5, ///< DPAD_DOWN_LEFT + GAMEPAD_NS_HAT_LEFT = 6, ///< DPAD_LEFT + GAMEPAD_NS_HAT_UP_LEFT = 7, ///< DPAD_UP_LEFT +}hid_gamepad_ns_hat_t; + +/// @} + +//--------------------------------------------------------------------+ +// MOUSE +//--------------------------------------------------------------------+ +/** \addtogroup ClassDriver_HID_Mouse Mouse + * @{ */ + +/// Standard HID Boot Protocol Mouse Report. +typedef struct TU_ATTR_PACKED +{ + uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */ + int8_t x; /**< Current delta x movement of the mouse. */ + int8_t y; /**< Current delta y movement on the mouse. */ + int8_t wheel; /**< Current delta wheel movement on the mouse. */ + int8_t pan; // using AC Pan +} hid_mouse_report_t; + +/// Standard Mouse Buttons Bitmap +typedef enum +{ + MOUSE_BUTTON_LEFT = TU_BIT(0), ///< Left button + MOUSE_BUTTON_RIGHT = TU_BIT(1), ///< Right button + MOUSE_BUTTON_MIDDLE = TU_BIT(2), ///< Middle button + MOUSE_BUTTON_BACKWARD = TU_BIT(3), ///< Backward button, + MOUSE_BUTTON_FORWARD = TU_BIT(4), ///< Forward button, +}hid_mouse_button_bm_t; + +/// @} + +//--------------------------------------------------------------------+ +// Keyboard +//--------------------------------------------------------------------+ +/** \addtogroup ClassDriver_HID_Keyboard Keyboard + * @{ */ + +/// Standard HID Boot Protocol Keyboard Report. +typedef struct TU_ATTR_PACKED +{ + uint8_t modifier; /**< Keyboard modifier (KEYBOARD_MODIFIER_* masks). */ + uint8_t reserved; /**< Reserved for OEM use, always set to 0. */ + uint8_t keycode[6]; /**< Key codes of the currently pressed keys. */ +} hid_keyboard_report_t; + +/// Keyboard modifier codes bitmap +typedef enum +{ + KEYBOARD_MODIFIER_LEFTCTRL = TU_BIT(0), ///< Left Control + KEYBOARD_MODIFIER_LEFTSHIFT = TU_BIT(1), ///< Left Shift + KEYBOARD_MODIFIER_LEFTALT = TU_BIT(2), ///< Left Alt + KEYBOARD_MODIFIER_LEFTGUI = TU_BIT(3), ///< Left Window + KEYBOARD_MODIFIER_RIGHTCTRL = TU_BIT(4), ///< Right Control + KEYBOARD_MODIFIER_RIGHTSHIFT = TU_BIT(5), ///< Right Shift + KEYBOARD_MODIFIER_RIGHTALT = TU_BIT(6), ///< Right Alt + KEYBOARD_MODIFIER_RIGHTGUI = TU_BIT(7) ///< Right Window +}hid_keyboard_modifier_bm_t; +typedef enum +{ + KEYBOARD_LED_NUMLOCK = TU_BIT(0), ///< Num Lock LED + KEYBOARD_LED_CAPSLOCK = TU_BIT(1), ///< Caps Lock LED + KEYBOARD_LED_SCROLLLOCK = TU_BIT(2), ///< Scroll Lock LED + KEYBOARD_LED_COMPOSE = TU_BIT(3), ///< Composition Mode + KEYBOARD_LED_KANA = TU_BIT(4) ///< Kana mode +}hid_keyboard_led_bm_t; + +/// @} + +//--------------------------------------------------------------------+ +// HID KEYCODE +//--------------------------------------------------------------------+ +#define HID_KEY_NONE 0x00 +#define HID_KEY_A 0x04 +#define HID_KEY_B 0x05 +#define HID_KEY_C 0x06 +#define HID_KEY_D 0x07 +#define HID_KEY_E 0x08 +#define HID_KEY_F 0x09 +#define HID_KEY_G 0x0A +#define HID_KEY_H 0x0B +#define HID_KEY_I 0x0C +#define HID_KEY_J 0x0D +#define HID_KEY_K 0x0E +#define HID_KEY_L 0x0F +#define HID_KEY_M 0x10 +#define HID_KEY_N 0x11 +#define HID_KEY_O 0x12 +#define HID_KEY_P 0x13 +#define HID_KEY_Q 0x14 +#define HID_KEY_R 0x15 +#define HID_KEY_S 0x16 +#define HID_KEY_T 0x17 +#define HID_KEY_U 0x18 +#define HID_KEY_V 0x19 +#define HID_KEY_W 0x1A +#define HID_KEY_X 0x1B +#define HID_KEY_Y 0x1C +#define HID_KEY_Z 0x1D +#define HID_KEY_1 0x1E +#define HID_KEY_2 0x1F +#define HID_KEY_3 0x20 +#define HID_KEY_4 0x21 +#define HID_KEY_5 0x22 +#define HID_KEY_6 0x23 +#define HID_KEY_7 0x24 +#define HID_KEY_8 0x25 +#define HID_KEY_9 0x26 +#define HID_KEY_0 0x27 +#define HID_KEY_ENTER 0x28 +#define HID_KEY_ESCAPE 0x29 +#define HID_KEY_BACKSPACE 0x2A +#define HID_KEY_TAB 0x2B +#define HID_KEY_SPACE 0x2C +#define HID_KEY_MINUS 0x2D +#define HID_KEY_EQUAL 0x2E +#define HID_KEY_BRACKET_LEFT 0x2F +#define HID_KEY_BRACKET_RIGHT 0x30 +#define HID_KEY_BACKSLASH 0x31 +#define HID_KEY_EUROPE_1 0x32 +#define HID_KEY_SEMICOLON 0x33 +#define HID_KEY_APOSTROPHE 0x34 +#define HID_KEY_GRAVE 0x35 +#define HID_KEY_COMMA 0x36 +#define HID_KEY_PERIOD 0x37 +#define HID_KEY_SLASH 0x38 +#define HID_KEY_CAPS_LOCK 0x39 +#define HID_KEY_F1 0x3A +#define HID_KEY_F2 0x3B +#define HID_KEY_F3 0x3C +#define HID_KEY_F4 0x3D +#define HID_KEY_F5 0x3E +#define HID_KEY_F6 0x3F +#define HID_KEY_F7 0x40 +#define HID_KEY_F8 0x41 +#define HID_KEY_F9 0x42 +#define HID_KEY_F10 0x43 +#define HID_KEY_F11 0x44 +#define HID_KEY_F12 0x45 +#define HID_KEY_PRINT_SCREEN 0x46 +#define HID_KEY_SCROLL_LOCK 0x47 +#define HID_KEY_PAUSE 0x48 +#define HID_KEY_INSERT 0x49 +#define HID_KEY_HOME 0x4A +#define HID_KEY_PAGE_UP 0x4B +#define HID_KEY_DELETE 0x4C +#define HID_KEY_END 0x4D +#define HID_KEY_PAGE_DOWN 0x4E +#define HID_KEY_ARROW_RIGHT 0x4F +#define HID_KEY_ARROW_LEFT 0x50 +#define HID_KEY_ARROW_DOWN 0x51 +#define HID_KEY_ARROW_UP 0x52 +#define HID_KEY_NUM_LOCK 0x53 +#define HID_KEY_KEYPAD_DIVIDE 0x54 +#define HID_KEY_KEYPAD_MULTIPLY 0x55 +#define HID_KEY_KEYPAD_SUBTRACT 0x56 +#define HID_KEY_KEYPAD_ADD 0x57 +#define HID_KEY_KEYPAD_ENTER 0x58 +#define HID_KEY_KEYPAD_1 0x59 +#define HID_KEY_KEYPAD_2 0x5A +#define HID_KEY_KEYPAD_3 0x5B +#define HID_KEY_KEYPAD_4 0x5C +#define HID_KEY_KEYPAD_5 0x5D +#define HID_KEY_KEYPAD_6 0x5E +#define HID_KEY_KEYPAD_7 0x5F +#define HID_KEY_KEYPAD_8 0x60 +#define HID_KEY_KEYPAD_9 0x61 +#define HID_KEY_KEYPAD_0 0x62 +#define HID_KEY_KEYPAD_DECIMAL 0x63 +#define HID_KEY_EUROPE_2 0x64 +#define HID_KEY_APPLICATION 0x65 +#define HID_KEY_POWER 0x66 +#define HID_KEY_KEYPAD_EQUAL 0x67 +#define HID_KEY_F13 0x68 +#define HID_KEY_F14 0x69 +#define HID_KEY_F15 0x6A +#define HID_KEY_F16 0x6B +#define HID_KEY_F17 0x6C +#define HID_KEY_F18 0x6D +#define HID_KEY_F19 0x6E +#define HID_KEY_F20 0x6F +#define HID_KEY_F21 0x70 +#define HID_KEY_F22 0x71 +#define HID_KEY_F23 0x72 +#define HID_KEY_F24 0x73 +#define HID_KEY_EXECUTE 0x74 +#define HID_KEY_HELP 0x75 +#define HID_KEY_MENU 0x76 +#define HID_KEY_SELECT 0x77 +#define HID_KEY_STOP 0x78 +#define HID_KEY_AGAIN 0x79 +#define HID_KEY_UNDO 0x7A +#define HID_KEY_CUT 0x7B +#define HID_KEY_COPY 0x7C +#define HID_KEY_PASTE 0x7D +#define HID_KEY_FIND 0x7E +#define HID_KEY_MUTE 0x7F +#define HID_KEY_VOLUME_UP 0x80 +#define HID_KEY_VOLUME_DOWN 0x81 +#define HID_KEY_LOCKING_CAPS_LOCK 0x82 +#define HID_KEY_LOCKING_NUM_LOCK 0x83 +#define HID_KEY_LOCKING_SCROLL_LOCK 0x84 +#define HID_KEY_KEYPAD_COMMA 0x85 +#define HID_KEY_KEYPAD_EQUAL_SIGN 0x86 +#define HID_KEY_KANJI1 0x87 +#define HID_KEY_KANJI2 0x88 +#define HID_KEY_KANJI3 0x89 +#define HID_KEY_KANJI4 0x8A +#define HID_KEY_KANJI5 0x8B +#define HID_KEY_KANJI6 0x8C +#define HID_KEY_KANJI7 0x8D +#define HID_KEY_KANJI8 0x8E +#define HID_KEY_KANJI9 0x8F +#define HID_KEY_LANG1 0x90 +#define HID_KEY_LANG2 0x91 +#define HID_KEY_LANG3 0x92 +#define HID_KEY_LANG4 0x93 +#define HID_KEY_LANG5 0x94 +#define HID_KEY_LANG6 0x95 +#define HID_KEY_LANG7 0x96 +#define HID_KEY_LANG8 0x97 +#define HID_KEY_LANG9 0x98 +#define HID_KEY_ALTERNATE_ERASE 0x99 +#define HID_KEY_SYSREQ_ATTENTION 0x9A +#define HID_KEY_CANCEL 0x9B +#define HID_KEY_CLEAR 0x9C +#define HID_KEY_PRIOR 0x9D +#define HID_KEY_RETURN 0x9E +#define HID_KEY_SEPARATOR 0x9F +#define HID_KEY_OUT 0xA0 +#define HID_KEY_OPER 0xA1 +#define HID_KEY_CLEAR_AGAIN 0xA2 +#define HID_KEY_CRSEL_PROPS 0xA3 +#define HID_KEY_EXSEL 0xA4 +// RESERVED 0xA5-DF +#define HID_KEY_CONTROL_LEFT 0xE0 +#define HID_KEY_SHIFT_LEFT 0xE1 +#define HID_KEY_ALT_LEFT 0xE2 +#define HID_KEY_GUI_LEFT 0xE3 +#define HID_KEY_CONTROL_RIGHT 0xE4 +#define HID_KEY_SHIFT_RIGHT 0xE5 +#define HID_KEY_ALT_RIGHT 0xE6 +#define HID_KEY_GUI_RIGHT 0xE7 + + +//--------------------------------------------------------------------+ +// REPORT DESCRIPTOR +//--------------------------------------------------------------------+ +//------------- ITEM & TAG -------------// +#define HID_REPORT_DATA_0(data) +#define HID_REPORT_DATA_1(data) , data +#define HID_REPORT_DATA_2(data) , U16_TO_U8S_LE(data) +#define HID_REPORT_DATA_3(data) , U32_TO_U8S_LE(data) + +#define HID_REPORT_ITEM(data, tag, type, size) \ + (((tag) << 4) | ((type) << 2) | (size)) HID_REPORT_DATA_##size(data) + +#define RI_TYPE_MAIN 0 +#define RI_TYPE_GLOBAL 1 +#define RI_TYPE_LOCAL 2 + +//------------- MAIN ITEMS 6.2.2.4 -------------// +#define HID_INPUT(x) HID_REPORT_ITEM(x, 8, RI_TYPE_MAIN, 1) +#define HID_OUTPUT(x) HID_REPORT_ITEM(x, 9, RI_TYPE_MAIN, 1) +#define HID_COLLECTION(x) HID_REPORT_ITEM(x, 10, RI_TYPE_MAIN, 1) +#define HID_FEATURE(x) HID_REPORT_ITEM(x, 11, RI_TYPE_MAIN, 1) +#define HID_COLLECTION_END HID_REPORT_ITEM(x, 12, RI_TYPE_MAIN, 0) + +//------------- INPUT, OUTPUT, FEATURE 6.2.2.5 -------------// +#define HID_DATA (0<<0) +#define HID_CONSTANT (1<<0) + +#define HID_ARRAY (0<<1) +#define HID_VARIABLE (1<<1) + +#define HID_ABSOLUTE (0<<2) +#define HID_RELATIVE (1<<2) + +#define HID_WRAP_NO (0<<3) +#define HID_WRAP (1<<3) + +#define HID_LINEAR (0<<4) +#define HID_NONLINEAR (1<<4) + +#define HID_PREFERRED_STATE (0<<5) +#define HID_PREFERRED_NO (1<<5) + +#define HID_NO_NULL_POSITION (0<<6) +#define HID_NULL_STATE (1<<6) + +#define HID_NON_VOLATILE (0<<7) +#define HID_VOLATILE (1<<7) + +#define HID_BITFIELD (0<<8) +#define HID_BUFFERED_BYTES (1<<8) + +//------------- COLLECTION ITEM 6.2.2.6 -------------// +enum { + HID_COLLECTION_PHYSICAL = 0, + HID_COLLECTION_APPLICATION, + HID_COLLECTION_LOGICAL, + HID_COLLECTION_REPORT, + HID_COLLECTION_NAMED_ARRAY, + HID_COLLECTION_USAGE_SWITCH, + HID_COLLECTION_USAGE_MODIFIER +}; + +//------------- GLOBAL ITEMS 6.2.2.7 -------------// +#define HID_USAGE_PAGE(x) HID_REPORT_ITEM(x, 0, RI_TYPE_GLOBAL, 1) +#define HID_USAGE_PAGE_N(x, n) HID_REPORT_ITEM(x, 0, RI_TYPE_GLOBAL, n) + +#define HID_LOGICAL_MIN(x) HID_REPORT_ITEM(x, 1, RI_TYPE_GLOBAL, 1) +#define HID_LOGICAL_MIN_N(x, n) HID_REPORT_ITEM(x, 1, RI_TYPE_GLOBAL, n) + +#define HID_LOGICAL_MAX(x) HID_REPORT_ITEM(x, 2, RI_TYPE_GLOBAL, 1) +#define HID_LOGICAL_MAX_N(x, n) HID_REPORT_ITEM(x, 2, RI_TYPE_GLOBAL, n) + +#define HID_PHYSICAL_MIN(x) HID_REPORT_ITEM(x, 3, RI_TYPE_GLOBAL, 1) +#define HID_PHYSICAL_MIN_N(x, n) HID_REPORT_ITEM(x, 3, RI_TYPE_GLOBAL, n) + +#define HID_PHYSICAL_MAX(x) HID_REPORT_ITEM(x, 4, RI_TYPE_GLOBAL, 1) +#define HID_PHYSICAL_MAX_N(x, n) HID_REPORT_ITEM(x, 4, RI_TYPE_GLOBAL, n) + +#define HID_UNIT_EXPONENT(x) HID_REPORT_ITEM(x, 5, RI_TYPE_GLOBAL, 1) +#define HID_UNIT_EXPONENT_N(x, n) HID_REPORT_ITEM(x, 5, RI_TYPE_GLOBAL, n) + +#define HID_UNIT(x) HID_REPORT_ITEM(x, 6, RI_TYPE_GLOBAL, 1) +#define HID_UNIT_N(x, n) HID_REPORT_ITEM(x, 6, RI_TYPE_GLOBAL, n) + +#define HID_REPORT_SIZE(x) HID_REPORT_ITEM(x, 7, RI_TYPE_GLOBAL, 1) +#define HID_REPORT_SIZE_N(x, n) HID_REPORT_ITEM(x, 7, RI_TYPE_GLOBAL, n) + +#define HID_REPORT_ID(x) HID_REPORT_ITEM(x, 8, RI_TYPE_GLOBAL, 1), +#define HID_REPORT_ID_N(x) HID_REPORT_ITEM(x, 8, RI_TYPE_GLOBAL, n), + +#define HID_REPORT_COUNT(x) HID_REPORT_ITEM(x, 9, RI_TYPE_GLOBAL, 1) +#define HID_REPORT_COUNT_N(x, n) HID_REPORT_ITEM(x, 9, RI_TYPE_GLOBAL, n) + +#define HID_PUSH HID_REPORT_ITEM(x, 10, RI_TYPE_GLOBAL, 0) +#define HID_POP HID_REPORT_ITEM(x, 11, RI_TYPE_GLOBAL, 0) + +//------------- LOCAL ITEMS 6.2.2.8 -------------// +#define HID_USAGE(x) HID_REPORT_ITEM(x, 0, RI_TYPE_LOCAL, 1) +#define HID_USAGE_N(x, n) HID_REPORT_ITEM(x, 0, RI_TYPE_LOCAL, n) + +#define HID_USAGE_MIN(x) HID_REPORT_ITEM(x, 1, RI_TYPE_LOCAL, 1) +#define HID_USAGE_MIN_N(x, n) HID_REPORT_ITEM(x, 1, RI_TYPE_LOCAL, n) + +#define HID_USAGE_MAX(x) HID_REPORT_ITEM(x, 2, RI_TYPE_LOCAL, 1) +#define HID_USAGE_MAX_N(x, n) HID_REPORT_ITEM(x, 2, RI_TYPE_LOCAL, n) + +//--------------------------------------------------------------------+ +// Usage Table +//--------------------------------------------------------------------+ + +/// HID Usage Table - Table 1: Usage Page Summary +enum { + HID_USAGE_PAGE_DESKTOP = 0x01, + HID_USAGE_PAGE_SIMULATE = 0x02, + HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, + HID_USAGE_PAGE_SPORT = 0x04, + HID_USAGE_PAGE_GAME = 0x05, + HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, + HID_USAGE_PAGE_KEYBOARD = 0x07, + HID_USAGE_PAGE_LED = 0x08, + HID_USAGE_PAGE_BUTTON = 0x09, + HID_USAGE_PAGE_ORDINAL = 0x0a, + HID_USAGE_PAGE_TELEPHONY = 0x0b, + HID_USAGE_PAGE_CONSUMER = 0x0c, + HID_USAGE_PAGE_DIGITIZER = 0x0d, + HID_USAGE_PAGE_PID = 0x0f, + HID_USAGE_PAGE_UNICODE = 0x10, + HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, + HID_USAGE_PAGE_MEDICAL = 0x40, + HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 + HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 + HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, + HID_USAGE_PAGE_SCALE = 0x8d, + HID_USAGE_PAGE_MSR = 0x8e, + HID_USAGE_PAGE_CAMERA = 0x90, + HID_USAGE_PAGE_ARCADE = 0x91, + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF +}; + +/// HID Usage Table - Table 6: Generic Desktop Page +enum { + HID_USAGE_DESKTOP_POINTER = 0x01, + HID_USAGE_DESKTOP_MOUSE = 0x02, + HID_USAGE_DESKTOP_JOYSTICK = 0x04, + HID_USAGE_DESKTOP_GAMEPAD = 0x05, + HID_USAGE_DESKTOP_KEYBOARD = 0x06, + HID_USAGE_DESKTOP_KEYPAD = 0x07, + HID_USAGE_DESKTOP_MULTI_AXIS_CONTROLLER = 0x08, + HID_USAGE_DESKTOP_TABLET_PC_SYSTEM = 0x09, + HID_USAGE_DESKTOP_X = 0x30, + HID_USAGE_DESKTOP_Y = 0x31, + HID_USAGE_DESKTOP_Z = 0x32, + HID_USAGE_DESKTOP_RX = 0x33, + HID_USAGE_DESKTOP_RY = 0x34, + HID_USAGE_DESKTOP_RZ = 0x35, + HID_USAGE_DESKTOP_SLIDER = 0x36, + HID_USAGE_DESKTOP_DIAL = 0x37, + HID_USAGE_DESKTOP_WHEEL = 0x38, + HID_USAGE_DESKTOP_HAT_SWITCH = 0x39, + HID_USAGE_DESKTOP_COUNTED_BUFFER = 0x3a, + HID_USAGE_DESKTOP_BYTE_COUNT = 0x3b, + HID_USAGE_DESKTOP_MOTION_WAKEUP = 0x3c, + HID_USAGE_DESKTOP_START = 0x3d, + HID_USAGE_DESKTOP_SELECT = 0x3e, + HID_USAGE_DESKTOP_VX = 0x40, + HID_USAGE_DESKTOP_VY = 0x41, + HID_USAGE_DESKTOP_VZ = 0x42, + HID_USAGE_DESKTOP_VBRX = 0x43, + HID_USAGE_DESKTOP_VBRY = 0x44, + HID_USAGE_DESKTOP_VBRZ = 0x45, + HID_USAGE_DESKTOP_VNO = 0x46, + HID_USAGE_DESKTOP_FEATURE_NOTIFICATION = 0x47, + HID_USAGE_DESKTOP_RESOLUTION_MULTIPLIER = 0x48, + HID_USAGE_DESKTOP_SYSTEM_CONTROL = 0x80, + HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN = 0x81, + HID_USAGE_DESKTOP_SYSTEM_SLEEP = 0x82, + HID_USAGE_DESKTOP_SYSTEM_WAKE_UP = 0x83, + HID_USAGE_DESKTOP_SYSTEM_CONTEXT_MENU = 0x84, + HID_USAGE_DESKTOP_SYSTEM_MAIN_MENU = 0x85, + HID_USAGE_DESKTOP_SYSTEM_APP_MENU = 0x86, + HID_USAGE_DESKTOP_SYSTEM_MENU_HELP = 0x87, + HID_USAGE_DESKTOP_SYSTEM_MENU_EXIT = 0x88, + HID_USAGE_DESKTOP_SYSTEM_MENU_SELECT = 0x89, + HID_USAGE_DESKTOP_SYSTEM_MENU_RIGHT = 0x8A, + HID_USAGE_DESKTOP_SYSTEM_MENU_LEFT = 0x8B, + HID_USAGE_DESKTOP_SYSTEM_MENU_UP = 0x8C, + HID_USAGE_DESKTOP_SYSTEM_MENU_DOWN = 0x8D, + HID_USAGE_DESKTOP_SYSTEM_COLD_RESTART = 0x8E, + HID_USAGE_DESKTOP_SYSTEM_WARM_RESTART = 0x8F, + HID_USAGE_DESKTOP_DPAD_UP = 0x90, + HID_USAGE_DESKTOP_DPAD_DOWN = 0x91, + HID_USAGE_DESKTOP_DPAD_RIGHT = 0x92, + HID_USAGE_DESKTOP_DPAD_LEFT = 0x93, + HID_USAGE_DESKTOP_SYSTEM_DOCK = 0xA0, + HID_USAGE_DESKTOP_SYSTEM_UNDOCK = 0xA1, + HID_USAGE_DESKTOP_SYSTEM_SETUP = 0xA2, + HID_USAGE_DESKTOP_SYSTEM_BREAK = 0xA3, + HID_USAGE_DESKTOP_SYSTEM_DEBUGGER_BREAK = 0xA4, + HID_USAGE_DESKTOP_APPLICATION_BREAK = 0xA5, + HID_USAGE_DESKTOP_APPLICATION_DEBUGGER_BREAK = 0xA6, + HID_USAGE_DESKTOP_SYSTEM_SPEAKER_MUTE = 0xA7, + HID_USAGE_DESKTOP_SYSTEM_HIBERNATE = 0xA8, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INVERT = 0xB0, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INTERNAL = 0xB1, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_EXTERNAL = 0xB2, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_BOTH = 0xB3, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_DUAL = 0xB4, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_SWAP_PRIMARY_SECONDARY = 0xB6, + HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7 +}; + + +/// HID Usage Table: Consumer Page (0x0C) +/// Only contains controls that supported by Windows (whole list is too long) +enum +{ + // Generic Control + HID_USAGE_CONSUMER_CONTROL = 0x0001, + + // Power Control + HID_USAGE_CONSUMER_POWER = 0x0030, + HID_USAGE_CONSUMER_RESET = 0x0031, + HID_USAGE_CONSUMER_SLEEP = 0x0032, + + // Screen Brightness + HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT = 0x006F, + HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT = 0x0070, + + // These HID usages operate only on mobile systems (battery powered) and + // require Windows 8 (build 8302 or greater). + HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS = 0x000C, + HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS = 0x00C6, + HID_USAGE_CONSUMER_WIRELESS_RADIO_LED = 0x00C7, + HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH = 0x00C8, + + // Media Control + HID_USAGE_CONSUMER_PLAY_PAUSE = 0x00CD, + HID_USAGE_CONSUMER_SCAN_NEXT = 0x00B5, + HID_USAGE_CONSUMER_SCAN_PREVIOUS = 0x00B6, + HID_USAGE_CONSUMER_STOP = 0x00B7, + HID_USAGE_CONSUMER_VOLUME = 0x00E0, + HID_USAGE_CONSUMER_MUTE = 0x00E2, + HID_USAGE_CONSUMER_BASS = 0x00E3, + HID_USAGE_CONSUMER_TREBLE = 0x00E4, + HID_USAGE_CONSUMER_BASS_BOOST = 0x00E5, + HID_USAGE_CONSUMER_VOLUME_INCREMENT = 0x00E9, + HID_USAGE_CONSUMER_VOLUME_DECREMENT = 0x00EA, + HID_USAGE_CONSUMER_BASS_INCREMENT = 0x0152, + HID_USAGE_CONSUMER_BASS_DECREMENT = 0x0153, + HID_USAGE_CONSUMER_TREBLE_INCREMENT = 0x0154, + HID_USAGE_CONSUMER_TREBLE_DECREMENT = 0x0155, + + // Application Launcher + HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x0183, + HID_USAGE_CONSUMER_AL_EMAIL_READER = 0x018A, + HID_USAGE_CONSUMER_AL_CALCULATOR = 0x0192, + HID_USAGE_CONSUMER_AL_LOCAL_BROWSER = 0x0194, + + // Browser/Explorer Specific + HID_USAGE_CONSUMER_AC_SEARCH = 0x0221, + HID_USAGE_CONSUMER_AC_HOME = 0x0223, + HID_USAGE_CONSUMER_AC_BACK = 0x0224, + HID_USAGE_CONSUMER_AC_FORWARD = 0x0225, + HID_USAGE_CONSUMER_AC_STOP = 0x0226, + HID_USAGE_CONSUMER_AC_REFRESH = 0x0227, + HID_USAGE_CONSUMER_AC_BOOKMARKS = 0x022A, + + // Mouse Horizontal scroll + HID_USAGE_CONSUMER_AC_PAN = 0x0238, +}; + +/*-------------------------------------------------------------------- + * ASCII to KEYCODE Conversion + * Expand to array of [128][2] (shift, keycode) + * + * Usage: example to convert input chr into keyboard report (modifier + keycode) + * + * uint8_t const conv_table[128][2] = { HID_ASCII_TO_KEYCODE }; + * + * uint8_t keycode[6] = { 0 }; + * uint8_t modifier = 0; + * + * if ( conv_table[chr][0] ) modifier = KEYBOARD_MODIFIER_LEFTSHIFT; + * keycode[0] = conv_table[chr][1]; + * tud_hid_keyboard_report(report_id, modifier, keycode); + * + *--------------------------------------------------------------------*/ +#define HID_ASCII_TO_KEYCODE \ + {0, 0 }, /* 0x00 Null */ \ + {0, 0 }, /* 0x01 */ \ + {0, 0 }, /* 0x02 */ \ + {0, 0 }, /* 0x03 */ \ + {0, 0 }, /* 0x04 */ \ + {0, 0 }, /* 0x05 */ \ + {0, 0 }, /* 0x06 */ \ + {0, 0 }, /* 0x07 */ \ + {0, HID_KEY_BACKSPACE }, /* 0x08 Backspace */ \ + {0, HID_KEY_TAB }, /* 0x09 Tab */ \ + {0, HID_KEY_RETURN }, /* 0x0A Line Feed */ \ + {0, 0 }, /* 0x0B */ \ + {0, 0 }, /* 0x0C */ \ + {0, HID_KEY_RETURN }, /* 0x0D CR */ \ + {0, 0 }, /* 0x0E */ \ + {0, 0 }, /* 0x0F */ \ + {0, 0 }, /* 0x10 */ \ + {0, 0 }, /* 0x11 */ \ + {0, 0 }, /* 0x12 */ \ + {0, 0 }, /* 0x13 */ \ + {0, 0 }, /* 0x14 */ \ + {0, 0 }, /* 0x15 */ \ + {0, 0 }, /* 0x16 */ \ + {0, 0 }, /* 0x17 */ \ + {0, 0 }, /* 0x18 */ \ + {0, 0 }, /* 0x19 */ \ + {0, 0 }, /* 0x1A */ \ + {0, HID_KEY_ESCAPE }, /* 0x1B Escape */ \ + {0, 0 }, /* 0x1C */ \ + {0, 0 }, /* 0x1D */ \ + {0, 0 }, /* 0x1E */ \ + {0, 0 }, /* 0x1F */ \ + \ + {0, HID_KEY_SPACE }, /* 0x20 */ \ + {1, HID_KEY_1 }, /* 0x21 ! */ \ + {1, HID_KEY_APOSTROPHE }, /* 0x22 " */ \ + {1, HID_KEY_3 }, /* 0x23 # */ \ + {1, HID_KEY_4 }, /* 0x24 $ */ \ + {1, HID_KEY_5 }, /* 0x25 % */ \ + {1, HID_KEY_7 }, /* 0x26 & */ \ + {0, HID_KEY_APOSTROPHE }, /* 0x27 ' */ \ + {1, HID_KEY_9 }, /* 0x28 ( */ \ + {1, HID_KEY_0 }, /* 0x29 ) */ \ + {1, HID_KEY_8 }, /* 0x2A * */ \ + {1, HID_KEY_EQUAL }, /* 0x2B + */ \ + {0, HID_KEY_COMMA }, /* 0x2C , */ \ + {0, HID_KEY_MINUS }, /* 0x2D - */ \ + {0, HID_KEY_PERIOD }, /* 0x2E . */ \ + {0, HID_KEY_SLASH }, /* 0x2F / */ \ + {0, HID_KEY_0 }, /* 0x30 0 */ \ + {0, HID_KEY_1 }, /* 0x31 1 */ \ + {0, HID_KEY_2 }, /* 0x32 2 */ \ + {0, HID_KEY_3 }, /* 0x33 3 */ \ + {0, HID_KEY_4 }, /* 0x34 4 */ \ + {0, HID_KEY_5 }, /* 0x35 5 */ \ + {0, HID_KEY_6 }, /* 0x36 6 */ \ + {0, HID_KEY_7 }, /* 0x37 7 */ \ + {0, HID_KEY_8 }, /* 0x38 8 */ \ + {0, HID_KEY_9 }, /* 0x39 9 */ \ + {1, HID_KEY_SEMICOLON }, /* 0x3A : */ \ + {0, HID_KEY_SEMICOLON }, /* 0x3B ; */ \ + {1, HID_KEY_COMMA }, /* 0x3C < */ \ + {0, HID_KEY_EQUAL }, /* 0x3D = */ \ + {1, HID_KEY_PERIOD }, /* 0x3E > */ \ + {1, HID_KEY_SLASH }, /* 0x3F ? */ \ + \ + {1, HID_KEY_2 }, /* 0x40 @ */ \ + {1, HID_KEY_A }, /* 0x41 A */ \ + {1, HID_KEY_B }, /* 0x42 B */ \ + {1, HID_KEY_C }, /* 0x43 C */ \ + {1, HID_KEY_D }, /* 0x44 D */ \ + {1, HID_KEY_E }, /* 0x45 E */ \ + {1, HID_KEY_F }, /* 0x46 F */ \ + {1, HID_KEY_G }, /* 0x47 G */ \ + {1, HID_KEY_H }, /* 0x48 H */ \ + {1, HID_KEY_I }, /* 0x49 I */ \ + {1, HID_KEY_J }, /* 0x4A J */ \ + {1, HID_KEY_K }, /* 0x4B K */ \ + {1, HID_KEY_L }, /* 0x4C L */ \ + {1, HID_KEY_M }, /* 0x4D M */ \ + {1, HID_KEY_N }, /* 0x4E N */ \ + {1, HID_KEY_O }, /* 0x4F O */ \ + {1, HID_KEY_P }, /* 0x50 P */ \ + {1, HID_KEY_Q }, /* 0x51 Q */ \ + {1, HID_KEY_R }, /* 0x52 R */ \ + {1, HID_KEY_S }, /* 0x53 S */ \ + {1, HID_KEY_T }, /* 0x55 T */ \ + {1, HID_KEY_U }, /* 0x55 U */ \ + {1, HID_KEY_V }, /* 0x56 V */ \ + {1, HID_KEY_W }, /* 0x57 W */ \ + {1, HID_KEY_X }, /* 0x58 X */ \ + {1, HID_KEY_Y }, /* 0x59 Y */ \ + {1, HID_KEY_Z }, /* 0x5A Z */ \ + {0, HID_KEY_BRACKET_LEFT }, /* 0x5B [ */ \ + {0, HID_KEY_BACKSLASH }, /* 0x5C '\' */ \ + {0, HID_KEY_BRACKET_RIGHT }, /* 0x5D ] */ \ + {1, HID_KEY_6 }, /* 0x5E ^ */ \ + {1, HID_KEY_MINUS }, /* 0x5F _ */ \ + \ + {0, HID_KEY_GRAVE }, /* 0x60 ` */ \ + {0, HID_KEY_A }, /* 0x61 a */ \ + {0, HID_KEY_B }, /* 0x62 b */ \ + {0, HID_KEY_C }, /* 0x63 c */ \ + {0, HID_KEY_D }, /* 0x66 d */ \ + {0, HID_KEY_E }, /* 0x65 e */ \ + {0, HID_KEY_F }, /* 0x66 f */ \ + {0, HID_KEY_G }, /* 0x67 g */ \ + {0, HID_KEY_H }, /* 0x68 h */ \ + {0, HID_KEY_I }, /* 0x69 i */ \ + {0, HID_KEY_J }, /* 0x6A j */ \ + {0, HID_KEY_K }, /* 0x6B k */ \ + {0, HID_KEY_L }, /* 0x6C l */ \ + {0, HID_KEY_M }, /* 0x6D m */ \ + {0, HID_KEY_N }, /* 0x6E n */ \ + {0, HID_KEY_O }, /* 0x6F o */ \ + {0, HID_KEY_P }, /* 0x70 p */ \ + {0, HID_KEY_Q }, /* 0x71 q */ \ + {0, HID_KEY_R }, /* 0x72 r */ \ + {0, HID_KEY_S }, /* 0x73 s */ \ + {0, HID_KEY_T }, /* 0x75 t */ \ + {0, HID_KEY_U }, /* 0x75 u */ \ + {0, HID_KEY_V }, /* 0x76 v */ \ + {0, HID_KEY_W }, /* 0x77 w */ \ + {0, HID_KEY_X }, /* 0x78 x */ \ + {0, HID_KEY_Y }, /* 0x79 y */ \ + {0, HID_KEY_Z }, /* 0x7A z */ \ + {1, HID_KEY_BRACKET_LEFT }, /* 0x7B { */ \ + {1, HID_KEY_BACKSLASH }, /* 0x7C | */ \ + {1, HID_KEY_BRACKET_RIGHT }, /* 0x7D } */ \ + {1, HID_KEY_GRAVE }, /* 0x7E ~ */ \ + {0, HID_KEY_DELETE } /* 0x7F Delete */ \ + +/*-------------------------------------------------------------------- + * KEYCODE to Ascii Conversion + * Expand to array of [128][2] (ascii without shift, ascii with shift) + * + * Usage: example to convert ascii from keycode (key) and shift modifier (shift). + * Here we assume key < 128 ( printable ) + * + * uint8_t const conv_table[128][2] = { HID_KEYCODE_TO_ASCII }; + * char ch = shift ? conv_table[chr][1] : conv_table[chr][0]; + * + *--------------------------------------------------------------------*/ +#define HID_KEYCODE_TO_ASCII \ + {0 , 0 }, /* 0x00 */ \ + {0 , 0 }, /* 0x01 */ \ + {0 , 0 }, /* 0x02 */ \ + {0 , 0 }, /* 0x03 */ \ + {'a' , 'A' }, /* 0x04 */ \ + {'b' , 'B' }, /* 0x05 */ \ + {'c' , 'C' }, /* 0x06 */ \ + {'d' , 'D' }, /* 0x07 */ \ + {'e' , 'E' }, /* 0x08 */ \ + {'f' , 'F' }, /* 0x09 */ \ + {'g' , 'G' }, /* 0x0a */ \ + {'h' , 'H' }, /* 0x0b */ \ + {'i' , 'I' }, /* 0x0c */ \ + {'j' , 'J' }, /* 0x0d */ \ + {'k' , 'K' }, /* 0x0e */ \ + {'l' , 'L' }, /* 0x0f */ \ + {'m' , 'M' }, /* 0x10 */ \ + {'n' , 'N' }, /* 0x11 */ \ + {'o' , 'O' }, /* 0x12 */ \ + {'p' , 'P' }, /* 0x13 */ \ + {'q' , 'Q' }, /* 0x14 */ \ + {'r' , 'R' }, /* 0x15 */ \ + {'s' , 'S' }, /* 0x16 */ \ + {'t' , 'T' }, /* 0x17 */ \ + {'u' , 'U' }, /* 0x18 */ \ + {'v' , 'V' }, /* 0x19 */ \ + {'w' , 'W' }, /* 0x1a */ \ + {'x' , 'X' }, /* 0x1b */ \ + {'y' , 'Y' }, /* 0x1c */ \ + {'z' , 'Z' }, /* 0x1d */ \ + {'1' , '!' }, /* 0x1e */ \ + {'2' , '@' }, /* 0x1f */ \ + {'3' , '#' }, /* 0x20 */ \ + {'4' , '$' }, /* 0x21 */ \ + {'5' , '%' }, /* 0x22 */ \ + {'6' , '^' }, /* 0x23 */ \ + {'7' , '&' }, /* 0x24 */ \ + {'8' , '*' }, /* 0x25 */ \ + {'9' , '(' }, /* 0x26 */ \ + {'0' , ')' }, /* 0x27 */ \ + {'\r' , '\r' }, /* 0x28 */ \ + {'\x1b', '\x1b' }, /* 0x29 */ \ + {'\b' , '\b' }, /* 0x2a */ \ + {'\t' , '\t' }, /* 0x2b */ \ + {' ' , ' ' }, /* 0x2c */ \ + {'-' , '_' }, /* 0x2d */ \ + {'=' , '+' }, /* 0x2e */ \ + {'[' , '{' }, /* 0x2f */ \ + {']' , '}' }, /* 0x30 */ \ + {'\\' , '|' }, /* 0x31 */ \ + {'#' , '~' }, /* 0x32 */ \ + {';' , ':' }, /* 0x33 */ \ + {'\'' , '\"' }, /* 0x34 */ \ + {'`' , '~' }, /* 0x35 */ \ + {',' , '<' }, /* 0x36 */ \ + {'.' , '>' }, /* 0x37 */ \ + {'/' , '?' }, /* 0x38 */ \ + \ + {0 , 0 }, /* 0x39 */ \ + {0 , 0 }, /* 0x3a */ \ + {0 , 0 }, /* 0x3b */ \ + {0 , 0 }, /* 0x3c */ \ + {0 , 0 }, /* 0x3d */ \ + {0 , 0 }, /* 0x3e */ \ + {0 , 0 }, /* 0x3f */ \ + {0 , 0 }, /* 0x40 */ \ + {0 , 0 }, /* 0x41 */ \ + {0 , 0 }, /* 0x42 */ \ + {0 , 0 }, /* 0x43 */ \ + {0 , 0 }, /* 0x44 */ \ + {0 , 0 }, /* 0x45 */ \ + {0 , 0 }, /* 0x46 */ \ + {0 , 0 }, /* 0x47 */ \ + {0 , 0 }, /* 0x48 */ \ + {0 , 0 }, /* 0x49 */ \ + {0 , 0 }, /* 0x4a */ \ + {0 , 0 }, /* 0x4b */ \ + {0 , 0 }, /* 0x4c */ \ + {0 , 0 }, /* 0x4d */ \ + {0 , 0 }, /* 0x4e */ \ + {0 , 0 }, /* 0x4f */ \ + {0 , 0 }, /* 0x50 */ \ + {0 , 0 }, /* 0x51 */ \ + {0 , 0 }, /* 0x52 */ \ + {0 , 0 }, /* 0x53 */ \ + \ + {'/' , '/' }, /* 0x54 */ \ + {'*' , '*' }, /* 0x55 */ \ + {'-' , '-' }, /* 0x56 */ \ + {'+' , '+' }, /* 0x57 */ \ + {'\r' , '\r' }, /* 0x58 */ \ + {'1' , 0 }, /* 0x59 */ \ + {'2' , 0 }, /* 0x5a */ \ + {'3' , 0 }, /* 0x5b */ \ + {'4' , 0 }, /* 0x5c */ \ + {'5' , '5' }, /* 0x5d */ \ + {'6' , 0 }, /* 0x5e */ \ + {'7' , 0 }, /* 0x5f */ \ + {'8' , 0 }, /* 0x60 */ \ + {'9' , 0 }, /* 0x61 */ \ + {'0' , 0 }, /* 0x62 */ \ + {'0' , 0 }, /* 0x63 */ \ + {'=' , '=' }, /* 0x67 */ \ + + +#ifdef __cplusplus + } #endif + + + + + +#endif /* _TUSB_TYPES_H_ */ + + diff --git a/examples_x035/usbdevice.incomplete/usbdevice.c b/examples_x035/usbdevice.incomplete/usbdevice.c index 6ac1225625a27377b72665d842be9fe1a027999e..4478a55d65502eaf34f8afd165de1d345160b57b 100644 --- a/examples_x035/usbdevice.incomplete/usbdevice.c +++ b/examples_x035/usbdevice.incomplete/usbdevice.c @@ -14,6 +14,55 @@ void handle_debug_input( int numbytes, uint8_t * data ) count += numbytes; } +int HandleHidNonStandardSetup( 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 HandleHidNonStandardDataOut( 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 HandleHidNonStandardDataIn( struct _USBState * ctx, uint8_t * data, int len ) +{ + memset( data, 0xcc, len ); +} + + int main() { SystemInit(); @@ -34,7 +83,7 @@ int main() uint32_t * buffer = (uint32_t*)USBFS_GetEPBufferIfAvailable( i ); if( buffer ) { - buffer[0] = 0x000101aa; + buffer[0] = 0x000000aa; USBFS_SendEndpoint( i, (i==1)?8:4 ); } }