diff --git a/mihome_bridge/Core/Inc/bsp_key_in_out.h b/mihome_bridge/Core/Inc/bsp_key_in_out.h index b601b40..21b46ce 100644 --- a/mihome_bridge/Core/Inc/bsp_key_in_out.h +++ b/mihome_bridge/Core/Inc/bsp_key_in_out.h @@ -26,9 +26,9 @@ typedef enum { typedef enum { bsp_key_event_none = 0, - bsp_key_event_press, - bsp_key_event_long, - bsp_key_event_double, + bsp_key_event_press, //输出按键短按 且按键输入的按下边沿会产生此事件 + bsp_key_event_long, //输出按键长按 且按键输入的时长达到阈值会产生此事件 + bsp_key_event_double, //输出按键双击 } bsp_key_event_type_e; void bsp_key_in_out_init(void); diff --git a/mihome_bridge/Core/Inc/hid_keyboard_mouse.h b/mihome_bridge/Core/Inc/hid_keyboard_mouse.h new file mode 100644 index 0000000..7c9fe1b --- /dev/null +++ b/mihome_bridge/Core/Inc/hid_keyboard_mouse.h @@ -0,0 +1,36 @@ +#ifndef __HID_KEYBOARD_MOUSE_H +#define __HID_KEYBOARD_MOUSE_H + +#include + +#define HID_CONSUMER_USAGE_NEXTTRACK 0x00B5 +#define HID_CONSUMER_USAGE_PREVTRACK 0x00B6 +#define HID_CONSUMER_USAGE_STOP 0x00B7 +#define HID_CONSUMER_USAGE_PLAYPAUSE 0x00CD +#define HID_CONSUMER_USAGE_MUTE 0x00E2 +#define HID_CONSUMER_USAGE_VOLUMEINC 0x00E9 +#define HID_CONSUMER_USAGE_VOLUMEDEC 0x00EA +#define HID_CONSUMER_USAGE_MEDIASELECT 0x0181 +#define HID_CONSUMER_USAGE_MAIL 0x018A +#define HID_CONSUMER_USAGE_CALCULATOR 0x0192 +#define HID_CONSUMER_USAGE_MYCOMPUTER 0x0194 +#define HID_CONSUMER_USAGE_WWWSEARCH 0x0221 +#define HID_CONSUMER_USAGE_WEBHOME 0x0223 +#define HID_CONSUMER_USAGE_WWWBACK 0x0224 +#define HID_CONSUMER_USAGE_WWWFORWARD 0x0225 +#define HID_CONSUMER_USAGE_WWWSTOP 0x0226 +#define HID_CONSUMER_USAGE_WWWREFRESH 0x0227 +#define HID_CONSUMER_USAGE_WWWFAVORITES 0x022A + +#define HID_SYSTEM_USAGE_POWER 0x01 +#define HID_SYSTEM_USAGE_SLEEP 0x02 +#define HID_SYSTEM_USAGE_WAKEUP 0x04 + +void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base); +void hid_keyboard_key_send(uint8_t busid, uint8_t modifier_keys, uint8_t key); +void hid_consumer_control_key_send(uint8_t busid, uint16_t consumer_control_key); +void hid_system_control_key_send(uint8_t busid, uint16_t system_control_key); +void hid_mouse_send(uint8_t busid, uint8_t buttons, int8_t x, int8_t y, int8_t wheel); + +#endif + diff --git a/mihome_bridge/Core/Src/bsp_key_in_out.c b/mihome_bridge/Core/Src/bsp_key_in_out.c index f68b750..93e3683 100644 --- a/mihome_bridge/Core/Src/bsp_key_in_out.c +++ b/mihome_bridge/Core/Src/bsp_key_in_out.c @@ -115,6 +115,12 @@ static void bsp_key_in_process(void) key_in_status[key_index].is_long_pressed = 0; key_in_status[key_index].long_press_count = 0; //复位长按状态 } + + /* 按键按下边沿 */ + if (is_pressed && !key_in_status[key_index].is_pressed_before) { + key_in_status[key_index].event = bsp_key_event_press; //产生短按事件 + } + /* 按键按下状态 */ if (is_pressed) { //按键处于被按下的状态 if (!key_in_status[key_index].is_long_pressed) { //如果还未触发长按事件 @@ -127,11 +133,6 @@ static void bsp_key_in_process(void) } } } - /* 按键抬起边沿 */ - if (!is_pressed && key_in_status[key_index].is_pressed_before && - !key_in_status[key_index].is_long_pressed) { //本次没有按下 但上次按下了 且未触发长按事件 - key_in_status[key_index].event = bsp_key_event_press; //产生短按事件 - } key_in_status[key_index].is_pressed_before = is_pressed; //记录上次按下的状态 } diff --git a/mihome_bridge/Core/Src/hid_keyboard_mouse.c b/mihome_bridge/Core/Src/hid_keyboard_mouse.c new file mode 100644 index 0000000..b9d7618 --- /dev/null +++ b/mihome_bridge/Core/Src/hid_keyboard_mouse.c @@ -0,0 +1,350 @@ +#include "hid_keyboard_mouse.h" +#include +#include "main.h" +#include "usbd_core.h" +#include "usbd_hid.h" + +#define USBD_VID 0x0483 +#define USBD_PID 0x5750 +#define USBD_MAX_POWER_MA 100 +#define USBD_LANGID_STRING 1033 + +#define HID_STATE_IDLE 0 +#define HID_STATE_BUSY 1 + +#define HID_KM_INT_EP 0x81 +#define HID_KM_INT_EP_SIZE 9 +#define HID_KM_INT_EP_INTERVAL 10 + +#define HID_CONFIG_DESCRIPTOR_SIZE 34 +#define HID_KM_REPORT_DESC_SIZE 187 + +static const uint8_t hid_descriptor[] = { + /* 设备(Device)描述符 所有设备有且只有一个 */ + USB_DEVICE_DESCRIPTOR_INIT(USB_1_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), + + /* 配置(Configuration)描述符 所有设备至少有一个 */ + USB_CONFIG_DESCRIPTOR_INIT(HID_CONFIG_DESCRIPTOR_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER_MA), + /* 截至此处的配置描述符长度 = 09 */ + + /* 接口(Interface)描述符 键盘 */ + 0x09, /* bLength: Descriptor size */ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: 1 */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0, /* iInterface: Index of string descriptor */ + /* 截至此处的配置描述符长度 = 18 */ + + /* HID描述符 键盘 */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ + 0x11, 0x01, /* bcdHID: HID Class Spec release number: HID1.11 */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + WBVAL(HID_KM_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ + /* 截至此处的配置描述符长度 = 27 */ + + /* 端点(Endpoint)描述符 键盘 */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + HID_KM_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + WBVAL(HID_KM_INT_EP_SIZE), /* wMaxPacketSize: 9 Bytes maximum */ + HID_KM_INT_EP_INTERVAL, /* bInterval: Polling Interval */ + /* 截至此处的配置描述符长度 = 34 */ + + /* 字符串(String)描述符 设备支持的语言描述符 */ + USB_LANGID_INIT(USBD_LANGID_STRING), + + /* 字符串(String)描述符 制造商字符串 */ + 0x02, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + + /* 字符串(String)描述符 产品字符串 */ + 0x1C, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'M', 0x00, /* wcChar0 */ + 'i', 0x00, /* wcChar1 */ + 'H', 0x00, /* wcChar2 */ + 'o', 0x00, /* wcChar3 */ + 'm', 0x00, /* wcChar4 */ + 'e', 0x00, /* wcChar5 */ + ' ', 0x00, /* wcChar6 */ + 'B', 0x00, /* wcChar7 */ + 'r', 0x00, /* wcChar8 */ + 'i', 0x00, /* wcChar9 */ + 'd', 0x00, /* wcChar10 */ + 'g', 0x00, /* wcChar11 */ + 'e', 0x00, /* wcChar12 */ + + /* 字符串(String)描述符 序列号字符串 */ + 0x16, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + '0', 0x00, /* wcChar0 */ + '1', 0x00, /* wcChar1 */ + '2', 0x00, /* wcChar2 */ + '3', 0x00, /* wcChar3 */ + '4', 0x00, /* wcChar4 */ + '5', 0x00, /* wcChar5 */ + '6', 0x00, /* wcChar6 */ + '7', 0x00, /* wcChar7 */ + '8', 0x00, /* wcChar8 */ + '9', 0x00, /* wcChar9 */ + 'A', 0x00, /* wcChar10 */ + 'B', 0x00, /* wcChar11 */ + +#ifdef CONFIG_USB_HS + /* 设备限定(Device Qualifier)描述符 同时支持全速与高速的设备必须有 */ + 0x0A, + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +#endif + /* 空描述符 */ + 0x00 +}; + +static const uint8_t hid_km_report_desc[HID_KM_REPORT_DESC_SIZE] = { + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x01, // Report ID (1) + 0x05, 0x07, // Usage Page (Kbrd/Keypad) + 0x19, 0xE0, // Usage Minimum (0xE0) + 0x29, 0xE7, // Usage Maximum (0xE7) + 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,No Wrap,Linear,Preferred State,No Null Position) + 0x75, 0x08, // Report Size (8) + 0x95, 0x01, // Report Count (1) + 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x19, 0x00, // Usage Minimum (0x00) + 0x29, 0x65, // Usage Maximum (0x65) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x65, // Logical Maximum (101) + 0x75, 0x08, // Report Size (8) + 0x95, 0x06, // Report Count (6) + 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x08, // Usage Page (LEDs) + 0x19, 0x01, // Usage Minimum (Num Lock) + 0x29, 0x03, // Usage Maximum (Scroll Lock) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x03, // Report Count (3) + 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0x75, 0x05, // Report Size (5) + 0x95, 0x01, // Report Count (1) + 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0xC0, // End Collection + + 0x05, 0x0C, // Usage Page (Consumer) + 0x09, 0x01, // Usage (Consumer Control) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x02, // Report ID (2) + 0x19, 0x00, // Usage Minimum (Unassigned) + 0x2A, 0x3C, 0x02, // Usage Maximum (AC Format) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0x3C, 0x02, // Logical Maximum (572) + 0x95, 0x01, // Report Count (1) + 0x75, 0x10, // Report Size (16) + 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x75, 0x08, // Report Size (8) + 0x95, 0x06, // Report Count (6) + 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, // End Collection + + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x80, // Usage (Sys Control) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x03, // Report ID (3) + 0x19, 0x81, // Usage Minimum (Sys Power Down) + 0x29, 0x83, // Usage Maximum (Sys Wake Up) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x03, // Report Count (3) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x05, // Report Count (5) + 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x75, 0x08, // Report Size (8) + 0x95, 0x07, // Report Count (7) + 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, // End Collection + + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x02, // Usage (Mouse) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x04, // Report ID (4) + 0x09, 0x01, // Usage (Pointer) + 0xA1, 0x00, // Collection (Physical) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (0x01) + 0x29, 0x03, // Usage Maximum (0x03) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x03, // Report Count (3) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x75, 0x05, // Report Size (5) + 0x95, 0x01, // Report Count (1) + 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x09, 0x38, // Usage (Wheel) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7F, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x95, 0x03, // Report Count (3) + 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, // End Collection + 0xC0, // End Collection +}; + +static volatile uint8_t hid_km_state = HID_STATE_BUSY; + +static void usbd_event_handler(uint8_t busid, uint8_t event) +{ + switch (event) { + case USBD_EVENT_RESET: + break; + case USBD_EVENT_CONNECTED: + break; + case USBD_EVENT_DISCONNECTED: + break; + case USBD_EVENT_RESUME: + break; + case USBD_EVENT_SUSPEND: + break; + case USBD_EVENT_CONFIGURED: + hid_km_state = HID_STATE_IDLE; + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; + } +} + +static void usbd_hid_keyboard_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + hid_km_state = HID_STATE_IDLE; +} + +static struct usbd_endpoint hid_keyboard_in_ep = { + .ep_cb = usbd_hid_keyboard_int_callback, + .ep_addr = HID_KM_INT_EP +}; + +void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base) +{ + static struct usbd_interface intf0; + + usbd_desc_register(busid, hid_descriptor); + usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_km_report_desc, HID_KM_REPORT_DESC_SIZE)); + usbd_add_endpoint(busid, &hid_keyboard_in_ep); //添加键盘鼠标INT IN端点 + + usbd_initialize(busid, reg_base, usbd_event_handler); +} + +void hid_keyboard_key_send(uint8_t busid, uint8_t modifier_keys, uint8_t key) +{ + static USB_MEM_ALIGNX uint8_t report[HID_KM_INT_EP_SIZE]; + memset(report, 0, HID_KM_INT_EP_SIZE); + + report[0] = 1; //ID + report[1] = modifier_keys; //修饰键 + report[3] = key; //第一个按键 + // report[4] = ...; //第二个按键 + // ... + // report[8] = ...; //第六个按键 + + int ret = usbd_ep_start_write(busid, HID_KM_INT_EP, report, HID_KM_INT_EP_SIZE); + if (ret < 0) { + return; + } + + hid_km_state = HID_STATE_BUSY; + while (hid_km_state == HID_STATE_BUSY) { + __WFI(); + } +} + +void hid_consumer_control_key_send(uint8_t busid, uint16_t consumer_control_key) +{ + static USB_MEM_ALIGNX uint8_t report[HID_KM_INT_EP_SIZE]; + memset(report, 0, HID_KM_INT_EP_SIZE); + + report[0] = 2; //ID + report[1] = consumer_control_key & 0xFF; //键码低字节 + report[2] = consumer_control_key >> 8; //键码高字节 + + int ret = usbd_ep_start_write(busid, HID_KM_INT_EP, report, HID_KM_INT_EP_SIZE); + if (ret < 0) { + return; + } + + hid_km_state = HID_STATE_BUSY; + while (hid_km_state == HID_STATE_BUSY) { + __WFI(); + } +} + +void hid_system_control_key_send(uint8_t busid, uint16_t system_control_key) +{ + static USB_MEM_ALIGNX uint8_t report[HID_KM_INT_EP_SIZE]; + memset(report, 0, HID_KM_INT_EP_SIZE); + + report[0] = 3; //ID + report[1] = system_control_key; //键码 + + int ret = usbd_ep_start_write(busid, HID_KM_INT_EP, report, HID_KM_INT_EP_SIZE); + if (ret < 0) { + return; + } + + hid_km_state = HID_STATE_BUSY; + while (hid_km_state == HID_STATE_BUSY) { + __WFI(); + } +} + +void hid_mouse_send(uint8_t busid, uint8_t buttons, int8_t x, int8_t y, int8_t wheel) +{ + static USB_MEM_ALIGNX uint8_t report[HID_KM_INT_EP_SIZE]; + memset(report, 0, HID_KM_INT_EP_SIZE); + + report[0] = 4; //ID + report[1] = buttons; //鼠标按键 + report[2] = x; //Delta x + report[3] = y; //Delta y + report[4] = wheel; //滚轮 + + int ret = usbd_ep_start_write(busid, HID_KM_INT_EP, report, HID_KM_INT_EP_SIZE); + if (ret < 0) { + return; + } + + hid_km_state = HID_STATE_BUSY; + while (hid_km_state == HID_STATE_BUSY) { + __WFI(); + } +} diff --git a/mihome_bridge/Core/Src/hid_keyboard_template.c b/mihome_bridge/Core/Src/hid_keyboard_template.c deleted file mode 100644 index ed7acdd..0000000 --- a/mihome_bridge/Core/Src/hid_keyboard_template.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usbd_hid.h" - -#define USBD_VID 0xffff -#define USBD_PID 0xffff -#define USBD_MAX_POWER 100 -#define USBD_LANGID_STRING 1033 - -#define HID_INT_EP 0x81 -#define HID_INT_EP_SIZE 8 -#define HID_INT_EP_INTERVAL 10 - -#define USB_HID_CONFIG_DESC_SIZ 34 -#define HID_KEYBOARD_REPORT_DESC_SIZE 63 - -static const uint8_t hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'H', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x01, - 0x00, -#endif - 0x00 -}; - -/* USB HID device Configuration Descriptor */ -static uint8_t hid_desc[9] __ALIGN_END = { - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, -}; - -static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = { - 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 -}; - -#define HID_STATE_IDLE 0 -#define HID_STATE_BUSY 1 - -/*!< hid state ! Data can be sent only when state is idle */ -static volatile uint8_t hid_state = HID_STATE_IDLE; - -static void usbd_event_handler(uint8_t busid, uint8_t event) -{ - switch (event) { - case USBD_EVENT_RESET: - break; - case USBD_EVENT_CONNECTED: - break; - case USBD_EVENT_DISCONNECTED: - break; - case USBD_EVENT_RESUME: - break; - case USBD_EVENT_SUSPEND: - break; - case USBD_EVENT_CONFIGURED: - hid_state = HID_STATE_IDLE; - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; - - default: - break; - } -} - -void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - hid_state = HID_STATE_IDLE; -} - -static struct usbd_endpoint hid_in_ep = { - .ep_cb = usbd_hid_int_callback, - .ep_addr = HID_INT_EP -}; - -struct usbd_interface intf0; - -void hid_keyboard_init(uint8_t busid, uint32_t reg_base) -{ - usbd_desc_register(busid, hid_descriptor); - usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE)); - usbd_add_endpoint(busid, &hid_in_ep); - - usbd_initialize(busid, reg_base, usbd_event_handler); -} - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[64]; - -void hid_keyboard_test(uint8_t busid, uint8_t key1, uint8_t key2) -{ - const uint8_t sendbuffer[8] = { key1, 0x00, key2, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - memcpy(write_buffer, sendbuffer, 8); - int ret = usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8); - if (ret < 0) { - return; - } - hid_state = HID_STATE_BUSY; - while (hid_state == HID_STATE_BUSY) { - } -} diff --git a/mihome_bridge/Core/Src/main.c b/mihome_bridge/Core/Src/main.c index 0902794..5123d34 100644 --- a/mihome_bridge/Core/Src/main.c +++ b/mihome_bridge/Core/Src/main.c @@ -24,6 +24,7 @@ #include "bsp_key_in_out.h" #include "usbd_core.h" #include "usb_hid.h" +#include "hid_keyboard_mouse.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -56,8 +57,7 @@ static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); static void MX_TIM6_Init(void); /* USER CODE BEGIN PFP */ -void hid_keyboard_init(uint8_t busid, uint32_t reg_base); -void hid_keyboard_test(uint8_t busid, uint8_t key1, uint8_t key2); + /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ @@ -110,50 +110,40 @@ int main(void) MX_USART1_UART_Init(); MX_TIM6_Init(); /* USER CODE BEGIN 2 */ - hid_keyboard_init(0, USB_BASE); bsp_key_in_out_init(); + hid_keyboard_mouse_init(0, USB_BASE); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ - bsp_key_number_e key; - bsp_key_event_type_e event; - while (1) { + bsp_key_number_e key; + bsp_key_event_type_e event; bsp_key_in_get_event(&key, &event); - - if (key != bsp_key_none) { //有按键按下 无论长短按 - bsp_key_out_set_event(key, bsp_key_event_press); //输出短按事件 将该按键恢复至未触发状态 - - if (key == bsp_key1) { //触发USB键盘按键 - hid_keyboard_test(0, 1u << 3, HID_KBD_USAGE_A + 'L' - 'A'); //Left GUI + L - } else if (key == bsp_key2) { - hid_keyboard_test(0, 1u << 3, HID_KBD_USAGE_A + 'R' - 'A'); //Left GUI + R - HAL_Delay(100); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'Y' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'U' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'A' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'N' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'S' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'H' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'E' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'N' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_PERIOD); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'E' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'X' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'E' - 'A'); - hid_keyboard_test(0, 0, HID_KBD_USAGE_ENTER); - HAL_Delay(500); - hid_keyboard_test(0, 0, HID_KBD_USAGE_LEFT); - HAL_Delay(100); - hid_keyboard_test(0, 0, HID_KBD_USAGE_ENTER); - } else if (key == bsp_key3) { - - } else if (key == bsp_key4) { - + + if (key != bsp_key_none) { //有按键按下 + if (event == bsp_key_event_long) { //按下超时 + bsp_key_out_set_event(key, bsp_key_event_press); //输出对应按键的短按事件 将该按键恢复至未触发状态 + } else { //按下边沿 + if (key == bsp_key1) { //触发USB键盘按键 + hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_PLAYPAUSE); //暂停/继续播放 + hid_consumer_control_key_send(0, 0); //抬起 + } else if (key == bsp_key2) { + hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_MUTE); //静音 + hid_consumer_control_key_send(0, 0); //抬起 + } else if (key == bsp_key3) { + hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_NEXTTRACK); //下一曲 + hid_consumer_control_key_send(0, 0); //抬起 + } else if (key == bsp_key4) { + hid_keyboard_key_send(0, HID_MODIFER_LGUI, HID_KBD_USAGE_A + ('L' - 'A')); //Win+L 锁屏 + hid_keyboard_key_send(0, 0, 0); //抬起 + HAL_Delay(400); + hid_system_control_key_send(0, HID_SYSTEM_USAGE_POWER); //关闭屏幕 + hid_system_control_key_send(0, 0); //抬起 + } } - } else { //抬起USB键盘按键 - hid_keyboard_test(0, 0x00, 0x00); + } else { + __WFI(); } /* USER CODE END WHILE */ diff --git a/mihome_bridge/MDK-ARM/mihome_bridge.uvprojx b/mihome_bridge/MDK-ARM/mihome_bridge.uvprojx index 1adead8..4160b08 100644 --- a/mihome_bridge/MDK-ARM/mihome_bridge.uvprojx +++ b/mihome_bridge/MDK-ARM/mihome_bridge.uvprojx @@ -393,11 +393,6 @@ Application/User/Core - - hid_keyboard_template.c - 1 - ..\Core\Src\hid_keyboard_template.c - usb_config.h 5 @@ -423,6 +418,11 @@ 1 ../Core/Src/stm32f0xx_hal_msp.c + + hid_keyboard_mouse.c + 1 + ..\Core\Src\hid_keyboard_mouse.c + diff --git a/stm32f0_cherryusb/Core/Inc/bsp_key.h b/stm32f0_cherryusb/Core/Inc/bsp_key.h new file mode 100644 index 0000000..6d06a87 --- /dev/null +++ b/stm32f0_cherryusb/Core/Inc/bsp_key.h @@ -0,0 +1,31 @@ +#ifndef __BSP_KEY_H +#define __BSP_KEY_H + +#include "main.h" + +#define BSP_KEY_COUNT 8 +#define BSP_KEY_PRESSED_GPIO_LEVEL GPIO_PIN_RESET +#define BSP_KEY_LONG_PRESS_THRESHOLD_MS 500 + +typedef enum { + bsp_key_none = 0, + bsp_key1 = 0x01, + bsp_key2 = 0x02, + bsp_key3 = 0x04, + bsp_key4 = 0x08, + bsp_key5 = 0x10, + bsp_key6 = 0x20, + bsp_key7 = 0x40, + bsp_key8 = 0x80 +} bsp_key_number_e; + +typedef enum { + bsp_key_event_none = 0, + bsp_key_event_press, + bsp_key_event_long, +} bsp_key_event_type_e; + +void bsp_key_init(void); +void bsp_key_get_event(bsp_key_number_e *key, bsp_key_event_type_e *event); + +#endif diff --git a/stm32f0_cherryusb/Core/Inc/main.h b/stm32f0_cherryusb/Core/Inc/main.h index 5ef36e2..9e9451b 100644 --- a/stm32f0_cherryusb/Core/Inc/main.h +++ b/stm32f0_cherryusb/Core/Inc/main.h @@ -41,7 +41,7 @@ extern "C" { /* Exported constants --------------------------------------------------------*/ /* USER CODE BEGIN EC */ - +extern TIM_HandleTypeDef htim6; /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ @@ -57,8 +57,8 @@ void Error_Handler(void); /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ -#define BSP_KEY_IN_OUT_INTERAEL_MS 10 -#define BSP_KEY_IN_OUT_TIM htim6 +#define BSP_KEY_SCAN_TIM htim6 +#define BSP_KEY_SCAN_INTERVAL_MS 10 #define KEY8_Pin GPIO_PIN_0 #define KEY8_GPIO_Port GPIOA #define KEY7_Pin GPIO_PIN_1 diff --git a/stm32f0_cherryusb/Core/Src/bsp_key.c b/stm32f0_cherryusb/Core/Src/bsp_key.c new file mode 100644 index 0000000..895b5f9 --- /dev/null +++ b/stm32f0_cherryusb/Core/Src/bsp_key.c @@ -0,0 +1,125 @@ +#include "bsp_key.h" + +typedef struct { + uint8_t is_pressed_before; + uint8_t is_long_pressed; + uint32_t long_press_count; + volatile bsp_key_event_type_e event; +} bsp_key_status_t; + +static bsp_key_status_t key_in_status[BSP_KEY_COUNT]; +static bsp_key_number_e key_out_gpio_value = bsp_key_none; + +static uint8_t bsp_key_number_to_index(bsp_key_number_e key_number) +{ + switch (key_number) { + case bsp_key1: return 0; + case bsp_key2: return 1; + case bsp_key3: return 2; + case bsp_key4: return 3; + case bsp_key5: return 4; + case bsp_key6: return 5; + case bsp_key7: return 6; + case bsp_key8: return 7; + default: return 0xFF; + } +} + +static bsp_key_number_e bsp_key_read(void) +{ + bsp_key_number_e key_in = bsp_key_none; + + if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { + key_in |= bsp_key1; + } + + if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { + key_in |= bsp_key2; + } + + if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { + key_in |= bsp_key3; + } + + if (HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { + key_in |= bsp_key4; + } + + if (HAL_GPIO_ReadPin(KEY5_GPIO_Port, KEY5_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { + key_in |= bsp_key5; + } + + if (HAL_GPIO_ReadPin(KEY6_GPIO_Port, KEY6_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { + key_in |= bsp_key6; + } + + if (HAL_GPIO_ReadPin(KEY7_GPIO_Port, KEY7_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { + key_in |= bsp_key7; + } + + if (HAL_GPIO_ReadPin(KEY8_GPIO_Port, KEY8_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { + key_in |= bsp_key8; + } + + return key_in; +} + +static void bsp_key_process(void) +{ + bsp_key_number_e key_in = bsp_key_read(); //读取按键值 + for (uint8_t key_index = 0; key_index < BSP_KEY_COUNT; key_index ++) { + uint8_t is_pressed = key_in & 1u << key_index ? 1 : 0; //第key_index个按键是否被按下 + /* 按键抬起状态 */ + if(!is_pressed && !key_in_status[key_index].is_pressed_before) { //本次没有按下 上次也没有按下 + key_in_status[key_index].is_long_pressed = 0; + key_in_status[key_index].long_press_count = 0; //复位长按状态 + } + /* 按键按下状态 */ + if (is_pressed) { //按键处于被按下的状态 + if (!key_in_status[key_index].is_long_pressed) { //如果还未触发长按事件 + key_in_status[key_index].long_press_count ++; //记录长按时间 + + if (key_in_status[key_index].long_press_count > //长按时间超过阈值 + BSP_KEY_LONG_PRESS_THRESHOLD_MS / BSP_KEY_SCAN_INTERVAL_MS) { + key_in_status[key_index].is_long_pressed = 1; //记录产生了长按事件 + key_in_status[key_index].event = bsp_key_event_long; //产生长按事件 + } + } + } + /* 按键抬起边沿 */ + if (!is_pressed && key_in_status[key_index].is_pressed_before && + !key_in_status[key_index].is_long_pressed) { //本次没有按下 但上次按下了 且未触发长按事件 + key_in_status[key_index].event = bsp_key_event_press; //产生短按事件 + } + + key_in_status[key_index].is_pressed_before = is_pressed; //记录上次按下的状态 + } +} + +void bsp_key_get_event(bsp_key_number_e *key, bsp_key_event_type_e *event) +{ + *key = bsp_key_none; + *event = bsp_key_event_none; + + for (uint8_t key_index = 0; key_index < BSP_KEY_COUNT; key_index ++) { + //第key_index个按键是否被按下 + if (key_in_status[key_index].event != bsp_key_event_none) { + *key = 1u << key_index; + *event = key_in_status[key_index].event; + key_in_status[key_index].event = bsp_key_event_none; + return; + } + } +} + +void bsp_key_init(void) +{ + HAL_TIM_Base_Start_IT(&BSP_KEY_SCAN_TIM); +} + +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + if (htim == &BSP_KEY_SCAN_TIM) { + bsp_key_process(); + } +} diff --git a/stm32f0_cherryusb/Core/Src/hid_keyboard_mouse.c b/stm32f0_cherryusb/Core/Src/hid_keyboard_mouse.c index da5c76b..2d28b8e 100644 --- a/stm32f0_cherryusb/Core/Src/hid_keyboard_mouse.c +++ b/stm32f0_cherryusb/Core/Src/hid_keyboard_mouse.c @@ -11,17 +11,16 @@ #define USBD_MAX_POWER_MA 100 #define USBD_LANGID_STRING 1033 -#define HID_KEYBOARD_INT_EP 0x81 -#define HID_KEYBOARD_INT_EP_SIZE 8 -#define HID_KEYBOARD_INT_EP_INTERVAL 10 +#define HID_KM_IN_EP 0x81 +#define HID_KM_IN_EP_SIZE 16 +#define HID_KM_IN_EP_INTERVAL 10 -#define HID_MOUSE_INT_EP 0x82 -#define HID_MOUSE_INT_EP_SIZE 4 -#define HID_MOUSE_INT_EP_INTERVAL 1 +#define HID_KM_OUT_EP 0x02 +#define HID_KM_OUT_EP_SIZE 4 +#define HID_KM_OUT_EP_INTERVAL 10 -#define HID_CONFIG_DESCRIPTOR_SIZE 59 -#define HID_KEYBOARD_REPORT_DESC_SIZE 63 -#define HID_MOUSE_REPORT_DESC_SIZE 74 +#define HID_CONFIG_DESCRIPTOR_SIZE 41 +#define HID_KM_REPORT_DESC_SIZE 187 static const uint8_t hid_descriptor[] = { /* 设备(Device)描述符 所有设备有且只有一个 */ @@ -31,17 +30,17 @@ static const uint8_t hid_descriptor[] = { USB_CONFIG_DESCRIPTOR_INIT(HID_CONFIG_DESCRIPTOR_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER_MA), /* Configuration Descriptor Length = 09 */ - /* 接口(Interface)描述符 键盘 */ - 0x09, /* bLength: Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: 1 */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /* 18 */ + /* 接口(Interface)描述符 键盘 */ + 0x09, /* bLength: Descriptor size */ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: 2 */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0, /* iInterface: Index of string descriptor */ + /* 截至此处的配置描述符长度 = 18 */ /* HID描述符 键盘 */ 0x09, /* bLength: HID Descriptor size */ @@ -53,100 +52,59 @@ static const uint8_t hid_descriptor[] = { WBVAL(HID_KEYBOARD_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ /* 27 */ - /* 端点(Endpoint)描述符 键盘 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - HID_KEYBOARD_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - WBVAL(HID_KEYBOARD_INT_EP_SIZE), /* wMaxPacketSize: 8 Byte max */ - HID_KEYBOARD_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ + /* 端点(Endpoint)描述符 键盘IN */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + HID_KM_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + WBVAL(HID_KM_IN_EP_SIZE), /* wMaxPacketSize: 9 Bytes maximum */ + HID_KM_IN_EP_INTERVAL, /* bInterval: Polling Interval */ + /* 截至此处的配置描述符长度 = 34 */ - /* 接口(Interface)描述符 鼠标 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /* 43 */ - - /* HID描述符 鼠标 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /* 52 */ - - /* 端点(Endpoint)描述符 鼠标 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_MOUSE_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_MOUSE_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_MOUSE_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 59 */ + /* 端点(Endpoint)描述符 键盘OUT */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + HID_KM_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + WBVAL(HID_KM_OUT_EP_SIZE), /* wMaxPacketSize: 9 Bytes maximum */ + HID_KM_OUT_EP_INTERVAL, /* bInterval: Polling Interval */ + /* 截至此处的配置描述符长度 = 41 */ /* 字符串(String)描述符 设备支持的语言描述符 */ USB_LANGID_INIT(USBD_LANGID_STRING), - /* 字符串(String)描述符 UNICODE String Descriptor */ - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ + /* 字符串(String)描述符 制造商字符串 */ + 0x02, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - /* 字符串(String)描述符 Product String Descriptor */ - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'H', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ + /* 字符串(String)描述符 产品字符串 */ + 0x12, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'H', 0x00, /* wcChar0 */ + 'I', 0x00, /* wcChar1 */ + 'D', 0x00, /* wcChar2 */ + ' ', 0x00, /* wcChar3 */ + 'D', 0x00, /* wcChar4 */ + 'e', 0x00, /* wcChar5 */ + 'm', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + + /* 字符串(String)描述符 序列号字符串 */ + 0x16, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + '2', 0x00, /* wcChar0 */ + '0', 0x00, /* wcChar1 */ + '2', 0x00, /* wcChar2 */ + '2', 0x00, /* wcChar3 */ + '1', 0x00, /* wcChar4 */ + '2', 0x00, /* wcChar5 */ + '3', 0x00, /* wcChar6 */ + '4', 0x00, /* wcChar7 */ + '5', 0x00, /* wcChar8 */ + '6', 0x00, /* wcChar9 */ + '7', 0x00, /* wcChar10 */ + '8', 0x00, /* wcChar11 */ - /* 字符串(String)描述符 Serial Number String Descriptor */ - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ #ifdef CONFIG_USB_HS /* 设备限定(Device Qualifier)描述符 同时支持全速与高速的设备必须有 */ 0x0a, @@ -247,55 +205,59 @@ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { 0x01, 0xc0 // END_COLLECTION }; -static volatile uint8_t hid_keyboard_state = HID_STATE_BUSY; -static volatile uint8_t hid_mouse_state = HID_STATE_BUSY; +static volatile uint8_t hid_km_state = HID_STATE_BUSY; + +USB_MEM_ALIGNX uint8_t read_buffer[HID_KM_OUT_EP_SIZE]; + +static void usbd_hid_keyboard_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + hid_km_state = HID_STATE_IDLE; +} + +static void usbd_hid_keyboard_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + usbd_ep_start_read(busid, ep, read_buffer, HID_KM_OUT_EP_SIZE); + + HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, read_buffer[1] & 0x01); + HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, read_buffer[1] & 0x02); + HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, read_buffer[1] & 0x04); +} static void usbd_event_handler(uint8_t busid, uint8_t event) { - switch (event) { - case USBD_EVENT_RESET: - break; - case USBD_EVENT_CONNECTED: - break; - case USBD_EVENT_DISCONNECTED: - break; - case USBD_EVENT_RESUME: - break; - case USBD_EVENT_SUSPEND: - break; - case USBD_EVENT_CONFIGURED: - hid_keyboard_state = HID_STATE_IDLE; - hid_mouse_state = HID_STATE_IDLE; - HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET); - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; + switch (event) { + case USBD_EVENT_RESET: + break; + case USBD_EVENT_CONNECTED: + break; + case USBD_EVENT_DISCONNECTED: + break; + case USBD_EVENT_RESUME: + break; + case USBD_EVENT_SUSPEND: + break; + case USBD_EVENT_CONFIGURED: + hid_km_state = HID_STATE_IDLE; + usbd_ep_start_read(busid, HID_KM_OUT_EP, read_buffer, HID_KM_OUT_EP_SIZE); + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; default: break; } } -static void usbd_hid_keyboard_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - hid_keyboard_state = HID_STATE_IDLE; -} - -static void usbd_hid_mouse_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - hid_mouse_state = HID_STATE_IDLE; -} - static struct usbd_endpoint hid_keyboard_in_ep = { - .ep_cb = usbd_hid_keyboard_int_callback, - .ep_addr = HID_KEYBOARD_INT_EP + .ep_cb = usbd_hid_keyboard_in_callback, + .ep_addr = HID_KM_IN_EP }; -static struct usbd_endpoint hid_mouse_in_ep = { - .ep_cb = usbd_hid_mouse_int_callback, - .ep_addr = HID_MOUSE_INT_EP +static struct usbd_endpoint hid_keyboard_out_ep = { + .ep_cb = usbd_hid_keyboard_out_callback, + .ep_addr = HID_KM_OUT_EP }; void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base) @@ -303,45 +265,102 @@ void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base) static struct usbd_interface intf0; static struct usbd_interface intf1; - usbd_desc_register(busid, hid_descriptor); - usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE)); - usbd_add_endpoint(busid, &hid_keyboard_in_ep); - usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf1, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE)); - usbd_add_endpoint(busid, &hid_mouse_in_ep); + usbd_desc_register(busid, hid_descriptor); + usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_km_report_desc, HID_KM_REPORT_DESC_SIZE)); //添加键盘鼠标INT IN端点 + usbd_add_endpoint(busid, &hid_keyboard_in_ep); + usbd_add_endpoint(busid, &hid_keyboard_out_ep); usbd_initialize(busid, reg_base, usbd_event_handler); } void hid_keyboard_send(uint8_t busid, hid_keyboard_report_t *keyboard_report) { - static USB_MEM_ALIGNX uint8_t write_buffer[64]; - memcpy(write_buffer, keyboard_report, sizeof(hid_keyboard_report_t)); + static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE]; + memset(report, 0, HID_KM_IN_EP_SIZE); - int ret = usbd_ep_start_write(busid, HID_KEYBOARD_INT_EP, write_buffer, sizeof(hid_keyboard_report_t)); - if (ret < 0) { - return; - } + report[0] = 1; //ID + report[1] = modifier_keys; //修饰键 + report[3] = key; //第一个按键 + // report[4] = ...; //第二个按键 + // ... + // report[8] = ...; //第六个按键 - hid_keyboard_state = HID_STATE_BUSY; - while (hid_keyboard_state == HID_STATE_BUSY) { - __WFI(); - } - HAL_GPIO_TogglePin(LED7_GPIO_Port, LED7_Pin); + int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE); + if (ret < 0) { + return; + } + + hid_km_state = HID_STATE_BUSY; + while (hid_km_state == HID_STATE_BUSY) { + HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET); + __WFI(); + HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_RESET); + } +} + +void hid_consumer_control_key_send(uint8_t busid, uint16_t consumer_control_key) +{ + static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE]; + memset(report, 0, HID_KM_IN_EP_SIZE); + + report[0] = 2; //ID + report[1] = consumer_control_key & 0xFF; //键码低字节 + report[2] = consumer_control_key >> 8; //键码高字节 + + int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE); + if (ret < 0) { + return; + } + + hid_km_state = HID_STATE_BUSY; + while (hid_km_state == HID_STATE_BUSY) { + HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, GPIO_PIN_SET); + __WFI(); + HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, GPIO_PIN_RESET); + } } void hid_mouse_send(uint8_t busid, hid_mouse_report_t *mouse_report) { - static USB_MEM_ALIGNX uint8_t write_buffer[64]; - memcpy(write_buffer, mouse_report, sizeof(hid_mouse_report_t)); + static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE]; + memset(report, 0, HID_KM_IN_EP_SIZE); - int ret = usbd_ep_start_write(busid, HID_MOUSE_INT_EP, write_buffer, sizeof(hid_mouse_report_t)); - if (ret < 0) { - return; - } + report[0] = 3; //ID + report[1] = system_control_key; //键码 - hid_mouse_state = HID_STATE_BUSY; - while (hid_mouse_state == HID_STATE_BUSY) { - __WFI(); - } - HAL_GPIO_TogglePin(LED8_GPIO_Port, LED8_Pin); + int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE); + if (ret < 0) { + return; + } + + hid_km_state = HID_STATE_BUSY; + while (hid_km_state == HID_STATE_BUSY) { + HAL_GPIO_WritePin(LED7_GPIO_Port, LED8_Pin, GPIO_PIN_SET); + __WFI(); + HAL_GPIO_WritePin(LED7_GPIO_Port, LED8_Pin, GPIO_PIN_RESET); + } +} + +void hid_mouse_send(uint8_t busid, uint8_t buttons, int8_t x, int8_t y, int8_t wheel) +{ + static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE]; + memset(report, 0, HID_KM_IN_EP_SIZE); + + report[0] = 4; //ID + report[1] = buttons; //鼠标按键 + report[2] = x; //Delta x + report[3] = y; //Delta y + report[4] = wheel; //滚轮 + + int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE); + if (ret < 0) { + return; + } + + hid_km_state = HID_STATE_BUSY; + while (hid_km_state == HID_STATE_BUSY) { + HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, GPIO_PIN_SET); + __WFI(); + HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, GPIO_PIN_RESET); + } } diff --git a/stm32f0_cherryusb/Core/Src/main.c b/stm32f0_cherryusb/Core/Src/main.c index d8b78c3..f5d0564 100644 --- a/stm32f0_cherryusb/Core/Src/main.c +++ b/stm32f0_cherryusb/Core/Src/main.c @@ -23,6 +23,7 @@ /* USER CODE BEGIN Includes */ #include "usbd_core.h" #include "usb_hid.h" +#include "bsp_key.h" #include "hid_keyboard_mouse.h" /* USER CODE END Includes */ @@ -109,6 +110,7 @@ int main(void) MX_USART1_UART_Init(); MX_TIM6_Init(); /* USER CODE BEGIN 2 */ + bsp_key_init(); hid_keyboard_mouse_init(0, USB_BASE); /* USER CODE END 2 */ @@ -119,38 +121,36 @@ int main(void) while (1) { - memset(&keyboard_report, 0, sizeof(hid_keyboard_report_t)); - memset(&mouse_report, 0, sizeof(hid_mouse_report_t)); + bsp_key_number_e key; + bsp_key_event_type_e event; + bsp_key_get_event(&key, &event); + bsp_key_number_e key; + bsp_key_event_type_e event; + bsp_key_get_event(&key, &event); - if (HAL_GPIO_ReadPin(KEY5_GPIO_Port, KEY5_Pin) == GPIO_PIN_RESET) { //鼠标X轴 - mouse_report.x = -10; - } else if(HAL_GPIO_ReadPin(KEY7_GPIO_Port, KEY7_Pin) == GPIO_PIN_RESET) { - mouse_report.x = 10; + if (key != bsp_key_none) { //有按键按下 + if (key == bsp_key1) { //触发USB键盘按键 + hid_mouse_send(0, 0, -20, 0, 0); + } else if (key == bsp_key2) { + hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_MUTE); //静音 + hid_consumer_control_key_send(0, 0); //抬起 + } else if (key == bsp_key3) { + + } else if (key == bsp_key4) { + hid_system_control_key_send(0, HID_SYSTEM_USAGE_POWER); //关闭屏幕 + hid_system_control_key_send(0, 0); //抬起 + } else if (key == bsp_key5) { + hid_mouse_send(0, 0, 20, 0, 0); + } else if (key == bsp_key6) { + + } else if (key == bsp_key7) { + + } else if (key == bsp_key8) { + + } + } else { + __WFI(); } - - if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET) { //鼠标Y轴 - mouse_report.y = -10; - } else if(HAL_GPIO_ReadPin(KEY6_GPIO_Port, KEY6_Pin) == GPIO_PIN_RESET) { - mouse_report.y = 10; - } - - if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET) { //左键 - mouse_report.buttons |= HID_MOUSE_LEFT_BUTTON; - } - - if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == GPIO_PIN_RESET) { //右键 - mouse_report.buttons |= HID_MOUSE_RIGHT_BUTTON; - } - - if (HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) == GPIO_PIN_RESET) { - keyboard_report.modifier_keys = HID_KEYBOARD_LEFT_GUI; - keyboard_report.key1 = HID_KBD_USAGE_A + 'L' - 'A'; //Win+L - } else if (HAL_GPIO_ReadPin(KEY8_GPIO_Port, KEY8_Pin) == GPIO_PIN_RESET) { - keyboard_report.key1 = HID_KBD_USAGE_1 + 5; - } - - hid_keyboard_send(0, &keyboard_report); - hid_mouse_send(0, &mouse_report); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ @@ -226,7 +226,7 @@ static void MX_TIM6_Init(void) htim6.Instance = TIM6; htim6.Init.Prescaler = SystemCoreClock / 1000 -1; htim6.Init.CounterMode = TIM_COUNTERMODE_UP; - htim6.Init.Period = BSP_KEY_IN_OUT_INTERAEL_MS - 1; + htim6.Init.Period = BSP_KEY_SCAN_INTERVAL_MS - 1; htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim6) != HAL_OK) { diff --git a/stm32f0_cherryusb/MDK-ARM/stm32f0_cherryusb.uvprojx b/stm32f0_cherryusb/MDK-ARM/stm32f0_cherryusb.uvprojx index 8b4ce97..a4f4622 100644 --- a/stm32f0_cherryusb/MDK-ARM/stm32f0_cherryusb.uvprojx +++ b/stm32f0_cherryusb/MDK-ARM/stm32f0_cherryusb.uvprojx @@ -393,6 +393,16 @@ Application/User/Core + + hid_keyboard_mouse.c + 1 + ..\Core\Src\hid_keyboard_mouse.c + + + bsp_key.c + 1 + ..\Core\Src\bsp_key.c + main.c 1 @@ -408,11 +418,6 @@ 1 ../Core/Src/stm32f0xx_hal_msp.c - - hid_keyboard_mouse.c - 1 - ..\Core\Src\hid_keyboard_mouse.c - diff --git a/stm32f0_cherryusb/stm32f0_cherryusb.ioc b/stm32f0_cherryusb/stm32f0_cherryusb.ioc index a2b7095..39ff988 100644 --- a/stm32f0_cherryusb/stm32f0_cherryusb.ioc +++ b/stm32f0_cherryusb/stm32f0_cherryusb.ioc @@ -43,7 +43,7 @@ Mcu.Pin8=PA6 Mcu.Pin9=PA7 Mcu.PinsNb=26 Mcu.ThirdPartyNb=0 -Mcu.UserConstants=BSP_KEY_IN_OUT_INTERAEL_MS,10;BSP_KEY_IN_OUT_TIM,$$_TIM6_IP_HANDLE_$$ +Mcu.UserConstants=BSP_KEY_SCAN_TIM,$$_TIM6_IP_HANDLE_$$;BSP_KEY_SCAN_INTERVAL_MS,10 Mcu.UserName=STM32F072C8Tx MxCube.Version=6.11.1 MxDb.Version=DB.6.0.111 @@ -239,8 +239,8 @@ RCC.USART1Freq_Value=48000000 RCC.USART2Freq_Value=48000000 RCC.VCOOutput2Freq_Value=8000000 TIM6.IPParameters=Prescaler,Period -TIM6.IPParametersWithoutCheck=Prescaler -TIM6.Period=BSP_KEY_IN_OUT_INTERAEL_MS - 1 +TIM6.IPParametersWithoutCheck=Prescaler,Period +TIM6.Period=BSP_KEY_SCAN_INTERVAL_MS - 1 TIM6.Prescaler=SystemCoreClock / 1000 -1 USART1.BaudRate=115200 USART1.IPParameters=VirtualMode-Asynchronous,BaudRate