@@ -72,6 +72,7 @@ pub struct Usbd<'c> {
72
72
iso_in_used : bool ,
73
73
iso_out_used : bool ,
74
74
ep0_state : Mutex < Cell < EP0State > > ,
75
+ busy_in_endpoints : Mutex < Cell < u16 > > ,
75
76
76
77
// used to freeze `Clocks` and ensure they remain in the `ExternalOscillator` state
77
78
_clocks : & ' c ( ) ,
@@ -102,6 +103,7 @@ impl<'c> Usbd<'c> {
102
103
in_transfer_state : TransferState :: NoTransfer ,
103
104
is_set_address : false ,
104
105
} ) ) ,
106
+ busy_in_endpoints : Mutex :: new ( Cell :: new ( 0 ) ) ,
105
107
_clocks : & ( ) ,
106
108
} )
107
109
}
@@ -303,6 +305,8 @@ impl UsbBus for Usbd<'_> {
303
305
regs. size . epout [ i] . reset ( ) ;
304
306
}
305
307
}
308
+
309
+ self . busy_in_endpoints . borrow ( cs) . set ( 0 ) ;
306
310
} ) ;
307
311
}
308
312
@@ -361,7 +365,11 @@ impl UsbBus for Usbd<'_> {
361
365
362
366
interrupt:: free ( |cs| {
363
367
let regs = self . periph . borrow ( cs) ;
368
+ let busy_in_endpoints = self . busy_in_endpoints . borrow ( cs) ;
364
369
370
+ if busy_in_endpoints. get ( ) & ( 1 << i) != 0 {
371
+ return Err ( UsbError :: WouldBlock ) ;
372
+ }
365
373
if regs. epstatus . read ( ) . bits ( ) & ( 1 << i) != 0 {
366
374
return Err ( UsbError :: WouldBlock ) ;
367
375
}
@@ -436,6 +444,9 @@ impl UsbBus for Usbd<'_> {
436
444
// Clear EPSTATUS.EPIN[i] flag
437
445
regs. epstatus . write ( |w| unsafe { w. bits ( 1 << i) } ) ;
438
446
447
+ // Mark the endpoint as busy
448
+ busy_in_endpoints. set ( busy_in_endpoints. get ( ) | ( 1 << i) ) ;
449
+
439
450
Ok ( buf. len ( ) )
440
451
} )
441
452
}
@@ -547,6 +558,11 @@ impl UsbBus for Usbd<'_> {
547
558
} ) ;
548
559
}
549
560
}
561
+
562
+ if stalled {
563
+ let busy_in_endpoints = self . busy_in_endpoints . borrow ( cs) ;
564
+ busy_in_endpoints. set ( busy_in_endpoints. get ( ) & !( 1 << ep_addr. index ( ) ) ) ;
565
+ }
550
566
} ) ;
551
567
}
552
568
@@ -576,6 +592,7 @@ impl UsbBus for Usbd<'_> {
576
592
fn poll ( & self ) -> PollResult {
577
593
interrupt:: free ( |cs| {
578
594
let regs = self . periph . borrow ( cs) ;
595
+ let busy_in_endpoints = self . busy_in_endpoints . borrow ( cs) ;
579
596
580
597
if regs. events_usbreset . read ( ) . events_usbreset ( ) . bit_is_set ( ) {
581
598
regs. events_usbreset . reset ( ) ;
@@ -628,6 +645,9 @@ impl UsbBus for Usbd<'_> {
628
645
let mut state = ep0_state. get ( ) ;
629
646
state. in_transfer_state = TransferState :: NoTransfer ;
630
647
ep0_state. set ( state) ;
648
+
649
+ // Mark the endpoint as not busy
650
+ busy_in_endpoints. set ( busy_in_endpoints. get ( ) & !1 ) ;
631
651
} else {
632
652
// Do not clear OUT events, since we have to continue reporting them until the
633
653
// buffer is read.
@@ -644,6 +664,9 @@ impl UsbBus for Usbd<'_> {
644
664
regs. epdatastatus . write ( |w| unsafe { w. bits ( 1 << i) } ) ;
645
665
646
666
in_complete |= 1 << i;
667
+
668
+ // Mark the endpoint as not busy
669
+ busy_in_endpoints. set ( busy_in_endpoints. get ( ) & !( 1 << i) ) ;
647
670
}
648
671
if epdatastatus & ( 1 << ( i + 16 ) ) != 0 {
649
672
// EPDATASTATUS.EPOUT[i] is set
0 commit comments