M4521_BSP V3.02.000
The Board Support Package for M4521
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 "M4521.h"
18#include "usbh_core.h"
19
20#include "usbh_hid.h"
21
22
41
42#define USB_TIMEOUT 100000
43
44extern HID_DEV_T *find_hid_deivce_by_urb(URB_T *urb);
45extern int find_hid_device(HID_DEV_T *hdev);
46extern EP_INFO_T *hid_get_ep_info(USB_DEV_T *dev, int ifnum, uint16_t dir);
47
48
49static int usb_snd_control_msg(HID_DEV_T *hdev, int requesttype, int request,
50 int value, int index, char *bytes, int size, int timeout)
51{
52 USB_DEV_T *udev = hdev->udev;
53
54 return USBH_SendCtrlMsg(udev, usb_sndctrlpipe(udev, 0),
55 request, requesttype, value, index, bytes, size, timeout);
56}
57
58int usb_rcv_control_msg(HID_DEV_T *hdev, int requesttype, int request,
59 int value, int index, char *bytes, int size, int timeout)
60{
61 USB_DEV_T *udev = hdev->udev;
62
63 return USBH_SendCtrlMsg(udev, usb_rcvctrlpipe(udev, 0),
64 request, requesttype, value, index, bytes, size, timeout);
65}
66
68
69
80int32_t HID_HidGetReportDescriptor(HID_DEV_T *hdev, uint8_t *desc_buf, int buf_max_len)
81{
82 int len;
83
84 if (buf_max_len < 9)
86
87 len = usb_rcv_control_msg(hdev,
88 USB_DIR_IN+1,
89 USB_REQ_GET_DESCRIPTOR,
90 (USB_DT_HID << 8) + 0, hdev->ifnum,
91 (char*)desc_buf, buf_max_len,
92 USB_TIMEOUT);
93
94 if (len < 0)
95 {
96 HID_DBGMSG("failed to get HID descriptor.\n");
97 return HID_RET_IO_ERR;
98 }
99
100 len = desc_buf[7] | (desc_buf[8] << 8);
101
102 HID_DBGMSG("Report descriptor size is %d\n", len);
103
104 if (buf_max_len < len)
106
107 len = usb_rcv_control_msg(hdev,
108 USB_DIR_IN+1,
109 USB_REQ_GET_DESCRIPTOR,
110 (USB_DT_REPORT << 8) + 0, hdev->ifnum,
111 (char*)desc_buf, len,
112 USB_TIMEOUT);
113
114 if (len < 0)
115 {
116 HID_DBGMSG("failed to get HID descriptor.\n");
117 return HID_RET_IO_ERR;
118 }
119
120 HID_DBGMSG("successfully initialised HID descriptor %d bytes.\n", len);
121
122 return len;
123}
124
125
142int32_t HID_HidGetReport(HID_DEV_T *hdev, int rtp_typ, int rtp_id,
143 uint8_t *data, int len)
144{
145 len = usb_rcv_control_msg(hdev,
146 USB_DIR_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
148 rtp_id + (rtp_typ << 8),
149 hdev->ifnum,
150 (char *)data, len, USB_TIMEOUT);
151
152 if (len < 0)
153 {
154 HID_DBGMSG("failed to get report!\n");
155 return HID_RET_IO_ERR;
156 }
157 return len;
158}
159
160
178int32_t HID_HidSetReport(HID_DEV_T *hdev, int rtp_typ, int rtp_id,
179 uint8_t *data, int len)
180{
181 len = usb_snd_control_msg(hdev,
182 USB_DIR_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
184 rtp_id + (rtp_typ << 8),
185 hdev->ifnum,
186 (char *)data, len, USB_TIMEOUT);
187
188 if (len < 0)
189 {
190 HID_DBGMSG("failed to set report!\n");
191 return HID_RET_IO_ERR;
192 }
193 return len;
194}
195
196
208int32_t HID_HidGetIdle(HID_DEV_T *hdev, int rtp_id, uint8_t *idle_rate)
209{
210 int len;
211
212 len = usb_rcv_control_msg(hdev,
213 USB_DIR_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
215 rtp_id,
216 hdev->ifnum,
217 (char *)idle_rate, 1, USB_TIMEOUT);
218
219 if (len != 1)
220 {
221 HID_DBGMSG("failed to get idle rate! %d\n", len);
222 return HID_RET_IO_ERR;
223 }
224 return HID_RET_OK;
225}
226
227
240int32_t HID_HidSetIdle(HID_DEV_T *hdev, int rtp_id, uint8_t idle_rate)
241{
242 int ret;
243 uint16_t wValue = idle_rate;
244
245 ret = usb_snd_control_msg(hdev,
246 USB_DIR_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
248 rtp_id + (wValue << 8),
249 hdev->ifnum,
250 NULL, 0, USB_TIMEOUT);
251
252 if (ret < 0)
253 {
254 HID_DBGMSG("failed to set idle rate! %d\n", ret);
255 return HID_RET_IO_ERR;
256 }
257 return HID_RET_OK;
258}
259
260
272int32_t HID_HidGetProtocol(HID_DEV_T *hdev, uint8_t *protocol)
273{
274 int len;
275
276 len = usb_rcv_control_msg(hdev,
277 USB_DIR_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
279 0,
280 hdev->ifnum,
281 (char *)protocol, 1, USB_TIMEOUT);
282
283 if (len != 1)
284 {
285 HID_DBGMSG("failed to get protocol! %d\n", len);
286 return HID_RET_IO_ERR;
287 }
288 return HID_RET_OK;
289}
290
302int32_t HID_HidSetProtocol(HID_DEV_T *hdev, uint8_t protocol)
303{
304 int ret;
305
306 ret = usb_snd_control_msg(hdev,
307 USB_DIR_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
309 protocol,
310 hdev->ifnum,
311 NULL, 0, USB_TIMEOUT);
312
313 if (ret < 0)
314 {
315 HID_DBGMSG("failed to set protocol! %d\n", ret);
316 return HID_RET_IO_ERR;
317 }
318 return HID_RET_OK;
319}
320
322
323/*
324 * HID INT-in complete function
325 */
326static void hid_read_irq(URB_T *urb)
327{
328 HID_DEV_T *hdev;
329
330 //HID_DBGMSG("hid_read_irq. %d\n", urb->actual_length);
331
332 hdev = find_hid_deivce_by_urb(urb);
333 if (hdev == NULL)
334 return;
335
336 if (urb->status)
337 {
338 HID_DBGMSG("hid_read_irq - has error: 0x%x\n", urb->status);
339 return;
340 }
341
342 if (hdev->read_func && urb->actual_length)
343 hdev->read_func(hdev, urb->transfer_buffer, urb->actual_length);
344}
345
346/*
347 * HID INT-out complete function
348 */
349static void hid_write_irq(URB_T *urb)
350{
351 HID_DEV_T *hdev;
352
353 //HID_DBGMSG("hid_write_irq. %d\n", urb->actual_length);
354
355 hdev = find_hid_deivce_by_urb(urb);
356 if (hdev == NULL)
357 return;
358
359 if (urb->status)
360 {
361 HID_DBGMSG("hid_write_irq - has error: 0x%x\n", urb->status);
362 return;
363 }
364
365 if (hdev->write_func)
366 hdev->write_func(hdev, (uint8_t **)&urb->transfer_buffer, &urb->transfer_buffer_length);
367}
368
369
371
381{
382 EP_INFO_T *ep_info;
383 URB_T *urb;
384 uint32_t pipe;
385 USB_DEV_T *udev;
386 int maxp, ret;
387
388 if (!func)
390
391 udev = hdev->udev;
392
393 if (hdev->urbin)
395
396 ep_info = hid_get_ep_info(udev, hdev->ifnum, USB_DIR_IN);
397 if (ep_info == NULL)
398 {
399 HID_DBGMSG("Interrupt-in endpoint not found in this device!\n");
401 }
402
403 urb = USBH_AllocUrb();
404 if (urb == NULL)
405 {
406 HID_DBGMSG("Failed to allocated URB!\n");
408 }
409
410 pipe = usb_rcvintpipe(udev, ep_info->bEndpointAddress);
411 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
412
413 HID_DBGMSG("Endpoint 0x%x maximum packet size is %d.\n", ep_info->bEndpointAddress, maxp);
414
415 FILL_INT_URB(urb, udev, pipe, &hdev->inbuf[0], maxp, hid_read_irq,
416 hdev, ep_info->bInterval);
417
418 hdev->urbin = urb;
419 hdev->read_func = func;
420
421 ret = USBH_SubmitUrb(urb);
422 if (ret)
423 {
424 HID_DBGMSG("Error - failed to submit interrupt read request (%d)", ret);
425 USBH_FreeUrb(urb);
426 hdev->urbin = NULL;
427 return HID_RET_IO_ERR;
428 }
429
430 return HID_RET_OK;
431}
432
442{
443 EP_INFO_T *ep_info;
444 URB_T *urb;
445 uint32_t pipe;
446 USB_DEV_T *udev;
447 int maxp, ret;
448
449 if (!func)
451
452 udev = hdev->udev;
453
454 if (hdev->urbout)
456
457 ep_info = hid_get_ep_info(hdev->udev, hdev->ifnum, USB_DIR_OUT);
458 if (ep_info == NULL)
459 {
460 HID_DBGMSG("Assigned endpoint address 0x%x not found in this device!\n", ep_info->bEndpointAddress);
462 }
463
464 urb = USBH_AllocUrb();
465 if (urb == NULL)
466 {
467 HID_DBGMSG("Failed to allocated URB!\n");
469 }
470
471 pipe = usb_sndintpipe(udev, ep_info->bEndpointAddress);
472 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
473
474 HID_DBGMSG("Endpoint 0x%x maximum packet size is %d.\n", ep_info->bEndpointAddress, maxp);
475
476 FILL_INT_URB(urb, udev, pipe, NULL, maxp, hid_write_irq,
477 hdev, ep_info->bInterval);
478
479 func(hdev, (uint8_t **)&urb->transfer_buffer, &urb->transfer_buffer_length);
480
481 hdev->urbout = urb;
482 hdev->write_func = func;
483
484 ret = USBH_SubmitUrb(urb);
485 if (ret)
486 {
487 HID_DBGMSG("Error - failed to submit interrupt read request (%d)", ret);
488 USBH_FreeUrb(urb);
489 hdev->urbout = NULL;
490 return HID_RET_IO_ERR;
491 }
492
493 return HID_RET_OK;
494}
495
496 /* end of group USBH_HID_EXPORTED_FUNCTIONS */
498 /* end of group USBH_HID_Driver */
500 /* end of group USB_Host_Driver */
502 /* end of group Component_Library */
504
505
506
507
508
#define NULL
Definition: M4521.h:13912
URB_T * USBH_AllocUrb(void)
Allocate an URB from USB Core driver internal URB pool.
Definition: usbh_support.c:76
int status
Definition: usbh_core.h:521
void * transfer_buffer
Definition: usbh_core.h:523
int32_t USBH_SubmitUrb(URB_T *urb)
Submit an URB to USB core for transfer data.
Definition: usbh_core.c:219
int actual_length
Definition: usbh_core.h:525
int transfer_buffer_length
Definition: usbh_core.h:524
void USBH_FreeUrb(URB_T *)
Free the URB allocated from USBH_AllocUrb()
Definition: usbh_support.c:99
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:375
#define HID_REPORT_GET
Definition: usbh_hid.h:57
#define HID_RET_IO_ERR
Definition: usbh_hid.h:51
#define HID_GET_IDLE
Definition: usbh_hid.h:58
#define HID_RET_INVALID_PARAMETER
Definition: usbh_hid.h:52
#define HID_REPORT_SET
Definition: usbh_hid.h:60
#define HID_RET_NOT_SUPPORTED
Definition: usbh_hid.h:54
#define HID_RET_OK
Definition: usbh_hid.h:49
#define HID_RET_OUT_OF_MEMORY
Definition: usbh_hid.h:53
#define HID_GET_PROTOCOL
Definition: usbh_hid.h:59
#define HID_SET_PROTOCOL
Definition: usbh_hid.h:62
#define HID_SET_IDLE
Definition: usbh_hid.h:61
HID_IW_FUNC * write_func
Definition: usbh_hid.h:108
USB_DEV_T * udev
Definition: usbh_hid.h:100
int32_t USBH_HidStartIntReadPipe(HID_DEV_T *hdev, HID_IR_FUNC *func)
Start purge the USB interrupt in transfer.
Definition: hid_core.c:380
URB_T * urbin
Definition: usbh_hid.h:104
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:272
HID_IR_FUNC * read_func
Definition: usbh_hid.h:107
int32_t HID_HidGetReportDescriptor(HID_DEV_T *hdev, uint8_t *desc_buf, int buf_max_len)
Get report descriptor request.
Definition: hid_core.c:80
URB_T * urbout
Definition: usbh_hid.h:105
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:208
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:240
uint8_t inbuf[HID_MAX_BUFFER_SIZE]
Definition: usbh_hid.h:106
int32_t USBH_HidStartIntWritePipe(HID_DEV_T *hdev, HID_IW_FUNC *func)
Start purge the USB interrupt out transfer.
Definition: hid_core.c:441
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:142
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:178
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:302
int ifnum
Definition: usbh_hid.h:101
void() HID_IR_FUNC(struct usbhid_dev *hdev, uint8_t *rdata, int data_len)
Definition: usbh_hid.h:83
void() HID_IW_FUNC(struct usbhid_dev *hdev, uint8_t **wbuff, int *buff_size)
Definition: usbh_hid.h:84
return value
Definition: semihosting.h:98
USB Host core driver header file.
HIDDEN_SYMBOLS struct usb_device USB_DEV_T