summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaiMianBBao <[email protected]>2021-11-20 10:46:16 +0800
committersakimisu <[email protected]>2021-11-20 13:42:33 +0800
commit0dd6ce2b62e7d8023535ef28d0a88a04a9fc0cf0 (patch)
treeccf241a8475b56839e276d19c32ab0353c23709c
parent04079a4189cbc8f0fc5b1ab5899eafee17e2b572 (diff)
add stm32 hid demos and remove cdc demo to example
-rw-r--r--demo/stm32/stm32f103c8t6/Core/Src/main.c377
-rw-r--r--demo/stm32/stm32f103c8t6/MDK-ARM/startup_stm32f103xb.s2
-rw-r--r--demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvoptx78
-rw-r--r--demo/stm32/stm32f103c8t6/MDK-ARM/stm32f103c8t6.uvprojx143
-rw-r--r--demo/stm32/stm32f103c8t6/example/cdc/cdc_init.c166
-rw-r--r--demo/stm32/stm32f103c8t6/example/example_select.h14
-rw-r--r--demo/stm32/stm32f103c8t6/example/hid_custom/hid_custom_init.c486
-rw-r--r--demo/stm32/stm32f103c8t6/example/hid_keyboard/hid_keyboard_init.c269
-rw-r--r--demo/stm32/stm32f103c8t6/example/hid_mouse/hid_mouse_init.c300
9 files changed, 1587 insertions, 248 deletions
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;
-}
-
-#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");
+ while ((USART1->SR & USART_SR_TXE) == 0)
+ ;
+ USART1->DR = ch;
+ return ch;
}
-
-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
+
+ /*!< init */
+ usb_dc_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 */
- /* 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 */
+#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 @@
<SetRegEntry>
<Number>0</Number>
<Key>ST-LINKIII-KEIL_SWO</Key>
- <Name>-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)</Name>
+ <Name>-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)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
@@ -152,7 +152,7 @@
<Bp>
<Number>0</Number>
<Type>0</Type>
- <LineNumber>210</LineNumber>
+ <LineNumber>205</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>0</Address>
<ByteObject>0</ByteObject>
@@ -161,7 +161,7 @@
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>0</BreakIfRCount>
- <Filename>../Core/Src/stm32f1xx_it.c</Filename>
+ <Filename>..\example\hid_keyboard\hid_keyboard_init.c</Filename>
<ExecCommand></ExecCommand>
<Expression></Expression>
</Bp>
@@ -220,7 +220,7 @@
<Group>
<GroupName>Application/MDK-ARM</GroupName>
- <tvExp>0</tvExp>
+ <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -284,7 +284,7 @@
<Group>
<GroupName>Drivers/STM32F1xx_HAL_Driver</GroupName>
- <tvExp>1</tvExp>
+ <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -556,6 +556,74 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
+ <File>
+ <GroupNumber>5</GroupNumber>
+ <FileNumber>26</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\..\..\..\class\hid\usbd_hid.c</PathWithFileName>
+ <FilenameWithoutPath>usbd_hid.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>example</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <RteFlg>0</RteFlg>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>27</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\example\cdc\cdc_init.c</PathWithFileName>
+ <FilenameWithoutPath>cdc_init.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>28</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\example\hid_mouse\hid_mouse_init.c</PathWithFileName>
+ <FilenameWithoutPath>hid_mouse_init.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>29</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\example\hid_keyboard\hid_keyboard_init.c</PathWithFileName>
+ <FilenameWithoutPath>hid_keyboard_init.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
+ <File>
+ <GroupNumber>6</GroupNumber>
+ <FileNumber>30</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <bDave2>0</bDave2>
+ <PathWithFileName>..\example\hid_custom\hid_custom_init.c</PathWithFileName>
+ <FilenameWithoutPath>hid_custom_init.c</FilenameWithoutPath>
+ <RteFlg>0</RteFlg>
+ <bShared>0</bShared>
+ </File>
</Group>
<Group>
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 @@
<MiscControls></MiscControls>
<Define>USE_HAL_DRIVER,STM32F103xB,STM32F1</Define>
<Undefine></Undefine>
- <IncludePath>../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</IncludePath>
+ <IncludePath>../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</IncludePath>
</VariousControls>
</Cads>
<Aads>
@@ -529,6 +529,138 @@
<FileType>1</FileType>
<FilePath>..\..\..\..\port\stm32\usb_dc_nohal.c</FilePath>
</File>
+ <File>
+ <FileName>usbd_hid.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\..\..\class\hid\usbd_hid.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>example</GroupName>
+ <Files>
+ <File>
+ <FileName>cdc_init.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\example\cdc\cdc_init.c</FilePath>
+ </File>
+ <File>
+ <FileName>hid_mouse_init.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\example\hid_mouse\hid_mouse_init.c</FilePath>
+ <FileOption>
+ <CommonProperty>
+ <UseCPPCompiler>2</UseCPPCompiler>
+ <RVCTCodeConst>0</RVCTCodeConst>
+ <RVCTZI>0</RVCTZI>
+ <RVCTOtherData>0</RVCTOtherData>
+ <ModuleSelection>0</ModuleSelection>
+ <IncludeInBuild>0</IncludeInBuild>
+ <AlwaysBuild>1</AlwaysBuild>
+ <GenerateAssemblyFile>2</GenerateAssemblyFile>
+ <AssembleAssemblyFile>2</AssembleAssemblyFile>
+ <PublicsOnly>2</PublicsOnly>
+ <StopOnExitCode>11</StopOnExitCode>
+ <CustomArgument></CustomArgument>
+ <IncludeLibraryModules></IncludeLibraryModules>
+ <ComprImg>1</ComprImg>
+ </CommonProperty>
+ <FileArmAds>
+ <Cads>
+ <interw>2</interw>
+ <Optim>0</Optim>
+ <oTime>2</oTime>
+ <SplitLS>2</SplitLS>
+ <OneElfS>2</OneElfS>
+ <Strict>2</Strict>
+ <EnumInt>2</EnumInt>
+ <PlainCh>2</PlainCh>
+ <Ropi>2</Ropi>
+ <Rwpi>2</Rwpi>
+ <wLevel>0</wLevel>
+ <uThumb>2</uThumb>
+ <uSurpInc>2</uSurpInc>
+ <uC99>2</uC99>
+ <uGnu>2</uGnu>
+ <useXO>2</useXO>
+ <v6Lang>0</v6Lang>
+ <v6LangP>0</v6LangP>
+ <vShortEn>2</vShortEn>
+ <vShortWch>2</vShortWch>
+ <v6Lto>2</v6Lto>
+ <v6WtE>2</v6WtE>
+ <v6Rtti>2</v6Rtti>
+ <VariousControls>
+ <MiscControls></MiscControls>
+ <Define></Define>
+ <Undefine></Undefine>
+ <IncludePath></IncludePath>
+ </VariousControls>
+ </Cads>
+ </FileArmAds>
+ </FileOption>
+ </File>
+ <File>
+ <FileName>hid_keyboard_init.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\example\hid_keyboard\hid_keyboard_init.c</FilePath>
+ </File>
+ <File>
+ <FileName>hid_custom_init.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\example\hid_custom\hid_custom_init.c</FilePath>
+ <FileOption>
+ <CommonProperty>
+ <UseCPPCompiler>2</UseCPPCompiler>
+ <RVCTCodeConst>0</RVCTCodeConst>
+ <RVCTZI>0</RVCTZI>
+ <RVCTOtherData>0</RVCTOtherData>
+ <ModuleSelection>0</ModuleSelection>
+ <IncludeInBuild>0</IncludeInBuild>
+ <AlwaysBuild>1</AlwaysBuild>
+ <GenerateAssemblyFile>2</GenerateAssemblyFile>
+ <AssembleAssemblyFile>2</AssembleAssemblyFile>
+ <PublicsOnly>2</PublicsOnly>
+ <StopOnExitCode>11</StopOnExitCode>
+ <CustomArgument></CustomArgument>
+ <IncludeLibraryModules></IncludeLibraryModules>
+ <ComprImg>1</ComprImg>
+ </CommonProperty>
+ <FileArmAds>
+ <Cads>
+ <interw>2</interw>
+ <Optim>0</Optim>
+ <oTime>2</oTime>
+ <SplitLS>2</SplitLS>
+ <OneElfS>2</OneElfS>
+ <Strict>2</Strict>
+ <EnumInt>2</EnumInt>
+ <PlainCh>2</PlainCh>
+ <Ropi>2</Ropi>
+ <Rwpi>2</Rwpi>
+ <wLevel>0</wLevel>
+ <uThumb>2</uThumb>
+ <uSurpInc>2</uSurpInc>
+ <uC99>2</uC99>
+ <uGnu>2</uGnu>
+ <useXO>2</useXO>
+ <v6Lang>0</v6Lang>
+ <v6LangP>0</v6LangP>
+ <vShortEn>2</vShortEn>
+ <vShortWch>2</vShortWch>
+ <v6Lto>2</v6Lto>
+ <v6WtE>2</v6WtE>
+ <v6Rtti>2</v6Rtti>
+ <VariousControls>
+ <MiscControls></MiscControls>
+ <Define></Define>
+ <Undefine></Undefine>
+ <IncludePath></IncludePath>
+ </VariousControls>
+ </Cads>
+ </FileArmAds>
+ </FileOption>
+ </File>
</Files>
</Group>
<Group>
@@ -551,4 +683,13 @@
<files/>
</RTE>
+ <LayerInfo>
+ <Layers>
+ <Layer>
+ <LayName>stm32f103c8t6</LayName>
+ <LayPrjMark>1</LayPrjMark>
+ </Layer>
+ </Layers>
+ </LayerInfo>
+
</Project>
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
+ * <table>
+ * <tr><th>Project <td>cdc_demo
+ * <tr><th>Author <td>LiGuo [email protected]
+ * </table>
+ * @section cdc class init demo
+ *
+ * -# You can use USB to create a virtual serial port
+ *
+ * @section 版本更新历史
+ *
+ * 版本|作者|时间|描述
+ * ----|----|----|----
+ * 1.0|LiGuo|2021.11.19|creat project
+ *
+ * <h2><center>&copy; Copyright 2021 LiGuo.
+ * All rights reserved.</center></h2>
+ *********************************************************************************
+ */
+
+/* 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
+ * <table>
+ * <tr><th>Project <td>hid_custom_demo
+ * <tr><th>Author <td>LiGuo [email protected]
+ * </table>
+ * @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
+ *
+ * <h2><center>&copy; Copyright 2021 LiGuo.
+ * All rights reserved.</center></h2>
+ *********************************************************************************
+ */
+
+/* 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
+ * <table>
+ * <tr><th>Project <td>hid_keyboard_demo
+ * <tr><th>Author <td>LiGuo [email protected]
+ * </table>
+ * @section hid keyboard init demo
+ *
+ * -# You can use USB to create a hid keyboard
+ *
+ * @section 版本更新历史
+ *
+ * 版本|作者|时间|描述
+ * ----|----|----|----
+ * 1.0|LiGuo|2021.11.19|creat project
+ *
+ * <h2><center>&copy; Copyright 2021 LiGuo.
+ * All rights reserved.</center></h2>
+ *********************************************************************************
+ */
+
+/* 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
+ * <table>
+ * <tr><th>Project <td>hid_mouse_demo
+ * <tr><th>Author <td>LiGuo [email protected]
+ * </table>
+ * @section hid mouse init demo
+ *
+ * -# You can use USB to create a hid mouse
+ *
+ * @section 版本更新历史
+ *
+ * 版本|作者|时间|描述
+ * ----|----|----|----
+ * 1.0|LiGuo|2021.11.19|creat project
+ *
+ * <h2><center>&copy; Copyright 2021 LiGuo.
+ * All rights reserved.</center></h2>
+ *********************************************************************************
+ */
+
+/* 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