# include <stdint.h>
# include "USBHID.h"
# include "USBHID_Types.h"
# include "USBDescriptor.h"
# include "HIDKeyboard.h"
# define DEFAULT_CONFIGURATION (1)
HIDKeyboard : : HIDKeyboard ( uint16_t vendor_id , uint16_t product_id , uint16_t product_release ) : USBDevice ( vendor_id , product_id , product_release )
{
USBDevice : : connect ( ) ;
}
bool HIDKeyboard : : sendReport ( report_keyboard_t report ) {
USBDevice : : write ( EP1IN , report . raw , sizeof ( report ) , MAX_PACKET_SIZE_EP1 ) ;
return true ;
}
uint8_t HIDKeyboard : : leds ( ) {
return led_state ;
}
bool HIDKeyboard : : USBCallback_setConfiguration ( uint8_t configuration ) {
if ( configuration ! = DEFAULT_CONFIGURATION ) {
return false ;
}
// Configure endpoints > 0
addEndpoint ( EPINT_IN , MAX_PACKET_SIZE_EPINT ) ;
//addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
// We activate the endpoint to be able to recceive data
//readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
return true ;
}
uint8_t * HIDKeyboard : : stringImanufacturerDesc ( ) {
static uint8_t stringImanufacturerDescriptor [ ] = {
0x18 , /*bLength*/
STRING_DESCRIPTOR , /*bDescriptorType 0x03*/
' t ' , 0 , ' m ' , 0 , ' k ' , 0 , ' - ' , 0 , ' k ' , 0 , ' b ' , 0 , ' d ' , 0 , ' . ' , 0 , ' c ' , 0 , ' o ' , 0 , ' m ' , 0 /*bString iManufacturer*/
} ;
return stringImanufacturerDescriptor ;
}
uint8_t * HIDKeyboard : : stringIproductDesc ( ) {
static uint8_t stringIproductDescriptor [ ] = {
0x0a , /*bLength*/
STRING_DESCRIPTOR , /*bDescriptorType 0x03*/
' m ' , 0 , ' b ' , 0 , ' e ' , 0 , ' d ' , 0 /*bString iProduct*/
} ;
return stringIproductDescriptor ;
}
uint8_t * HIDKeyboard : : stringIserialDesc ( ) {
static uint8_t stringIserialDescriptor [ ] = {
0x04 , /*bLength*/
STRING_DESCRIPTOR , /*bDescriptorType 0x03*/
' 0 ' , 0 /*bString iSerial*/
} ;
return stringIserialDescriptor ;
}
uint8_t * HIDKeyboard : : reportDesc ( ) {
static uint8_t reportDescriptor [ ] = {
USAGE_PAGE ( 1 ) , 0x01 , // Generic Desktop
USAGE ( 1 ) , 0x06 , // Keyboard
COLLECTION ( 1 ) , 0x01 , // Application
USAGE_PAGE ( 1 ) , 0x07 , // Key Codes
USAGE_MINIMUM ( 1 ) , 0xE0 ,
USAGE_MAXIMUM ( 1 ) , 0xE7 ,
LOGICAL_MINIMUM ( 1 ) , 0x00 ,
LOGICAL_MAXIMUM ( 1 ) , 0x01 ,
REPORT_SIZE ( 1 ) , 0x01 ,
REPORT_COUNT ( 1 ) , 0x08 ,
INPUT ( 1 ) , 0x02 , // Data, Variable, Absolute
REPORT_COUNT ( 1 ) , 0x01 ,
REPORT_SIZE ( 1 ) , 0x08 ,
INPUT ( 1 ) , 0x01 , // Constant
REPORT_COUNT ( 1 ) , 0x05 ,
REPORT_SIZE ( 1 ) , 0x01 ,
USAGE_PAGE ( 1 ) , 0x08 , // LEDs
USAGE_MINIMUM ( 1 ) , 0x01 ,
USAGE_MAXIMUM ( 1 ) , 0x05 ,
OUTPUT ( 1 ) , 0x02 , // Data, Variable, Absolute
REPORT_COUNT ( 1 ) , 0x01 ,
REPORT_SIZE ( 1 ) , 0x03 ,
OUTPUT ( 1 ) , 0x01 , // Constant
REPORT_COUNT ( 1 ) , 0x06 ,
REPORT_SIZE ( 1 ) , 0x08 ,
LOGICAL_MINIMUM ( 1 ) , 0x00 ,
LOGICAL_MAXIMUM ( 1 ) , 0xFF ,
USAGE_PAGE ( 1 ) , 0x07 , // Key Codes
USAGE_MINIMUM ( 1 ) , 0x00 ,
USAGE_MAXIMUM ( 1 ) , 0xFF ,
INPUT ( 1 ) , 0x00 , // Data, Array
END_COLLECTION ( 0 ) ,
} ;
reportLength = sizeof ( reportDescriptor ) ;
return reportDescriptor ;
}
uint16_t HIDKeyboard : : reportDescLength ( ) {
reportDesc ( ) ;
return reportLength ;
}
# define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ ( 1 * INTERFACE_DESCRIPTOR_LENGTH ) \
+ ( 1 * HID_DESCRIPTOR_LENGTH ) \
+ ( 1 * ENDPOINT_DESCRIPTOR_LENGTH ) )
uint8_t * HIDKeyboard : : configurationDesc ( ) {
static uint8_t configurationDescriptor [ ] = {
CONFIGURATION_DESCRIPTOR_LENGTH , // bLength
CONFIGURATION_DESCRIPTOR , // bDescriptorType
LSB ( TOTAL_DESCRIPTOR_LENGTH ) , // wTotalLength (LSB)
MSB ( TOTAL_DESCRIPTOR_LENGTH ) , // wTotalLength (MSB)
0x01 , // bNumInterfaces
DEFAULT_CONFIGURATION , // bConfigurationValue
0x00 , // iConfiguration
C_RESERVED | C_REMOTE_WAKEUP , // bmAttributes
C_POWER ( 100 ) , // bMaxPowerHello World from Mbed
INTERFACE_DESCRIPTOR_LENGTH , // bLength
INTERFACE_DESCRIPTOR , // bDescriptorType
0x00 , // bInterfaceNumber
0x00 , // bAlternateSetting
0x01 , // bNumEndpoints
HID_CLASS , // bInterfaceClass
1 , // bInterfaceSubClass (boot)
1 , // bInterfaceProtocol (keyboard)
0x00 , // iInterface
HID_DESCRIPTOR_LENGTH , // bLength
HID_DESCRIPTOR , // bDescriptorType
LSB ( HID_VERSION_1_11 ) , // bcdHID (LSB)
MSB ( HID_VERSION_1_11 ) , // bcdHID (MSB)
0x00 , // bCountryCode
0x01 , // bNumDescriptors
REPORT_DESCRIPTOR , // bDescriptorType
( uint8_t ) ( LSB ( reportDescLength ( ) ) ) , // wDescriptorLength (LSB)
( uint8_t ) ( MSB ( reportDescLength ( ) ) ) , // wDescriptorLength (MSB)
ENDPOINT_DESCRIPTOR_LENGTH , // bLength
ENDPOINT_DESCRIPTOR , // bDescriptorType
PHY_TO_DESC ( EP1IN ) , // bEndpointAddress
E_INTERRUPT , // bmAttributes
LSB ( MAX_PACKET_SIZE_EPINT ) , // wMaxPacketSize (LSB)
MSB ( MAX_PACKET_SIZE_EPINT ) , // wMaxPacketSize (MSB)
1 , // bInterval (milliseconds)
} ;
return configurationDescriptor ;
}
#if 0
uint8_t * HIDKeyboard : : deviceDesc ( ) {
static uint8_t deviceDescriptor [ ] = {
DEVICE_DESCRIPTOR_LENGTH , /* bLength */
DEVICE_DESCRIPTOR , /* bDescriptorType */
LSB ( USB_VERSION_2_0 ) , /* bcdUSB (LSB) */
MSB ( USB_VERSION_2_0 ) , /* bcdUSB (MSB) */
0x00 , /* bDeviceClass */
0x00 , /* bDeviceSubClass */
0x00 , /* bDeviceprotocol */
MAX_PACKET_SIZE_EP0 , /* bMaxPacketSize0 */
( uint8_t ) ( LSB ( 0xfeed ) ) , /* idVendor (LSB) */
( uint8_t ) ( MSB ( 0xfeed ) ) , /* idVendor (MSB) */
( uint8_t ) ( LSB ( 0x1bed ) ) , /* idProduct (LSB) */
( uint8_t ) ( MSB ( 0x1bed ) ) , /* idProduct (MSB) */
( uint8_t ) ( LSB ( 0x0002 ) ) , /* bcdDevice (LSB) */
( uint8_t ) ( MSB ( 0x0002 ) ) , /* bcdDevice (MSB) */
0 , /* iManufacturer */
0 , /* iProduct */
0 , /* iSerialNumber */
0x01 /* bNumConfigurations */
} ;
return deviceDescriptor ;
}
# endif
bool HIDKeyboard : : USBCallback_request ( ) {
bool success = false ;
CONTROL_TRANSFER * transfer = getTransferPtr ( ) ;
uint8_t * hidDescriptor ;
// Process additional standard requests
if ( ( transfer - > setup . bmRequestType . Type = = STANDARD_TYPE ) )
{
switch ( transfer - > setup . bRequest )
{
case GET_DESCRIPTOR :
switch ( DESCRIPTOR_TYPE ( transfer - > setup . wValue ) )
{
case REPORT_DESCRIPTOR :
if ( ( reportDesc ( ) ! = NULL ) \
& & ( reportDescLength ( ) ! = 0 ) )
{
transfer - > remaining = reportDescLength ( ) ;
transfer - > ptr = reportDesc ( ) ;
transfer - > direction = DEVICE_TO_HOST ;
success = true ;
}
break ;
case HID_DESCRIPTOR :
// Find the HID descriptor, after the configuration descriptor
hidDescriptor = findDescriptor ( HID_DESCRIPTOR ) ;
if ( hidDescriptor ! = NULL )
{
transfer - > remaining = HID_DESCRIPTOR_LENGTH ;
transfer - > ptr = hidDescriptor ;
transfer - > direction = DEVICE_TO_HOST ;
success = true ;
}
break ;
default :
break ;
}
break ;
default :
break ;
}
}
// Process class-specific requests
if ( transfer - > setup . bmRequestType . Type = = CLASS_TYPE )
{
switch ( transfer - > setup . bRequest ) {
case SET_REPORT :
// LED indicator
// TODO: check Interface and Report length?
// if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
// if (transfer->setup.wLength == 1)
transfer - > remaining = 1 ;
//transfer->ptr = ?? what ptr should be set when OUT(not used?)
transfer - > direction = HOST_TO_DEVICE ;
transfer - > notify = true ; /* notify with USBCallback_requestCompleted */
success = true ;
default :
break ;
}
}
return success ;
}
void HIDKeyboard : : USBCallback_requestCompleted ( uint8_t * buf , uint32_t length )
{
if ( length > 0 ) {
CONTROL_TRANSFER * transfer = getTransferPtr ( ) ;
if ( transfer - > setup . bmRequestType . Type = = CLASS_TYPE ) {
switch ( transfer - > setup . bRequest ) {
case SET_REPORT :
led_state = buf [ 0 ] ;
break ;
default :
break ;
}
}
}
}