mihome_bridge: add multimedia and system keys

This commit is contained in:
wangyz1997 2024-05-21 01:11:45 +08:00
parent 2c381a1910
commit 6415b32d5a
14 changed files with 821 additions and 511 deletions

View File

@ -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);

View 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

View File

@ -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; //记录上次按下的状态
}

View 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();
}
}

View File

@ -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) {
}
}

View File

@ -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 */
while (1) {
bsp_key_number_e key;
bsp_key_event_type_e event;
while (1) {
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_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_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) {
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);
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 */

View File

@ -393,11 +393,6 @@
<Group>
<GroupName>Application/User/Core</GroupName>
<Files>
<File>
<FileName>hid_keyboard_template.c</FileName>
<FileType>1</FileType>
<FilePath>..\Core\Src\hid_keyboard_template.c</FilePath>
</File>
<File>
<FileName>usb_config.h</FileName>
<FileType>5</FileType>
@ -423,6 +418,11 @@
<FileType>1</FileType>
<FilePath>../Core/Src/stm32f0xx_hal_msp.c</FilePath>
</File>
<File>
<FileName>hid_keyboard_mouse.c</FileName>
<FileType>1</FileType>
<FilePath>..\Core\Src\hid_keyboard_mouse.c</FilePath>
</File>
</Files>
</Group>
<Group>

View 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

View File

@ -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

View 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();
}
}

View File

@ -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)描述符 所有设备有且只有一个 */
@ -36,12 +35,12 @@ static const uint8_t hid_descriptor[] = {
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: 1 */
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 */
/* 截至此处的配置描述符长度 = 18 */
/* HID描述符 键盘 */
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 */
/* 27 */
/* 端点(Endpoint)描述符 键盘 */
/* 端点(Endpoint)描述符 键盘IN */
0x07, /* bLength: Endpoint Descriptor size */
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 */
WBVAL(HID_KEYBOARD_INT_EP_SIZE), /* wMaxPacketSize: 8 Byte max */
HID_KEYBOARD_INT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 34 */
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)描述符 鼠标 */
/* 端点(Endpoint)描述符 键盘OUT */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_MOUSE_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
HID_KM_OUT_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 */
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 */
/* 字符串(String)描述符 制造商字符串 */
0x02, /* 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)描述符 Product String Descriptor */
0x26, /* bLength */
/* 字符串(String)描述符 产品字符串 */
0x12, /* 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 */
'H', 0x00, /* wcChar0 */
'I', 0x00, /* wcChar1 */
'D', 0x00, /* wcChar2 */
' ', 0x00, /* wcChar3 */
'D', 0x00, /* wcChar4 */
'e', 0x00, /* wcChar5 */
'm', 0x00, /* wcChar6 */
'o', 0x00, /* wcChar7 */
/* 字符串(String)描述符 Serial Number String Descriptor */
/* 字符串(String)描述符 序列号字符串 */
0x16, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'2', 0x00, /* wcChar0 */
@ -147,6 +102,9 @@ static const uint8_t hid_descriptor[] = {
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'6', 0x00, /* wcChar9 */
'7', 0x00, /* wcChar10 */
'8', 0x00, /* wcChar11 */
#ifdef CONFIG_USB_HS
/* 设备限定(Device Qualifier)描述符 同时支持全速与高速的设备必须有 */
0x0a,
@ -247,8 +205,23 @@ 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)
{
@ -264,9 +237,8 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
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);
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;
@ -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 = {
.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)
@ -304,44 +266,101 @@ void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base)
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_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_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_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));
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) {
return;
}
hid_keyboard_state = HID_STATE_BUSY;
while (hid_keyboard_state == HID_STATE_BUSY) {
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);
}
HAL_GPIO_TogglePin(LED7_GPIO_Port, LED7_Pin);
}
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));
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) {
return;
}
hid_mouse_state = HID_STATE_BUSY;
while (hid_mouse_state == HID_STATE_BUSY) {
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);
}
HAL_GPIO_TogglePin(LED8_GPIO_Port, LED8_Pin);
}

View File

@ -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 (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;
}
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;
} else {
__WFI();
}
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)
{

View File

@ -393,6 +393,16 @@
<Group>
<GroupName>Application/User/Core</GroupName>
<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>
<FileName>main.c</FileName>
<FileType>1</FileType>
@ -408,11 +418,6 @@
<FileType>1</FileType>
<FilePath>../Core/Src/stm32f0xx_hal_msp.c</FilePath>
</File>
<File>
<FileName>hid_keyboard_mouse.c</FileName>
<FileType>1</FileType>
<FilePath>..\Core\Src\hid_keyboard_mouse.c</FilePath>
</File>
</Files>
</Group>
<Group>

View File

@ -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