| M480 BSP V3.05.001 The Board Support Package for M480 Series

hid_driver.c
Go to the documentation of this file.
1 /**************************************************************************/
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "NuMicro.h"
14
15 #include "usb.h"
16 #include "usbh_lib.h"
17 #include "usbh_hid.h"
18
19
21
22 extern int hid_parse_report_descriptor(HID_DEV_T *hdev, IFACE_T *iface);
23
24 static HID_DEV_T g_hid_dev[CONFIG_HID_MAX_DEV];
25
26 static HID_DEV_T *g_hdev_list = NULL;
27
28 static HID_DEV_T *alloc_hid_device(void)
29 {
30 int i;
31
32 for (i = 0; i < CONFIG_HID_MAX_DEV; i++)
33 {
34 if (g_hid_dev[i].iface == NULL)
35 {
36 memset((char *)&g_hid_dev[i], 0, sizeof(HID_DEV_T));
37 g_hid_dev[i].uid = get_ticks();
38 return &g_hid_dev[i];
39 }
40 }
41 return NULL;
42 }
43
44 void free_hid_device(HID_DEV_T *hid_dev)
45 {
46 hid_dev->iface = NULL;
47 memset((char *)hid_dev, 0, sizeof(HID_DEV_T));
48 }
49
50
51 static int hid_probe(IFACE_T *iface)
52 {
53 UDEV_T *udev = iface->udev;
54 ALT_IFACE_T *aif = iface->aif;
55 DESC_IF_T *ifd;
56 EP_INFO_T *ep;
57 HID_DEV_T *hdev, *p;
58 int i;
59
60 ifd = aif->ifd;
61
62 /* Is this interface HID class? */
63 if (ifd->bInterfaceClass != USB_CLASS_HID)
64 return USBH_ERR_NOT_MATCHED;
65
66 HID_DBGMSG("hid_probe - device (vid=0x%x, pid=0x%x), interface %d, subclass 0x%x, protocol 0x%x.\n",
67 udev->descriptor.idVendor, udev->descriptor.idProduct, ifd->bInterfaceNumber,
68 ifd->bInterfaceSubClass, ifd->bInterfaceProtocol);
69
70 /*
71 * Try to find any interrupt endpoints
72 */
73 for (i = 0; i < aif->ifd->bNumEndpoints; i++)
74 {
75 if ((aif->ep[i].bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_INT)
76 {
77 ep = &aif->ep[i];
78 break;
79 }
80 }
81
82 if (ep == NULL)
83 return USBH_ERR_NOT_MATCHED; // No endpoints, Ignore this interface
84
85 hdev = alloc_hid_device();
86 if (hdev == NULL)
87 return HID_RET_OUT_OF_MEMORY;
88
89 hdev->iface = iface;
90 hdev->idVendor = udev->descriptor.idVendor;
91 hdev->idProduct = udev->descriptor.idProduct;
92 hdev->bSubClassCode = ifd->bInterfaceSubClass;
93 hdev->bProtocolCode = ifd->bInterfaceProtocol;
94 hdev->next = NULL;
95 iface->context = (void *)hdev;
96
97 hid_parse_report_descriptor(hdev, iface);
98
99 /*
100 * Chaining newly found HID device to end of HID device list.
101 */
102 if (g_hdev_list == NULL)
103 g_hdev_list = hdev;
104 else
105 {
106 for (p = g_hdev_list; p->next != NULL; p = p->next)
107 ;
108 p->next = hdev;
109 }
110
111 HID_DBGMSG("usbhid_probe OK. hdev=0x%x\n", (int)hdev);
112
113 return 0;
114 }
115
116
117 static void hid_disconnect(IFACE_T *iface)
118 {
119 HID_DEV_T *hdev, *p;
120 UTR_T *utr;
121 RP_INFO_T *rp, *next_rp;
122 int i;
123
124 hdev = (HID_DEV_T *)(iface->context);
125
126 for (i = 0; i < iface->aif->ifd->bNumEndpoints; i++)
127 {
128 iface->udev->hc_driver->quit_xfer(NULL, &(iface->aif->ep[i]));
129 }
130
131 /*
132 * Abort all UTR of this HID device (interface)
133 */
134 for (i = 0; i < CONFIG_HID_DEV_MAX_PIPE; i++)
135 {
136 utr = hdev->utr_list[i];
137 if (utr != NULL)
138 {
139 usbh_quit_utr(utr); /* Quit the UTR */
140 usbh_free_mem(utr->buff, utr->ep->wMaxPacketSize);
141 free_utr(utr);
142 }
143 }
144
145 if (hdev->rpd.utr_led != NULL)
146 {
147 usbh_quit_utr(hdev->rpd.utr_led); /* Quit the UTR */
148 free_utr(hdev->rpd.utr_led);
149 }
150
151 if (hdev->rpd.report != NULL)
152 {
153 for (rp = hdev->rpd.report; rp != NULL; )
154 {
155 next_rp = rp->next;
156 usbh_free_mem(rp, sizeof(RP_INFO_T));
157 rp = next_rp;
158 };
159 }
160
161 /*
162 * remove it from HID device list
163 */
164 for (i = 0; i < CONFIG_HID_MAX_DEV; i++)
165 {
166 if (g_hid_dev[i].iface == iface)
167 {
168 hdev = &g_hid_dev[i];
169
170 if (hdev == g_hdev_list)
171 {
172 g_hdev_list = g_hdev_list->next;
173 }
174 else
175 {
176 for (p = g_hdev_list; p != NULL; p = p->next)
177 {
178 if (p->next == hdev)
179 {
180 p->next = hdev->next;
181 break;
182 }
183 }
184 }
185 HID_DBGMSG("hid_disconnect - device (vid=0x%x, pid=0x%x), interface %d.\n",
186 hdev->idVendor, hdev->idProduct, iface->if_num);
187 free_hid_device(hdev);
188 }
189 }
190 }
191
192
193 UDEV_DRV_T hid_driver =
194 {
195 hid_probe,
196 hid_disconnect,
197 NULL, /* suspend */
198 NULL, /* resume */
199 };
200
201
203
204
209 void usbh_hid_init(void)
210 {
211 memset((char *)&g_hid_dev[0], 0, sizeof(g_hid_dev));
212 g_hdev_list = NULL;
213 usbh_register_driver(&hid_driver);
214 }
215
216
225 HID_DEV_T * usbh_hid_get_device_list(void)
226 {
227 return g_hdev_list;
228 }
229
230
231 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
232
usbh_hid_get_device_list
HID_DEV_T * usbh_hid_get_device_list(void)
Get a list of currently connected USB Hid devices.
Definition: hid_driver.c:225
NuMicro.h
NuMicro peripheral access layer header file.
usbh_hid_init
void usbh_hid_init(void)
Initialize USB Host HID driver.
Definition: hid_driver.c:209
usbh_hid.h
USB Host HID class driver header file.
usbh_lib.h
USB Host library exported header file.
get_ticks
uint32_t get_ticks(void)
A function return current tick count.
uac_dev_t::udev
UDEV_T * udev
Definition: usbh_uac.h:111
usb.h
USB Host library header file.
HID_RET_OUT_OF_MEMORY
#define HID_RET_OUT_OF_MEMORY
Definition: usbh_lib.h:89
CONFIG_HID_DEV_MAX_PIPE
#define CONFIG_HID_DEV_MAX_PIPE
Definition: usbh_hid.h:53
NULL
#define NULL
NULL pointer.
Definition: M480.h:604
USBH_ERR_NOT_MATCHED
#define USBH_ERR_NOT_MATCHED
Definition: usbh_lib.h:36
CONFIG_HID_MAX_DEV
#define CONFIG_HID_MAX_DEV
Definition: usbh_hid.h:52
HID_DEV_T
HIDDEN_SYMBOLS struct usbhid_dev HID_DEV_T