NUC472_NUC442_BSP V3.03.004
The Board Support Package for NUC472/NUC442
hid_core.c
Go to the documentation of this file.
1/**************************************************************************/
13#include <stdio.h>
14#include <string.h>
15#include <stdlib.h>
16
17#include "NUC472_442.h"
18#include "usbh_core.h"
19
20#include "usbh_hid.h"
21
22
37
38#define USB_TIMEOUT 100000
39
40extern HID_DEV_T *find_hid_deivce_by_urb(URB_T *urb);
41extern int find_hid_device(HID_DEV_T *hdev);
42extern EP_INFO_T *hid_get_ep_info(USB_DEV_T *dev, int ifnum, uint16_t dir);
43
44
45static int usb_snd_control_msg(HID_DEV_T *hdev, int requesttype, int request,
46 int value, int index, char *bytes, int size, int timeout)
47{
48 USB_DEV_T *udev = hdev->udev;
49
50 return USBH_SendCtrlMsg(udev, usb_sndctrlpipe(udev, 0),
51 request, requesttype, value, index, bytes, size, timeout);
52}
53
54int usb_rcv_control_msg(HID_DEV_T *hdev, int requesttype, int request,
55 int value, int index, char *bytes, int size, int timeout)
56{
57 USB_DEV_T *udev = hdev->udev;
58
59 return USBH_SendCtrlMsg(udev, usb_rcvctrlpipe(udev, 0),
60 request, requesttype, value, index, bytes, size, timeout);
61}
62
64
65
76int32_t HID_HidGetReportDescriptor(HID_DEV_T *hdev, uint8_t *desc_buf, int buf_max_len)
77{
78 int len;
79
80 if (buf_max_len < 9)
82
83 len = usb_rcv_control_msg(hdev,
84 USB_DIR_IN+1,
85 USB_REQ_GET_DESCRIPTOR,
86 (USB_DT_HID << 8) + 0, hdev->ifnum,
87 (char*)desc_buf, buf_max_len,
88 USB_TIMEOUT);
89
90 if (len < 0)
91 {
92 HID_DBGMSG("failed to get HID descriptor.\n");
93 return HID_RET_IO_ERR;
94 }
95
96 len = desc_buf[7] | (desc_buf[8] << 8);
97
98 HID_DBGMSG("Report descriptor size is %d\n", len);
99
100 if (buf_max_len < len)
102
103 len = usb_rcv_control_msg(hdev,
104 USB_DIR_IN+1,
105 USB_REQ_GET_DESCRIPTOR,
106 (USB_DT_REPORT << 8) + 0, hdev->ifnum,
107 (char*)desc_buf, len,
108 USB_TIMEOUT);
109
110 if (len < 0)
111 {
112 HID_DBGMSG("failed to get HID descriptor.\n");
113 return HID_RET_IO_ERR;
114 }
115
116 HID_DBGMSG("successfully initialised HID descriptor %d bytes.\n", len);
117
118 return len;
119}
120
121
138int32_t HID_HidGetReport(HID_DEV_T *hdev, int rtp_typ, int rtp_id,
139 uint8_t *data, int len)
140{
141 len = usb_rcv_control_msg(hdev,
142 USB_DIR_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
144 rtp_id + (rtp_typ << 8),
145 hdev->ifnum,
146 (char *)data, len, USB_TIMEOUT);
147
148 if (len < 0)
149 {
150 HID_DBGMSG("failed to get report!\n");
151 return HID_RET_IO_ERR;
152 }
153 return len;
154}
155
156
174int32_t HID_HidSetReport(HID_DEV_T *hdev, int rtp_typ, int rtp_id,
175 uint8_t *data, int len)
176{
177 len = usb_snd_control_msg(hdev,
178 USB_DIR_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
180 rtp_id + (rtp_typ << 8),
181 hdev->ifnum,
182 (char *)data, len, USB_TIMEOUT);
183
184 if (len < 0)
185 {
186 HID_DBGMSG("failed to set report!\n");
187 return HID_RET_IO_ERR;
188 }
189 return len;
190}
191
192
204int32_t HID_HidGetIdle(HID_DEV_T *hdev, int rtp_id, uint8_t *idle_rate)
205{
206 int len;
207
208 len = usb_rcv_control_msg(hdev,
209 USB_DIR_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
211 rtp_id,
212 hdev->ifnum,
213 (char *)idle_rate, 1, USB_TIMEOUT);
214
215 if (len != 1)
216 {
217 HID_DBGMSG("failed to get idle rate! %d\n", len);
218 return HID_RET_IO_ERR;
219 }
220 return HID_RET_OK;
221}
222
223
236int32_t HID_HidSetIdle(HID_DEV_T *hdev, int rtp_id, uint8_t idle_rate)
237{
238 int ret;
239 uint16_t wValue = idle_rate;
240
241 ret = usb_snd_control_msg(hdev,
242 USB_DIR_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
244 rtp_id + (wValue << 8),
245 hdev->ifnum,
246 NULL, 0, USB_TIMEOUT);
247
248 if (ret < 0)
249 {
250 HID_DBGMSG("failed to set idle rate! %d\n", ret);
251 return HID_RET_IO_ERR;
252 }
253 return HID_RET_OK;
254}
255
256
268int32_t HID_HidGetProtocol(HID_DEV_T *hdev, uint8_t *protocol)
269{
270 int len;
271
272 len = usb_rcv_control_msg(hdev,
273 USB_DIR_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
275 0,
276 hdev->ifnum,
277 (char *)protocol, 1, USB_TIMEOUT);
278
279 if (len != 1)
280 {
281 HID_DBGMSG("failed to get protocol! %d\n", len);
282 return HID_RET_IO_ERR;
283 }
284 return HID_RET_OK;
285}
286
287
299int32_t HID_HidSetProtocol(HID_DEV_T *hdev, uint8_t protocol)
300{
301 int ret;
302
303 ret = usb_snd_control_msg(hdev,
304 USB_DIR_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
306 protocol,
307 hdev->ifnum,
308 NULL, 0, USB_TIMEOUT);
309
310 if (ret < 0)
311 {
312 HID_DBGMSG("failed to set protocol! %d\n", ret);
313 return HID_RET_IO_ERR;
314 }
315 return HID_RET_OK;
316}
317
318
320
321/*
322 * HID INT-in complete function
323 */
324static void hid_read_irq(URB_T *urb)
325{
326 HID_DEV_T *hdev;
327
328 //HID_DBGMSG("hid_read_irq. %d\n", urb->actual_length);
329
330 hdev = find_hid_deivce_by_urb(urb);
331 if (hdev == NULL)
332 return;
333
334 if (urb->status)
335 {
336 HID_DBGMSG("hid_read_irq - has error: 0x%x\n", urb->status);
337 return;
338 }
339
340 if (hdev->read_func && urb->actual_length)
341 hdev->read_func(hdev, urb->transfer_buffer, urb->actual_length);
342}
343
344/*
345 * HID INT-out complete function
346 */
347static void hid_write_irq(URB_T *urb)
348{
349 HID_DEV_T *hdev;
350
351 //HID_DBGMSG("hid_write_irq. %d\n", urb->actual_length);
352
353 hdev = find_hid_deivce_by_urb(urb);
354 if (hdev == NULL)
355 return;
356
357 if (urb->status)
358 {
359 HID_DBGMSG("hid_write_irq - has error: 0x%x\n", urb->status);
360 return;
361 }
362
363 if (hdev->write_func)
364 hdev->write_func(hdev, (uint8_t **)&urb->transfer_buffer, &urb->transfer_buffer_length);
365}
366
367
369
379{
380 EP_INFO_T *ep_info;
381 URB_T *urb;
382 uint32_t pipe;
383 USB_DEV_T *udev;
384 int maxp, ret;
385
386 if (!func)
388
389 udev = hdev->udev;
390
391 if (hdev->urbin)
393
394 ep_info = hid_get_ep_info(udev, hdev->ifnum, USB_DIR_IN);
395 if (ep_info == NULL)
396 {
397 HID_DBGMSG("Interrupt-in endpoint not found in this device!\n");
399 }
400
401 urb = USBH_AllocUrb();
402 if (urb == NULL)
403 {
404 HID_DBGMSG("Failed to allocated URB!\n");
406 }
407
408 pipe = usb_rcvintpipe(udev, ep_info->bEndpointAddress);
409 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
410
411 HID_DBGMSG("Endpoint 0x%x maximum packet size is %d.\n", ep_info->bEndpointAddress, maxp);
412
413 FILL_INT_URB(urb, udev, pipe, &hdev->inbuf[0], maxp, hid_read_irq,
414 hdev, ep_info->bInterval);
415
416 hdev->urbin = urb;
417 hdev->read_func = func;
418
419 ret = USBH_SubmitUrb(urb);
420 if (ret)
421 {
422 HID_DBGMSG("Error - failed to submit interrupt read request (%d)", ret);
423 USBH_FreeUrb(urb);
424 hdev->urbin = NULL;
425 return HID_RET_IO_ERR;
426 }
427
428 return HID_RET_OK;
429}
430
440{
441 EP_INFO_T *ep_info;
442 URB_T *urb;
443 uint32_t pipe;
444 USB_DEV_T *udev;
445 int maxp, ret;
446
447 if (!func)
449
450 udev = hdev->udev;
451
452 if (hdev->urbout)
454
455 ep_info = hid_get_ep_info(hdev->udev, hdev->ifnum, USB_DIR_OUT);
456 if (ep_info == NULL)
457 {
458 HID_DBGMSG("Assigned endpoint address 0x%x not found in this device!\n", ep_info->bEndpointAddress);
460 }
461
462 urb = USBH_AllocUrb();
463 if (urb == NULL)
464 {
465 HID_DBGMSG("Failed to allocated URB!\n");
467 }
468
469 pipe = usb_sndintpipe(udev, ep_info->bEndpointAddress);
470 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
471
472 HID_DBGMSG("Endpoint 0x%x maximum packet size is %d.\n", ep_info->bEndpointAddress, maxp);
473
474 FILL_INT_URB(urb, udev, pipe, NULL, maxp, hid_write_irq,
475 hdev, ep_info->bInterval);
476
477 func(hdev, (uint8_t **)&urb->transfer_buffer, &urb->transfer_buffer_length);
478
479 hdev->urbout = urb;
480 hdev->write_func = func;
481
482 ret = USBH_SubmitUrb(urb);
483 if (ret)
484 {
485 HID_DBGMSG("Error - failed to submit interrupt read request (%d)", ret);
486 USBH_FreeUrb(urb);
487 hdev->urbout = NULL;
488 return HID_RET_IO_ERR;
489 }
490
491 return HID_RET_OK;
492}
493
494 /* end of group NUC472_442_USBH_HID_EXPORTED_FUNCTIONS */
496 /* end of group NUC472_442_USBH_HID_Driver */
498 /* end of group NUC472_442_Device_Driver */
500
501/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
502
503
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
int status
Definition: usbh_core.h:543
void * transfer_buffer
Definition: usbh_core.h:545
int32_t USBH_SubmitUrb(URB_T *urb)
Submit an URB to USB core for transfer data.
Definition: usbh_core.c:218
int actual_length
Definition: usbh_core.h:547
int transfer_buffer_length
Definition: usbh_core.h:546
URB_T * USBH_AllocUrb(void)
Allocate an URB from USB Core driver internal URB pool.
Definition: usbh_support.c:90
void USBH_FreeUrb(URB_T *)
Free the URB allocated from USBH_AllocUrb()
Definition: usbh_support.c:113
int32_t USBH_SendCtrlMsg(USB_DEV_T *dev, uint32_t pipe, uint8_t request, uint8_t requesttype, uint16_t value, uint16_t index, void *data, uint16_t size, int timeout)
Execute a control transfer.
Definition: usbh_core.c:378
HIDDEN_SYMBOLS struct usb_device USB_DEV_T
#define HID_REPORT_GET
Definition: usbh_hid.h:50
#define HID_RET_IO_ERR
Definition: usbh_hid.h:44
#define HID_GET_IDLE
Definition: usbh_hid.h:51
#define HID_RET_INVALID_PARAMETER
Definition: usbh_hid.h:45
#define HID_REPORT_SET
Definition: usbh_hid.h:53
#define HID_RET_NOT_SUPPORTED
Definition: usbh_hid.h:47
#define HID_RET_OK
Definition: usbh_hid.h:42
#define HID_RET_OUT_OF_MEMORY
Definition: usbh_hid.h:46
#define HID_GET_PROTOCOL
Definition: usbh_hid.h:52
#define HID_SET_PROTOCOL
Definition: usbh_hid.h:55
#define HID_SET_IDLE
Definition: usbh_hid.h:54
HID_IW_FUNC * write_func
Definition: usbh_hid.h:101
USB_DEV_T * udev
Definition: usbh_hid.h:93
int32_t USBH_HidStartIntReadPipe(HID_DEV_T *hdev, HID_IR_FUNC *func)
Start purge the USB interrupt in transfer.
Definition: hid_core.c:378
URB_T * urbin
Definition: usbh_hid.h:97
int32_t HID_HidGetProtocol(HID_DEV_T *hdev, uint8_t *protocol)
HID class standard request Get_Protocol request. The Get_Protocol request reads which protocol is cur...
Definition: hid_core.c:268
HID_IR_FUNC * read_func
Definition: usbh_hid.h:100
int32_t HID_HidGetReportDescriptor(HID_DEV_T *hdev, uint8_t *desc_buf, int buf_max_len)
Get report descriptor request.
Definition: hid_core.c:76
URB_T * urbout
Definition: usbh_hid.h:98
int32_t HID_HidGetIdle(HID_DEV_T *hdev, int rtp_id, uint8_t *idle_rate)
HID class standard request Get_Idle request. The Get_Idle request reads the current idle rate for a p...
Definition: hid_core.c:204
int32_t HID_HidSetIdle(HID_DEV_T *hdev, int rtp_id, uint8_t idle_rate)
HID class standard request Set_Idle request. The Set_Idle request silences a particular report on the...
Definition: hid_core.c:236
uint8_t inbuf[HID_MAX_BUFFER_SIZE]
Definition: usbh_hid.h:99
int32_t USBH_HidStartIntWritePipe(HID_DEV_T *hdev, HID_IW_FUNC *func)
Start purge the USB interrupt out transfer.
Definition: hid_core.c:439
int32_t HID_HidGetReport(HID_DEV_T *hdev, int rtp_typ, int rtp_id, uint8_t *data, int len)
HID class standard request Get_Report request. The Get_Report request allows the host to receive a re...
Definition: hid_core.c:138
int32_t HID_HidSetReport(HID_DEV_T *hdev, int rtp_typ, int rtp_id, uint8_t *data, int len)
HID class standard request Set_Report request. The Set_Report request allows the host to send a repor...
Definition: hid_core.c:174
int32_t HID_HidSetProtocol(HID_DEV_T *hdev, uint8_t protocol)
HID class standard request Set_Protocol request. The Set_Protocol switches between the boot protocol ...
Definition: hid_core.c:299
int ifnum
Definition: usbh_hid.h:94
void() HID_IR_FUNC(struct usbhid_dev *hdev, uint8_t *rdata, int data_len)
Definition: usbh_hid.h:76
void() HID_IW_FUNC(struct usbhid_dev *hdev, uint8_t **wbuff, int *buff_size)
Definition: usbh_hid.h:77
#define NULL
NULL pointer.
Definition: NUC472_442.h:29018
return value
Definition: semihosting.h:98
USB Host core driver header file.