NUC472_NUC442_BSP V3.03.005
The Board Support Package for NUC472/NUC442
usbh_support.c
Go to the documentation of this file.
1/******************************************************************************
2 * @file usbh_ohci.c
3 * @version V1.00
4 * $Revision: 10 $
5 * $Date: 14/10/07 5:47p $
6 * @brief NUC472/NUC442 MCU USB Host OHCI driver
7 *
8 * @note
9 * SPDX-License-Identifier: Apache-2.0
10 * Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
11*****************************************************************************/
12#include <stdio.h>
13#include <string.h>
14
15#include "NUC472_442.h"
16#include "usbh_core.h"
17#include "usbh_hub.h"
18#include "usbh_ohci.h"
19
20
34
35#ifdef __ICCARM__
36#pragma data_alignment=32
37static ED_T g_ed_pool[ED_MAX_NUM];
38#pragma data_alignment=32
39static TD_T g_td_pool[TD_MAX_NUM];
40static URB_T g_urb_pool[URB_MAX_NUM];
41#else
42static ED_T g_ed_pool[ED_MAX_NUM] __attribute__((aligned(32)));
43static TD_T g_td_pool[TD_MAX_NUM] __attribute__((aligned(32)));
44static URB_T g_urb_pool[URB_MAX_NUM] __attribute__((aligned(32)));
45#endif
46
47USB_DEV_T g_dev_pool[DEV_MAX_NUM];
48static USB_HUB_T g_hub_pool[MAX_HUB_DEVICE];
49
50static uint8_t ed_alloc_mark[ED_MAX_NUM];
51static uint8_t td_alloc_mark[TD_MAX_NUM];
52USB_DEV_T * td_alloc_dev[TD_MAX_NUM];
53uint8_t dev_alloc_mark[DEV_MAX_NUM];
54static uint8_t urb_alloc_mark[URB_MAX_NUM];
55static uint8_t hub_alloc_mark[MAX_HUB_DEVICE];
56
57int _td_cnt, _ed_cnt;
58
59void usbh_init_memory()
60{
61 int i;
62
63 for (i = 0; i < ED_MAX_NUM; i++)
64 ed_alloc_mark[i] = 0;
65 _ed_cnt = ED_MAX_NUM;
66
67 for (i = 0; i < TD_MAX_NUM; i++)
68 td_alloc_mark[i] = 0;
69 _td_cnt = TD_MAX_NUM;
70
71 for (i = 0; i < DEV_MAX_NUM; i++)
72 dev_alloc_mark[i] = 0;
73
74 for (i = 0; i < URB_MAX_NUM; i++)
75 urb_alloc_mark[i] = 0;
76
77 for (i = 0; i < MAX_HUB_DEVICE; i++)
78 hub_alloc_mark[i] = 0;
79}
80
82
83
91{
92 int i;
93
94 for (i = 0; i < URB_MAX_NUM; i++)
95 {
96 if (urb_alloc_mark[i] == 0)
97 {
98 urb_alloc_mark[i] = 1;
99 memset((char *)&g_urb_pool[i], 0, sizeof(URB_T));
100 return &g_urb_pool[i];
101 }
102 }
103 USB_error("USBH_AllocUrb failed!\n");
104 return NULL;
105}
106
107
114{
115 int i;
116
117 for (i = 0; i < URB_MAX_NUM; i++)
118 {
119 if (&g_urb_pool[i] == urb)
120 {
121 urb_alloc_mark[i] = 0;
122 return;
123 }
124 }
125 USB_error("USBH_FreeUrb - missed!\n");
126}
127
128
130
131void usbh_free_dev_urbs(USB_DEV_T *dev)
132{
133 int i;
134
135 for (i = 0; i < URB_MAX_NUM; i++)
136 {
137 if (urb_alloc_mark[i])
138 {
139 if (g_urb_pool[i].dev == dev)
140 {
141 USBH_UnlinkUrb(&g_urb_pool[i]);
142 urb_alloc_mark[i] = 0;
143 }
144 }
145 }
146}
147
148
149ED_T * ohci_alloc_ed()
150{
151 int i;
152
153 for (i = 0; i < ED_MAX_NUM; i++)
154 {
155 if (ed_alloc_mark[i] == 0)
156 {
157 ed_alloc_mark[i] = 1;
158 memset((char *)&g_ed_pool[i], 0, sizeof(ED_T));
159 _ed_cnt--;
160 return &g_ed_pool[i];
161 }
162 }
163 USB_error("ohci_alloc_ed failed!\n");
164 return NULL;
165}
166
167
168void ohci_free_ed(ED_T *ed_p)
169{
170 int i;
171
172 for (i = 0; i < ED_MAX_NUM; i++)
173 {
174 if (&g_ed_pool[i] == ed_p)
175 {
176 ed_alloc_mark[i] = 0;
177 _ed_cnt++;
178 return;
179 }
180 }
181 USB_error("ohci_free_ed - missed!\n");
182}
183
184
185TD_T * ohci_alloc_td(USB_DEV_T *dev)
186{
187 int i;
188
189 for (i = 0; i < TD_MAX_NUM; i++)
190 {
191 if (td_alloc_mark[i] == 0)
192 {
193 td_alloc_mark[i] = 1;
194 td_alloc_dev[i] = dev;
195 memset((char *)&g_td_pool[i], 0, sizeof(TD_T));
196 _td_cnt--;
197 return &g_td_pool[i];
198 }
199 }
200 USB_error("ohci_alloc_td failed!\n");
201 return NULL;
202}
203
204
205void ohci_free_td(TD_T *td_p)
206{
207 int i;
208
209 for (i = 0; i < TD_MAX_NUM; i++)
210 {
211 if ((&g_td_pool[i] == td_p) && (td_alloc_mark[i]))
212 {
213 _td_cnt++;
214 td_alloc_mark[i] = 0;
215 return;
216 }
217 }
218}
219
220
221void ohci_free_dev_td(USB_DEV_T *dev)
222{
223 int i;
224 for (i = 0; i < TD_MAX_NUM; i++)
225 {
226 if ((td_alloc_mark[i]) && (td_alloc_dev[i] == dev))
227 {
228 _td_cnt++;
229 td_alloc_mark[i] = 0;
230 return;
231 }
232 }
233}
234
235
236/*
237 * Only HC's should call usbh_alloc_device and usbh_free_device directly
238 * Anybody may use USB_IncreaseDeviceUser or usb_dec_dev_use
239 */
240USB_DEV_T *usbh_alloc_device(USB_DEV_T *parent, USB_BUS_T *bus)
241{
242 int i;
243 USB_DEV_T *dev;
244
245 for (i = 0; i < DEV_MAX_NUM; i++)
246 {
247 if (dev_alloc_mark[i] == 0)
248 {
249 dev_alloc_mark[i] = 1;
250 dev = &g_dev_pool[i];
251 memset((char *)dev, 0, sizeof(*dev));
252 dev->act_config = -1;
253 dev->parent = parent;
254 dev->bus = bus;
255 if (dev->bus->op->allocate(dev) != 0)
256 {
257 dev_alloc_mark[i] = 0;
258 return NULL;
259 }
260 return dev;
261 }
262 }
263 USB_error("usbh_alloc_device failed!\n");
264 return NULL;
265}
266
267
268void usbh_free_device(USB_DEV_T *dev)
269{
270 int i, j;
271 OHCI_DEVICE_T *ohcidev;
272
273 dev->bus->op->deallocate(dev);
274 for (i = 0; i < DEV_MAX_NUM; i++)
275 {
276 if (&g_dev_pool[i] == dev)
277 {
278 ohcidev = usb_to_ohci(dev);
279 for (j = 0; j < NUM_EDS; j++)
280 {
281 if (ohcidev->edp[j] != NULL)
282 ohci_free_ed(ohcidev->edp[j]);
283 }
284 dev_alloc_mark[i] = 0;
285 return;
286 }
287 }
288 USB_error("usbh_free_device - missed!\n");
289}
290
291
292USB_HUB_T * usbh_alloc_hubdev()
293{
294 int i;
295
296 for (i = 0; i < MAX_HUB_DEVICE; i++)
297 {
298 if (hub_alloc_mark[i] == 0)
299 {
300 hub_alloc_mark[i] = 1;
301 memset((char *)&g_hub_pool[i], 0, sizeof(USB_HUB_T));
302 return &g_hub_pool[i];
303 }
304 }
305 USB_error("usbh_alloc_hubdev failed!\n");
306 return NULL;
307}
308
309
310void usbh_free_hubdev(USB_HUB_T *hub)
311{
312 int i;
313
314 for (i = 0; i < MAX_HUB_DEVICE; i++)
315 {
316 if (&g_hub_pool[i] == hub)
317 {
318 hub_alloc_mark[i] = 0;
319 return;
320 }
321 }
322 USB_error("ohci_free_ed - missed!\n");
323}
324
325
326USB_HUB_T * usbh_get_hub_by_dev(USB_DEV_T *dev)
327{
328 int i;
329
330 for (i = 0; i < MAX_HUB_DEVICE; i++)
331 {
332 if (hub_alloc_mark[i])
333 {
334 if (g_hub_pool[i].dev == dev)
335 return &g_hub_pool[i];
336 }
337 }
338 return NULL;
339}
340
341
342/*-------------------------------------------------------------------------
343 * Milisecond delay
344 *-------------------------------------------------------------------------*/
345
346void usbh_mdelay(uint32_t msec)
347{
348 volatile uint32_t t0;
349 volatile uint32_t frame_no;
350
351 if ((USBH->HcControl & 0xC0) == 0x40)
352 {
353 /* OHCI in operational state */
354 for (t0 = 0; t0 < msec; t0++)
355 {
356 frame_no = USBH->HcFmNumber;
357 while (USBH->HcFmNumber == frame_no) ;
358 }
359 }
360 else
361 {
362 for (t0 = 0; t0 < msec * 0x1000; t0++) ;
363 }
364}
365
367
368 /* end of group NUC472_442_USBH_EXPORTED_FUNCTIONS */
370 /* end of group NUC472_442_USBH_Driver */
372 /* end of group NUC472_442_Device_Driver */
374
375/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/
376
377
void *__dso_handle __attribute__((weak))
Definition: _syscalls.c:35
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
#define USBH
Definition: NUC472_442.h:28818
#define DEV_MAX_NUM
Definition: usbh_config.h:48
#define MAX_HUB_DEVICE
Definition: usbh_config.h:56
#define URB_MAX_NUM
Definition: usbh_config.h:49
#define ED_MAX_NUM
Definition: usbh_config.h:50
#define TD_MAX_NUM
Definition: usbh_config.h:51
int32_t USBH_UnlinkUrb(URB_T *urb)
Cancel an URB which has been submit to USB core.
Definition: usbh_core.c:236
URB_T * USBH_AllocUrb(void)
Allocate an URB from USB Core driver internal URB pool.
Definition: usbh_support.c:90
void USBH_FreeUrb(URB_T *)
Free the URB allocated from USBH_AllocUrb()
Definition: usbh_support.c:113
HIDDEN_SYMBOLS struct usb_device USB_DEV_T
#define NULL
NULL pointer.
Definition: NUC472_442.h:29018
USB Host core driver header file.