mihome_bridge: add multimedia and system keys
This commit is contained in:
parent
2c381a1910
commit
6415b32d5a
@ -26,9 +26,9 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
bsp_key_event_none = 0,
|
bsp_key_event_none = 0,
|
||||||
bsp_key_event_press,
|
bsp_key_event_press, //输出按键短按 且按键输入的按下边沿会产生此事件
|
||||||
bsp_key_event_long,
|
bsp_key_event_long, //输出按键长按 且按键输入的时长达到阈值会产生此事件
|
||||||
bsp_key_event_double,
|
bsp_key_event_double, //输出按键双击
|
||||||
} bsp_key_event_type_e;
|
} bsp_key_event_type_e;
|
||||||
|
|
||||||
void bsp_key_in_out_init(void);
|
void bsp_key_in_out_init(void);
|
||||||
|
|||||||
36
mihome_bridge/Core/Inc/hid_keyboard_mouse.h
Normal file
36
mihome_bridge/Core/Inc/hid_keyboard_mouse.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef __HID_KEYBOARD_MOUSE_H
|
||||||
|
#define __HID_KEYBOARD_MOUSE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
@ -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].is_long_pressed = 0;
|
||||||
key_in_status[key_index].long_press_count = 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 (is_pressed) { //按键处于被按下的状态
|
||||||
if (!key_in_status[key_index].is_long_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; //记录上次按下的状态
|
key_in_status[key_index].is_pressed_before = is_pressed; //记录上次按下的状态
|
||||||
}
|
}
|
||||||
|
|||||||
350
mihome_bridge/Core/Src/hid_keyboard_mouse.c
Normal file
350
mihome_bridge/Core/Src/hid_keyboard_mouse.c
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
#include "hid_keyboard_mouse.h"
|
||||||
|
#include <string.h>
|
||||||
|
#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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -24,6 +24,7 @@
|
|||||||
#include "bsp_key_in_out.h"
|
#include "bsp_key_in_out.h"
|
||||||
#include "usbd_core.h"
|
#include "usbd_core.h"
|
||||||
#include "usb_hid.h"
|
#include "usb_hid.h"
|
||||||
|
#include "hid_keyboard_mouse.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@ -56,8 +57,7 @@ static void MX_GPIO_Init(void);
|
|||||||
static void MX_USART1_UART_Init(void);
|
static void MX_USART1_UART_Init(void);
|
||||||
static void MX_TIM6_Init(void);
|
static void MX_TIM6_Init(void);
|
||||||
/* USER CODE BEGIN PFP */
|
/* 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 */
|
/* USER CODE END PFP */
|
||||||
|
|
||||||
/* Private user code ---------------------------------------------------------*/
|
/* Private user code ---------------------------------------------------------*/
|
||||||
@ -110,50 +110,40 @@ int main(void)
|
|||||||
MX_USART1_UART_Init();
|
MX_USART1_UART_Init();
|
||||||
MX_TIM6_Init();
|
MX_TIM6_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
hid_keyboard_init(0, USB_BASE);
|
|
||||||
bsp_key_in_out_init();
|
bsp_key_in_out_init();
|
||||||
|
hid_keyboard_mouse_init(0, USB_BASE);
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
/* USER CODE BEGIN WHILE */
|
/* USER CODE BEGIN WHILE */
|
||||||
|
while (1) {
|
||||||
bsp_key_number_e key;
|
bsp_key_number_e key;
|
||||||
bsp_key_event_type_e event;
|
bsp_key_event_type_e event;
|
||||||
|
|
||||||
while (1) {
|
|
||||||
bsp_key_in_get_event(&key, &event);
|
bsp_key_in_get_event(&key, &event);
|
||||||
|
|
||||||
if (key != bsp_key_none) { //有按键按下 无论长短按
|
if (key != bsp_key_none) { //有按键按下
|
||||||
bsp_key_out_set_event(key, bsp_key_event_press); //输出短按事件 将该按键恢复至未触发状态
|
if (event == bsp_key_event_long) { //按下超时
|
||||||
|
bsp_key_out_set_event(key, bsp_key_event_press); //输出对应按键的短按事件 将该按键恢复至未触发状态
|
||||||
|
} else { //按下边沿
|
||||||
if (key == bsp_key1) { //触发USB键盘按键
|
if (key == bsp_key1) { //触发USB键盘按键
|
||||||
hid_keyboard_test(0, 1u << 3, HID_KBD_USAGE_A + 'L' - 'A'); //Left GUI + L
|
hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_PLAYPAUSE); //暂停/继续播放
|
||||||
|
hid_consumer_control_key_send(0, 0); //抬起
|
||||||
} else if (key == bsp_key2) {
|
} else if (key == bsp_key2) {
|
||||||
hid_keyboard_test(0, 1u << 3, HID_KBD_USAGE_A + 'R' - 'A'); //Left GUI + R
|
hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_MUTE); //静音
|
||||||
HAL_Delay(100);
|
hid_consumer_control_key_send(0, 0); //抬起
|
||||||
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_key3) {
|
||||||
|
hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_NEXTTRACK); //下一曲
|
||||||
|
hid_consumer_control_key_send(0, 0); //抬起
|
||||||
} else if (key == bsp_key4) {
|
} 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 */
|
/* USER CODE END WHILE */
|
||||||
|
|
||||||
|
|||||||
@ -393,11 +393,6 @@
|
|||||||
<Group>
|
<Group>
|
||||||
<GroupName>Application/User/Core</GroupName>
|
<GroupName>Application/User/Core</GroupName>
|
||||||
<Files>
|
<Files>
|
||||||
<File>
|
|
||||||
<FileName>hid_keyboard_template.c</FileName>
|
|
||||||
<FileType>1</FileType>
|
|
||||||
<FilePath>..\Core\Src\hid_keyboard_template.c</FilePath>
|
|
||||||
</File>
|
|
||||||
<File>
|
<File>
|
||||||
<FileName>usb_config.h</FileName>
|
<FileName>usb_config.h</FileName>
|
||||||
<FileType>5</FileType>
|
<FileType>5</FileType>
|
||||||
@ -423,6 +418,11 @@
|
|||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<FilePath>../Core/Src/stm32f0xx_hal_msp.c</FilePath>
|
<FilePath>../Core/Src/stm32f0xx_hal_msp.c</FilePath>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>hid_keyboard_mouse.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Core\Src\hid_keyboard_mouse.c</FilePath>
|
||||||
|
</File>
|
||||||
</Files>
|
</Files>
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
|
|||||||
31
stm32f0_cherryusb/Core/Inc/bsp_key.h
Normal file
31
stm32f0_cherryusb/Core/Inc/bsp_key.h
Normal file
@ -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
|
||||||
@ -41,7 +41,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* Exported constants --------------------------------------------------------*/
|
/* Exported constants --------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN EC */
|
/* USER CODE BEGIN EC */
|
||||||
|
extern TIM_HandleTypeDef htim6;
|
||||||
/* USER CODE END EC */
|
/* USER CODE END EC */
|
||||||
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
@ -57,8 +57,8 @@ void Error_Handler(void);
|
|||||||
/* USER CODE END EFP */
|
/* USER CODE END EFP */
|
||||||
|
|
||||||
/* Private defines -----------------------------------------------------------*/
|
/* Private defines -----------------------------------------------------------*/
|
||||||
#define BSP_KEY_IN_OUT_INTERAEL_MS 10
|
#define BSP_KEY_SCAN_TIM htim6
|
||||||
#define BSP_KEY_IN_OUT_TIM htim6
|
#define BSP_KEY_SCAN_INTERVAL_MS 10
|
||||||
#define KEY8_Pin GPIO_PIN_0
|
#define KEY8_Pin GPIO_PIN_0
|
||||||
#define KEY8_GPIO_Port GPIOA
|
#define KEY8_GPIO_Port GPIOA
|
||||||
#define KEY7_Pin GPIO_PIN_1
|
#define KEY7_Pin GPIO_PIN_1
|
||||||
|
|||||||
125
stm32f0_cherryusb/Core/Src/bsp_key.c
Normal file
125
stm32f0_cherryusb/Core/Src/bsp_key.c
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,17 +11,16 @@
|
|||||||
#define USBD_MAX_POWER_MA 100
|
#define USBD_MAX_POWER_MA 100
|
||||||
#define USBD_LANGID_STRING 1033
|
#define USBD_LANGID_STRING 1033
|
||||||
|
|
||||||
#define HID_KEYBOARD_INT_EP 0x81
|
#define HID_KM_IN_EP 0x81
|
||||||
#define HID_KEYBOARD_INT_EP_SIZE 8
|
#define HID_KM_IN_EP_SIZE 16
|
||||||
#define HID_KEYBOARD_INT_EP_INTERVAL 10
|
#define HID_KM_IN_EP_INTERVAL 10
|
||||||
|
|
||||||
#define HID_MOUSE_INT_EP 0x82
|
#define HID_KM_OUT_EP 0x02
|
||||||
#define HID_MOUSE_INT_EP_SIZE 4
|
#define HID_KM_OUT_EP_SIZE 4
|
||||||
#define HID_MOUSE_INT_EP_INTERVAL 1
|
#define HID_KM_OUT_EP_INTERVAL 10
|
||||||
|
|
||||||
#define HID_CONFIG_DESCRIPTOR_SIZE 59
|
#define HID_CONFIG_DESCRIPTOR_SIZE 41
|
||||||
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
|
#define HID_KM_REPORT_DESC_SIZE 187
|
||||||
#define HID_MOUSE_REPORT_DESC_SIZE 74
|
|
||||||
|
|
||||||
static const uint8_t hid_descriptor[] = {
|
static const uint8_t hid_descriptor[] = {
|
||||||
/* 设备(Device)描述符 所有设备有且只有一个 */
|
/* 设备(Device)描述符 所有设备有且只有一个 */
|
||||||
@ -36,12 +35,12 @@ static const uint8_t hid_descriptor[] = {
|
|||||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Descriptor type */
|
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Descriptor type */
|
||||||
0x00, /* bInterfaceNumber: Number of Interface */
|
0x00, /* bInterfaceNumber: Number of Interface */
|
||||||
0x00, /* bAlternateSetting: Alternate setting */
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
0x01, /* bNumEndpoints: 1 */
|
0x02, /* bNumEndpoints: 2 */
|
||||||
0x03, /* bInterfaceClass: HID */
|
0x03, /* bInterfaceClass: HID */
|
||||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||||
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||||
0, /* iInterface: Index of string descriptor */
|
0, /* iInterface: Index of string descriptor */
|
||||||
/* 18 */
|
/* 截至此处的配置描述符长度 = 18 */
|
||||||
|
|
||||||
/* HID描述符 键盘 */
|
/* HID描述符 键盘 */
|
||||||
0x09, /* bLength: HID Descriptor size */
|
0x09, /* bLength: HID Descriptor size */
|
||||||
@ -53,88 +52,44 @@ static const uint8_t hid_descriptor[] = {
|
|||||||
WBVAL(HID_KEYBOARD_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */
|
WBVAL(HID_KEYBOARD_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */
|
||||||
/* 27 */
|
/* 27 */
|
||||||
|
|
||||||
/* 端点(Endpoint)描述符 键盘 */
|
/* 端点(Endpoint)描述符 键盘IN */
|
||||||
0x07, /* bLength: Endpoint Descriptor size */
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
HID_KEYBOARD_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
HID_KM_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||||
0x03, /* bmAttributes: Interrupt endpoint */
|
0x03, /* bmAttributes: Interrupt endpoint */
|
||||||
WBVAL(HID_KEYBOARD_INT_EP_SIZE), /* wMaxPacketSize: 8 Byte max */
|
WBVAL(HID_KM_IN_EP_SIZE), /* wMaxPacketSize: 9 Bytes maximum */
|
||||||
HID_KEYBOARD_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
HID_KM_IN_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||||
/* 34 */
|
/* 截至此处的配置描述符长度 = 34 */
|
||||||
|
|
||||||
/* 接口(Interface)描述符 鼠标 */
|
/* 端点(Endpoint)描述符 键盘OUT */
|
||||||
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 */
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
HID_MOUSE_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
HID_KM_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||||
0x03, /* bmAttributes: Interrupt endpoint */
|
0x03, /* bmAttributes: Interrupt endpoint */
|
||||||
HID_MOUSE_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
WBVAL(HID_KM_OUT_EP_SIZE), /* wMaxPacketSize: 9 Bytes maximum */
|
||||||
0x00,
|
HID_KM_OUT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||||
HID_MOUSE_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
/* 截至此处的配置描述符长度 = 41 */
|
||||||
/* 59 */
|
|
||||||
|
|
||||||
/* 字符串(String)描述符 设备支持的语言描述符 */
|
/* 字符串(String)描述符 设备支持的语言描述符 */
|
||||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||||
|
|
||||||
/* 字符串(String)描述符 UNICODE String Descriptor */
|
/* 字符串(String)描述符 制造商字符串 */
|
||||||
0x14, /* bLength */
|
0x02, /* bLength */
|
||||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
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)描述符 Product String Descriptor */
|
/* 字符串(String)描述符 产品字符串 */
|
||||||
0x26, /* bLength */
|
0x12, /* bLength */
|
||||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||||
'C', 0x00, /* wcChar0 */
|
'H', 0x00, /* wcChar0 */
|
||||||
'h', 0x00, /* wcChar1 */
|
'I', 0x00, /* wcChar1 */
|
||||||
'e', 0x00, /* wcChar2 */
|
'D', 0x00, /* wcChar2 */
|
||||||
'r', 0x00, /* wcChar3 */
|
' ', 0x00, /* wcChar3 */
|
||||||
'r', 0x00, /* wcChar4 */
|
'D', 0x00, /* wcChar4 */
|
||||||
'y', 0x00, /* wcChar5 */
|
'e', 0x00, /* wcChar5 */
|
||||||
'U', 0x00, /* wcChar6 */
|
'm', 0x00, /* wcChar6 */
|
||||||
'S', 0x00, /* wcChar7 */
|
'o', 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)描述符 Serial Number String Descriptor */
|
/* 字符串(String)描述符 序列号字符串 */
|
||||||
0x16, /* bLength */
|
0x16, /* bLength */
|
||||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||||
'2', 0x00, /* wcChar0 */
|
'2', 0x00, /* wcChar0 */
|
||||||
@ -147,6 +102,9 @@ static const uint8_t hid_descriptor[] = {
|
|||||||
'4', 0x00, /* wcChar7 */
|
'4', 0x00, /* wcChar7 */
|
||||||
'5', 0x00, /* wcChar8 */
|
'5', 0x00, /* wcChar8 */
|
||||||
'6', 0x00, /* wcChar9 */
|
'6', 0x00, /* wcChar9 */
|
||||||
|
'7', 0x00, /* wcChar10 */
|
||||||
|
'8', 0x00, /* wcChar11 */
|
||||||
|
|
||||||
#ifdef CONFIG_USB_HS
|
#ifdef CONFIG_USB_HS
|
||||||
/* 设备限定(Device Qualifier)描述符 同时支持全速与高速的设备必须有 */
|
/* 设备限定(Device Qualifier)描述符 同时支持全速与高速的设备必须有 */
|
||||||
0x0a,
|
0x0a,
|
||||||
@ -247,8 +205,23 @@ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
|
|||||||
0x01, 0xc0 // END_COLLECTION
|
0x01, 0xc0 // END_COLLECTION
|
||||||
};
|
};
|
||||||
|
|
||||||
static volatile uint8_t hid_keyboard_state = HID_STATE_BUSY;
|
static volatile uint8_t hid_km_state = HID_STATE_BUSY;
|
||||||
static volatile uint8_t hid_mouse_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)
|
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||||
{
|
{
|
||||||
@ -264,9 +237,8 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
|
|||||||
case USBD_EVENT_SUSPEND:
|
case USBD_EVENT_SUSPEND:
|
||||||
break;
|
break;
|
||||||
case USBD_EVENT_CONFIGURED:
|
case USBD_EVENT_CONFIGURED:
|
||||||
hid_keyboard_state = HID_STATE_IDLE;
|
hid_km_state = HID_STATE_IDLE;
|
||||||
hid_mouse_state = HID_STATE_IDLE;
|
usbd_ep_start_read(busid, HID_KM_OUT_EP, read_buffer, HID_KM_OUT_EP_SIZE);
|
||||||
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET);
|
|
||||||
break;
|
break;
|
||||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||||
break;
|
break;
|
||||||
@ -278,24 +250,14 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = {
|
static struct usbd_endpoint hid_keyboard_in_ep = {
|
||||||
.ep_cb = usbd_hid_keyboard_int_callback,
|
.ep_cb = usbd_hid_keyboard_in_callback,
|
||||||
.ep_addr = HID_KEYBOARD_INT_EP
|
.ep_addr = HID_KM_IN_EP
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usbd_endpoint hid_mouse_in_ep = {
|
static struct usbd_endpoint hid_keyboard_out_ep = {
|
||||||
.ep_cb = usbd_hid_mouse_int_callback,
|
.ep_cb = usbd_hid_keyboard_out_callback,
|
||||||
.ep_addr = HID_MOUSE_INT_EP
|
.ep_addr = HID_KM_OUT_EP
|
||||||
};
|
};
|
||||||
|
|
||||||
void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base)
|
void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base)
|
||||||
@ -304,44 +266,101 @@ void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base)
|
|||||||
static struct usbd_interface intf1;
|
static struct usbd_interface intf1;
|
||||||
|
|
||||||
usbd_desc_register(busid, hid_descriptor);
|
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_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_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_keyboard_out_ep);
|
||||||
usbd_add_endpoint(busid, &hid_mouse_in_ep);
|
|
||||||
|
|
||||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hid_keyboard_send(uint8_t busid, hid_keyboard_report_t *keyboard_report)
|
void hid_keyboard_send(uint8_t busid, hid_keyboard_report_t *keyboard_report)
|
||||||
{
|
{
|
||||||
static USB_MEM_ALIGNX uint8_t write_buffer[64];
|
static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE];
|
||||||
memcpy(write_buffer, keyboard_report, sizeof(hid_keyboard_report_t));
|
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));
|
report[0] = 1; //ID
|
||||||
|
report[1] = modifier_keys; //修饰键
|
||||||
|
report[3] = key; //第一个按键
|
||||||
|
// report[4] = ...; //第二个按键
|
||||||
|
// ...
|
||||||
|
// report[8] = ...; //第六个按键
|
||||||
|
|
||||||
|
int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hid_keyboard_state = HID_STATE_BUSY;
|
hid_km_state = HID_STATE_BUSY;
|
||||||
while (hid_keyboard_state == HID_STATE_BUSY) {
|
while (hid_km_state == HID_STATE_BUSY) {
|
||||||
|
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET);
|
||||||
__WFI();
|
__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);
|
||||||
}
|
}
|
||||||
HAL_GPIO_TogglePin(LED7_GPIO_Port, LED7_Pin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hid_mouse_send(uint8_t busid, hid_mouse_report_t *mouse_report)
|
void hid_mouse_send(uint8_t busid, hid_mouse_report_t *mouse_report)
|
||||||
{
|
{
|
||||||
static USB_MEM_ALIGNX uint8_t write_buffer[64];
|
static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE];
|
||||||
memcpy(write_buffer, mouse_report, sizeof(hid_mouse_report_t));
|
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));
|
report[0] = 3; //ID
|
||||||
|
report[1] = system_control_key; //键码
|
||||||
|
|
||||||
|
int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hid_mouse_state = HID_STATE_BUSY;
|
hid_km_state = HID_STATE_BUSY;
|
||||||
while (hid_mouse_state == HID_STATE_BUSY) {
|
while (hid_km_state == HID_STATE_BUSY) {
|
||||||
|
HAL_GPIO_WritePin(LED7_GPIO_Port, LED8_Pin, GPIO_PIN_SET);
|
||||||
__WFI();
|
__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);
|
||||||
}
|
}
|
||||||
HAL_GPIO_TogglePin(LED8_GPIO_Port, LED8_Pin);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
#include "usbd_core.h"
|
#include "usbd_core.h"
|
||||||
#include "usb_hid.h"
|
#include "usb_hid.h"
|
||||||
|
#include "bsp_key.h"
|
||||||
#include "hid_keyboard_mouse.h"
|
#include "hid_keyboard_mouse.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
@ -109,6 +110,7 @@ int main(void)
|
|||||||
MX_USART1_UART_Init();
|
MX_USART1_UART_Init();
|
||||||
MX_TIM6_Init();
|
MX_TIM6_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
|
bsp_key_init();
|
||||||
hid_keyboard_mouse_init(0, USB_BASE);
|
hid_keyboard_mouse_init(0, USB_BASE);
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
@ -119,38 +121,36 @@ int main(void)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
memset(&keyboard_report, 0, sizeof(hid_keyboard_report_t));
|
bsp_key_number_e key;
|
||||||
memset(&mouse_report, 0, sizeof(hid_mouse_report_t));
|
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 (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) {
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET) { //鼠标Y轴
|
__WFI();
|
||||||
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 END WHILE */
|
||||||
|
|
||||||
/* USER CODE BEGIN 3 */
|
/* USER CODE BEGIN 3 */
|
||||||
@ -226,7 +226,7 @@ static void MX_TIM6_Init(void)
|
|||||||
htim6.Instance = TIM6;
|
htim6.Instance = TIM6;
|
||||||
htim6.Init.Prescaler = SystemCoreClock / 1000 -1;
|
htim6.Init.Prescaler = SystemCoreClock / 1000 -1;
|
||||||
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
|
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;
|
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||||
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
|
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -393,6 +393,16 @@
|
|||||||
<Group>
|
<Group>
|
||||||
<GroupName>Application/User/Core</GroupName>
|
<GroupName>Application/User/Core</GroupName>
|
||||||
<Files>
|
<Files>
|
||||||
|
<File>
|
||||||
|
<FileName>hid_keyboard_mouse.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Core\Src\hid_keyboard_mouse.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>bsp_key.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Core\Src\bsp_key.c</FilePath>
|
||||||
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<FileName>main.c</FileName>
|
<FileName>main.c</FileName>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
@ -408,11 +418,6 @@
|
|||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<FilePath>../Core/Src/stm32f0xx_hal_msp.c</FilePath>
|
<FilePath>../Core/Src/stm32f0xx_hal_msp.c</FilePath>
|
||||||
</File>
|
</File>
|
||||||
<File>
|
|
||||||
<FileName>hid_keyboard_mouse.c</FileName>
|
|
||||||
<FileType>1</FileType>
|
|
||||||
<FilePath>..\Core\Src\hid_keyboard_mouse.c</FilePath>
|
|
||||||
</File>
|
|
||||||
</Files>
|
</Files>
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
|
|||||||
@ -43,7 +43,7 @@ Mcu.Pin8=PA6
|
|||||||
Mcu.Pin9=PA7
|
Mcu.Pin9=PA7
|
||||||
Mcu.PinsNb=26
|
Mcu.PinsNb=26
|
||||||
Mcu.ThirdPartyNb=0
|
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
|
Mcu.UserName=STM32F072C8Tx
|
||||||
MxCube.Version=6.11.1
|
MxCube.Version=6.11.1
|
||||||
MxDb.Version=DB.6.0.111
|
MxDb.Version=DB.6.0.111
|
||||||
@ -239,8 +239,8 @@ RCC.USART1Freq_Value=48000000
|
|||||||
RCC.USART2Freq_Value=48000000
|
RCC.USART2Freq_Value=48000000
|
||||||
RCC.VCOOutput2Freq_Value=8000000
|
RCC.VCOOutput2Freq_Value=8000000
|
||||||
TIM6.IPParameters=Prescaler,Period
|
TIM6.IPParameters=Prescaler,Period
|
||||||
TIM6.IPParametersWithoutCheck=Prescaler
|
TIM6.IPParametersWithoutCheck=Prescaler,Period
|
||||||
TIM6.Period=BSP_KEY_IN_OUT_INTERAEL_MS - 1
|
TIM6.Period=BSP_KEY_SCAN_INTERVAL_MS - 1
|
||||||
TIM6.Prescaler=SystemCoreClock / 1000 -1
|
TIM6.Prescaler=SystemCoreClock / 1000 -1
|
||||||
USART1.BaudRate=115200
|
USART1.BaudRate=115200
|
||||||
USART1.IPParameters=VirtualMode-Asynchronous,BaudRate
|
USART1.IPParameters=VirtualMode-Asynchronous,BaudRate
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user