@@ -111,7 +111,7 @@ impl<USB: UsbPeripheral> UsbBus<USB> {
111
111
}
112
112
}
113
113
114
- fn deconfigure_all ( & self , cs : CriticalSection < ' _ > ) {
114
+ fn deconfigure_all ( & self , cs : CriticalSection < ' _ > , core_id : u32 ) {
115
115
let regs = self . regs . borrow ( cs) ;
116
116
117
117
// disable interrupts
@@ -125,7 +125,7 @@ impl<USB: UsbPeripheral> UsbBus<USB> {
125
125
126
126
for ep in & self . allocator . endpoints_out {
127
127
if let Some ( ep) = ep {
128
- ep. deconfigure ( cs) ;
128
+ ep. deconfigure ( cs, core_id ) ;
129
129
}
130
130
}
131
131
}
@@ -454,13 +454,14 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
454
454
455
455
// Configuring Vbus sense and SOF output
456
456
match core_id {
457
- 0x0000_1200 | 0x0000_1100 => {
457
+ 0x0000_1000 | 0x0000_1200 | 0x0000_1100 => {
458
458
// F429-like chips have the GCCFG.NOVBUSSENS bit
459
459
460
460
//modify_reg!(otg_global, regs.global, GCCFG, NOVBUSSENS: 1);
461
461
modify_reg ! ( otg_global, regs. global( ) , GCCFG , |r| r | ( 1 << 21 ) ) ;
462
462
463
- modify_reg ! ( otg_global, regs. global( ) , GCCFG , VBUSASEN : 0 , VBUSBSEN : 0 , SOFOUTEN : 0 ) ;
463
+ // VBUSBSEN=1 is required for GD32VF103
464
+ modify_reg ! ( otg_global, regs. global( ) , GCCFG , VBUSASEN : 0 , VBUSBSEN : 1 , SOFOUTEN : 0 ) ;
464
465
}
465
466
0x0000_2000 | 0x0000_2100 | 0x0000_2300 | 0x0000_3000 | 0x0000_3100 => {
466
467
// F446-like chips have the GCCFG.VBDEN bit with the opposite meaning
@@ -604,7 +605,7 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
604
605
if reset != 0 {
605
606
write_reg ! ( otg_global, regs. global( ) , GINTSTS , USBRST : 1 ) ;
606
607
607
- self . deconfigure_all ( cs) ;
608
+ self . deconfigure_all ( cs, core_id ) ;
608
609
609
610
// Flush RX
610
611
modify_reg ! ( otg_global, regs. global( ) , GRSTCTL , RXFFLSH : 1 ) ;
@@ -632,20 +633,25 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
632
633
0b01 | 0b11 => {
633
634
// Full speed
634
635
635
- // From RM0431 (F72xx), RM0090 (F429)
636
- trdt = match self . peripheral . ahb_frequency_hz ( ) {
637
- 0 ..=14_199_999 => panic ! ( "AHB frequency is too low" ) ,
638
- 14_200_000 ..=14_999_999 => 0xF ,
639
- 15_000_000 ..=15_999_999 => 0xE ,
640
- 16_000_000 ..=17_199_999 => 0xD ,
641
- 17_200_000 ..=18_499_999 => 0xC ,
642
- 18_500_000 ..=19_999_999 => 0xB ,
643
- 20_000_000 ..=21_799_999 => 0xA ,
644
- 21_800_000 ..=23_999_999 => 0x9 ,
645
- 24_000_000 ..=27_499_999 => 0x8 ,
646
- 27_500_000 ..=31_999_999 => 0x7 , // 27.7..32 in code from CubeIDE
647
- 32_000_000 ..=u32:: MAX => 0x6 ,
648
- } ;
636
+ if core_id == 0x0000_1000 {
637
+ // From GD32VF103_Firmware_Library_V1.0.2.rar.
638
+ trdt = 0x05 ;
639
+ } else {
640
+ // From RM0431 (F72xx), RM0090 (F429)
641
+ trdt = match self . peripheral . ahb_frequency_hz ( ) {
642
+ 0 ..=14_199_999 => panic ! ( "AHB frequency is too low" ) ,
643
+ 14_200_000 ..=14_999_999 => 0xF ,
644
+ 15_000_000 ..=15_999_999 => 0xE ,
645
+ 16_000_000 ..=17_199_999 => 0xD ,
646
+ 17_200_000 ..=18_499_999 => 0xC ,
647
+ 18_500_000 ..=19_999_999 => 0xB ,
648
+ 20_000_000 ..=21_799_999 => 0xA ,
649
+ 21_800_000 ..=23_999_999 => 0x9 ,
650
+ 24_000_000 ..=27_499_999 => 0x8 ,
651
+ 27_500_000 ..=31_999_999 => 0x7 , // 27.7..32 in code from CubeIDE
652
+ 32_000_000 ..=u32:: MAX => 0x6 ,
653
+ } ;
654
+ }
649
655
}
650
656
_ => unimplemented ! ( ) ,
651
657
}
@@ -685,16 +691,35 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
685
691
modify_reg ! ( otg_global, regs. global( ) , GRSTCTL , TXFNUM : epnum, TXFFLSH : 1 ) ;
686
692
while read_reg ! ( otg_global, regs. global( ) , GRSTCTL , TXFFLSH ) == 1 { }
687
693
}
688
- ep_setup |= 1 << epnum;
689
694
}
690
695
0x03 | 0x04 => {
691
696
// OUT completed | SETUP completed
697
+
698
+ // It's important to read this register before re-enabling the relevant
699
+ // endpoint on GD32VF103, otherwise DOEPCTL.EPENA resets back to 0 after
700
+ // reading GRXSTSP.
701
+ read_reg ! ( otg_global, regs. global( ) , GRXSTSP ) ; // pop GRXSTSP
702
+
703
+ if status == 0x04 && core_id == 0x0000_1000 {
704
+ // For GD32VF103 report SETUP event only after the "SETUP completed"
705
+ // event. For newer chips SETUP event is reported after successful
706
+ // read from the endpoint FIFO to the buffer.
707
+ ep_setup |= 1 << epnum;
708
+
709
+ // We indicate presence of SETUP packet here, because otherwise
710
+ // usb-device starts IN transfer after the "SETUP received" event.
711
+ // This transfer gets interrupted by the "SETUP completed" event:
712
+ // USB peripheral automatically disables EP0 IN endpoint.
713
+ }
714
+
692
715
// Re-enable the endpoint, F429-like chips only
693
- if core_id == 0x0000_1200 || core_id == 0x0000_1100 {
716
+ if core_id == 0x0000_1000
717
+ || core_id == 0x0000_1200
718
+ || core_id == 0x0000_1100
719
+ {
694
720
let ep = regs. endpoint_out ( epnum as usize ) ;
695
721
modify_reg ! ( endpoint_out, ep, DOEPCTL , CNAK : 1 , EPENA : 1 ) ;
696
722
}
697
- read_reg ! ( otg_global, regs. global( ) , GRXSTSP ) ; // pop GRXSTSP
698
723
}
699
724
_ => {
700
725
read_reg ! ( otg_global, regs. global( ) , GRXSTSP ) ; // pop GRXSTSP
@@ -746,7 +771,9 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
746
771
ep_out |= 1 << ep. address ( ) . index ( ) ;
747
772
}
748
773
EndpointBufferState :: DataSetup => {
749
- ep_setup |= 1 << ep. address ( ) . index ( ) ;
774
+ if core_id > 0x0000_1000 {
775
+ ep_setup |= 1 << ep. address ( ) . index ( ) ;
776
+ }
750
777
}
751
778
EndpointBufferState :: Empty => { }
752
779
}
0 commit comments