@@ -396,12 +396,53 @@ static void numaker_usbd_hw_shutdown(const struct device *dev)
396
396
SYS_LockReg ();
397
397
}
398
398
399
+ /* Interrupt top half processing for vbus plug */
400
+ static void numaker_usbd_vbus_plug_th (const struct device * dev )
401
+ {
402
+ const struct udc_numaker_config * config = dev -> config ;
403
+ USBD_T * base = config -> base ;
404
+
405
+ /* Enable back USB/PHY */
406
+ base -> ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk ;
407
+
408
+ /* UDC stack would handle bottom-half processing */
409
+ udc_submit_event (dev , UDC_EVT_VBUS_READY , 0 );
410
+
411
+ LOG_DBG ("USB plug-in" );
412
+ }
413
+
414
+ /* Interrupt top half processing for vbus unplug */
415
+ static void numaker_usbd_vbus_unplug_th (const struct device * dev )
416
+ {
417
+ const struct udc_numaker_config * config = dev -> config ;
418
+ USBD_T * base = config -> base ;
419
+
420
+ /* Disable USB */
421
+ base -> ATTR &= ~USBD_USB_EN ;
422
+
423
+ /* UDC stack would handle bottom-half processing */
424
+ udc_submit_event (dev , UDC_EVT_VBUS_REMOVED , 0 );
425
+
426
+ LOG_DBG ("USB unplug" );
427
+ }
428
+
429
+ /* Interrupt top half processing for bus wakeup */
430
+ static void numaker_usbd_bus_wakeup_th (const struct device * dev )
431
+ {
432
+ LOG_DBG ("USB wake-up" );
433
+ }
434
+
399
435
/* Interrupt top half processing for bus reset */
400
436
static void numaker_usbd_bus_reset_th (const struct device * dev )
401
437
{
438
+ const struct udc_numaker_config * config = dev -> config ;
439
+ USBD_T * base = config -> base ;
402
440
struct udc_numaker_data * priv = udc_get_private (dev );
403
441
USBD_EP_T * ep_base ;
404
442
443
+ /* Enable back USB/PHY */
444
+ base -> ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk ;
445
+
405
446
for (uint32_t i = 0ul ; i < priv -> ep_pool_size ; i ++ ) {
406
447
ep_base = numaker_usbd_ep_base (dev , EP0 + i );
407
448
@@ -421,6 +462,128 @@ static void numaker_usbd_bus_reset_th(const struct device *dev)
421
462
}
422
463
423
464
numaker_usbd_reset_addr (dev );
465
+
466
+ /* UDC stack would handle bottom-half processing,
467
+ * including reset device address (udc_set_address),
468
+ * un-configure device (udc_ep_disable), etc.
469
+ */
470
+ udc_submit_event (dev , UDC_EVT_RESET , 0 );
471
+
472
+ LOG_DBG ("USB reset" );
473
+ }
474
+
475
+ /* Interrupt top half processing for bus suspend */
476
+ static void numaker_usbd_bus_suspend_th (const struct device * dev )
477
+ {
478
+ const struct udc_numaker_config * config = dev -> config ;
479
+ USBD_T * base = config -> base ;
480
+
481
+ /* Enable USB but disable PHY */
482
+ base -> ATTR &= ~USBD_PHY_EN ;
483
+
484
+ /* UDC stack would handle bottom-half processing */
485
+ udc_submit_event (dev , UDC_EVT_SUSPEND , 0 );
486
+
487
+ LOG_DBG ("USB suspend" );
488
+ }
489
+
490
+ /* Interrupt top half processing for bus resume */
491
+ static void numaker_usbd_bus_resume_th (const struct device * dev )
492
+ {
493
+ const struct udc_numaker_config * config = dev -> config ;
494
+ USBD_T * base = config -> base ;
495
+
496
+ /* Enable back USB/PHY */
497
+ base -> ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk ;
498
+
499
+ /* UDC stack would handle bottom-half processing */
500
+ udc_submit_event (dev , UDC_EVT_RESUME , 0 );
501
+
502
+ LOG_DBG ("USB resume" );
503
+ }
504
+
505
+ /* Interrupt top half processing for SOF */
506
+ static void numaker_usbd_sof_th (const struct device * dev )
507
+ {
508
+ /* UDC stack would handle bottom-half processing */
509
+ udc_submit_sof_event (dev );
510
+ }
511
+
512
+ static void numaker_usbd_setup_copy_to_user (const struct device * dev , uint8_t * usrbuf );
513
+
514
+ /* Interrupt top half processing for Setup packet */
515
+ static void numaker_usbd_setup_th (const struct device * dev )
516
+ {
517
+ USBD_EP_T * ep0_base = numaker_usbd_ep_base (dev , EP0 );
518
+ USBD_EP_T * ep1_base = numaker_usbd_ep_base (dev , EP1 );
519
+ struct numaker_usbd_msg msg = {0 };
520
+
521
+ /* Clear the data IN/OUT ready flag of control endpoints */
522
+ ep0_base -> CFGP |= USBD_CFGP_CLRRDY_Msk ;
523
+ ep1_base -> CFGP |= USBD_CFGP_CLRRDY_Msk ;
524
+
525
+ /* By USB spec, following transactions, regardless of Data/Status stage,
526
+ * will always be DATA1
527
+ */
528
+ ep0_base -> CFG |= USBD_CFG_DSQSYNC_Msk ;
529
+ ep1_base -> CFG |= USBD_CFG_DSQSYNC_Msk ;
530
+
531
+ /* Message for bottom-half processing */
532
+ /* NOTE: In Zephyr USB device stack, Setup packet is passed via
533
+ * CTRL OUT EP
534
+ */
535
+ msg .type = NUMAKER_USBD_MSG_TYPE_SETUP ;
536
+ numaker_usbd_setup_copy_to_user (dev , msg .setup .packet );
537
+ numaker_usbd_send_msg (dev , & msg );
538
+ }
539
+
540
+ /* Interrupt top half processing for EP (excluding Setup) */
541
+ static void numaker_usbd_ep_th (const struct device * dev , uint32_t ep_hw_idx )
542
+ {
543
+ struct udc_numaker_data * priv = udc_get_private (dev );
544
+ USBD_EP_T * ep_base = numaker_usbd_ep_base (dev , ep_hw_idx );
545
+ uint8_t ep_dir ;
546
+ uint8_t ep_idx ;
547
+ uint8_t ep ;
548
+ struct numaker_usbd_msg msg = {0 };
549
+
550
+ /* We don't enable INNAKEN interrupt, so as long as EP event occurs,
551
+ * we can just regard one data transaction has completed (ACK for
552
+ * CTRL/BULK/INT or no-ACK for Iso), that is, no need to check EPSTS0,
553
+ * EPSTS1, etc.
554
+ */
555
+
556
+ /* EP direction, number, and address */
557
+ ep_dir = ((ep_base -> CFG & USBD_CFG_STATE_Msk ) == USBD_CFG_EPMODE_IN ) ? USB_EP_DIR_IN
558
+ : USB_EP_DIR_OUT ;
559
+ ep_idx = (ep_base -> CFG & USBD_CFG_EPNUM_Msk ) >> USBD_CFG_EPNUM_Pos ;
560
+ ep = USB_EP_GET_ADDR (ep_idx , ep_dir );
561
+
562
+ /* NOTE: See comment in udc_numaker_set_address()'s implementation
563
+ * for safe place to change USB device address
564
+ */
565
+ if (ep == USB_EP_GET_ADDR (0 , USB_EP_DIR_IN )) {
566
+ numaker_usbd_set_addr (dev );
567
+ }
568
+
569
+ /* NOTE: See comment on mxpld_ctrlout for why make one copy of
570
+ * CTRL OUT's MXPLD
571
+ */
572
+ if (ep == USB_EP_GET_ADDR (0 , USB_EP_DIR_OUT )) {
573
+ struct numaker_usbd_ep * ep_ctrlout = priv -> ep_pool + 0 ;
574
+
575
+ ep_ctrlout -> mxpld_ctrlout = ep_base -> MXPLD ;
576
+ }
577
+
578
+ /* Message for bottom-half processing */
579
+ if (USB_EP_DIR_IS_OUT (ep )) {
580
+ msg .type = NUMAKER_USBD_MSG_TYPE_OUT ;
581
+ msg .out .ep = ep ;
582
+ } else {
583
+ msg .type = NUMAKER_USBD_MSG_TYPE_IN ;
584
+ msg .in .ep = ep ;
585
+ }
586
+ numaker_usbd_send_msg (dev , & msg );
424
587
}
425
588
426
589
/* USBD SRAM base for DMA */
@@ -1209,11 +1372,7 @@ static void numaker_usbd_msg_handler(const struct device *dev)
1209
1372
static void numaker_usbd_isr (const struct device * dev )
1210
1373
{
1211
1374
const struct udc_numaker_config * config = dev -> config ;
1212
- struct udc_numaker_data * priv = udc_get_private (dev );
1213
1375
USBD_T * const base = config -> base ;
1214
-
1215
- struct numaker_usbd_msg msg = {0 };
1216
-
1217
1376
uint32_t usbd_intsts = base -> INTSTS ;
1218
1377
uint32_t usbd_bus_state = base -> ATTR ;
1219
1378
@@ -1232,75 +1391,39 @@ static void numaker_usbd_isr(const struct device *dev)
1232
1391
if (usbd_intsts & USBD_INTSTS_FLDET ) {
1233
1392
if (base -> VBUSDET & USBD_VBUSDET_VBUSDET_Msk ) {
1234
1393
/* USB plug-in */
1235
-
1236
- /* Enable back USB/PHY */
1237
- base -> ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk ;
1238
-
1239
- /* UDC stack would handle bottom-half processing */
1240
- udc_submit_event (dev , UDC_EVT_VBUS_READY , 0 );
1241
-
1242
- LOG_DBG ("USB plug-in" );
1394
+ numaker_usbd_vbus_plug_th (dev );
1243
1395
} else {
1244
1396
/* USB unplug */
1245
-
1246
- /* Disable USB */
1247
- base -> ATTR &= ~USBD_USB_EN ;
1248
-
1249
- /* UDC stack would handle bottom-half processing */
1250
- udc_submit_event (dev , UDC_EVT_VBUS_REMOVED , 0 );
1251
-
1252
- LOG_DBG ("USB unplug" );
1397
+ numaker_usbd_vbus_unplug_th (dev );
1253
1398
}
1254
1399
}
1255
1400
1256
1401
/* USB wake-up */
1257
1402
if (usbd_intsts & USBD_INTSTS_WAKEUP ) {
1258
- LOG_DBG ( "USB wake-up" );
1403
+ numaker_usbd_bus_wakeup_th ( dev );
1259
1404
}
1260
1405
1261
1406
/* USB reset/suspend/resume */
1262
1407
if (usbd_intsts & USBD_INTSTS_BUS ) {
1408
+ /* Bus reset */
1263
1409
if (usbd_bus_state & USBD_STATE_USBRST ) {
1264
- /* Bus reset */
1265
-
1266
- /* Enable back USB/PHY */
1267
- base -> ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk ;
1268
-
1269
- /* Bus reset top half */
1270
1410
numaker_usbd_bus_reset_th (dev );
1271
-
1272
- /* UDC stack would handle bottom-half processing,
1273
- * including reset device address (udc_set_address),
1274
- * un-configure device (udc_ep_disable), etc.
1275
- */
1276
- udc_submit_event (dev , UDC_EVT_RESET , 0 );
1277
-
1278
- LOG_DBG ("USB reset" );
1279
1411
}
1280
- if (usbd_bus_state & USBD_STATE_SUSPEND ) {
1281
- /* Enable USB but disable PHY */
1282
- base -> ATTR &= ~USBD_PHY_EN ;
1283
-
1284
- /* UDC stack would handle bottom-half processing */
1285
- udc_submit_event (dev , UDC_EVT_SUSPEND , 0 );
1286
1412
1287
- LOG_DBG ("USB suspend" );
1413
+ /* Bus suspend */
1414
+ if (usbd_bus_state & USBD_STATE_SUSPEND ) {
1415
+ numaker_usbd_bus_suspend_th (dev );
1288
1416
}
1289
- if (usbd_bus_state & USBD_STATE_RESUME ) {
1290
- /* Enable back USB/PHY */
1291
- base -> ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk ;
1292
1417
1293
- /* UDC stack would handle bottom-half processing */
1294
- udc_submit_event (dev , UDC_EVT_RESUME , 0 );
1295
-
1296
- LOG_DBG ("USB resume" );
1418
+ /* Bus resume */
1419
+ if (usbd_bus_state & USBD_STATE_RESUME ) {
1420
+ numaker_usbd_bus_resume_th (dev );
1297
1421
}
1298
1422
}
1299
1423
1300
1424
/* USB SOF */
1301
1425
if (usbd_intsts & USBD_INTSTS_SOFIF_Msk ) {
1302
- /* UDC stack would handle bottom-half processing */
1303
- udc_submit_sof_event (dev );
1426
+ numaker_usbd_sof_th (dev );
1304
1427
}
1305
1428
1306
1429
/* USB Setup/EP */
@@ -1309,26 +1432,7 @@ static void numaker_usbd_isr(const struct device *dev)
1309
1432
1310
1433
/* Setup event */
1311
1434
if (usbd_intsts & USBD_INTSTS_SETUP ) {
1312
- USBD_EP_T * ep0_base = numaker_usbd_ep_base (dev , EP0 );
1313
- USBD_EP_T * ep1_base = numaker_usbd_ep_base (dev , EP1 );
1314
-
1315
- /* Clear the data IN/OUT ready flag of control endpoints */
1316
- ep0_base -> CFGP |= USBD_CFGP_CLRRDY_Msk ;
1317
- ep1_base -> CFGP |= USBD_CFGP_CLRRDY_Msk ;
1318
-
1319
- /* By USB spec, following transactions, regardless of Data/Status stage,
1320
- * will always be DATA1
1321
- */
1322
- ep0_base -> CFG |= USBD_CFG_DSQSYNC_Msk ;
1323
- ep1_base -> CFG |= USBD_CFG_DSQSYNC_Msk ;
1324
-
1325
- /* Message for bottom-half processing */
1326
- /* NOTE: In Zephyr USB device stack, Setup packet is passed via
1327
- * CTRL OUT EP
1328
- */
1329
- msg .type = NUMAKER_USBD_MSG_TYPE_SETUP ;
1330
- numaker_usbd_setup_copy_to_user (dev , msg .setup .packet );
1331
- numaker_usbd_send_msg (dev , & msg );
1435
+ numaker_usbd_setup_th (dev );
1332
1436
}
1333
1437
1334
1438
/* EP events */
@@ -1339,51 +1443,8 @@ static void numaker_usbd_isr(const struct device *dev)
1339
1443
1340
1444
while (epintsts ) {
1341
1445
uint32_t ep_hw_idx = u32_count_trailing_zeros (epintsts );
1342
- USBD_EP_T * ep_base = numaker_usbd_ep_base (dev , ep_hw_idx );
1343
- uint8_t ep_dir ;
1344
- uint8_t ep_idx ;
1345
- uint8_t ep ;
1346
1446
1347
- /* We don't enable INNAKEN interrupt, so as long as EP event occurs,
1348
- * we can just regard one data transaction has completed (ACK for
1349
- * CTRL/BULK/INT or no-ACK for Iso), that is, no need to check EPSTS0,
1350
- * EPSTS1, etc.
1351
- */
1352
-
1353
- /* EP direction, number, and address */
1354
- ep_dir = ((ep_base -> CFG & USBD_CFG_STATE_Msk ) == USBD_CFG_EPMODE_IN )
1355
- ? USB_EP_DIR_IN
1356
- : USB_EP_DIR_OUT ;
1357
- ep_idx = (ep_base -> CFG & USBD_CFG_EPNUM_Msk ) >> USBD_CFG_EPNUM_Pos ;
1358
- ep = USB_EP_GET_ADDR (ep_idx , ep_dir );
1359
-
1360
- /* NOTE: See comment in udc_numaker_set_address()'s implementation
1361
- * for safe place to change USB device address
1362
- */
1363
- if (ep == USB_EP_GET_ADDR (0 , USB_EP_DIR_IN )) {
1364
- numaker_usbd_set_addr (dev );
1365
- }
1366
-
1367
- /* NOTE: See comment on mxpld_ctrlout for why make one copy of
1368
- * CTRL OUT's MXPLD
1369
- */
1370
- if (ep == USB_EP_GET_ADDR (0 , USB_EP_DIR_OUT )) {
1371
- struct numaker_usbd_ep * ep_ctrlout = priv -> ep_pool + 0 ;
1372
- USBD_EP_T * ep_ctrlout_base = numaker_usbd_ep_base (
1373
- dev , ep_ctrlout -> ep_hw_idx );
1374
-
1375
- ep_ctrlout -> mxpld_ctrlout = ep_ctrlout_base -> MXPLD ;
1376
- }
1377
-
1378
- /* Message for bottom-half processing */
1379
- if (USB_EP_DIR_IS_OUT (ep )) {
1380
- msg .type = NUMAKER_USBD_MSG_TYPE_OUT ;
1381
- msg .out .ep = ep ;
1382
- } else {
1383
- msg .type = NUMAKER_USBD_MSG_TYPE_IN ;
1384
- msg .in .ep = ep ;
1385
- }
1386
- numaker_usbd_send_msg (dev , & msg );
1447
+ numaker_usbd_ep_th (dev , ep_hw_idx );
1387
1448
1388
1449
/* Have handled this EP and go next */
1389
1450
epintsts &= ~BIT (ep_hw_idx );
0 commit comments