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