bleSDK_expansion_board/examples/usb2hid/src/hid_custom.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)