293 lines
9.0 KiB
C
293 lines
9.0 KiB
C
#include "usbd.h"
|
|
#include "usbd_hid.h"
|
|
#include "drvs.h"
|
|
|
|
#if (DEMO_HID_CUSTOM)
|
|
|
|
#define USBD_BCD USB_2_0 // Version
|
|
#define USBD_VID 0xFFFF // Vendor ID
|
|
#define USBD_PID 0xFFFF // Product ID
|
|
#define USBD_MAX_POWER 100 // unit in mA
|
|
#define USBD_LANGID_STRING 0x0409 // English(US)
|
|
|
|
|
|
/*
|
|
* Descriptor
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*!< count of hid interface descriptor */
|
|
#define USB_HID_INTF_CNT 2
|
|
#define USB_HID_INTF_END (USB_HID_INTF_CNT - 1)
|
|
|
|
/*!< config descriptor size (in & out endpoints) */
|
|
#define USB_HID_CONFIG_SIZE (9+(18+7+7)*USB_HID_INTF_CNT)
|
|
|
|
/*!< keyboard interface config */
|
|
#define KBD_INTF_NUM 0 /*!< interfaceNumber */
|
|
#define KBD_IN_EP 0x81 /*!< address */
|
|
#define KBD_IN_EP_SIZE 8 /*!< max packet length */
|
|
#define KBD_IN_EP_INTERVAL 10 /*!< polling time */
|
|
#define KBD_OUT_EP 0x01
|
|
#define KBD_OUT_EP_SIZE 1
|
|
#define KBD_OUT_EP_INTERVAL 10
|
|
#define KBD_REPORT_DESC_SIZE sizeof(hid_kbd_report_desc)
|
|
|
|
/*!< custom-raw interface config */
|
|
#define RAW_INTF_NUM 1
|
|
#define RAW_IN_EP 0x82
|
|
#define RAW_IN_EP_SIZE 64
|
|
#define RAW_IN_EP_INTERVAL 10
|
|
#define RAW_OUT_EP 0x02
|
|
#define RAW_OUT_EP_SIZE 64
|
|
#define RAW_OUT_EP_INTERVAL 10
|
|
#define RAW_REPORT_DESC_SIZE sizeof(hid_raw_report_desc)
|
|
|
|
/*!< Declaration of endpoint Handlers */
|
|
void usbd_hid_kbd_out_handler(uint8_t ep);
|
|
void usbd_hid_raw_out_handler(uint8_t ep);
|
|
|
|
/*!< hid keyboard report descriptor */
|
|
static const uint8_t hid_kbd_report_desc[] = {
|
|
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
|
0x09, 0x06, // USAGE (Keyboard)
|
|
0xa1, 0x01, // COLLECTION (Application)
|
|
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
|
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
|
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
|
0x75, 0x01, // REPORT_SIZE (1)
|
|
0x95, 0x08, // REPORT_COUNT (8)
|
|
0x81, 0x02, // INPUT (Data,Var,Abs)
|
|
0x95, 0x01, // REPORT_COUNT (1)
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
|
0x95, 0x05, // REPORT_COUNT (5)
|
|
0x75, 0x01, // REPORT_SIZE (1)
|
|
0x05, 0x08, // USAGE_PAGE (LEDs)
|
|
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
|
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
|
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
|
0x95, 0x01, // REPORT_COUNT (1)
|
|
0x75, 0x03, // REPORT_SIZE (3)
|
|
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
|
0x95, 0x06, // REPORT_COUNT (6)
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
|
|
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
|
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
|
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
|
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
|
0xc0 // END_COLLECTION
|
|
};
|
|
|
|
/*!< hid custom-raw report descriptor */
|
|
static const uint8_t hid_raw_report_desc[] = {
|
|
0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined Page 1)
|
|
0x09, 0x01, // USAGE (Vendor Usage 1)
|
|
0xa1, 0x01, // COLLECTION (Application)
|
|
0x09, 0x01, // USAGE (Vendor Usage 1)
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
|
0x95, 0x40, // REPORT_COUNT (64)
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
0x81, 0x02, // INPUT (Data,Var,Abs)
|
|
0x09, 0x01, // USAGE (Vendor Usage 1)
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
|
0x95, 0x40, // REPORT_COUNT (64)
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
|
0xC0 // END_COLLECTION
|
|
};
|
|
|
|
/*!< hid device descriptor */
|
|
static const uint8_t hid_descriptor[] = {
|
|
/* Descriptor - Device (Size:18) */
|
|
USB_DEVICE_DESCRIPTOR_INIT(USBD_BCD, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
|
|
|
|
/* Descriptor - Configuration (Total Size:9+Intf_Size) */
|
|
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_SIZE, USB_HID_INTF_CNT,
|
|
0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
|
|
|
/* Descriptor - Keyboard Interface (Size:18+7*2) */
|
|
HID_INTERFACE_INIT(KBD_INTF_NUM, 2, HID_SUBCLASS_BOOTIF, HID_PROTOCOL_KEYBOARD, 0, KBD_REPORT_DESC_SIZE),
|
|
HID_ENDPOINT_DESC(KBD_IN_EP, KBD_IN_EP_SIZE, KBD_IN_EP_INTERVAL),
|
|
HID_ENDPOINT_DESC(KBD_OUT_EP, KBD_OUT_EP_SIZE, KBD_OUT_EP_INTERVAL),
|
|
|
|
/* Descriptor - Custom-Raw Interface (Size:18+7*2) */
|
|
HID_INTERFACE_INIT(RAW_INTF_NUM, 2, HID_SUBCLASS_BOOTIF, HID_PROTOCOL_NONE, 0, RAW_REPORT_DESC_SIZE),
|
|
HID_ENDPOINT_DESC(RAW_IN_EP, RAW_IN_EP_SIZE, RAW_IN_EP_INTERVAL),
|
|
HID_ENDPOINT_DESC(RAW_OUT_EP, RAW_OUT_EP_SIZE, RAW_OUT_EP_INTERVAL),
|
|
|
|
/* Descriptor - String */
|
|
// String0 - Language ID (Size:4)
|
|
USB_LANGID_INIT(USBD_LANGID_STRING),
|
|
|
|
// String1 - iManufacturer
|
|
0x02, /* bLength */
|
|
USB_DESC_TYPE_STRING, /* bDescriptorType */
|
|
|
|
// String2 - iProduct
|
|
0x16, /* bLength */
|
|
USB_DESC_TYPE_STRING, /* bDescriptorType */
|
|
WCHAR('U'),
|
|
WCHAR('S'),
|
|
WCHAR('B'),
|
|
WCHAR(' '),
|
|
WCHAR('R'),
|
|
WCHAR('a'),
|
|
WCHAR('w'),
|
|
WCHAR('H'),
|
|
WCHAR('I'),
|
|
WCHAR('D'),
|
|
|
|
// String3 - iSerialNumber
|
|
// 0x10, /* bLength */
|
|
// USB_DESC_TYPE_STRING, /* bDescriptorType */
|
|
// WCHAR('6'),
|
|
// WCHAR('.'),
|
|
// WCHAR('2'),
|
|
// WCHAR('2'),
|
|
// WCHAR('.'),
|
|
// WCHAR('0'),
|
|
// WCHAR('8'),
|
|
|
|
/* Descriptor - Device Qualifier (Size:10) */
|
|
#if (USBD_BCD == USB_2_0)
|
|
USB_QUALIFIER_INIT(0x01),
|
|
#endif
|
|
|
|
/* Descriptor - EOF */
|
|
0x00
|
|
};
|
|
|
|
|
|
/*
|
|
* Configuration
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*!< table of hid interface */
|
|
static const hid_intf_t hid_interface[] = {
|
|
HID_INTF_T(KBD_INTF_NUM, KBD_IN_EP, hid_kbd_report_desc),
|
|
HID_INTF_T(RAW_INTF_NUM, RAW_IN_EP, hid_raw_report_desc),
|
|
};
|
|
|
|
/*!< table of endpoints */
|
|
static const usbd_ep_t endpoint_tab[] = {
|
|
USBD_EP_T(KBD_IN_EP, USB_EP_TYPE_INTERRUPT, KBD_IN_EP_SIZE, &usbd_hid_ep_in_handler),
|
|
USBD_EP_T(KBD_OUT_EP, USB_EP_TYPE_INTERRUPT, KBD_OUT_EP_SIZE, &usbd_hid_kbd_out_handler),
|
|
|
|
USBD_EP_T(RAW_IN_EP, USB_EP_TYPE_INTERRUPT, RAW_IN_EP_SIZE, &usbd_hid_ep_in_handler),
|
|
USBD_EP_T(RAW_OUT_EP, USB_EP_TYPE_INTERRUPT, RAW_OUT_EP_SIZE, &usbd_hid_raw_out_handler),
|
|
};
|
|
|
|
/*!< table of class */
|
|
static const usbd_class_t class_tab[] = {
|
|
USBD_CLASS_T(0, USB_HID_INTF_END, &usbd_hid_class_handler),
|
|
};
|
|
|
|
/*!< USBD Configuration */
|
|
static const usbd_config_t hid_configuration[] = {
|
|
USBD_CONFIG_T(1, USB_HID_INTF_CNT, class_tab, endpoint_tab)
|
|
};
|
|
|
|
|
|
/*
|
|
* Handlers
|
|
****************************************************************************
|
|
*/
|
|
|
|
void usbd_hid_kbd_out_handler(uint8_t ep)
|
|
{
|
|
uint8_t led_state;
|
|
|
|
/*!< read the led data from host send */
|
|
usbd_ep_read(ep, KBD_OUT_EP_SIZE, &led_state);
|
|
USB_LOG_RAW("led_state:%02X\r\n", led_state);
|
|
|
|
/*!< here you can write the LED processing from the host */
|
|
usbd_hid_leds(led_state);
|
|
}
|
|
|
|
void usbd_hid_raw_out_handler(uint8_t ep)
|
|
{
|
|
uint8_t custom_data[RAW_OUT_EP_SIZE];
|
|
|
|
/*!< read the data from host send */
|
|
usbd_ep_read(RAW_OUT_EP, RAW_OUT_EP_SIZE, custom_data);
|
|
|
|
/*!< you can use the data do some thing you like */
|
|
}
|
|
|
|
__USBIRQ void usbd_notify_handler(uint8_t event, void *arg)
|
|
{
|
|
switch (event) {
|
|
case USBD_EVENT_RESET:
|
|
usbd_hid_reset();
|
|
break;
|
|
case USBD_EVENT_RESUME:
|
|
break;
|
|
case USBD_EVENT_SUSPEND:
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Test Functions
|
|
****************************************************************************
|
|
*/
|
|
|
|
void usbdInit(void)
|
|
{
|
|
usbd_init();
|
|
usbd_register(hid_descriptor, hid_configuration);
|
|
|
|
for (uint8_t idx = 0; idx < USB_HID_INTF_CNT; idx++) {
|
|
usbd_hid_init(idx, &hid_interface[idx]);
|
|
}
|
|
}
|
|
|
|
void usbdTest(void)
|
|
{
|
|
// circle polling to send report
|
|
static uint8_t keynum = 0;
|
|
|
|
if (!usbd_is_configured())
|
|
return;
|
|
|
|
/*!< keyboard test */
|
|
{
|
|
uint8_t sendbuffer1[KBD_IN_EP_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //A
|
|
|
|
sendbuffer1[2] = HID_KEY_A + keynum;
|
|
usbd_hid_send_report(KBD_IN_EP, KBD_IN_EP_SIZE, sendbuffer1);
|
|
/*!< delay 10ms */
|
|
bootDelayMs(10);
|
|
/*!< send button up */
|
|
sendbuffer1[2] = 0;
|
|
usbd_hid_send_report(KBD_IN_EP, KBD_IN_EP_SIZE, sendbuffer1);
|
|
}
|
|
|
|
/*!< delay 100ms the custom test */
|
|
{
|
|
bootDelayMs(100);
|
|
/*!< custom test */
|
|
uint8_t sendbuffer2[RAW_IN_EP_SIZE];
|
|
|
|
memset(sendbuffer2, keynum, RAW_IN_EP_SIZE);
|
|
usbd_hid_send_report(RAW_IN_EP, RAW_IN_EP_SIZE, sendbuffer2);
|
|
}
|
|
|
|
if (++keynum > 94) keynum = 0;
|
|
}
|
|
|
|
#endif // (DEMO_HID_CUSTOM)
|