28#define USB_CTRL_TIMEOUT_MS 100
31static int get_free_utr_slot(
HID_DEV_T *hdev)
37 if (hdev->utr_list[i] ==
NULL)
65 if (!hdev || !hdev->iface)
68 iface = (IFACE_T *)hdev->iface;
70 ret = usbh_ctrl_xfer(iface->udev,
71 REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_IFACE,
72 USB_REQ_GET_DESCRIPTOR,
73 (USB_DT_REPORT << 8) + 0,
76 desc_buf, &xfer_len, USB_CTRL_TIMEOUT_MS);
78 if ((ret < 0) || (xfer_len == 0))
80 HID_DBGMSG(
"failed to get HID descriptor.\n");
103 uint8_t *data,
int len)
109 if (!hdev || !hdev->iface)
112 iface = (IFACE_T *)hdev->iface;
114 ret = usbh_ctrl_xfer(iface->udev,
115 REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE,
117 rtp_id + (rtp_typ << 8),
120 data, &xfer_len, USB_CTRL_TIMEOUT_MS);
123 HID_DBGMSG(
"failed to get report!\n");
126 return (
int)xfer_len;
148 uint8_t *data,
int len)
154 if (!hdev || !hdev->iface)
157 iface = (IFACE_T *)hdev->iface;
159 ret = usbh_ctrl_xfer(iface->udev,
160 REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE,
162 rtp_id + (rtp_typ << 8),
165 data, &xfer_len, USB_CTRL_TIMEOUT_MS);
168 HID_DBGMSG(
"failed to set report!\n");
171 return (
int)xfer_len;
177static void led_ctrl_irq(UTR_T *utr)
180 utr->bIsTransferDone = 1;
183int32_t usbh_hid_set_report_non_blocking(
HID_DEV_T *hdev,
int rtp_typ,
int rtp_id,
184 uint8_t *data,
int len)
190 if (!hdev || !hdev->iface)
193 iface = (IFACE_T *)hdev->iface;
195 utr = hdev->rpd.utr_led;
198 utr = alloc_utr(iface->udev);
201 hdev->rpd.utr_led = utr;
205 if (utr->bIsTransferDone == 0)
209 utr->setup.bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
211 utr->setup.wValue = rtp_id + (rtp_typ << 8);
212 utr->setup.wIndex = iface->if_num;
213 utr->setup.wLength = len;
217 utr->func = led_ctrl_irq;
218 utr->bIsTransferDone = 0;
220 status = iface->udev->hc_driver->ctrl_xfer(utr);
223 iface->udev->ep0.hw_pipe =
NULL;
249 if (!hdev || !hdev->iface)
252 iface = (IFACE_T *)hdev->iface;
254 ret = usbh_ctrl_xfer(iface->udev,
255 REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE,
260 idle_rate, &xfer_len, USB_CTRL_TIMEOUT_MS);
262 if ((ret < 0) || (xfer_len != 1))
264 HID_DBGMSG(
"failed to get idle rate! %d\n", ret);
287 uint16_t wValue = idle_rate;
290 if (!hdev || !hdev->iface)
293 iface = (IFACE_T *)hdev->iface;
295 ret = usbh_ctrl_xfer(iface->udev,
296 REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE,
298 rtp_id + (wValue << 8),
301 NULL, &xfer_len, USB_CTRL_TIMEOUT_MS);
305 HID_DBGMSG(
"failed to set idle rate! %d\n", ret);
329 if (!hdev || !hdev->iface)
332 iface = (IFACE_T *)hdev->iface;
334 ret = usbh_ctrl_xfer(iface->udev,
335 REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE,
340 protocol, &xfer_len, USB_CTRL_TIMEOUT_MS);
342 if ((ret < 0) || (xfer_len != 1))
344 HID_DBGMSG(
"failed to get idle rate! %d\n", ret);
368 if (!hdev || !hdev->iface)
371 iface = (IFACE_T *)hdev->iface;
373 ret = usbh_ctrl_xfer(iface->udev,
374 REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE,
379 NULL, &xfer_len, USB_CTRL_TIMEOUT_MS);
383 HID_DBGMSG(
"failed to set idle rate! %d\n", ret);
396static void hid_read_irq(UTR_T *utr)
405 if (utr->status != 0)
407 HID_DBGMSG(
"hid_read_irq - has error: 0x%x\n", utr->status);
409 hdev->read_func(hdev, utr->ep->bEndpointAddress, utr->status, utr->buff, 0);
413 if (hdev->bSubClassCode == HID_SUBCLASS_BOOT_DEVICE)
415 if (hdev->bProtocolCode == HID_PROTOCOL_MOUSE)
416 hid_parse_mouse_reports(hdev, utr->buff, utr->xfer_len);
418 if (hdev->bProtocolCode == HID_PROTOCOL_KEYBOARD)
419 hid_parse_keyboard_reports(hdev, utr->buff, utr->xfer_len);
422 if (hdev->read_func && utr->xfer_len)
423 hdev->read_func(hdev, utr->ep->bEndpointAddress, utr->status, utr->buff, utr->xfer_len);
426 ret = usbh_int_xfer(utr);
429 HID_DBGMSG(
"hid_read_irq - failed to submit interrupt-in request (%d)", ret);
431 hdev->read_func(hdev, utr->ep->bEndpointAddress, ret, utr->buff, 0);
432 usbh_free_mem(utr->buff, utr->data_len);
440static void hid_write_irq(UTR_T *utr)
451 HID_DBGMSG(
"hid_write_irq - has error: 0x%x\n", utr->status);
452 hdev->write_func(hdev, utr->ep->bEndpointAddress, utr->status, utr->buff, &(utr->data_len));
456 if (hdev->write_func)
458 utr->data_len = utr->ep->wMaxPacketSize;
459 hdev->write_func(hdev, utr->ep->bEndpointAddress, utr->status, utr->buff, &(utr->data_len));
463 ret = usbh_int_xfer(utr);
466 HID_DBGMSG(
"hid_write_irq - failed to submit interrupt-out request (%d)", ret);
467 hdev->write_func(hdev, utr->ep->bEndpointAddress, ret, utr->buff, &(utr->data_len));
487 IFACE_T *iface = (IFACE_T *)hdev->iface;
492 if ((!iface) || (!iface->udev))
499 ep = usbh_iface_find_ep(iface, 0, EP_ADDR_DIR_IN | EP_ATTR_TT_INT);
501 ep = usbh_iface_find_ep(iface, ep_addr, 0);
506 utr = alloc_utr(iface->udev);
510 utr->buff = usbh_alloc_mem(ep->wMaxPacketSize);
511 if (utr->buff ==
NULL)
517 hdev->read_func = func;
520 utr->data_len = ep->wMaxPacketSize;
522 utr->func = hid_read_irq;
524 ret = usbh_int_xfer(utr);
527 HID_DBGMSG(
"Error - failed to submit interrupt read request (%d)", ret);
528 usbh_free_mem(utr->buff, utr->data_len);
533 i = get_free_utr_slot(hdev);
536 HID_DBGMSG(
"Error - No free HID slot!\n");
538 usbh_free_mem(utr->buff, utr->data_len);
544 hdev->utr_list[i] = utr;
561 IFACE_T *iface = (IFACE_T *)hdev->iface;
565 if ((!iface) || (!iface->udev))
570 utr = hdev->utr_list[i];
574 if ((utr !=
NULL) && (utr->ep !=
NULL) &&
575 ((utr->ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_IN))
583 if ((utr !=
NULL) && (utr->ep !=
NULL) && (utr->ep->bEndpointAddress == ep_addr))
594 hdev->utr_list[i] =
NULL;
596 ret = usbh_quit_utr(utr);
598 usbh_free_mem(utr->buff, utr->ep->wMaxPacketSize);
616 IFACE_T *iface = (IFACE_T *)hdev->iface;
621 if ((!iface) || (!iface->udev))
628 ep = usbh_iface_find_ep(iface, 0, EP_ADDR_DIR_OUT | EP_ATTR_TT_INT);
630 ep = usbh_iface_find_ep(iface, ep_addr, 0);
635 utr = alloc_utr(iface->udev);
639 utr->buff = usbh_alloc_mem(ep->wMaxPacketSize);
640 if (utr->buff ==
NULL)
646 hdev->write_func = func;
650 utr->data_len = ep->wMaxPacketSize;
652 utr->func = hid_write_irq;
655 func(hdev, ep->bEndpointAddress, 0, utr->buff, &(utr->data_len));
657 ret = usbh_int_xfer(utr);
660 HID_DBGMSG(
"Error - failed to submit interrupt read request (%d)", ret);
665 i = get_free_utr_slot(hdev);
668 HID_DBGMSG(
"Error - No free HID slot!\n");
670 usbh_free_mem(utr->buff, utr->data_len);
676 hdev->utr_list[i] = utr;
693 IFACE_T *iface = (IFACE_T *)hdev->iface;
697 if ((!iface) || (!iface->udev))
702 utr = hdev->utr_list[i];
706 if ((utr !=
NULL) && (utr->ep !=
NULL) &&
707 ((utr->ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_OUT))
715 if ((utr !=
NULL) && (utr->ep !=
NULL) && (utr->ep->bEndpointAddress == ep_addr))
726 hdev->utr_list[i] =
NULL;
728 ret = usbh_quit_utr(utr);
730 usbh_free_mem(utr->buff, utr->ep->wMaxPacketSize);
745 _mouse_callback = func;
757 _keyboard_callback = func;
NuMicro peripheral access layer header file.
#define NULL
NULL pointer.
#define USBH_ERR_EP_NOT_FOUND
#define HID_RET_DEV_NOT_FOUND
#define HID_RET_INVALID_PARAMETER
#define USBH_ERR_NOT_FOUND
#define CONFIG_HID_DEV_MAX_PIPE
#define USBH_ERR_MEMORY_OUT
void usbh_hid_regitser_mouse_callback(HID_MOUSE_FUNC *func)
Register the mouse event callback function to HID class driver. Any mouse reports will be sent to use...
void usbh_hid_regitser_keyboard_callback(HID_KEYBOARD_FUNC *func)
Register the keyboard event callback function to HID class driver. Any keyboard reports will be sent ...
void() HID_KEYBOARD_FUNC(struct usbhid_dev *hdev, KEYBOARD_EVENT_T *kbd)
void() HID_MOUSE_FUNC(struct usbhid_dev *hdev, MOUSE_EVENT_T *mouse)
HIDDEN_SYMBOLS struct usbhid_dev HID_DEV_T
void() HID_IR_FUNC(struct usbhid_dev *hdev, uint16_t ep_addr, int status, uint8_t *rdata, uint32_t data_len)
void() HID_IW_FUNC(struct usbhid_dev *hdev, uint16_t ep_addr, int status, uint8_t *wbuff, uint32_t *data_len)
int32_t usbh_hid_stop_int_write(HID_DEV_T *hdev, uint8_t ep_addr)
stop purge the USB interrupt out transfer.
int32_t usbh_hid_set_protocol(HID_DEV_T *hdev, uint8_t protocol)
Issue a HID class SET_PROTOCOL request. The SET_PROTOCOL switches between the boot protocol and the r...
int32_t usbh_hid_stop_int_read(HID_DEV_T *hdev, uint8_t ep_addr)
Stop purge the USB interrupt in transfer.
int32_t usbh_hid_set_report(HID_DEV_T *hdev, int rtp_typ, int rtp_id, uint8_t *data, int len)
Issue a HID class SET_REPORT request. The Set_Report request allows the host to send a report to the ...
int32_t usbh_hid_get_report(HID_DEV_T *hdev, int rtp_typ, int rtp_id, uint8_t *data, int len)
Issue a HID class GET_REPORT request.
HIDDEN_SYMBOLS int32_t usbh_hid_start_int_read(HID_DEV_T *hdev, uint8_t ep_addr, HID_IR_FUNC *func)
Start purge the USB interrupt in transfer.
int32_t usbh_hid_get_report_descriptor(HID_DEV_T *hdev, uint8_t *desc_buf, int buf_max_len)
Read report descriptor from HID device.
int32_t usbh_hid_set_idle(HID_DEV_T *hdev, int rtp_id, uint8_t idle_rate)
Issue a HID class SET_IDLE request. The SET_IDLE request silences a particular report on the Interrup...
int32_t usbh_hid_get_protocol(HID_DEV_T *hdev, uint8_t *protocol)
Issue a HID class GET_PROTOCOL request. The GET_PROTOCOL request reads which protocol is currently ac...
HIDDEN_SYMBOLS int32_t usbh_hid_get_idle(HID_DEV_T *hdev, int rtp_id, uint8_t *idle_rate)
Issue a HID class GET_IDLE request. The GET_IDLE request reads the current idle rate for a particular...
int32_t usbh_hid_start_int_write(HID_DEV_T *hdev, uint8_t ep_addr, HID_IW_FUNC *func)
Start purge the USB interrupt out transfer.
M480 MCU USB Host HID report descriptor parser.
USB Host library header file.
USB Host HID class driver header file.
USB Host library exported header file.