1 /**************************************************************************//**
2 *
3 * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date Author Notes
9 * 2020-09-17 CHChen First version
10 * 2023-10-11 ChuShicheng change rt_size_t to rt_ssize_t
11 *
12 ******************************************************************************/
13
14 #include <rtconfig.h>
15
16 #ifdef BSP_USING_USBD
17 #include <rtthread.h>
18 #include <rtdevice.h>
19 #include <string.h>
20 #include "NuMicro.h"
21
22 #define LOG_TAG "drv.usbd"
23 #define DBG_ENABLE
24 #define DBG_SECTION_NAME "drv.usbd"
25 #define DBG_LEVEL DBG_ERROR
26 #define DBG_COLOR
27 #include <rtdbg.h>
28
29 /* Private define ---------------------------------------------------------------*/
30 /* Define EP maximum packet size */
31 #define EP0_MAX_PKT_SIZE 64
32 #define EP1_MAX_PKT_SIZE EP0_MAX_PKT_SIZE /* EP0 and EP1 are assigned the same size for control endpoint */
33 #define EP2_MAX_PKT_SIZE 64
34 #define EP3_MAX_PKT_SIZE 64
35 #define EP4_MAX_PKT_SIZE 64
36 #define EP5_MAX_PKT_SIZE 64
37 #define EP6_MAX_PKT_SIZE 64
38 #define EP7_MAX_PKT_SIZE 64
39 #define EP8_MAX_PKT_SIZE 64
40 #define EP9_MAX_PKT_SIZE 64
41 #define EP10_MAX_PKT_SIZE 64
42 #define EP11_MAX_PKT_SIZE 64
43
44 #define SETUP_BUF_BASE 0
45 #define SETUP_BUF_LEN 8
46 #define EP0_BUF_BASE (SETUP_BUF_BASE + SETUP_BUF_LEN)
47 #define EP0_BUF_LEN EP0_MAX_PKT_SIZE
48
49 #define EP1_BUF_BASE (SETUP_BUF_BASE + SETUP_BUF_LEN)
50 #define EP1_BUF_LEN EP1_MAX_PKT_SIZE
51 #define EP2_BUF_BASE (EP1_BUF_BASE + EP1_BUF_LEN)
52 #define EP2_BUF_LEN EP2_MAX_PKT_SIZE
53 #define EP3_BUF_BASE (EP2_BUF_BASE + EP2_BUF_LEN)
54 #define EP3_BUF_LEN EP3_MAX_PKT_SIZE
55 #define EP4_BUF_BASE (EP3_BUF_BASE + EP3_BUF_LEN)
56 #define EP4_BUF_LEN EP4_MAX_PKT_SIZE
57 #define EP5_BUF_BASE (EP4_BUF_BASE + EP4_BUF_LEN)
58 #define EP5_BUF_LEN EP5_MAX_PKT_SIZE
59 #define EP6_BUF_BASE (EP5_BUF_BASE + EP5_BUF_LEN)
60 #define EP6_BUF_LEN EP6_MAX_PKT_SIZE
61 #define EP7_BUF_BASE (EP6_BUF_BASE + EP6_BUF_LEN)
62 #define EP7_BUF_LEN EP7_MAX_PKT_SIZE
63 #define EP8_BUF_BASE (EP7_BUF_BASE + EP7_BUF_LEN)
64 #define EP8_BUF_LEN EP8_MAX_PKT_SIZE
65 #define EP9_BUF_BASE (EP8_BUF_BASE + EP8_BUF_LEN)
66 #define EP9_BUF_LEN EP9_MAX_PKT_SIZE
67 #define EP10_BUF_BASE (EP9_BUF_BASE + EP9_BUF_LEN)
68 #define EP10_BUF_LEN EP10_MAX_PKT_SIZE
69 #define EP11_BUF_BASE (EP10_BUF_BASE + EP10_BUF_LEN)
70 #define EP11_BUF_LEN EP11_MAX_PKT_SIZE
71
72 #define EPADR_SW2HW(address) ((((address & USB_EPNO_MASK) * 2) + (!(address & USB_DIR_IN))))
73 #define EPADR_HW2SW(address) ((address & USB_EPNO_MASK) / 2)
74 /* Private typedef --------------------------------------------------------------*/
75 typedef struct _nu_usbd_t
76 {
77 USBD_T *Instance; /* REG base */
78 uint8_t address_tmp; /* Keep assigned address for flow control */
79 } nu_usbd_t;
80
81
82 /* Private variables ------------------------------------------------------------*/
83 static nu_usbd_t nu_usbd =
84 {
85 .Instance = USBD,
86 .address_tmp = 0,
87 };
88
89 static struct udcd _rt_obj_udc;
90
91 static struct ep_id _ep_pool[] =
92 {
93 {EPADR_HW2SW(EP0), USB_EP_ATTR_CONTROL, USB_DIR_INOUT, EP0_MAX_PKT_SIZE, ID_ASSIGNED },
94 {EPADR_HW2SW(EP2), USB_EP_ATTR_BULK, USB_DIR_IN, EP2_MAX_PKT_SIZE, ID_UNASSIGNED},
95 {EPADR_HW2SW(EP3), USB_EP_ATTR_BULK, USB_DIR_OUT, EP3_MAX_PKT_SIZE, ID_UNASSIGNED},
96 {EPADR_HW2SW(EP4), USB_EP_ATTR_INT, USB_DIR_IN, EP4_MAX_PKT_SIZE, ID_UNASSIGNED},
97 {EPADR_HW2SW(EP5), USB_EP_ATTR_INT, USB_DIR_OUT, EP5_MAX_PKT_SIZE, ID_UNASSIGNED},
98 {EPADR_HW2SW(EP6), USB_EP_ATTR_BULK, USB_DIR_IN, EP6_MAX_PKT_SIZE, ID_UNASSIGNED},
99 {EPADR_HW2SW(EP7), USB_EP_ATTR_BULK, USB_DIR_OUT, EP7_MAX_PKT_SIZE, ID_UNASSIGNED},
100 {EPADR_HW2SW(EP8), USB_EP_ATTR_INT, USB_DIR_IN, EP8_MAX_PKT_SIZE, ID_UNASSIGNED},
101 {EPADR_HW2SW(EP9), USB_EP_ATTR_INT, USB_DIR_OUT, EP9_MAX_PKT_SIZE, ID_UNASSIGNED},
102 {EPADR_HW2SW(EP10), USB_EP_ATTR_BULK, USB_DIR_IN, EP6_MAX_PKT_SIZE, ID_UNASSIGNED},
103 {EPADR_HW2SW(EP11), USB_EP_ATTR_BULK, USB_DIR_OUT, EP7_MAX_PKT_SIZE, ID_UNASSIGNED},
104 {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
105 };
106
_nu_ep_partition(void)107 static void _nu_ep_partition(void)
108 {
109 /* Init setup packet buffer */
110 /* Buffer range for setup packet -> [0 ~ 0x7] */
111 USBD->STBUFSEG = SETUP_BUF_BASE;
112
113 /*****************************************************/
114 /* EP0 ==> control IN endpoint, address 0 */
115 USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP0));
116 /* Buffer range for EP0 */
117 USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE);
118
119 /* EP1 ==> control OUT endpoint, address 0 */
120 USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP1));
121 /* Buffer range for EP1 */
122 USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE);
123
124 /*****************************************************/
125 /* EP2 ==> Bulk IN endpoint, address 1 */
126 USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP2));
127 /* Buffer range for EP2 */
128 USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE);
129
130 /* EP3 ==> Bulk OUT endpoint, address 1 */
131 USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP3));
132 /* Buffer range for EP3 */
133 USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE);
134
135 /*****************************************************/
136 /* EP4 ==> Interrupt IN endpoint, address 2 */
137 USBD_CONFIG_EP(EP4, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP4));
138 /* Buffer range for EP4 */
139 USBD_SET_EP_BUF_ADDR(EP4, EP4_BUF_BASE);
140
141 /* EP5 ==> Interrupt Out endpoint, address 2 */
142 USBD_CONFIG_EP(EP5, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP5));
143 /* Buffer range for EP5 */
144 USBD_SET_EP_BUF_ADDR(EP5, EP5_BUF_BASE);
145
146 /*****************************************************/
147 /* EP6 ==> Bulk IN endpoint, address 3 */
148 USBD_CONFIG_EP(EP6, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP6));
149 /* Buffer range for EP4 */
150 USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE);
151
152 /* EP7 ==> Bulk Out endpoint, address 3 */
153 USBD_CONFIG_EP(EP7, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP7));
154 /* Buffer range for EP5 */
155 USBD_SET_EP_BUF_ADDR(EP7, EP7_BUF_BASE);
156
157 /*****************************************************/
158 /* EP8 ==> Interrupt IN endpoint, address 4 */
159 USBD_CONFIG_EP(EP8, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP8));
160 /* Buffer range for EP4 */
161 USBD_SET_EP_BUF_ADDR(EP8, EP8_BUF_BASE);
162
163 /* EP9 ==> Interrupt Out endpoint, address 4 */
164 USBD_CONFIG_EP(EP9, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP9));
165 /* Buffer range for EP9 */
166 USBD_SET_EP_BUF_ADDR(EP9, EP9_BUF_BASE);
167
168 /*****************************************************/
169 /* EP10 ==> Bulk IN endpoint, address 5 */
170 USBD_CONFIG_EP(EP10, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP10));
171 /* Buffer range for EP10 */
172 USBD_SET_EP_BUF_ADDR(EP10, EP10_BUF_BASE);
173
174 /* EP11 ==> Bulk Out endpoint, address 5 */
175 USBD_CONFIG_EP(EP11, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP11));
176 /* Buffer range for EP11 */
177 USBD_SET_EP_BUF_ADDR(EP11, EP11_BUF_BASE);
178
179 }
180
_ep_set_stall(rt_uint8_t address)181 static rt_err_t _ep_set_stall(rt_uint8_t address)
182 {
183 USBD_SET_EP_STALL(EPADR_SW2HW(address));
184 return RT_EOK;
185 }
186
_ep_clear_stall(rt_uint8_t address)187 static rt_err_t _ep_clear_stall(rt_uint8_t address)
188 {
189 USBD_ClearStall(EPADR_SW2HW(address));
190
191 return RT_EOK;
192 }
193
194
_set_address(rt_uint8_t address)195 static rt_err_t _set_address(rt_uint8_t address)
196 {
197 if (0 != address)
198 {
199 nu_usbd.address_tmp = address;
200 }
201
202 return RT_EOK;
203 }
204
_set_config(rt_uint8_t address)205 static rt_err_t _set_config(rt_uint8_t address)
206 {
207 return RT_EOK;
208 }
209
_ep_enable(uep_t ep)210 static rt_err_t _ep_enable(uep_t ep)
211 {
212 RT_ASSERT(ep != RT_NULL);
213 RT_ASSERT(ep->ep_desc != RT_NULL);
214
215 USBD_CONFIG_EP(EPADR_SW2HW(EP_ADDRESS(ep)),
216 USBD_CFG_CSTALL
217 | ((EP_ADDRESS(ep) & USB_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT)
218 | (EP_ADDRESS(ep) & USB_EPNO_MASK));
219
220 return RT_EOK;
221 }
222
_ep_disable(uep_t ep)223 static rt_err_t _ep_disable(uep_t ep)
224 {
225 RT_ASSERT(ep != RT_NULL);
226 RT_ASSERT(ep->ep_desc != RT_NULL);
227
228 USBD_CONFIG_EP(EPADR_SW2HW(EP_ADDRESS(ep)), USBD_CFG_EPMODE_DISABLE);
229
230 return RT_EOK;
231 }
232
_ep_read(rt_uint8_t address,void * buffer)233 static rt_ssize_t _ep_read(rt_uint8_t address, void *buffer)
234 {
235 rt_size_t size = 0;
236 rt_uint8_t *buf;
237 rt_uint32_t hw_ep_num = EPADR_SW2HW(address);
238
239 RT_ASSERT(!(address & USB_DIR_IN));
240 RT_ASSERT(buffer != RT_NULL);
241
242 size = USBD_GET_PAYLOAD_LEN(hw_ep_num);
243 buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(hw_ep_num));
244 USBD_MemCopy(buffer, (uint8_t *)buf, size);
245
246 return size;
247 }
248
_ep_read_prepare(rt_uint8_t address,void * buffer,rt_size_t size)249 static rt_ssize_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
250 {
251 RT_ASSERT(!(address & USB_DIR_IN));
252
253 USBD_SET_PAYLOAD_LEN(EPADR_SW2HW(address), size);
254
255 return size;
256 }
257
_ep_write(rt_uint8_t address,void * buffer,rt_size_t size)258 static rt_ssize_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
259 {
260 RT_ASSERT((address & USB_DIR_IN));
261
262 /* even number is for IN endpoint */
263 rt_uint32_t hw_ep_num = EPADR_SW2HW(address);
264 uint8_t *buf;
265 buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(hw_ep_num));
266
267 USBD_MemCopy(buf, (uint8_t *)buffer, size);
268
269 USBD_SET_PAYLOAD_LEN(hw_ep_num, size);
270
271 return size;
272 }
273
_ep0_send_status(void)274 static rt_err_t _ep0_send_status(void)
275 {
276 /* Status stage */
277 USBD_SET_DATA1(EP0);
278 USBD_SET_PAYLOAD_LEN(EP0, 0);
279 return RT_EOK;
280 }
281
_suspend(void)282 static rt_err_t _suspend(void)
283 {
284 return RT_EOK;
285 }
286
_wakeup(void)287 static rt_err_t _wakeup(void)
288 {
289 return RT_EOK;
290 }
291
_USBD_IRQHandler(void)292 __STATIC_INLINE void _USBD_IRQHandler(void)
293 {
294 rt_uint32_t u32IntSts = USBD_GET_INT_FLAG();
295 rt_uint32_t u32State = USBD_GET_BUS_STATE();
296
297 //------------------------------------------------------------------
298 if (u32IntSts & USBD_INTSTS_VBDETIF_Msk)
299 {
300 // Floating detect
301 USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk);
302
303 if (USBD_IS_ATTACHED())
304 {
305 /* USB Plug In */
306 USBD_ENABLE_USB();
307 rt_usbd_connect_handler(&_rt_obj_udc);
308 }
309 else
310 {
311 /* USB Unplug */
312 USBD_DISABLE_USB();
313 rt_usbd_disconnect_handler(&_rt_obj_udc);
314 }
315 }
316
317 if (u32IntSts & USBD_INTSTS_SOFIF_Msk)
318 {
319 USBD_CLR_INT_FLAG(USBD_INTSTS_SOFIF_Msk);
320 rt_usbd_sof_handler(&_rt_obj_udc);
321 }
322 //------------------------------------------------------------------
323 if (u32IntSts & USBD_INTSTS_BUSIF_Msk)
324 {
325 /* Clear event flag */
326 USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk);
327
328 if (u32State & USBD_ATTR_USBRST_Msk)
329 {
330 USBD_ENABLE_USB();
331
332 /* Reset PID DATA0 */
333 for (rt_uint32_t i = 0ul; i < USBD_MAX_EP; i++)
334 {
335 nu_usbd.Instance->EP[i].CFG &= ~USBD_CFG_DSQSYNC_Msk;
336 }
337
338 /* Reset USB device address */
339 USBD_SET_ADDR(0ul);
340
341 /* Bus reset */
342 rt_usbd_reset_handler(&_rt_obj_udc);
343 }
344 if (u32State & USBD_ATTR_SUSPEND_Msk)
345 {
346 /* Enable USB but disable PHY */
347 USBD_DISABLE_PHY();
348 }
349 if (u32State & USBD_ATTR_RESUME_Msk)
350 {
351 /* Enable USB and enable PHY */
352 USBD_ENABLE_USB();
353 }
354 }
355
356 //------------------------------------------------------------------
357 if (u32IntSts & USBD_INTSTS_WAKEUP)
358 {
359 /* Clear event flag */
360 USBD_CLR_INT_FLAG(USBD_INTSTS_WAKEUP);
361 USBD_ENABLE_USB();
362 }
363
364 if (u32IntSts & USBD_INTSTS_USBIF_Msk)
365 {
366 // USB event
367 if (u32IntSts & USBD_INTSTS_SETUP_Msk)
368 {
369 // Setup packet
370 /* Clear event flag */
371 USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk);
372
373 /* Clear the data IN/OUT ready flag of control end-points */
374 USBD_STOP_TRANSACTION(EP0);
375 USBD_STOP_TRANSACTION(EP1);
376
377 USBD_SET_DATA1(EP0);
378 rt_usbd_ep0_setup_handler(&_rt_obj_udc, (struct urequest *)USBD_BUF_BASE);
379 }
380
381 // EP events
382 if (u32IntSts & USBD_INTSTS_EP0)
383 {
384 /* Clear event flag */
385 USBD_CLR_INT_FLAG(USBD_INTSTS_EP0);
386
387 if ((USBD_GET_ADDR() == 0)
388 && (nu_usbd.address_tmp)
389 )
390 {
391 USBD_SET_ADDR(nu_usbd.address_tmp);
392 LOG_I("SET ADDR: 0x%02x", nu_usbd.address_tmp);
393 nu_usbd.address_tmp = 0;
394 }
395
396 rt_usbd_ep0_in_handler(&_rt_obj_udc);
397 }
398
399 if (u32IntSts & USBD_INTSTS_EP1)
400 {
401 /* Clear event flag */
402 USBD_CLR_INT_FLAG(USBD_INTSTS_EP1);
403 rt_usbd_ep0_out_handler(&_rt_obj_udc, 0);
404 }
405
406 if (u32IntSts & USBD_INTSTS_EP2)
407 {
408 /* Clear event flag */
409 USBD_CLR_INT_FLAG(USBD_INTSTS_EP2);
410 rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP2), 0);
411 }
412
413 if (u32IntSts & USBD_INTSTS_EP3)
414 {
415 /* Clear event flag */
416 USBD_CLR_INT_FLAG(USBD_INTSTS_EP3);
417 rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP3), 0);
418 }
419
420 if (u32IntSts & USBD_INTSTS_EP4)
421 {
422 /* Clear event flag */
423 USBD_CLR_INT_FLAG(USBD_INTSTS_EP4);
424 rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP4), 0);
425 }
426
427 if (u32IntSts & USBD_INTSTS_EP5)
428 {
429 /* Clear event flag */
430 USBD_CLR_INT_FLAG(USBD_INTSTS_EP5);
431 rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP5), 0);
432 }
433
434 if (u32IntSts & USBD_INTSTS_EP6)
435 {
436 /* Clear event flag */
437 USBD_CLR_INT_FLAG(USBD_INTSTS_EP6);
438 rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP6), 0);
439 }
440
441 if (u32IntSts & USBD_INTSTS_EP7)
442 {
443 /* Clear event flag */
444 USBD_CLR_INT_FLAG(USBD_INTSTS_EP7);
445 rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP7), 0);
446 }
447
448 if (u32IntSts & USBD_INTSTS_EP8)
449 {
450 /* Clear event flag */
451 USBD_CLR_INT_FLAG(USBD_INTSTS_EP8);
452 rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP8), 0);
453 }
454
455 if (u32IntSts & USBD_INTSTS_EP9)
456 {
457 /* Clear event flag */
458 USBD_CLR_INT_FLAG(USBD_INTSTS_EP9);
459 rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP9), 0);
460 }
461
462 if (u32IntSts & USBD_INTSTS_EP10)
463 {
464 /* Clear event flag */
465 USBD_CLR_INT_FLAG(USBD_INTSTS_EP10);
466 rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP10), 0);
467 }
468
469 if (u32IntSts & USBD_INTSTS_EP11)
470 {
471 /* Clear event flag */
472 USBD_CLR_INT_FLAG(USBD_INTSTS_EP11);
473 rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP11), 0);
474 }
475
476 }
477 }
478
USBD_IRQHandler(void)479 void USBD_IRQHandler(void)
480 {
481 rt_interrupt_enter();
482
483 _USBD_IRQHandler();
484
485 rt_interrupt_leave();
486 }
487
_init(rt_device_t device)488 static rt_err_t _init(rt_device_t device)
489 {
490 nu_usbd_t *nu_usbd = (nu_usbd_t *)device->user_data;
491
492 #if !defined(BSP_USING_OTG)
493
494 /* Initialize USB PHY */
495 SYS_UnlockReg();
496 /* Select USBD */
497 SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | SYS_USBPHY_OTGPHYEN_Msk | SYS_USBPHY_SBO_Msk;
498 SYS_ResetModule(USBD_RST);
499 SYS_LockReg();
500 #endif
501
502 _nu_ep_partition();
503
504 /* Initial USB engine */
505 nu_usbd->Instance->ATTR = 0x6D0ul;
506
507 /* Force SE0 */
508 USBD_SET_SE0();
509
510 NVIC_EnableIRQ(USBD_IRQn);
511
512 USBD_Start();
513 return RT_EOK;
514 }
515
516 const static struct udcd_ops _udc_ops =
517 {
518 _set_address,
519 _set_config,
520 _ep_set_stall,
521 _ep_clear_stall,
522 _ep_enable,
523 _ep_disable,
524 _ep_read_prepare,
525 _ep_read,
526 _ep_write,
527 _ep0_send_status,
528 _suspend,
529 _wakeup,
530 };
531
532 #ifdef RT_USING_DEVICE_OPS
533 const static struct rt_device_ops _ops =
534 {
535 _init,
536 RT_NULL,
537 RT_NULL,
538 RT_NULL,
539 RT_NULL,
540 RT_NULL,
541 };
542 #endif
543
nu_usbd_register(void)544 int nu_usbd_register(void)
545 {
546 if (RT_NULL != rt_device_find("usbd"))
547 {
548 LOG_E("\nUSBD Register failed. Another USBD device registered\n");
549 return -RT_ERROR;
550 }
551
552 rt_memset((void *)&_rt_obj_udc, 0, sizeof(struct udcd));
553 _rt_obj_udc.parent.type = RT_Device_Class_USBDevice;
554
555 #ifdef RT_USING_DEVICE_OPS
556 _rt_obj_udc.parent.ops = &_ops;
557 #else
558 _rt_obj_udc.parent.init = _init;
559 #endif
560
561 _rt_obj_udc.parent.user_data = &nu_usbd;
562 _rt_obj_udc.ops = &_udc_ops;
563 /* Register endpoint information */
564 _rt_obj_udc.ep_pool = _ep_pool;
565 _rt_obj_udc.ep0.id = &_ep_pool[0];
566
567 _rt_obj_udc.device_is_hs = RT_FALSE; /* Support Full-Speed only */
568
569 rt_device_register((rt_device_t)&_rt_obj_udc, "usbd", 0);
570 rt_usb_device_init();
571 return RT_EOK;
572 }
573 INIT_DEVICE_EXPORT(nu_usbd_register);
574 #endif
575