/
ux_device_customhid.c
383 lines (298 loc) · 10.2 KB
/
ux_device_customhid.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file ux_device_customhid.c
* @author MCD Application Team
* @brief USBX Device Custom HID applicative source file
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "ux_device_customhid.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
UX_SLAVE_CLASS_HID *hid_custom;
UX_SLAVE_CLASS_HID_EVENT hid_event;
UX_DEVICE_CLASS_HID_RECEIVED_EVENT hid_received_event;
extern TX_QUEUE ux_hid_msgqueue;
extern ADC_HandleTypeDef hadc1;
ALIGN_32BYTES (int32_t ADCConvertedValue[8]) = {0};
int32_t ADC_Prev_ConvertedValue = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
static VOID Led_Toggle(UINT event_idx, UINT state);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief USBD_Custom_HID_Activate
* This function is called when insertion of a Custom HID device.
* @param hid_instance: Pointer to the hid class instance.
* @retval none
*/
VOID USBD_Custom_HID_Activate(VOID *hid_instance)
{
/* USER CODE BEGIN USBD_Custom_HID_Activate */
/* Save the Custom HID instance */
hid_custom = (UX_SLAVE_CLASS_HID*) hid_instance;
/* Perform an ADC automatic self-calibration */
HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
/* Enable ADC, start conversion of regular group and transfer result through DMA */
HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &ADCConvertedValue, 1);
/* USER CODE END USBD_Custom_HID_Activate */
return;
}
/**
* @brief USBD_Custom_HID_Deactivate
* This function is called when extraction of a Custom HID device.
* @param hid_instance: Pointer to the hid class instance.
* @retval none
*/
VOID USBD_Custom_HID_Deactivate(VOID *hid_instance)
{
/* USER CODE BEGIN USBD_Custom_HID_Deactivate */
UX_PARAMETER_NOT_USED(hid_instance);
/* Reset the Custom HID instance */
hid_custom = UX_NULL;
/* Stop ADC conversion of regular group */
HAL_ADC_Stop_DMA(&hadc1);
/* USER CODE END USBD_Custom_HID_Deactivate */
return;
}
/**
* @brief USBD_Custom_HID_SetFeature
* This function is invoked when the host sends a HID SET_REPORT
* to the application over Endpoint 0 (Set Feature).
* @param hid_instance: Pointer to the hid class instance.
* @param hid_event: Pointer to structure of the hid event.
* @retval status
*/
UINT USBD_Custom_HID_SetFeature(UX_SLAVE_CLASS_HID *hid_instance,
UX_SLAVE_CLASS_HID_EVENT *hid_event)
{
UINT status = UX_SUCCESS;
/* USER CODE BEGIN USBD_Custom_HID_SetFeature */
UX_PARAMETER_NOT_USED(hid_instance);
UINT event_idx, state;
/* Get LED report number */
event_idx = hid_event->ux_device_class_hid_event_report_id;
/* Get LED states from hid event buffer */
state = hid_event->ux_device_class_hid_event_buffer[0];
Led_Toggle(event_idx, state);
/* USER CODE END USBD_Custom_HID_SetFeature */
return status;
}
/**
* @brief USBD_Custom_HID_GetReport
* This function is invoked when host is requesting event through
* control GET_REPORT request.
* @param hid_instance: Pointer to the hid class instance.
* @param hid_event: Pointer to structure of the hid event.
* @retval status
*/
UINT USBD_Custom_HID_GetReport(UX_SLAVE_CLASS_HID *hid_instance,
UX_SLAVE_CLASS_HID_EVENT *hid_event)
{
UINT status = UX_SUCCESS;
/* USER CODE BEGIN USBD_Custom_HID_GetReport */
UX_PARAMETER_NOT_USED(hid_instance);
UX_PARAMETER_NOT_USED(hid_event);
/* USER CODE END USBD_Custom_HID_GetReport */
return status;
}
#ifdef UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT
/**
* @brief USBD_Custom_HID_SetReport
* This function is invoked when the host sends a HID SET_REPORT
* to the application over Endpoint OUT (Set Report).
* @param hid_instance: Pointer to the hid class instance.
* @retval none
*/
VOID USBD_Custom_HID_SetReport(struct UX_SLAVE_CLASS_HID_STRUCT *hid_instance)
{
/* USER CODE BEGIN USBD_Custom_HID_SetReport */
UX_PARAMETER_NOT_USED(hid_instance);
UINT event_idx, state;
ux_utility_memory_set(&hid_received_event, 0, sizeof(UX_DEVICE_CLASS_HID_RECEIVED_EVENT));
if(ux_device_class_hid_receiver_event_get(hid_custom, &hid_received_event) == UX_SUCCESS)
{
/* Get LED report number */
event_idx = hid_received_event.ux_device_class_hid_received_event_data[0];
/* Get LED states from hid event buffer */
state = hid_received_event.ux_device_class_hid_received_event_data[1];
/* Toggle Leds */
Led_Toggle(event_idx, state);
/* Free hid received event */
ux_device_class_hid_receiver_event_free(hid_custom);
}
/* USER CODE END USBD_Custom_HID_SetReport */
return;
}
/**
* @brief USBD_Custom_HID_EventMaxNumber
* This function to set receiver event max number parameter.
* @param none
* @retval receiver event max number
*/
ULONG USBD_Custom_HID_EventMaxNumber(VOID)
{
ULONG max_number = 0U;
/* USER CODE BEGIN USBD_Custom_HID_EventMaxNumber */
max_number = 1;
/* USER CODE END USBD_Custom_HID_EventMaxNumber */
return max_number;
}
/**
* @brief USBD_Custom_HID_EventMaxLength
* This function to set receiver event max length parameter.
* @param none
* @retval receiver event max length
*/
ULONG USBD_Custom_HID_EventMaxLength(VOID)
{
ULONG max_length = 0U;
/* USER CODE BEGIN USBD_Custom_HID_EventMaxLength */
/* Set max event length */
max_length = USBD_HID_CUSTOM_EPOUT_HS_MPS;
/* USER CODE END USBD_Custom_HID_EventMaxLength */
return max_length;
}
#endif /* UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT */
/* USER CODE BEGIN 1 */
/**
* @brief Function implementing usbx_cutomhid_thread_entry.
* @param thread_input: not used
* @retval none
*/
VOID usbx_cutomhid_thread_entry(ULONG thread_input)
{
UX_SLAVE_DEVICE *device;
UX_PARAMETER_NOT_USED(thread_input);
device = &_ux_system_slave->ux_system_slave_device;
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
while (1)
{
/* Check if the device state already configured */
if ((device->ux_slave_device_state == UX_DEVICE_CONFIGURED) && (hid_custom != UX_NULL))
{
/* Wait for a hid event */
if (tx_queue_receive(&ux_hid_msgqueue, &hid_event, TX_WAIT_FOREVER) != TX_SUCCESS)
{
Error_Handler();
}
/* Send hid event */
ux_device_class_hid_event_set(hid_custom, &hid_event);
}
else
{
/* Sleep thread for 10ms */
tx_thread_sleep(MS_TO_TICK(10));
}
}
}
/**
* @brief HAL_GPIO_EXTI_Callback
* EXTI line detection callbacks.
* @param GPIO_Pin: Specifies the pins connected EXTI line
* @retval none
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Set hid event length */
hid_event.ux_device_class_hid_event_length = 1;
/* Set button tamper report id */
hid_event.ux_device_class_hid_event_report_id = TAMPER_REPORT_ID;
/* Set button tamper event buffer */
if(HAL_GPIO_ReadPin(BUTTON_USER_GPIO_Port, BUTTON_USER_Pin) == GPIO_PIN_RESET)
{
hid_event.ux_device_class_hid_event_buffer[0] = 0x01;
}
else
{
hid_event.ux_device_class_hid_event_buffer[0] = 0x00;
}
/* Send hid event */
ux_device_class_hid_event_set(hid_custom, &hid_event);
}
/**
* @brief HAL_ADC_ConvCpltCallback
* Conversion complete callback in non-blocking mode.
* @param hadc: ADC handle
* @retval none
*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
/* Set hid event length */
hid_event.ux_device_class_hid_event_length = 1;
/* Set potentiometer report id */
hid_event.ux_device_class_hid_event_report_id = ADC_REPORT_ID;
/* D-Cache Invalidate by address of ADCConvertedValue */
SCB_InvalidateDCache_by_Addr(ADCConvertedValue, 4);
if (abs((ADCConvertedValue[0] >> 4) - (ADC_Prev_ConvertedValue >> 4)) > 4)
{
/* Set event buffer */
hid_event.ux_device_class_hid_event_buffer[0] = (uint8_t)(ADCConvertedValue[0] >> 4);
/* Put a hid event message queue */
if(tx_queue_send(&ux_hid_msgqueue, &hid_event, TX_NO_WAIT) != TX_SUCCESS)
{
Error_Handler();
}
/* Update previous ADC Converted value */
ADC_Prev_ConvertedValue = ADCConvertedValue[0];
}
}
/**
* @brief Led_Toggle
* @param event_idx: LED Report Number
* @param state: LED states (ON/OFF)
* @retval none
*/
static VOID Led_Toggle(UINT event_idx, UINT state)
{
switch (event_idx)
{
case LED1_REPORT_ID:
(state == 1) ? BSP_LED_On(LED1) : BSP_LED_Off(LED1);
break;
case LED2_REPORT_ID:
(state == 1) ? BSP_LED_On(LED2) : BSP_LED_Off(LED2);
break;
case LED3_REPORT_ID:
(state == 1) ? BSP_LED_On(LED3) : BSP_LED_Off(LED3);
break;
case LED4_REPORT_ID:
(state == 1) ? BSP_LED_On(LED4) : BSP_LED_Off(LED4);
break;
default:
BSP_LED_Off(LED1);
BSP_LED_Off(LED2);
BSP_LED_Off(LED3);
BSP_LED_Off(LED4);
break;
}
}
/* USER CODE END 1 */