diff --git a/stm32f072_usb_mouse_keyboard/Core/Inc/hid_keyboard_mouse.h b/stm32f072_usb_mouse_keyboard/Core/Inc/hid_keyboard_mouse.h index 7c9fe1b..e574a96 100644 --- a/stm32f072_usb_mouse_keyboard/Core/Inc/hid_keyboard_mouse.h +++ b/stm32f072_usb_mouse_keyboard/Core/Inc/hid_keyboard_mouse.h @@ -3,6 +3,10 @@ #include +#define HID_MOUSE_BUTTON_LEFT 0x01 +#define HID_MOUSE_BUTTON_MIDDLE 0x02 +#define HID_MOUSE_BUTTON_RIGHT 0x04 + #define HID_CONSUMER_USAGE_NEXTTRACK 0x00B5 #define HID_CONSUMER_USAGE_PREVTRACK 0x00B6 #define HID_CONSUMER_USAGE_STOP 0x00B7 @@ -26,6 +30,19 @@ #define HID_SYSTEM_USAGE_SLEEP 0x02 #define HID_SYSTEM_USAGE_WAKEUP 0x04 +#define USBD_VID 0x0483 +#define USBD_PID 0x5750 +#define USBD_MAX_POWER_MA 100 +#define USBD_LANGID_STRING 1033 + +#define HID_KM_IN_EP 0x81 +#define HID_KM_IN_EP_SIZE 8 //对于fsdev必须2字节对齐 +#define HID_KM_IN_EP_INTERVAL 1 + +#define HID_KM_OUT_EP 0x02 +#define HID_KM_OUT_EP_SIZE 2 +#define HID_KM_OUT_EP_INTERVAL 1 + 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); diff --git a/stm32f072_usb_mouse_keyboard/Core/Src/hid_keyboard_mouse.c b/stm32f072_usb_mouse_keyboard/Core/Src/hid_keyboard_mouse.c index db4f374..3309c53 100644 --- a/stm32f072_usb_mouse_keyboard/Core/Src/hid_keyboard_mouse.c +++ b/stm32f072_usb_mouse_keyboard/Core/Src/hid_keyboard_mouse.c @@ -7,28 +7,15 @@ #define HID_STATE_IDLE 0 #define HID_STATE_BUSY 1 -#define USBD_VID 0x0483 -#define USBD_PID 0x5750 -#define USBD_MAX_POWER_MA 100 -#define USBD_LANGID_STRING 1033 +#define HID_KM_CONF_DESC_SIZE 41 +#define HID_KM_REPORT_DESC_SIZE 187 -#define HID_KM_IN_EP 0x81 -#define HID_KM_IN_EP_SIZE 9 -#define HID_KM_IN_EP_INTERVAL 1 - -#define HID_KM_OUT_EP 0x02 -#define HID_KM_OUT_EP_SIZE 2 -#define HID_KM_OUT_EP_INTERVAL 1 - -#define HID_CONFIG_DESCRIPTOR_SIZE 41 -#define HID_KM_REPORT_DESC_SIZE 187 - -static const uint8_t hid_descriptor[] = { +static uint8_t hid_km_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), + USB_CONFIG_DESCRIPTOR_INIT(HID_KM_CONF_DESC_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER_MA), /* 截至此处的配置描述符长度 = 09 */ /* 接口(Interface)描述符 键盘 */ @@ -75,36 +62,65 @@ static const uint8_t hid_descriptor[] = { USB_LANGID_INIT(USBD_LANGID_STRING), /* 字符串(String)描述符 制造商字符串 */ - 0x02, /* bLength */ + 0x0C, /* bLength */ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'S', 0x00, + 'T', 0x00, + 'M', 0x00, + '3', 0x00, + '2', 0x00, /* 5字符 */ /* 字符串(String)描述符 产品字符串 */ - 0x12, /* bLength */ + 0x2A, /* 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 */ + 'H', 0x00, + 'I', 0x00, + 'D', 0x00, + ' ', 0x00, + 'C', 0x00, + 'o', 0x00, + 'm', 0x00, + 'p', 0x00, + 'o', 0x00, + 's', 0x00, + 'i', 0x00, + 't', 0x00, + 'e', 0x00, + ' ', 0x00, + 'D', 0x00, + 'e', 0x00, + 'v', 0x00, + 'i', 0x00, + 'c', 0x00, + 'e', 0x00, /* 共20字符 */ /* 字符串(String)描述符 序列号字符串 */ - 0x16, /* bLength */ + 0x32, /* 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 */ + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, /* 24字符 */ #ifdef CONFIG_USB_HS /* 设备限定(Device Qualifier)描述符 同时支持全速与高速的设备必须有 */ @@ -144,7 +160,7 @@ static const uint8_t hid_km_report_desc[HID_KM_REPORT_DESC_SIZE] = { 0x15, 0x00, // Logical Minimum (0) 0x25, 0x65, // Logical Maximum (101) 0x75, 0x08, // Report Size (8) - 0x95, 0x06, // Report Count (6) + 0x95, 0x06, // Report Count (5) 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) @@ -238,9 +254,11 @@ static void usbd_hid_keyboard_out_callback(uint8_t busid, uint8_t ep, uint32_t n { 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); + if (read_buffer[0] == 1) { + 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) @@ -258,7 +276,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event) 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); + usbd_ep_start_read(busid, HID_KM_OUT_EP, read_buffer, sizeof(read_buffer)); break; case USBD_EVENT_SET_REMOTE_WAKEUP: break; @@ -270,21 +288,45 @@ static void usbd_event_handler(uint8_t busid, uint8_t event) } } -static struct usbd_endpoint hid_keyboard_in_ep = { - .ep_cb = usbd_hid_keyboard_in_callback, - .ep_addr = HID_KM_IN_EP -}; +static void fill_usb_descriptor_serial_number(void) +{ + char uid_string[25]; + sprintf(uid_string, "%08X%08X%08X", HAL_GetUIDw0(), HAL_GetUIDw1(), HAL_GetUIDw2()); -static struct usbd_endpoint hid_keyboard_out_ep = { - .ep_cb = usbd_hid_keyboard_out_callback, - .ep_addr = HID_KM_OUT_EP -}; + uint16_t serial_number_offset = 0; + + for (uint16_t i = 0; i < sizeof(hid_km_descriptor) - 3; i ++) { //查找USB描述符中序列号字符描述符的偏移 + if (hid_km_descriptor[i + 0] == '0' && hid_km_descriptor[i + 1] == 0x00 && + hid_km_descriptor[i + 2] == '0' && hid_km_descriptor[i + 3] == 0x00) { + serial_number_offset = i; + break; + } + } + + if (serial_number_offset == 0) { //未找到 + return; + } + + for (uint8_t i = 0; i < 24; i ++) { //共24位 + hid_km_descriptor[serial_number_offset + i * 2] = uid_string[i]; + } +} void hid_keyboard_mouse_init(uint8_t busid, uint32_t reg_base) { static struct usbd_interface intf0; + static struct usbd_endpoint hid_keyboard_in_ep = { + .ep_cb = usbd_hid_keyboard_in_callback, + .ep_addr = HID_KM_IN_EP + }; + static struct usbd_endpoint hid_keyboard_out_ep = { + .ep_cb = usbd_hid_keyboard_out_callback, + .ep_addr = HID_KM_OUT_EP + }; - usbd_desc_register(busid, hid_descriptor); + fill_usb_descriptor_serial_number(); + + usbd_desc_register(busid, hid_km_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_add_endpoint(busid, &hid_keyboard_out_ep); //添加键盘鼠标INT OUT端点 @@ -295,75 +337,82 @@ 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) { static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE]; - memset(report, 0, HID_KM_IN_EP_SIZE); + memset(report, 0, sizeof(report)); report[0] = 1; //ID report[1] = modifier_keys; //修饰键 report[3] = key; //第一个按键 // report[4] = ...; //第二个按键 // ... - // report[8] = ...; //第六个按键 + // report[7] = ...; //第五个按键 - int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, HID_KM_IN_EP_SIZE); + int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, sizeof(report)); if (ret < 0) { return; } + HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET); + 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); } + + 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); + memset(report, 0, sizeof(report)); 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); + int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, sizeof(report)); if (ret < 0) { return; } + HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, GPIO_PIN_SET); + 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_WritePin(LED6_GPIO_Port, LED6_Pin, GPIO_PIN_RESET); } void hid_system_control_key_send(uint8_t busid, uint16_t system_control_key) { static USB_MEM_ALIGNX uint8_t report[HID_KM_IN_EP_SIZE]; - memset(report, 0, HID_KM_IN_EP_SIZE); + memset(report, 0, sizeof(report)); 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); + int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, sizeof(report)); if (ret < 0) { return; } + HAL_GPIO_WritePin(LED7_GPIO_Port, LED8_Pin, GPIO_PIN_SET); 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); } + + 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); + memset(report, 0, sizeof(report)); report[0] = 4; //ID report[1] = buttons; //鼠标按键 @@ -371,15 +420,17 @@ void hid_mouse_send(uint8_t busid, uint8_t buttons, int8_t x, int8_t y, int8_t w 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); + int ret = usbd_ep_start_write(busid, HID_KM_IN_EP, report, sizeof(report)); if (ret < 0) { return; } + HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, GPIO_PIN_SET); 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_WritePin(LED8_GPIO_Port, LED8_Pin, GPIO_PIN_RESET); } diff --git a/stm32f072_usb_mouse_keyboard/Core/Src/main.c b/stm32f072_usb_mouse_keyboard/Core/Src/main.c index 3663ec0..feb99b2 100644 --- a/stm32f072_usb_mouse_keyboard/Core/Src/main.c +++ b/stm32f072_usb_mouse_keyboard/Core/Src/main.c @@ -108,28 +108,73 @@ int main(void) bsp_key_event_type_e event; bsp_key_get_event(&key, &event); - if (key != bsp_key_none) { //有按键按下 - if (key == bsp_key1) { //触发USB键盘按键 + if (event == bsp_key_event_press) { //按键短按 鼠标事件 + switch (key) { + case bsp_key2: //鼠标向上移动 hid_mouse_send(0, 0, 0, -20, 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) { + break; + case bsp_key6: //鼠标向下移动 + hid_mouse_send(0, 0, 0, 20, 0); + break; + case bsp_key5: //鼠标向左移动 + hid_mouse_send(0, 0, -20, 0, 0); + break; + case bsp_key7: //鼠标向右移动 + hid_mouse_send(0, 0, 20, 0, 0); + break; + case bsp_key1: //鼠标左键 + hid_mouse_send(0, HID_MOUSE_BUTTON_LEFT, 0, 0, 0); + hid_mouse_send(0, 0, 0, 0, 0); + break; + case bsp_key3: //鼠标右键 + hid_mouse_send(0, HID_MOUSE_BUTTON_RIGHT, 0, 0, 0); + hid_mouse_send(0, 0, 0, 0, 0); + break; + case bsp_key4: //鼠标滚轮上 + hid_mouse_send(0, 0, 0, 0, 1); + break; + case bsp_key8: //鼠标滚轮下 + hid_mouse_send(0, 0, 0, 0, -1); + break; + default: + break; + } + } else if (event == bsp_key_event_long) { + switch (key) { + case bsp_key1: //键盘A hid_keyboard_key_send(0, 0, HID_KBD_USAGE_A); hid_keyboard_key_send(0, 0, 0); - } else if (key == bsp_key4) { - hid_mouse_send(0, 0, 0, 0, -1); - } else if (key == bsp_key5) { - hid_mouse_send(0, 0, 0, 20, 0); - } else if (key == bsp_key6) { - hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_PLAYPAUSE); //静音 - hid_consumer_control_key_send(0, 0); //抬起 - } else if (key == bsp_key7) { + break; + case bsp_key2: //键盘1 + hid_keyboard_key_send(0, 0, HID_KBD_USAGE_1); + hid_keyboard_key_send(0, 0, 0); + break; + case bsp_key3: //Win+L锁屏 hid_keyboard_key_send(0, HID_MODIFER_LGUI, HID_KBD_USAGE_A + ('L' - 'A')); hid_keyboard_key_send(0, 0, 0); - } else if (key == bsp_key8) { - hid_system_control_key_send(0, HID_SYSTEM_USAGE_POWER); //关闭屏幕 - hid_system_control_key_send(0, 0); //抬起 + break; + case bsp_key4: //电源键 + hid_system_control_key_send(0, HID_SYSTEM_USAGE_POWER); + hid_system_control_key_send(0, 0); + break; + case bsp_key5: //音量减 + hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_VOLUMEDEC); + hid_consumer_control_key_send(0, 0); + break; + case bsp_key6: //音量加 + hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_VOLUMEINC); + hid_consumer_control_key_send(0, 0); + break; + case bsp_key7: //静音 + hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_MUTE); + hid_consumer_control_key_send(0, 0); + break; + case bsp_key8: //播放/暂停 + hid_consumer_control_key_send(0, HID_CONSUMER_USAGE_PLAYPAUSE); + hid_consumer_control_key_send(0, 0); + break; + default: + break; } } else { __WFI(); diff --git a/stm32f072_usb_mouse_keyboard/MDK-ARM/stm32f072_usb_mouse_keyboard.uvprojx b/stm32f072_usb_mouse_keyboard/MDK-ARM/stm32f072_usb_mouse_keyboard.uvprojx index a20749c..ed6efd8 100644 --- a/stm32f072_usb_mouse_keyboard/MDK-ARM/stm32f072_usb_mouse_keyboard.uvprojx +++ b/stm32f072_usb_mouse_keyboard/MDK-ARM/stm32f072_usb_mouse_keyboard.uvprojx @@ -137,7 +137,7 @@ 4101 1 - BIN\UL2V8M.DLL + BIN\UL2CM3.DLL diff --git a/stm32f072_usb_mouse_keyboard/Third_Party/CherryUSB/port/fsdev/usb_dc_fsdev.c b/stm32f072_usb_mouse_keyboard/Third_Party/CherryUSB/port/fsdev/usb_dc_fsdev.c index b2dd9cc..2cc70f5 100644 --- a/stm32f072_usb_mouse_keyboard/Third_Party/CherryUSB/port/fsdev/usb_dc_fsdev.c +++ b/stm32f072_usb_mouse_keyboard/Third_Party/CherryUSB/port/fsdev/usb_dc_fsdev.c @@ -168,6 +168,10 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) g_fsdev_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); g_fsdev_udc.out_ep[ep_idx].ep_enable = true; if (g_fsdev_udc.out_ep[ep_idx].ep_mps > g_fsdev_udc.out_ep[ep_idx].ep_pma_buf_len) { + /* PMA address must be halfword-aligned */ + if (g_fsdev_udc.pma_offset % 2) { + g_fsdev_udc.pma_offset ++; + } if (g_fsdev_udc.pma_offset + g_fsdev_udc.out_ep[ep_idx].ep_mps > CONFIG_USB_FSDEV_RAM_SIZE) { USB_LOG_ERR("Ep pma %02x overflow\r\n", ep->bEndpointAddress); return -1; @@ -186,6 +190,10 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) g_fsdev_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); g_fsdev_udc.in_ep[ep_idx].ep_enable = true; if (g_fsdev_udc.in_ep[ep_idx].ep_mps > g_fsdev_udc.in_ep[ep_idx].ep_pma_buf_len) { + /* PMA address must be halfword-aligned */ + if (g_fsdev_udc.pma_offset % 2) { + g_fsdev_udc.pma_offset ++; + } if (g_fsdev_udc.pma_offset + g_fsdev_udc.in_ep[ep_idx].ep_mps > CONFIG_USB_FSDEV_RAM_SIZE) { USB_LOG_ERR("Ep pma %02x overflow\r\n", ep->bEndpointAddress); return -1;