M471M/R1/S BSP V3.01.000
The Board Support Package for M4521
cdc_driver.c
Go to the documentation of this file.
1/**************************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "NuMicro.h"
14
15#include "usb.h"
16#include "usbh_lib.h"
17#include "usbh_cdc.h"
18
19
21
22extern int cdc_config_parser(CDC_DEV_T *cdev);
23
24static CDC_DEV_T *g_cdev_list = NULL;
25
26static CDC_DEV_T *alloc_cdc_device(void)
27{
28 CDC_DEV_T *cdev;
29
30 cdev = (CDC_DEV_T *)usbh_alloc_mem(sizeof(CDC_DEV_T));
31 if(cdev == NULL)
32 return NULL;
33
34 memset((char *)cdev, 0, sizeof(CDC_DEV_T));
35 cdev->ifnum_data = -1;
36 return cdev;
37}
38
39void free_cdc_device(CDC_DEV_T *cdev)
40{
41 usbh_free_mem(cdev, sizeof(CDC_DEV_T));
42}
43
44static void add_new_cdc_device(CDC_DEV_T *cdev)
45{
46 if(g_cdev_list == NULL)
47 {
48 cdev->next = NULL;
49 g_cdev_list = cdev;
50 }
51 else
52 {
53 cdev->next = g_cdev_list;
54 g_cdev_list = cdev;
55 }
56}
57
58static void remove_cdc_device(CDC_DEV_T *cdev)
59{
60 CDC_DEV_T *p;
61
62 if(g_cdev_list == cdev)
63 {
64 g_cdev_list = g_cdev_list->next;
65 return;
66 }
67
68 p = g_cdev_list;
69 while(p != NULL)
70 {
71 if(p->next == cdev)
72 {
73 p->next = cdev->next;
74 return;
75 }
76 p = p->next;
77 }
78 CDC_DBGMSG("Warning! remove_cdc_device 0x%x not found!\n", (int)cdev);
79}
80
81/*
82 * Try to find the companion CDC interface of a DATA interface.
83 */
84static CDC_DEV_T * find_cdc_com_iface(IFACE_T *iface_data)
85{
86 CDC_DEV_T *p;
87
88 p = g_cdev_list;
89 while(p != NULL)
90 {
91 if(p->ifnum_data == iface_data->if_num)
92 {
93 return p;
94 }
95 p = p->next;
96 }
97 return NULL;
98}
99
100/*
101 * Try to find any temporary CDC device holder of data interface
102 */
103static CDC_DEV_T * find_cdc_data_iface(int ifnum)
104{
105 CDC_DEV_T *p;
106
107 p = g_cdev_list;
108 while(p != NULL)
109 {
110 if((p->iface_cdc == NULL) && (p->iface_data != NULL) &&
111 (p->ifnum_data == ifnum))
112 {
113 return p;
114 }
115 p = p->next;
116 }
117 return NULL;
118}
119
120static int cdc_probe(IFACE_T *iface)
121{
122 UDEV_T *udev = iface->udev;
123 ALT_IFACE_T *aif = iface->aif;
124 DESC_IF_T *ifd;
125 CDC_DEV_T *cdev, *d;
126 int ret;
127
128 ifd = aif->ifd;
129
130 /* Is this interface CDC class? */
131 if((ifd->bInterfaceClass != USB_CLASS_COMM) && (ifd->bInterfaceClass != USB_CLASS_DATA))
133
134 CDC_DBGMSG("cdc_probe %s - device (vid=0x%x, pid=0x%x), interface %d.\n",
135 (ifd->bInterfaceClass == USB_CLASS_COMM) ? "COMM" : "DATA",
136 udev->descriptor.idVendor, udev->descriptor.idProduct, ifd->bInterfaceNumber);
137
138 if(ifd->bInterfaceClass == USB_CLASS_DATA)
139 {
140 cdev = find_cdc_com_iface(iface); /* If this CDC device may have been created in the previous inetrface probing? */
141 if(cdev == NULL)
142 {
143 CDC_DBGMSG("Warning! CDC device DTAT interface %d cannot find COMM interface!\n", iface->if_num);
144
145 /* create a temporary CDC device holder */
146 cdev = alloc_cdc_device();
147 if(cdev == NULL)
148 return USBH_ERR_NOT_FOUND;
149
150 cdev->udev = udev;
151 add_new_cdc_device(cdev);
152 cdev->ifnum_data = iface->if_num;
153 }
154 cdev->iface_data = iface;
155 iface->context = cdev;
156 return 0;
157 }
158
159 /*------- Is CDC COMM interface ----------*/
160
161 cdev = alloc_cdc_device();
162 if(cdev == NULL)
163 return USBH_ERR_NOT_FOUND;
164
165 cdev->udev = udev;
166 cdev->iface_cdc = iface;
167 iface->context = (void *)cdev;
168
169 ret = cdc_config_parser(cdev);
170 if(ret != 0)
171 {
172 CDC_DBGMSG("Parsing CDC desceiptor failed! 0x%x\n", ret);
173 free_cdc_device(cdev);
174 return -1;
175 }
176
177 add_new_cdc_device(cdev);
178
179 /* find temporary CDC device holder of data interface */
180 d = find_cdc_data_iface(cdev->ifnum_data); /* If this CDC device may have been created in the previous inetrface probing? */
181 if(d)
182 {
183 cdev->iface_data = d->iface_data;
184 cdev->iface_data->context = cdev;
185 remove_cdc_device(d);
186 free_cdc_device(d);
187 }
188
189 return 0;
190}
191
192static void cdc_disconnect(IFACE_T *iface)
193{
194 IFACE_T *if_cdc, *if_data;
195 CDC_DEV_T *cdev;
196 int i;
197
198 CDC_DBGMSG("CDC device interface %d disconnected!\n", iface->if_num);
199
200 cdev = (CDC_DEV_T *)(iface->context);
201
202 if(cdev == NULL)
203 return; /* should have been disconnected. */
204
205 if_cdc = cdev->iface_cdc;
206 if_data = cdev->iface_data;
207
208 /*
209 * Quit transfers of all endpoints of COMM and DATA interface.
210 */
211 if(if_cdc)
212 {
213 for(i = 0; i < if_cdc->aif->ifd->bNumEndpoints; i++)
214 {
215 if_cdc->udev->hc_driver->quit_xfer(NULL, &(if_cdc->aif->ep[i]));
216 }
217 }
218
219 if(if_data)
220 {
221 for(i = 0; i < if_data->aif->ifd->bNumEndpoints; i++)
222 {
223 if_data->udev->hc_driver->quit_xfer(NULL, &(if_data->aif->ep[i]));
224 }
225 }
226
227 if(cdev->utr_sts)
228 {
229 usbh_quit_utr(cdev->utr_sts); /* Quit the UTR */
230 free_utr(cdev->utr_sts);
231 cdev->utr_sts = NULL;
232 }
233 if(cdev->utr_rx)
234 {
235 usbh_quit_utr(cdev->utr_rx); /* Quit the UTR */
236 free_utr(cdev->utr_rx);
237 cdev->utr_rx = NULL;
238 }
239
240 if_cdc->context = NULL;
241 if_data->context = NULL;
242
243 remove_cdc_device(cdev);
244 free_cdc_device(cdev);
245}
246
247
248static UDEV_DRV_T cdc_driver =
249{
250 cdc_probe,
251 cdc_disconnect,
252 NULL,
253 NULL,
254};
255
256
258
259
265{
266 g_cdev_list = NULL;
267 usbh_register_driver(&cdc_driver);
268}
269
270
280{
281 return g_cdev_list;
282}
283
284
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 USBH_ERR_NOT_FOUND
Definition: usbh_lib.h:38
void usbh_cdc_init(void)
Init USB Host CDC driver.
Definition: cdc_driver.c:264
CDC_DEV_T * usbh_cdc_get_device_list(void)
Get a list of currently connected USB Hid devices.
Definition: cdc_driver.c:279
int ifnum_data
Definition: usbh_cdc.h:179
IFACE_T * iface_data
Definition: usbh_cdc.h:178
UDEV_T * udev
Definition: usbh_cdc.h:176
IFACE_T * iface_cdc
Definition: usbh_cdc.h:177
UTR_T * utr_sts
Definition: usbh_cdc.h:183
struct cdc_dev_t * next
Definition: usbh_cdc.h:190
UTR_T * utr_rx
Definition: usbh_cdc.h:184
USB Host library header file.
USB Host CDC(Communication Device Class) driver header file.
USB Host library exported header file.