From 0dd6ce2b62e7d8023535ef28d0a88a04a9fc0cf0 Mon Sep 17 00:00:00 2001 From: HaiMianBBao <1570139720@qq.com> Date: Sat, 20 Nov 2021 10:46:16 +0800 Subject: [PATCH] add stm32 hid demos and remove cdc demo to example --- demo/stm32/stm32f103c8t6/Core/Src/main.c | 377 +++++--------- .../MDK-ARM/startup_stm32f103xb.s | 2 +- .../MDK-ARM/stm32f103c8t6.uvoptx | 78 ++- .../MDK-ARM/stm32f103c8t6.uvprojx | 143 +++++- .../stm32f103c8t6/example/cdc/cdc_init.c | 166 ++++++ .../stm32f103c8t6/example/example_select.h | 14 + .../example/hid_custom/hid_custom_init.c | 486 ++++++++++++++++++ .../example/hid_keyboard/hid_keyboard_init.c | 269 ++++++++++ .../example/hid_mouse/hid_mouse_init.c | 300 +++++++++++ 9 files changed, 1587 insertions(+), 248 deletions(-) create mode 100644 demo/stm32/stm32f103c8t6/example/cdc/cdc_init.c create mode 100644 demo/stm32/stm32f103c8t6/example/example_select.h create mode 100644 demo/stm32/stm32f103c8t6/example/hid_custom/hid_custom_init.c create mode 100644 demo/stm32/stm32f103c8t6/example/hid_keyboard/hid_keyboard_init.c create mode 100644 demo/stm32/stm32f103c8t6/example/hid_mouse/hid_mouse_init.c diff --git a/demo/stm32/stm32f103c8t6/Core/Src/main.c b/demo/stm32/stm32f103c8t6/Core/Src/main.c index eed68d53..d2f353d6 100644 --- a/demo/stm32/stm32f103c8t6/Core/Src/main.c +++ b/demo/stm32/stm32f103c8t6/Core/Src/main.c @@ -23,7 +23,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "usbd_core.h" -#include "usbd_cdc.h" +#include "example_select.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -62,127 +62,11 @@ static void MX_USB_PCD_Init(void); /* USER CODE BEGIN 0 */ int fputc(int ch, FILE *f) { - - while((USART1->SR & USART_SR_TXE) == 0); - USART1->DR = ch; - return ch; + while ((USART1->SR & USART_SR_TXE) == 0) + ; + USART1->DR = ch; + return ch; } - -#define CDC_IN_EP 0x81 -#define CDC_OUT_EP 0x01 -#define CDC_INT_EP 0x82 - -#define USBD_VID 0xFFFF -#define USBD_PID 0xFFFF -#define USBD_MAX_POWER 100 -#define USBD_LANGID_STRING 1033 - -#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN) - -const uint8_t cdc_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x02, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x12, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'B', 0x00, /* wcChar0 */ - 'o', 0x00, /* wcChar1 */ - 'u', 0x00, /* wcChar2 */ - 'f', 0x00, /* wcChar3 */ - 'f', 0x00, /* wcChar4 */ - 'a', 0x00, /* wcChar5 */ - 'l', 0x00, /* wcChar6 */ - 'o', 0x00, /* wcChar7 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x24, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'B', 0x00, /* wcChar0 */ - 'o', 0x00, /* wcChar1 */ - 'u', 0x00, /* wcChar2 */ - 'f', 0x00, /* wcChar3 */ - 'f', 0x00, /* wcChar4 */ - 'a', 0x00, /* wcChar5 */ - 'l', 0x00, /* wcChar6 */ - 'o', 0x00, /* wcChar7 */ - ' ', 0x00, /* wcChar8 */ - 'C', 0x00, /* wcChar9 */ - 'D', 0x00, /* wcChar10 */ - 'C', 0x00, /* wcChar11 */ - ' ', 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 */ - '1', 0x00, /* wcChar3 */ - '0', 0x00, /* wcChar4 */ - '3', 0x00, /* wcChar5 */ - '1', 0x00, /* wcChar6 */ - '0', 0x00, /* wcChar7 */ - '0', 0x00, /* wcChar8 */ - '0', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x02, - 0x02, - 0x01, - 0x40, - 0x01, - 0x00, -#endif - 0x00 -}; - -usbd_class_t cdc_class; -usbd_interface_t cdc_cmd_intf; -usbd_interface_t cdc_data_intf; - -void usbd_cdc_acm_out(uint8_t ep) -{ - uint8_t data[64]; - uint32_t read_byte; - usbd_ep_read(ep,data,64,&read_byte); - printf("out\r\n"); - printf("read len:%d\r\n",read_byte); -} - -void usbd_cdc_acm_in(uint8_t ep) -{ - printf("in\r\n"); -} - -usbd_endpoint_t cdc_out_ep = { - .ep_addr = CDC_OUT_EP, - .ep_cb = usbd_cdc_acm_out -}; - -usbd_endpoint_t cdc_in_ep = { - .ep_addr = CDC_IN_EP, - .ep_cb = usbd_cdc_acm_in -}; - extern void usb_dc_init(void); /* USER CODE END 0 */ @@ -192,54 +76,78 @@ extern void usb_dc_init(void); */ int main(void) { - /* USER CODE BEGIN 1 */ + /* USER CODE BEGIN 1 */ - /* USER CODE END 1 */ + /* USER CODE END 1 */ - /* MCU Configuration--------------------------------------------------------*/ + /* MCU Configuration--------------------------------------------------------*/ - /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ - HAL_Init(); + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); - /* USER CODE BEGIN Init */ + /* USER CODE BEGIN Init */ - /* USER CODE END Init */ + /* USER CODE END Init */ - /* Configure the system clock */ - SystemClock_Config(); + /* Configure the system clock */ + SystemClock_Config(); - /* USER CODE BEGIN SysInit */ + /* USER CODE BEGIN SysInit */ - /* USER CODE END SysInit */ + /* USER CODE END SysInit */ - /* Initialize all configured peripherals */ - MX_GPIO_Init(); - MX_USART1_UART_Init(); - //MX_USB_PCD_Init(); - /* USER CODE BEGIN 2 */ - usbd_desc_register(cdc_descriptor); + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_USART1_UART_Init(); + //MX_USB_PCD_Init(); + /* USER CODE BEGIN 2 */ - usbd_cdc_add_acm_interface(&cdc_class, &cdc_cmd_intf); - usbd_cdc_add_acm_interface(&cdc_class, &cdc_data_intf); - usbd_interface_add_endpoint(&cdc_data_intf, &cdc_out_ep); - usbd_interface_add_endpoint(&cdc_data_intf, &cdc_in_ep); +#ifdef USB_CDC + /*!< demo init */ + extern void cdc_init(void); + cdc_init(); +#elif defined USB_HID_KEYBOARD + extern void hid_keyboard_init(void); + hid_keyboard_init(); +#elif defined USB_HID_MOUSE + extern void hid_mouse_init(void); + hid_mouse_init(); +#elif defined USB_HID_CUSTOM + extern void hid_custom_init(void); + hid_custom_init(); +#endif - usb_dc_init(); + /*!< init */ + usb_dc_init(); - /* USER CODE END 2 */ + /* USER CODE END 2 */ - /* Infinite loop */ - /* USER CODE BEGIN WHILE */ - while (1) - { - /* USER CODE END WHILE */ + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) { + /* USER CODE END WHILE */ - /* USER CODE BEGIN 3 */ - uint8_t data_buffer[10] = {0x31,0x32,0x33,0x34,0x35,0x31,0x32,0x33,0x34,0x35}; - usbd_ep_write(0x81,data_buffer,10,NULL); - HAL_Delay(500); - } - /* USER CODE END 3 */ + /* USER CODE BEGIN 3 */ + +#ifdef USB_CDC + /*!< cdc demo test */ + extern void cdc_test(void); + cdc_test(); +#elif defined USB_HID_KEYBOARD + /*!< hid keyboard demo test */ + extern void hid_keyboard_test(void); + hid_keyboard_test(); +#elif defined USB_HID_MOUSE + /*!< hid mouse demo test */ + extern void hid_mouse_test(void); + hid_mouse_test(); +#elif defined USB_HID_CUSTOM + /*!< hid custom demo test */ + extern void hid_custom_test(void); + hid_custom_test(); +#endif + } + /* USER CODE END 3 */ } /** @@ -248,43 +156,39 @@ int main(void) */ void SystemClock_Config(void) { - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; - /** Initializes the RCC Oscillators according to the specified parameters + /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) - { - Error_Handler(); - } - /** Initializes the CPU, AHB and APB buses clocks + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + Error_Handler(); + } + /** Initializes the CPU, AHB and APB buses clocks */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK - |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) - { - Error_Handler(); - } - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; - PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) - { - Error_Handler(); - } + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { + Error_Handler(); + } } /** @@ -294,30 +198,27 @@ void SystemClock_Config(void) */ static void MX_USART1_UART_Init(void) { + /* USER CODE BEGIN USART1_Init 0 */ - /* USER CODE BEGIN USART1_Init 0 */ + /* USER CODE END USART1_Init 0 */ - /* USER CODE END USART1_Init 0 */ + /* USER CODE BEGIN USART1_Init 1 */ - /* USER CODE BEGIN USART1_Init 1 */ - - /* USER CODE END USART1_Init 1 */ - huart1.Instance = USART1; - huart1.Init.BaudRate = 115200; - huart1.Init.WordLength = UART_WORDLENGTH_8B; - huart1.Init.StopBits = UART_STOPBITS_1; - huart1.Init.Parity = UART_PARITY_NONE; - huart1.Init.Mode = UART_MODE_TX_RX; - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; - huart1.Init.OverSampling = UART_OVERSAMPLING_16; - if (HAL_UART_Init(&huart1) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN USART1_Init 2 */ - - /* USER CODE END USART1_Init 2 */ + /* USER CODE END USART1_Init 1 */ + huart1.Instance = USART1; + huart1.Init.BaudRate = 115200; + huart1.Init.WordLength = UART_WORDLENGTH_8B; + huart1.Init.StopBits = UART_STOPBITS_1; + huart1.Init.Parity = UART_PARITY_NONE; + huart1.Init.Mode = UART_MODE_TX_RX; + huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart1.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart1) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN USART1_Init 2 */ + /* USER CODE END USART1_Init 2 */ } /** @@ -327,28 +228,25 @@ static void MX_USART1_UART_Init(void) */ static void MX_USB_PCD_Init(void) { + /* USER CODE BEGIN USB_Init 0 */ - /* USER CODE BEGIN USB_Init 0 */ + /* USER CODE END USB_Init 0 */ - /* USER CODE END USB_Init 0 */ + /* USER CODE BEGIN USB_Init 1 */ - /* USER CODE BEGIN USB_Init 1 */ - - /* USER CODE END USB_Init 1 */ - hpcd_USB_FS.Instance = USB; - hpcd_USB_FS.Init.dev_endpoints = 8; - hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; - hpcd_USB_FS.Init.low_power_enable = DISABLE; - hpcd_USB_FS.Init.lpm_enable = DISABLE; - hpcd_USB_FS.Init.battery_charging_enable = DISABLE; - if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN USB_Init 2 */ - - /* USER CODE END USB_Init 2 */ + /* USER CODE END USB_Init 1 */ + hpcd_USB_FS.Instance = USB; + hpcd_USB_FS.Init.dev_endpoints = 8; + hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; + hpcd_USB_FS.Init.low_power_enable = DISABLE; + hpcd_USB_FS.Init.lpm_enable = DISABLE; + hpcd_USB_FS.Init.battery_charging_enable = DISABLE; + if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN USB_Init 2 */ + /* USER CODE END USB_Init 2 */ } /** @@ -358,11 +256,9 @@ static void MX_USB_PCD_Init(void) */ static void MX_GPIO_Init(void) { - - /* GPIO Ports Clock Enable */ - __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); } /* USER CODE BEGIN 4 */ @@ -375,16 +271,15 @@ static void MX_GPIO_Init(void) */ void Error_Handler(void) { - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - __disable_irq(); - while (1) - { - } - /* USER CODE END Error_Handler_Debug */ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) { + } + /* USER CODE END Error_Handler_Debug */ } -#ifdef USE_FULL_ASSERT +#ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. @@ -394,10 +289,10 @@ void Error_Handler(void) */ void assert_failed(uint8_t *file, uint32_t line) { - /* USER CODE BEGIN 6 */ - /* User can add his own implementation to report the file name and line number, + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ - /* USER CODE END 6 */ + /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ diff --git a/demo/stm32/stm32f103c8t6/MDK-ARM/startup_stm32f103xb.s b/demo/stm32/stm32f103c8t6/MDK-ARM/startup_stm32f103xb.s index f70c548c..c4d79748 100644 --- a/demo/stm32/stm32f103c8t6/MDK-ARM/startup_stm32f103xb.s +++ b/demo/stm32/stm32f103c8t6/MDK-ARM/startup_stm32f103xb.s @@ -130,7 +130,7 @@ Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit - LDR R0, =SystemInit +a LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 diff --git a/demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx b/demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx index c4e37e1f..9654f322 100644 --- a/demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx +++ b/demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx @@ -125,7 +125,7 @@ 0 ST-LINKIII-KEIL_SWO - -U066EFF555453774987091527 -O2287 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("") -D00(00000000) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8000 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:STM32F103C8$Flash\STM32F10x_128.FLM) + -U38FF6E065254313254222343 -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(1BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8000 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:STM32F103C8$Flash\STM32F10x_128.FLM) 0 @@ -152,7 +152,7 @@ 0 0 - 210 + 205 1 0 0 @@ -161,7 +161,7 @@ 0 0 0 - ../Core/Src/stm32f1xx_it.c + ..\example\hid_keyboard\hid_keyboard_init.c @@ -220,7 +220,7 @@ Application/MDK-ARM - 0 + 1 0 0 0 @@ -284,7 +284,7 @@ Drivers/STM32F1xx_HAL_Driver - 1 + 0 0 0 0 @@ -556,6 +556,74 @@ 0 0 + + 5 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\class\hid\usbd_hid.c + usbd_hid.c + 0 + 0 + + + + + example + 1 + 0 + 0 + 0 + + 6 + 27 + 1 + 0 + 0 + 0 + ..\example\cdc\cdc_init.c + cdc_init.c + 0 + 0 + + + 6 + 28 + 1 + 0 + 0 + 0 + ..\example\hid_mouse\hid_mouse_init.c + hid_mouse_init.c + 0 + 0 + + + 6 + 29 + 1 + 0 + 0 + 0 + ..\example\hid_keyboard\hid_keyboard_init.c + hid_keyboard_init.c + 0 + 0 + + + 6 + 30 + 1 + 0 + 0 + 0 + ..\example\hid_custom\hid_custom_init.c + hid_custom_init.c + 0 + 0 + diff --git a/demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx b/demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx index 71430fe3..3fd75c1c 100644 --- a/demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx +++ b/demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx @@ -340,7 +340,7 @@ USE_HAL_DRIVER,STM32F103xB,STM32F1 - ../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;..\..\..\..\common;..\..\..\..\core;..\..\..\..\class\cdc;..\..\..\..\class\winusb + ../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;..\..\..\..\common;..\..\..\..\core;..\..\..\..\class\cdc;..\..\..\..\class\winusb;..\example\hid_custom;..\example\cdc;..\example\hid_keyboard;..\example\hid_mouse;..\..\..\..\class\hid;..\example @@ -529,6 +529,138 @@ 1 ..\..\..\..\port\stm32\usb_dc_nohal.c + + usbd_hid.c + 1 + ..\..\..\..\class\hid\usbd_hid.c + + + + + example + + + cdc_init.c + 1 + ..\example\cdc\cdc_init.c + + + hid_mouse_init.c + 1 + ..\example\hid_mouse\hid_mouse_init.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + hid_keyboard_init.c + 1 + ..\example\hid_keyboard\hid_keyboard_init.c + + + hid_custom_init.c + 1 + ..\example\hid_custom\hid_custom_init.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + @@ -551,4 +683,13 @@ + + + + stm32f103c8t6 + 1 + + + + diff --git a/demo/stm32/stm32f103c8t6/example/cdc/cdc_init.c b/demo/stm32/stm32f103c8t6/example/cdc/cdc_init.c new file mode 100644 index 00000000..c7c9bd06 --- /dev/null +++ b/demo/stm32/stm32f103c8t6/example/cdc/cdc_init.c @@ -0,0 +1,166 @@ +/** @mainpage cdc_demo_init + * + * Project cdc_demo + * Author LiGuo 1570139720@qq.com + * + * @section cdc class init demo + * + * -# You can use USB to create a virtual serial port + * + * @section 版本更新历史 + * + * 版本|作者|时间|描述 + * ----|----|----|---- + * 1.0|LiGuo|2021.11.19|creat project + * + * © Copyright 2021 LiGuo. + * All rights reserved. + ********************************************************************************* + */ + +/* include ------------------------------------------------------------------*/ +#include "main.h" +#include "usbd_core.h" +#include "usb_def.h" +#include "usbd_cdc.h" + +/*!< endpoint address */ +#define CDC_IN_EP 0x81 +#define CDC_OUT_EP 0x01 +#define CDC_INT_EP 0x82 + +#define USBD_VID 0xFFFF +#define USBD_PID 0xFFFF +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +/*!< config descriptor size */ +#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN) + +/*!< global descriptor */ +static const uint8_t cdc_descriptor[] = { + USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x02, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02), + /////////////////////////////////////// + /// string0 descriptor + /////////////////////////////////////// + USB_LANGID_INIT(USBD_LANGID_STRING), + /////////////////////////////////////// + /// string1 descriptor + /////////////////////////////////////// + 0x12, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'B', 0x00, /* wcChar0 */ + 'o', 0x00, /* wcChar1 */ + 'u', 0x00, /* wcChar2 */ + 'f', 0x00, /* wcChar3 */ + 'f', 0x00, /* wcChar4 */ + 'a', 0x00, /* wcChar5 */ + 'l', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + /////////////////////////////////////// + /// string2 descriptor + /////////////////////////////////////// + 0x24, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'B', 0x00, /* wcChar0 */ + 'o', 0x00, /* wcChar1 */ + 'u', 0x00, /* wcChar2 */ + 'f', 0x00, /* wcChar3 */ + 'f', 0x00, /* wcChar4 */ + 'a', 0x00, /* wcChar5 */ + 'l', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + ' ', 0x00, /* wcChar8 */ + 'C', 0x00, /* wcChar9 */ + 'D', 0x00, /* wcChar10 */ + 'C', 0x00, /* wcChar11 */ + ' ', 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 */ + '1', 0x00, /* wcChar3 */ + '0', 0x00, /* wcChar4 */ + '3', 0x00, /* wcChar5 */ + '1', 0x00, /* wcChar6 */ + '0', 0x00, /* wcChar7 */ + '0', 0x00, /* wcChar8 */ + '0', 0x00, /* wcChar9 */ +#ifdef CONFIG_USB_HS + /////////////////////////////////////// + /// device qualifier descriptor + /////////////////////////////////////// + 0x0a, + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x02, + 0x02, + 0x01, + 0x40, + 0x01, + 0x00, +#endif + 0x00 +}; +/*!< class */ +usbd_class_t cdc_class; +/*!< interface one */ +usbd_interface_t cdc_cmd_intf; +/*!< interface two */ +usbd_interface_t cdc_data_intf; + +/* function ------------------------------------------------------------------*/ +void usbd_cdc_acm_out(uint8_t ep) +{ + uint8_t data[64]; + uint32_t read_byte; + usbd_ep_read(ep, data, 64, &read_byte); + printf("out\r\n"); + printf("read len:%d\r\n", read_byte); +} + +void usbd_cdc_acm_in(uint8_t ep) +{ + printf("in\r\n"); +} + +/*!< endpoint call back */ +usbd_endpoint_t cdc_out_ep = { + .ep_addr = CDC_OUT_EP, + .ep_cb = usbd_cdc_acm_out +}; + +usbd_endpoint_t cdc_in_ep = { + .ep_addr = CDC_IN_EP, + .ep_cb = usbd_cdc_acm_in +}; + +/* function ------------------------------------------------------------------*/ +void cdc_init(void) +{ + usbd_desc_register(cdc_descriptor); + /*!< add interface */ + usbd_cdc_add_acm_interface(&cdc_class, &cdc_cmd_intf); + usbd_cdc_add_acm_interface(&cdc_class, &cdc_data_intf); + /*!< interface add endpoint */ + usbd_interface_add_endpoint(&cdc_data_intf, &cdc_out_ep); + usbd_interface_add_endpoint(&cdc_data_intf, &cdc_in_ep); +} + +void cdc_test(void) +{ + uint8_t data_buffer[10] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x31, 0x32, 0x33, 0x34, 0x35 }; + usbd_ep_write(CDC_IN_EP, data_buffer, 10, NULL); + HAL_Delay(500); +} \ No newline at end of file diff --git a/demo/stm32/stm32f103c8t6/example/example_select.h b/demo/stm32/stm32f103c8t6/example/example_select.h new file mode 100644 index 00000000..04f0cf80 --- /dev/null +++ b/demo/stm32/stm32f103c8t6/example/example_select.h @@ -0,0 +1,14 @@ + +/*!< Use macros to select the examples to test */ + +/*!< cdc */ +//#define USB_CDC + +/*!< hid keyboard */ +#define USB_HID_KEYBOARD + +/*!< hid mouse */ +//#define USB_HID_MOUSE + +/*!< hid custom */ +//#define USB_HID_CUSTOM diff --git a/demo/stm32/stm32f103c8t6/example/hid_custom/hid_custom_init.c b/demo/stm32/stm32f103c8t6/example/hid_custom/hid_custom_init.c new file mode 100644 index 00000000..5bfd2486 --- /dev/null +++ b/demo/stm32/stm32f103c8t6/example/hid_custom/hid_custom_init.c @@ -0,0 +1,486 @@ +/** @mainpage hid_custom_demo_init + * + * Project hid_custom_demo + * Author LiGuo 1570139720@qq.com + * + * @section hid custom init demo + * + * -# You can use this demo to create a hid composite device + * such as keyboard + mouse + hidraw + * use two interface and four endpoint + * the first interface :keyboard ! ep1_in:0x81 ! ep1_out:0x01 + * the second interface :hidraw ! ep2_in:0x82 ! ep2_out:0x02 + * + * @section 版本更新历史 + * + * 版本|作者|时间|描述 + * ----|----|----|---- + * 1.0|LiGuo|2021.11.19|creat project + * + * © Copyright 2021 LiGuo. + * All rights reserved. + ********************************************************************************* + */ + +/* include ------------------------------------------------------------------*/ +#include "main.h" +#include "usb_def.h" +#include "usbd_core.h" +#include "usbd_hid.h" + +#define HID_STATE_IDLE 0 +#define HID_STATE_BUSY 1 + +/*!< keyboard in endpoint */ +#define KBD_IN_EP 0x81 /*!< address */ +#define KBD_IN_EP_SIZE 8 /*!< max packet length */ +#define KBD_IN_EP_INTERVAL 10 /*!< polling time */ + +/*!< keyboard out endpoint */ +#define KBD_OUT_EP 0x01 /*!< address */ +#define KBD_OUT_EP_SIZE 1 /*!< max packet length */ +#define KBD_OUT_EP_INTERVAL 10 /*!< polling time */ + +/*!< hidraw in endpoint */ +#define HIDRAW_IN_EP 0x82 +#define HIDRAW_IN_SIZE 64 +#define HIDRAW_IN_INTERVAL 10 + +/*!< hidraw out endpoint */ +#define HIDRAW_OUT_EP 0x02 +#define HIDRAW_OUT_EP_SIZE 64 +#define HIDRAW_OUT_EP_INTERVAL 10 + +#define USBD_VID 0xffff +#define USBD_PID 0xffff +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +/*!< hid state ! Data can be sent only when state is idle */ +uint8_t keyboard_state = HID_STATE_IDLE; +uint8_t custom_state = HID_STATE_IDLE; + +/*!< config descriptor size */ +#define USB_HID_CONFIG_DESC_SIZ 73 + +/*!< report descriptor size */ +#define HID_KEYBOARD_REPORT_DESC_SIZE 63 + +/*!< custom hid report descriptor size */ +#define HID_CUSTOM_REPORT_DESC_SIZE 34 + +/*!< global descriptor */ +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, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + /************** Descriptor of Keyboard interface ****************/ + /* 09 */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* 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 Keyboard 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 Keyboard in endpoint ********************/ + /* 27 */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ + KBD_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + KBD_IN_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ + 0x00, + KBD_IN_EP_INTERVAL, /* bInterval: Polling Interval */ + /******************** Descriptor of Keyboard out endpoint ********************/ + /* 34 */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ + KBD_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + KBD_OUT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ + 0x00, + KBD_OUT_EP_INTERVAL, /* bInterval: Polling Interval */ + /************** Descriptor of Custom interface *****************/ + /* 41 */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0, /* iInterface: Index of string descriptor */ + /******************** Descriptor of Custom HID ********************/ + /* 50 */ + 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_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, + /******************** Descriptor of Custom in endpoint ********************/ + /* 59 */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ + HIDRAW_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HIDRAW_IN_SIZE, /* wMaxPacketSize: 4 Byte max */ + 0x00, + HIDRAW_IN_INTERVAL, /* bInterval: Polling Interval */ + /******************** Descriptor of Custom out endpoint ********************/ + /* 66 */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ + HIDRAW_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HIDRAW_OUT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ + 0x00, + HIDRAW_OUT_EP_INTERVAL, /* bInterval: Polling Interval */ + /* 73 */ + /////////////////////////////////////// + /// string0 descriptor + /////////////////////////////////////// + USB_LANGID_INIT(USBD_LANGID_STRING), + /////////////////////////////////////// + /// string1 descriptor + /////////////////////////////////////// + 0x12, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'B', 0x00, /* wcChar0 */ + 'o', 0x00, /* wcChar1 */ + 'u', 0x00, /* wcChar2 */ + 'f', 0x00, /* wcChar3 */ + 'f', 0x00, /* wcChar4 */ + 'a', 0x00, /* wcChar5 */ + 'l', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + /////////////////////////////////////// + /// string2 descriptor + /////////////////////////////////////// + 0x28, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'B', 0x00, /* wcChar0 */ + 'o', 0x00, /* wcChar1 */ + 'u', 0x00, /* wcChar2 */ + 'f', 0x00, /* wcChar3 */ + 'f', 0x00, /* wcChar4 */ + 'a', 0x00, /* wcChar5 */ + 'l', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + ' ', 0x00, /* wcChar8 */ + 'H', 0x00, /* wcChar9 */ + 'I', 0x00, /* wcChar10 */ + 'D', 0x00, /* wcChar11 */ + ' ', 0x00, /* wcChar12 */ + 'C', 0x00, /* wcChar13 */ + 'U', 0x00, /* wcChar14 */ + 'S', 0x00, /* wcChar15 */ + 'T', 0x00, /* wcChar16 */ + 'O', 0x00, /* wcChar17 */ + 'M', 0x00, /* wcChar18 */ + /////////////////////////////////////// + /// string3 descriptor + /////////////////////////////////////// + 0x16, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + '2', 0x00, /* wcChar0 */ + '0', 0x00, /* wcChar1 */ + '2', 0x00, /* wcChar2 */ + '1', 0x00, /* wcChar3 */ + '0', 0x00, /* wcChar4 */ + '3', 0x00, /* wcChar5 */ + '1', 0x00, /* wcChar6 */ + '0', 0x00, /* wcChar7 */ + '0', 0x00, /* wcChar8 */ + '0', 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 +}; + +/*!< hid keyboard report descriptor */ +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 +}; + +/*!< custom hid report descriptor */ +static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = { + /* USER CODE BEGIN 0 */ + 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined Page 1) + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x95, 0x40, // REPORT_COUNT (64) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + /* <___________________________________________________> */ + 0x09, 0x01, // USAGE (Vendor Usage 1) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x95, 0x40, // REPORT_COUNT (64) + 0x75, 0x08, // REPORT_SIZE (8) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + /* USER CODE END 0 */ + 0xC0 /* END_COLLECTION */ +}; + +/*!< class */ +static usbd_class_t hid_class; + +/*!< interface one */ +static usbd_interface_t hid_intf_1; + +/*!< interface two */ +static usbd_interface_t hid_intf_2; + +/* function ------------------------------------------------------------------*/ +static void usbd_hid_kbd_in_callback(uint8_t ep) +{ + /*!< endpoint call back */ + /*!< transfer successfully */ + if (keyboard_state == HID_STATE_BUSY) { + /*!< update the state */ + keyboard_state = HID_STATE_IDLE; + } +} + +static void usbd_hid_kbd_out_callback(uint8_t ep) +{ + /*!< here you can write the LED processing from the host */ + enum hid_kbd_led led_state; + /*!< read the led data from host send */ + usbd_ep_read(ep, &led_state, KBD_OUT_EP_SIZE, NULL); + /*!< diy */ + if (led_state & HID_KBD_LED_NUM_LOCK) { + /*!< num lock */ + /*!< do what you like */ + } else { + } + if (led_state & HID_KBD_LED_CAPS_LOCK) { + /*!< caps lock */ + /*!< do what you like */ + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0); + } else { + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1); + } + + if (led_state & HID_KBD_LED_SCROLL_LOCK) { + /*!< scroll lock */ + /*!< do what you like */ + } else { + } + if (led_state & HID_KBD_LED_COMPOSE) { + /*!< compose led */ + /*!< do what you like */ + } else { + } + if (led_state & HID_KBD_LED_KANA) { + /*!< kana led */ + /*!< do what you like */ + } else { + } +} + +static void usbd_hid_custom_in_callback(uint8_t ep) +{ + /*!< endpoint call back */ + /*!< transfer successfully */ + if (custom_state == HID_STATE_BUSY) { + /*!< update the state */ + custom_state = HID_STATE_IDLE; + } +} + +static void usbd_hid_custom_out_callback(uint8_t ep) +{ + /*!< read the data from host send */ + uint8_t custom_data[HIDRAW_OUT_EP_SIZE]; + usbd_ep_read(HIDRAW_OUT_EP, custom_data, HIDRAW_OUT_EP_SIZE, NULL); + + /*!< you can use the data do some thing you like */ +} + +/*!< endpoint call back */ +static usbd_endpoint_t keyboard_in_ep = { + .ep_cb = usbd_hid_kbd_in_callback, + .ep_addr = 0x81 +}; + +static usbd_endpoint_t keyboard_out_ep = { + .ep_cb = usbd_hid_kbd_out_callback, + .ep_addr = 0x01 +}; + +static usbd_endpoint_t custom_in_ep = { + .ep_cb = usbd_hid_custom_in_callback, + .ep_addr = 0x82 +}; + +static usbd_endpoint_t custom_out_ep = { + .ep_cb = usbd_hid_custom_out_callback, + .ep_addr = 0x02 +}; + +/* function ------------------------------------------------------------------*/ +/** + * @brief hid custom init + * @pre none + * @param[in] none + * @retval none + */ +void hid_custom_init(void) +{ + usbd_desc_register(hid_descriptor); + /*!< add interface ! the first interface */ + usbd_hid_add_interface(&hid_class, &hid_intf_1); + /*!< interface0 add endpoint ! the first endpoint */ + usbd_interface_add_endpoint(&hid_intf_1, &keyboard_in_ep); + /*!< interface0 add endpoint ! the second endpoint */ + usbd_interface_add_endpoint(&hid_intf_1, &keyboard_out_ep); + /*!< add interface the ! second interface */ + usbd_hid_add_interface(&hid_class, &hid_intf_2); + /*!< interface1 add endpoint ! the first endpoint */ + usbd_interface_add_endpoint(&hid_intf_2, &custom_in_ep); + /*!< interface1 add endpoint ! the second endpoint */ + usbd_interface_add_endpoint(&hid_intf_2, &custom_out_ep); + /*!< register report descriptor interface 0 */ + usbd_hid_report_descriptor_register(0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE); + /*!< register report descriptor interface 1 */ + usbd_hid_report_descriptor_register(1, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE); + + /*!< user init a gpio pc13 test capslk led */ + /*!< enable gpioc clock */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + /*!< set pc13 is out put */ + GPIOC->CRH &= 0XFF0FFFFF; + GPIOC->CRH |= 0X00000003 << (13 - 8) * 4; + + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0); +} + +/** + * @brief device send report to host + * @pre none + * @param[in] ep endpoint address + * @param[in] data points to the data buffer waiting to be sent + * @param[in] len length of data to be sent + * @retval none + */ +void hid_keyboard_send_report(uint8_t ep, uint8_t *data, uint8_t len) +{ + if (usb_device_is_configured()) { + if (keyboard_state == HID_STATE_IDLE) { + /*!< updata the state */ + keyboard_state = HID_STATE_BUSY; + /*!< write buffer */ + usbd_ep_write(ep, data, len, NULL); + } + } +} + +/** + * @brief device send report to host + * @pre none + * @param[in] ep endpoint address + * @param[in] data points to the data buffer waiting to be sent + * @param[in] len length of data to be sent + * @retval none + */ +void hid_custom_send_report(uint8_t ep, uint8_t *data, uint8_t len) +{ + if (usb_device_is_configured()) { + if (custom_state == HID_STATE_IDLE) { + /*!< updata the state */ + custom_state = HID_STATE_BUSY; + /*!< write buffer */ + usbd_ep_write(ep, data, len, NULL); + } + } +} + +/** + * @brief hid custom test + * @pre none + * @param[in] none + * @retval none + */ +void hid_custom_test(void) +{ + /*!< keyboard test */ + uint8_t sendbuffer1[8] = { 0x00, 0x00, HID_KEY_A, 0x00, 0x00, 0x00, 0x00, 0x00 }; //A + hid_keyboard_send_report(KBD_IN_EP, sendbuffer1, KBD_IN_EP_SIZE); + /*!< delay 10ms */ + HAL_Delay(10); + /*!< send button up */ + sendbuffer1[2] = 0; + hid_keyboard_send_report(KBD_IN_EP, sendbuffer1, KBD_IN_EP_SIZE); + /*!< delay 1000ms the custom test */ + HAL_Delay(1000); + /*!< custom test */ + uint8_t sendbuffer2[64] = { 6 }; + hid_custom_send_report(HIDRAW_IN_EP, sendbuffer2, HIDRAW_IN_SIZE); + HAL_Delay(1000); +} \ No newline at end of file diff --git a/demo/stm32/stm32f103c8t6/example/hid_keyboard/hid_keyboard_init.c b/demo/stm32/stm32f103c8t6/example/hid_keyboard/hid_keyboard_init.c new file mode 100644 index 00000000..0fe851a5 --- /dev/null +++ b/demo/stm32/stm32f103c8t6/example/hid_keyboard/hid_keyboard_init.c @@ -0,0 +1,269 @@ +/** @mainpage hid_keyboard_demo_init + * + * Project hid_keyboard_demo + * Author LiGuo 1570139720@qq.com + * + * @section hid keyboard init demo + * + * -# You can use USB to create a hid keyboard + * + * @section 版本更新历史 + * + * 版本|作者|时间|描述 + * ----|----|----|---- + * 1.0|LiGuo|2021.11.19|creat project + * + * © Copyright 2021 LiGuo. + * All rights reserved. + ********************************************************************************* + */ + +/* include ------------------------------------------------------------------*/ +#include "main.h" +#include "usb_def.h" +#include "usbd_core.h" +#include "usbd_hid.h" + +#define HID_STATE_IDLE 0 +#define HID_STATE_BUSY 1 + +/*!< endpoint address */ +#define HID_INT_EP 0x81 +#define HID_INT_EP_SIZE 8 +#define HID_INT_EP_INTERVAL 10 + +#define USBD_VID 0xffff +#define USBD_PID 0xffff +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +/*!< hid state ! Data can be sent only when state is idle */ +uint8_t hid_state = HID_STATE_IDLE; + +/*!< config descriptor size */ +#define USB_HID_CONFIG_DESC_SIZ 34 +/*!< report descriptor size */ +#define HID_KEYBOARD_REPORT_DESC_SIZE 63 + +/*!< global descriptor */ +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 + /////////////////////////////////////// + 0x12, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'B', 0x00, /* wcChar0 */ + 'o', 0x00, /* wcChar1 */ + 'u', 0x00, /* wcChar2 */ + 'f', 0x00, /* wcChar3 */ + 'f', 0x00, /* wcChar4 */ + 'a', 0x00, /* wcChar5 */ + 'l', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + /////////////////////////////////////// + /// string2 descriptor + /////////////////////////////////////// + 0x2C, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'B', 0x00, /* wcChar0 */ + 'o', 0x00, /* wcChar1 */ + 'u', 0x00, /* wcChar2 */ + 'f', 0x00, /* wcChar3 */ + 'f', 0x00, /* wcChar4 */ + 'a', 0x00, /* wcChar5 */ + 'l', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + ' ', 0x00, /* wcChar8 */ + 'H', 0x00, /* wcChar9 */ + 'I', 0x00, /* wcChar10 */ + 'D', 0x00, /* wcChar11 */ + ' ', 0x00, /* wcChar12 */ + 'K', 0x00, /* wcChar13 */ + 'E', 0x00, /* wcChar14 */ + 'Y', 0x00, /* wcChar15 */ + 'B', 0x00, /* wcChar16 */ + 'O', 0x00, /* wcChar17 */ + 'A', 0x00, /* wcChar18 */ + 'R', 0x00, /* wcChar19 */ + 'D', 0x00, /* wcChar20 */ + /////////////////////////////////////// + /// string3 descriptor + /////////////////////////////////////// + 0x16, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + '2', 0x00, /* wcChar0 */ + '0', 0x00, /* wcChar1 */ + '2', 0x00, /* wcChar2 */ + '1', 0x00, /* wcChar3 */ + '0', 0x00, /* wcChar4 */ + '3', 0x00, /* wcChar5 */ + '1', 0x00, /* wcChar6 */ + '0', 0x00, /* wcChar7 */ + '0', 0x00, /* wcChar8 */ + '0', 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 +}; + +/*!< hid keyboard report descriptor */ +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 +}; + +/*!< class */ +static usbd_class_t hid_class; + +/*!< interface */ +static usbd_interface_t hid_intf; + +/* function ------------------------------------------------------------------*/ +static void usbd_hid_int_callback(uint8_t ep) +{ + /*!< endpoint call back */ + /*!< transfer successfully */ + if (hid_state == HID_STATE_BUSY) { + /*!< update the state */ + hid_state = HID_STATE_IDLE; + } +} + +/*!< endpoint call back */ +static usbd_endpoint_t hid_in_ep = { + .ep_cb = usbd_hid_int_callback, + .ep_addr = 0x81 +}; + +/* function ------------------------------------------------------------------*/ +/** + * @brief hid keyborad init + * @pre none + * @param[in] none + * @retval none + */ +void hid_keyboard_init(void) +{ + usbd_desc_register(hid_descriptor); + /*!< add interface */ + usbd_hid_add_interface(&hid_class, &hid_intf); + /*!< interface add endpoint */ + usbd_interface_add_endpoint(&hid_intf, &hid_in_ep); + /*!< register report descriptor */ + usbd_hid_report_descriptor_register(0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE); +} + +/** + * @brief device send report to host + * @pre none + * @param[in] ep endpoint address + * @param[in] data Points to the data buffer waiting to be sent + * @param[in] len Length of data to be sent + * @retval none + */ +void hid_keyboard_send_report(uint8_t ep, uint8_t *data, uint8_t len) +{ + if (usb_device_is_configured()) { + if (hid_state == HID_STATE_IDLE) { + /*!< updata the state */ + hid_state = HID_STATE_BUSY; + /*!< write buffer */ + usbd_ep_write(ep, data, len, NULL); + } + } +} + +/** + * @brief hid keyborad test + * @pre none + * @param[in] none + * @retval none + */ +void hid_keyboard_test(void) +{ + uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KEY_A, 0x00, 0x00, 0x00, 0x00, 0x00 }; //A + hid_keyboard_send_report(HID_INT_EP, sendbuffer, HID_INT_EP_SIZE); + HAL_Delay(1000); +} \ No newline at end of file diff --git a/demo/stm32/stm32f103c8t6/example/hid_mouse/hid_mouse_init.c b/demo/stm32/stm32f103c8t6/example/hid_mouse/hid_mouse_init.c new file mode 100644 index 00000000..458865a2 --- /dev/null +++ b/demo/stm32/stm32f103c8t6/example/hid_mouse/hid_mouse_init.c @@ -0,0 +1,300 @@ +/** @mainpage hid_mouse_demo_init + * + * Project hid_mouse_demo + * Author LiGuo 1570139720@qq.com + * + * @section hid mouse init demo + * + * -# You can use USB to create a hid mouse + * + * @section 版本更新历史 + * + * 版本|作者|时间|描述 + * ----|----|----|---- + * 1.0|LiGuo|2021.11.19|creat project + * + * © Copyright 2021 LiGuo. + * All rights reserved. + ********************************************************************************* + */ + +/* include ------------------------------------------------------------------*/ +#include "main.h" +#include "usb_def.h" +#include "usbd_core.h" +#include "usbd_hid.h" + +#define HID_STATE_IDLE 0 +#define HID_STATE_BUSY 1 + +/*!< endpoint address */ +#define HID_INT_EP 0x81 +#define HID_INT_EP_SIZE 8 +#define HID_INT_EP_INTERVAL 10 + +#define USBD_VID 0xffff +#define USBD_PID 0xffff +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +/*!< hid state ! Data can be sent only when state is idle */ +uint8_t hid_state = HID_STATE_IDLE; + +/*!< config descriptor size */ +#define USB_HID_CONFIG_DESC_SIZ 34 +/*!< report descriptor size */ +#define HID_MOUSE_REPORT_DESC_SIZE 74 + +/*!< global descriptor */ +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 */ + 0x02, /* 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_MOUSE_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 + /////////////////////////////////////// + 0x12, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'B', 0x00, /* wcChar0 */ + 'o', 0x00, /* wcChar1 */ + 'u', 0x00, /* wcChar2 */ + 'f', 0x00, /* wcChar3 */ + 'f', 0x00, /* wcChar4 */ + 'a', 0x00, /* wcChar5 */ + 'l', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + /////////////////////////////////////// + /// string2 descriptor + /////////////////////////////////////// + 0x26, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'B', 0x00, /* wcChar0 */ + 'o', 0x00, /* wcChar1 */ + 'u', 0x00, /* wcChar2 */ + 'f', 0x00, /* wcChar3 */ + 'f', 0x00, /* wcChar4 */ + 'a', 0x00, /* wcChar5 */ + 'l', 0x00, /* wcChar6 */ + 'o', 0x00, /* wcChar7 */ + ' ', 0x00, /* wcChar8 */ + 'H', 0x00, /* wcChar9 */ + 'I', 0x00, /* wcChar10 */ + 'D', 0x00, /* wcChar11 */ + ' ', 0x00, /* wcChar12 */ + 'M', 0x00, /* wcChar13 */ + 'O', 0x00, /* wcChar14 */ + 'U', 0x00, /* wcChar15 */ + 'S', 0x00, /* wcChar16 */ + 'E', 0x00, /* wcChar17 */ + /////////////////////////////////////// + /// string3 descriptor + /////////////////////////////////////// + 0x16, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + '2', 0x00, /* wcChar0 */ + '0', 0x00, /* wcChar1 */ + '2', 0x00, /* wcChar2 */ + '1', 0x00, /* wcChar3 */ + '0', 0x00, /* wcChar4 */ + '3', 0x00, /* wcChar5 */ + '1', 0x00, /* wcChar6 */ + '0', 0x00, /* wcChar7 */ + '0', 0x00, /* wcChar8 */ + '0', 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 +}; + +/*!< hid mouse report descriptor */ +static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x02, // USAGE (Mouse) + 0xA1, 0x01, // COLLECTION (Application) + 0x09, 0x01, // USAGE (Pointer) + + 0xA1, 0x00, // COLLECTION (Physical) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x01, // INPUT (Cnst,Var,Abs) + + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, + + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (2) + + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xC0, 0x09, + 0x3c, 0x05, + 0xff, 0x09, + + 0x01, 0x15, + 0x00, 0x25, + 0x01, 0x75, + 0x01, 0x95, + + 0x02, 0xb1, + 0x22, 0x75, + 0x06, 0x95, + 0x01, 0xb1, + + 0x01, 0xc0 // END_COLLECTION +}; + +/*!< mouse report struct */ +struct hid_mouse { + uint8_t buttons; + int8_t x; + int8_t y; + int8_t wheel; +}; + +/*!< class */ +static usbd_class_t hid_class; + +/*!< interface */ +static usbd_interface_t hid_intf; + +/*!< mouse report */ +static struct hid_mouse mouse_cfg; + +/* function ------------------------------------------------------------------*/ +static void usbd_hid_int_callback(uint8_t ep) +{ + /*!< endpoint call back */ + /*!< transfer successfully */ + if (hid_state == HID_STATE_BUSY) { + /*!< update the state */ + hid_state = HID_STATE_IDLE; + } +} + +/*!< endpoint call back */ +static usbd_endpoint_t hid_in_ep = { + .ep_cb = usbd_hid_int_callback, + .ep_addr = 0x81 +}; + +/* function ------------------------------------------------------------------*/ +/** + * @brief hid mouse init + * @pre none + * @param[in] none + * @retval none + */ +void hid_mouse_init(void) +{ + usbd_desc_register(hid_descriptor); + /*!< add interface */ + usbd_hid_add_interface(&hid_class, &hid_intf); + /*!< interface add endpoint */ + usbd_interface_add_endpoint(&hid_intf, &hid_in_ep); + /*!< register report descriptor */ + usbd_hid_report_descriptor_register(0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE); + /*!< init mouse report data */ + mouse_cfg.buttons = 0; + mouse_cfg.wheel = 0; + mouse_cfg.x = 0; + mouse_cfg.y = 0; +} + +/** + * @brief device send report to host + * @pre none + * @param[in] ep endpoint address + * @param[in] data Points to the data buffer waiting to be sent + * @param[in] len Length of data to be sent + * @retval none + */ +void hid_mouse_send_report(uint8_t ep, uint8_t *data, uint8_t len) +{ + if (usb_device_is_configured()) { + if (hid_state == HID_STATE_IDLE) { + /*!< updata the state */ + hid_state = HID_STATE_BUSY; + /*!< write buffer */ + usbd_ep_write(ep, data, len, NULL); + } + } +} + +/** + * @brief hid mouse test + * @pre none + * @param[in] none + * @retval none + */ +void hid_mouse_test(void) +{ + /*!< remove mouse pointer */ + mouse_cfg.x += 10; + mouse_cfg.y = 0; + /*!< send repotr to host */ + hid_mouse_send_report(HID_INT_EP, (uint8_t *)&mouse_cfg, 4); + /*!< delay 1000ms */ + HAL_Delay(1000); +} \ No newline at end of file