@@ -498,7 +498,8 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
498
498
write_reg ! ( otg_global, regs. global( ) , GINTMSK ,
499
499
USBRST : 1 , ENUMDNEM : 1 ,
500
500
USBSUSPM : 1 , WUIM : 1 ,
501
- IEPINT : 1 , RXFLVLM : 1
501
+ IEPINT : 1 , RXFLVLM : 1 ,
502
+ IISOIXFRM : 1
502
503
) ;
503
504
504
505
// clear pending interrupts
@@ -585,8 +586,8 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
585
586
586
587
let core_id = read_reg ! ( otg_global, regs. global( ) , CID ) ;
587
588
588
- let ( wakeup, suspend, enum_done, reset, iep, rxflvl) = read_reg ! ( otg_global, regs. global( ) , GINTSTS ,
589
- WKUPINT , USBSUSP , ENUMDNE , USBRST , IEPINT , RXFLVL
589
+ let ( wakeup, suspend, enum_done, reset, iep, rxflvl, iisoixfr ) = read_reg ! ( otg_global, regs. global( ) , GINTSTS ,
590
+ WKUPINT , USBSUSP , ENUMDNE , USBRST , IEPINT , RXFLVL , IISOIXFR
590
591
) ;
591
592
592
593
if reset != 0 {
@@ -649,6 +650,53 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
649
650
write_reg ! ( otg_global, regs. global( ) , GINTSTS , USBSUSP : 1 ) ;
650
651
651
652
PollResult :: Suspend
653
+ } else if iisoixfr != 0 {
654
+ use crate :: ral:: endpoint_in;
655
+
656
+ // Incomplete isochronous IN transfer; see
657
+ // RM0383 Rev 3 pp797 "Incomplete isochronous IN data transfers"
658
+ write_reg ! ( otg_global, regs. global( ) , GINTSTS , IISOIXFR : 1 ) ;
659
+
660
+ let in_endpoints = self . allocator . endpoints_in
661
+ . iter ( )
662
+ . flatten ( )
663
+ . map ( |ep| ep. address ( ) . index ( ) ) ;
664
+
665
+ let mut iep: u16 = 0 ;
666
+
667
+ for epnum in in_endpoints {
668
+ let ep_regs = regs. endpoint_in ( epnum) ;
669
+
670
+ // filter out non-isochronous endpoints
671
+ if read_reg ! ( endpoint_in, ep_regs, DIEPCTL , EPTYP ) & 0x11 != 0x01 { continue ; }
672
+
673
+ // identify incomplete transfers by the presence of the NAK event
674
+ // see RM0383 Rev 3 pp 746 description of NAK:
675
+ //
676
+ // > In case of isochronous IN endpoints the interrupt gets
677
+ // > generated when a zero length packet is transmitted due
678
+ // > to unavailability of data in the Tx FIFO.
679
+ if read_reg ! ( endpoint_in, ep_regs, DIEPINT ) & 1 <<13 == 0 { continue ; }
680
+
681
+ // Set NAK
682
+ modify_reg ! ( endpoint_in, ep_regs, DIEPCTL , SNAK : 1 ) ;
683
+ while read_reg ! ( endpoint_in, ep_regs, DIEPINT , INEPNE ) == 0 { }
684
+
685
+ // Disable the endpoint
686
+ modify_reg ! ( endpoint_in, ep_regs, DIEPCTL , SNAK : 1 , EPDIS : 1 ) ;
687
+ while read_reg ! ( endpoint_in, ep_regs, DIEPINT , EPDISD ) == 0 { }
688
+ modify_reg ! ( endpoint_in, ep_regs, DIEPINT , EPDISD : 1 ) ;
689
+ assert ! ( read_reg!( endpoint_in, ep_regs, DIEPCTL , EPENA ) == 0 ) ;
690
+ assert ! ( read_reg!( endpoint_in, ep_regs, DIEPCTL , EPDIS ) == 0 ) ;
691
+
692
+ // Flush the TX FIFO
693
+ modify_reg ! ( otg_global, regs. global( ) , GRSTCTL , TXFNUM : epnum as u32 , TXFFLSH : 1 ) ;
694
+ while read_reg ! ( otg_global, regs. global( ) , GRSTCTL , TXFFLSH ) == 1 { }
695
+
696
+ iep |= 1 << epnum;
697
+ }
698
+
699
+ PollResult :: Data { ep_out : 0 , ep_in_complete : iep, ep_setup : 0 }
652
700
} else {
653
701
let mut ep_out = 0 ;
654
702
let mut ep_in_complete = 0 ;
0 commit comments