mihome_bridge: add multimedia and system keys
This commit is contained in:
parent
2c381a1910
commit
6415b32d5a
@ -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);
|
||||
|
||||
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].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; //记录上次按下的状态
|
||||
}
|
||||
|
||||
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 "usbd_core.h"
|
||||
#include "usb_hid.h"
|
||||
#include "hid_keyboard_mouse.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@ -56,8 +57,7 @@ static void MX_GPIO_Init(void);
|
||||
static void MX_USART1_UART_Init(void);
|
||||
static void MX_TIM6_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
void hid_keyboard_init(uint8_t busid, uint32_t reg_base);
|
||||
void hid_keyboard_test(uint8_t busid, uint8_t key1, uint8_t key2);
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
@ -110,50 +110,40 @@ int main(void)
|
||||
MX_USART1_UART_Init();
|
||||
MX_TIM6_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
hid_keyboard_init(0, USB_BASE);
|
||||
bsp_key_in_out_init();
|
||||
hid_keyboard_mouse_init(0, USB_BASE);
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
bsp_key_number_e key;
|
||||
bsp_key_event_type_e event;
|
||||
|
||||
while (1) {
|
||||
bsp_key_number_e key;
|
||||
bsp_key_event_type_e event;
|
||||
bsp_key_in_get_event(&key, &event);
|
||||
|
||||
if (key != bsp_key_none) { //有按键按下 无论长短按
|
||||
bsp_key_out_set_event(key, bsp_key_event_press); //输出短按事件 将该按键恢复至未触发状态
|
||||
|
||||
if (key == bsp_key1) { //触发USB键盘按键
|
||||
hid_keyboard_test(0, 1u << 3, HID_KBD_USAGE_A + 'L' - 'A'); //Left GUI + L
|
||||
} else if (key == bsp_key2) {
|
||||
hid_keyboard_test(0, 1u << 3, HID_KBD_USAGE_A + 'R' - 'A'); //Left GUI + R
|
||||
HAL_Delay(100);
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'Y' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'U' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'A' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'N' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'S' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'H' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'E' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'N' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_PERIOD);
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'E' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'X' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_A + 'E' - 'A');
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_ENTER);
|
||||
HAL_Delay(500);
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_LEFT);
|
||||
HAL_Delay(100);
|
||||
hid_keyboard_test(0, 0, HID_KBD_USAGE_ENTER);
|
||||
} else if (key == bsp_key3) {
|
||||
|
||||
} else if (key == bsp_key4) {
|
||||
|
||||
|
||||
if (key != bsp_key_none) { //有按键按下
|
||||
if (event == bsp_key_event_long) { //按下超时
|
||||
bsp_key_out_set_event(key, bsp_key_event_press); //输出对应按键的短按事件 将该按键恢复至未触发状态
|
||||
} else { //按下边沿
|
||||
if (key == bsp_key1) { //触发USB键盘按键
|
||||
hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_PLAYPAUSE); //暂停/继续播放
|
||||
hid_consumer_control_key_send(0, 0); //抬起
|
||||
} else if (key == bsp_key2) {
|
||||
hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_MUTE); //静音
|
||||
hid_consumer_control_key_send(0, 0); //抬起
|
||||
} else if (key == bsp_key3) {
|
||||
hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_NEXTTRACK); //下一曲
|
||||
hid_consumer_control_key_send(0, 0); //抬起
|
||||
} else if (key == bsp_key4) {
|
||||
hid_keyboard_key_send(0, HID_MODIFER_LGUI, HID_KBD_USAGE_A + ('L' - 'A')); //Win+L 锁屏
|
||||
hid_keyboard_key_send(0, 0, 0); //抬起
|
||||
HAL_Delay(400);
|
||||
hid_system_control_key_send(0, HID_SYSTEM_USAGE_POWER); //关闭屏幕
|
||||
hid_system_control_key_send(0, 0); //抬起
|
||||
}
|
||||
}
|
||||
} else { //抬起USB键盘按键
|
||||
hid_keyboard_test(0, 0x00, 0x00);
|
||||
} else {
|
||||
__WFI();
|
||||
}
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
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 --------------------------------------------------------*/
|
||||
/* 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
|
||||
|
||||
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_LANGID_STRING 1033
|
||||
|
||||
#define HID_KEYBOARD_INT_EP 0x81
|
||||
#define HID_KEYBOARD_INT_EP_SIZE 8
|
||||
#define HID_KEYBOARD_INT_EP_INTERVAL 10
|
||||
#define HID_KM_IN_EP 0x81
|
||||
#define HID_KM_IN_EP_SIZE 16
|
||||
#define HID_KM_IN_EP_INTERVAL 10
|
||||
|
||||
#define HID_MOUSE_INT_EP 0x82
|
||||
#define HID_MOUSE_INT_EP_SIZE 4
|
||||
#define HID_MOUSE_INT_EP_INTERVAL 1
|
||||
#define HID_KM_OUT_EP 0x02
|
||||
#define HID_KM_OUT_EP_SIZE 4
|
||||
#define HID_KM_OUT_EP_INTERVAL 10
|
||||
|
||||
#define HID_CONFIG_DESCRIPTOR_SIZE 59
|
||||
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
|
||||
#define HID_MOUSE_REPORT_DESC_SIZE 74
|
||||
#define HID_CONFIG_DESCRIPTOR_SIZE 41
|
||||
#define HID_KM_REPORT_DESC_SIZE 187
|
||||
|
||||
static const uint8_t hid_descriptor[] = {
|
||||
/* 设备(Device)描述符 所有设备有且只有一个 */
|
||||
@ -31,17 +30,17 @@ static const uint8_t hid_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(HID_CONFIG_DESCRIPTOR_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER_MA),
|
||||
/* Configuration Descriptor Length = 09 */
|
||||
|
||||
/* 接口(Interface)描述符 键盘 */
|
||||
0x09, /* bLength: Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: 1 */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/* 18 */
|
||||
/* 接口(Interface)描述符 键盘 */
|
||||
0x09, /* bLength: Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints: 2 */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/* 截至此处的配置描述符长度 = 18 */
|
||||
|
||||
/* HID描述符 键盘 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
@ -53,100 +52,59 @@ static const uint8_t hid_descriptor[] = {
|
||||
WBVAL(HID_KEYBOARD_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */
|
||||
/* 27 */
|
||||
|
||||
/* 端点(Endpoint)描述符 键盘 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
HID_KEYBOARD_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
WBVAL(HID_KEYBOARD_INT_EP_SIZE), /* wMaxPacketSize: 8 Byte max */
|
||||
HID_KEYBOARD_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 34 */
|
||||
/* 端点(Endpoint)描述符 键盘IN */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
HID_KM_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
WBVAL(HID_KM_IN_EP_SIZE), /* wMaxPacketSize: 9 Bytes maximum */
|
||||
HID_KM_IN_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 截至此处的配置描述符长度 = 34 */
|
||||
|
||||
/* 接口(Interface)描述符 鼠标 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x01, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/* 43 */
|
||||
|
||||
/* HID描述符 鼠标 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/* 52 */
|
||||
|
||||
/* 端点(Endpoint)描述符 鼠标 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_MOUSE_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_MOUSE_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_MOUSE_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 59 */
|
||||
/* 端点(Endpoint)描述符 键盘OUT */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
HID_KM_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
WBVAL(HID_KM_OUT_EP_SIZE), /* wMaxPacketSize: 9 Bytes maximum */
|
||||
HID_KM_OUT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 截至此处的配置描述符长度 = 41 */
|
||||
|
||||
/* 字符串(String)描述符 设备支持的语言描述符 */
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
|
||||
/* 字符串(String)描述符 UNICODE String Descriptor */
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
/* 字符串(String)描述符 制造商字符串 */
|
||||
0x02, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
|
||||
/* 字符串(String)描述符 Product String Descriptor */
|
||||
0x26, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'H', 0x00, /* wcChar10 */
|
||||
'I', 0x00, /* wcChar11 */
|
||||
'D', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'D', 0x00, /* wcChar14 */
|
||||
'E', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
'O', 0x00, /* wcChar17 */
|
||||
/* 字符串(String)描述符 产品字符串 */
|
||||
0x12, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'H', 0x00, /* wcChar0 */
|
||||
'I', 0x00, /* wcChar1 */
|
||||
'D', 0x00, /* wcChar2 */
|
||||
' ', 0x00, /* wcChar3 */
|
||||
'D', 0x00, /* wcChar4 */
|
||||
'e', 0x00, /* wcChar5 */
|
||||
'm', 0x00, /* wcChar6 */
|
||||
'o', 0x00, /* wcChar7 */
|
||||
|
||||
/* 字符串(String)描述符 序列号字符串 */
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
'7', 0x00, /* wcChar10 */
|
||||
'8', 0x00, /* wcChar11 */
|
||||
|
||||
/* 字符串(String)描述符 Serial Number String Descriptor */
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
/* 设备限定(Device Qualifier)描述符 同时支持全速与高速的设备必须有 */
|
||||
0x0a,
|
||||
@ -247,55 +205,59 @@ static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
|
||||
0x01, 0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
static volatile uint8_t hid_keyboard_state = HID_STATE_BUSY;
|
||||
static volatile uint8_t hid_mouse_state = HID_STATE_BUSY;
|
||||
static volatile uint8_t hid_km_state = HID_STATE_BUSY;
|
||||
|
||||
USB_MEM_ALIGNX uint8_t read_buffer[HID_KM_OUT_EP_SIZE];
|
||||
|
||||
static void usbd_hid_keyboard_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
hid_km_state = HID_STATE_IDLE;
|
||||
}
|
||||
|
||||
static void usbd_hid_keyboard_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
usbd_ep_start_read(busid, ep, read_buffer, HID_KM_OUT_EP_SIZE);
|
||||
|
||||
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, read_buffer[1] & 0x01);
|
||||
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, read_buffer[1] & 0x02);
|
||||
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, read_buffer[1] & 0x04);
|
||||
}
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
hid_keyboard_state = HID_STATE_IDLE;
|
||||
hid_mouse_state = HID_STATE_IDLE;
|
||||
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
hid_km_state = HID_STATE_IDLE;
|
||||
usbd_ep_start_read(busid, HID_KM_OUT_EP, read_buffer, HID_KM_OUT_EP_SIZE);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void usbd_hid_keyboard_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
hid_keyboard_state = HID_STATE_IDLE;
|
||||
}
|
||||
|
||||
static void usbd_hid_mouse_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
hid_mouse_state = HID_STATE_IDLE;
|
||||
}
|
||||
|
||||
static struct usbd_endpoint hid_keyboard_in_ep = {
|
||||
.ep_cb = usbd_hid_keyboard_int_callback,
|
||||
.ep_addr = HID_KEYBOARD_INT_EP
|
||||
.ep_cb = usbd_hid_keyboard_in_callback,
|
||||
.ep_addr = HID_KM_IN_EP
|
||||
};
|
||||
|
||||
static struct usbd_endpoint hid_mouse_in_ep = {
|
||||
.ep_cb = usbd_hid_mouse_int_callback,
|
||||
.ep_addr = HID_MOUSE_INT_EP
|
||||
static struct usbd_endpoint hid_keyboard_out_ep = {
|
||||
.ep_cb = usbd_hid_keyboard_out_callback,
|
||||
.ep_addr = HID_KM_OUT_EP
|
||||
};
|
||||
|
||||
void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base)
|
||||
@ -303,45 +265,102 @@ void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base)
|
||||
static struct usbd_interface intf0;
|
||||
static struct usbd_interface intf1;
|
||||
|
||||
usbd_desc_register(busid, hid_descriptor);
|
||||
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
|
||||
usbd_add_endpoint(busid, &hid_keyboard_in_ep);
|
||||
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf1, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
|
||||
usbd_add_endpoint(busid, &hid_mouse_in_ep);
|
||||
usbd_desc_register(busid, hid_descriptor);
|
||||
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_km_report_desc, HID_KM_REPORT_DESC_SIZE)); //添加键盘鼠标INT IN端点
|
||||
usbd_add_endpoint(busid, &hid_keyboard_in_ep);
|
||||
usbd_add_endpoint(busid, &hid_keyboard_out_ep);
|
||||
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
void hid_keyboard_send(uint8_t busid, hid_keyboard_report_t *keyboard_report)
|
||||
{
|
||||
static USB_MEM_ALIGNX uint8_t write_buffer[64];
|
||||
memcpy(write_buffer, keyboard_report, sizeof(hid_keyboard_report_t));
|
||||
static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE];
|
||||
memset(report, 0, HID_KM_IN_EP_SIZE);
|
||||
|
||||
int ret = usbd_ep_start_write(busid, HID_KEYBOARD_INT_EP, write_buffer, sizeof(hid_keyboard_report_t));
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
report[0] = 1; //ID
|
||||
report[1] = modifier_keys; //修饰键
|
||||
report[3] = key; //第一个按键
|
||||
// report[4] = ...; //第二个按键
|
||||
// ...
|
||||
// report[8] = ...; //第六个按键
|
||||
|
||||
hid_keyboard_state = HID_STATE_BUSY;
|
||||
while (hid_keyboard_state == HID_STATE_BUSY) {
|
||||
__WFI();
|
||||
}
|
||||
HAL_GPIO_TogglePin(LED7_GPIO_Port, LED7_Pin);
|
||||
int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
hid_km_state = HID_STATE_BUSY;
|
||||
while (hid_km_state == HID_STATE_BUSY) {
|
||||
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET);
|
||||
__WFI();
|
||||
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
void hid_consumer_control_key_send(uint8_t busid, uint16_t consumer_control_key)
|
||||
{
|
||||
static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE];
|
||||
memset(report, 0, HID_KM_IN_EP_SIZE);
|
||||
|
||||
report[0] = 2; //ID
|
||||
report[1] = consumer_control_key & 0xFF; //键码低字节
|
||||
report[2] = consumer_control_key >> 8; //键码高字节
|
||||
|
||||
int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
hid_km_state = HID_STATE_BUSY;
|
||||
while (hid_km_state == HID_STATE_BUSY) {
|
||||
HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, GPIO_PIN_SET);
|
||||
__WFI();
|
||||
HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
void hid_mouse_send(uint8_t busid, hid_mouse_report_t *mouse_report)
|
||||
{
|
||||
static USB_MEM_ALIGNX uint8_t write_buffer[64];
|
||||
memcpy(write_buffer, mouse_report, sizeof(hid_mouse_report_t));
|
||||
static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE];
|
||||
memset(report, 0, HID_KM_IN_EP_SIZE);
|
||||
|
||||
int ret = usbd_ep_start_write(busid, HID_MOUSE_INT_EP, write_buffer, sizeof(hid_mouse_report_t));
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
report[0] = 3; //ID
|
||||
report[1] = system_control_key; //键码
|
||||
|
||||
hid_mouse_state = HID_STATE_BUSY;
|
||||
while (hid_mouse_state == HID_STATE_BUSY) {
|
||||
__WFI();
|
||||
}
|
||||
HAL_GPIO_TogglePin(LED8_GPIO_Port, LED8_Pin);
|
||||
int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
hid_km_state = HID_STATE_BUSY;
|
||||
while (hid_km_state == HID_STATE_BUSY) {
|
||||
HAL_GPIO_WritePin(LED7_GPIO_Port, LED8_Pin, GPIO_PIN_SET);
|
||||
__WFI();
|
||||
HAL_GPIO_WritePin(LED7_GPIO_Port, LED8_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
void hid_mouse_send(uint8_t busid, uint8_t buttons, int8_t x, int8_t y, int8_t wheel)
|
||||
{
|
||||
static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE];
|
||||
memset(report, 0, HID_KM_IN_EP_SIZE);
|
||||
|
||||
report[0] = 4; //ID
|
||||
report[1] = buttons; //鼠标按键
|
||||
report[2] = x; //Delta x
|
||||
report[3] = y; //Delta y
|
||||
report[4] = wheel; //滚轮
|
||||
|
||||
int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
hid_km_state = HID_STATE_BUSY;
|
||||
while (hid_km_state == HID_STATE_BUSY) {
|
||||
HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, GPIO_PIN_SET);
|
||||
__WFI();
|
||||
HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "usbd_core.h"
|
||||
#include "usb_hid.h"
|
||||
#include "bsp_key.h"
|
||||
#include "hid_keyboard_mouse.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
@ -109,6 +110,7 @@ int main(void)
|
||||
MX_USART1_UART_Init();
|
||||
MX_TIM6_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
bsp_key_init();
|
||||
hid_keyboard_mouse_init(0, USB_BASE);
|
||||
/* USER CODE END 2 */
|
||||
|
||||
@ -119,38 +121,36 @@ int main(void)
|
||||
|
||||
while (1)
|
||||
{
|
||||
memset(&keyboard_report, 0, sizeof(hid_keyboard_report_t));
|
||||
memset(&mouse_report, 0, sizeof(hid_mouse_report_t));
|
||||
bsp_key_number_e key;
|
||||
bsp_key_event_type_e event;
|
||||
bsp_key_get_event(&key, &event);
|
||||
bsp_key_number_e key;
|
||||
bsp_key_event_type_e event;
|
||||
bsp_key_get_event(&key, &event);
|
||||
|
||||
if (HAL_GPIO_ReadPin(KEY5_GPIO_Port, KEY5_Pin) == GPIO_PIN_RESET) { //鼠标X轴
|
||||
mouse_report.x = -10;
|
||||
} else if(HAL_GPIO_ReadPin(KEY7_GPIO_Port, KEY7_Pin) == GPIO_PIN_RESET) {
|
||||
mouse_report.x = 10;
|
||||
if (key != bsp_key_none) { //有按键按下
|
||||
if (key == bsp_key1) { //触发USB键盘按键
|
||||
hid_mouse_send(0, 0, -20, 0, 0);
|
||||
} else if (key == bsp_key2) {
|
||||
hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_MUTE); //静音
|
||||
hid_consumer_control_key_send(0, 0); //抬起
|
||||
} else if (key == bsp_key3) {
|
||||
|
||||
} else if (key == bsp_key4) {
|
||||
hid_system_control_key_send(0, HID_SYSTEM_USAGE_POWER); //关闭屏幕
|
||||
hid_system_control_key_send(0, 0); //抬起
|
||||
} else if (key == bsp_key5) {
|
||||
hid_mouse_send(0, 0, 20, 0, 0);
|
||||
} else if (key == bsp_key6) {
|
||||
|
||||
} else if (key == bsp_key7) {
|
||||
|
||||
} else if (key == bsp_key8) {
|
||||
|
||||
}
|
||||
} else {
|
||||
__WFI();
|
||||
}
|
||||
|
||||
if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET) { //鼠标Y轴
|
||||
mouse_report.y = -10;
|
||||
} else if(HAL_GPIO_ReadPin(KEY6_GPIO_Port, KEY6_Pin) == GPIO_PIN_RESET) {
|
||||
mouse_report.y = 10;
|
||||
}
|
||||
|
||||
if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET) { //左键
|
||||
mouse_report.buttons |= HID_MOUSE_LEFT_BUTTON;
|
||||
}
|
||||
|
||||
if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == GPIO_PIN_RESET) { //右键
|
||||
mouse_report.buttons |= HID_MOUSE_RIGHT_BUTTON;
|
||||
}
|
||||
|
||||
if (HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) == GPIO_PIN_RESET) {
|
||||
keyboard_report.modifier_keys = HID_KEYBOARD_LEFT_GUI;
|
||||
keyboard_report.key1 = HID_KBD_USAGE_A + 'L' - 'A'; //Win+L
|
||||
} else if (HAL_GPIO_ReadPin(KEY8_GPIO_Port, KEY8_Pin) == GPIO_PIN_RESET) {
|
||||
keyboard_report.key1 = HID_KBD_USAGE_1 + 5;
|
||||
}
|
||||
|
||||
hid_keyboard_send(0, &keyboard_report);
|
||||
hid_mouse_send(0, &mouse_report);
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
@ -226,7 +226,7 @@ static void MX_TIM6_Init(void)
|
||||
htim6.Instance = TIM6;
|
||||
htim6.Init.Prescaler = SystemCoreClock / 1000 -1;
|
||||
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim6.Init.Period = BSP_KEY_IN_OUT_INTERAEL_MS - 1;
|
||||
htim6.Init.Period = BSP_KEY_SCAN_INTERVAL_MS - 1;
|
||||
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
|
||||
{
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user