@@ -72,6 +72,7 @@ pub struct Usbd<'c> {
7272 iso_in_used : bool ,
7373 iso_out_used : bool ,
7474 ep0_state : Mutex < Cell < EP0State > > ,
75+ busy_in_endpoints : Mutex < Cell < u16 > > ,
7576
7677 // used to freeze `Clocks` and ensure they remain in the `ExternalOscillator` state
7778 _clocks : & ' c ( ) ,
@@ -102,6 +103,7 @@ impl<'c> Usbd<'c> {
102103 in_transfer_state : TransferState :: NoTransfer ,
103104 is_set_address : false ,
104105 } ) ) ,
106+ busy_in_endpoints : Mutex :: new ( Cell :: new ( 0 ) ) ,
105107 _clocks : & ( ) ,
106108 } )
107109 }
@@ -303,6 +305,8 @@ impl UsbBus for Usbd<'_> {
303305 regs. size . epout [ i] . reset ( ) ;
304306 }
305307 }
308+
309+ self . busy_in_endpoints . borrow ( cs) . set ( 0 ) ;
306310 } ) ;
307311 }
308312
@@ -361,7 +365,11 @@ impl UsbBus for Usbd<'_> {
361365
362366 interrupt:: free ( |cs| {
363367 let regs = self . periph . borrow ( cs) ;
368+ let busy_in_endpoints = self . busy_in_endpoints . borrow ( cs) ;
364369
370+ if busy_in_endpoints. get ( ) & ( 1 << i) != 0 {
371+ return Err ( UsbError :: WouldBlock ) ;
372+ }
365373 if regs. epstatus . read ( ) . bits ( ) & ( 1 << i) != 0 {
366374 return Err ( UsbError :: WouldBlock ) ;
367375 }
@@ -436,6 +444,9 @@ impl UsbBus for Usbd<'_> {
436444 // Clear EPSTATUS.EPIN[i] flag
437445 regs. epstatus . write ( |w| unsafe { w. bits ( 1 << i) } ) ;
438446
447+ // Mark the endpoint as busy
448+ busy_in_endpoints. set ( busy_in_endpoints. get ( ) | ( 1 << i) ) ;
449+
439450 Ok ( buf. len ( ) )
440451 } )
441452 }
@@ -547,6 +558,11 @@ impl UsbBus for Usbd<'_> {
547558 } ) ;
548559 }
549560 }
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+ }
550566 } ) ;
551567 }
552568
@@ -576,6 +592,7 @@ impl UsbBus for Usbd<'_> {
576592 fn poll ( & self ) -> PollResult {
577593 interrupt:: free ( |cs| {
578594 let regs = self . periph . borrow ( cs) ;
595+ let busy_in_endpoints = self . busy_in_endpoints . borrow ( cs) ;
579596
580597 if regs. events_usbreset . read ( ) . events_usbreset ( ) . bit_is_set ( ) {
581598 regs. events_usbreset . reset ( ) ;
@@ -628,6 +645,9 @@ impl UsbBus for Usbd<'_> {
628645 let mut state = ep0_state. get ( ) ;
629646 state. in_transfer_state = TransferState :: NoTransfer ;
630647 ep0_state. set ( state) ;
648+
649+ // Mark the endpoint as not busy
650+ busy_in_endpoints. set ( busy_in_endpoints. get ( ) & !1 ) ;
631651 } else {
632652 // Do not clear OUT events, since we have to continue reporting them until the
633653 // buffer is read.
@@ -644,6 +664,9 @@ impl UsbBus for Usbd<'_> {
644664 regs. epdatastatus . write ( |w| unsafe { w. bits ( 1 << i) } ) ;
645665
646666 in_complete |= 1 << i;
667+
668+ // Mark the endpoint as not busy
669+ busy_in_endpoints. set ( busy_in_endpoints. get ( ) & !( 1 << i) ) ;
647670 }
648671 if epdatastatus & ( 1 << ( i + 16 ) ) != 0 {
649672 // EPDATASTATUS.EPOUT[i] is set
0 commit comments