@@ -111,7 +111,7 @@ impl<USB: UsbPeripheral> UsbBus<USB> {
111111 }
112112 }
113113
114- fn deconfigure_all ( & self , cs : CriticalSection < ' _ > ) {
114+ fn deconfigure_all ( & self , cs : CriticalSection < ' _ > , core_id : u32 ) {
115115 let regs = self . regs . borrow ( cs) ;
116116
117117 // disable interrupts
@@ -125,7 +125,7 @@ impl<USB: UsbPeripheral> UsbBus<USB> {
125125
126126 for ep in & self . allocator . endpoints_out {
127127 if let Some ( ep) = ep {
128- ep. deconfigure ( cs) ;
128+ ep. deconfigure ( cs, core_id ) ;
129129 }
130130 }
131131 }
@@ -454,13 +454,14 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
454454
455455 // Configuring Vbus sense and SOF output
456456 match core_id {
457- 0x0000_1200 | 0x0000_1100 => {
457+ 0x0000_1000 | 0x0000_1200 | 0x0000_1100 => {
458458 // F429-like chips have the GCCFG.NOVBUSSENS bit
459459
460460 //modify_reg!(otg_global, regs.global, GCCFG, NOVBUSSENS: 1);
461461 modify_reg ! ( otg_global, regs. global( ) , GCCFG , |r| r | ( 1 << 21 ) ) ;
462462
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 ) ;
464465 }
465466 0x0000_2000 | 0x0000_2100 | 0x0000_2300 | 0x0000_3000 | 0x0000_3100 => {
466467 // 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> {
604605 if reset != 0 {
605606 write_reg ! ( otg_global, regs. global( ) , GINTSTS , USBRST : 1 ) ;
606607
607- self . deconfigure_all ( cs) ;
608+ self . deconfigure_all ( cs, core_id ) ;
608609
609610 // Flush RX
610611 modify_reg ! ( otg_global, regs. global( ) , GRSTCTL , RXFFLSH : 1 ) ;
@@ -632,20 +633,25 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
632633 0b01 | 0b11 => {
633634 // Full speed
634635
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+ }
649655 }
650656 _ => unimplemented ! ( ) ,
651657 }
@@ -685,16 +691,35 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
685691 modify_reg ! ( otg_global, regs. global( ) , GRSTCTL , TXFNUM : epnum, TXFFLSH : 1 ) ;
686692 while read_reg ! ( otg_global, regs. global( ) , GRSTCTL , TXFFLSH ) == 1 { }
687693 }
688- ep_setup |= 1 << epnum;
689694 }
690695 0x03 | 0x04 => {
691696 // 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+
692715 // 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+ {
694720 let ep = regs. endpoint_out ( epnum as usize ) ;
695721 modify_reg ! ( endpoint_out, ep, DOEPCTL , CNAK : 1 , EPENA : 1 ) ;
696722 }
697- read_reg ! ( otg_global, regs. global( ) , GRXSTSP ) ; // pop GRXSTSP
698723 }
699724 _ => {
700725 read_reg ! ( otg_global, regs. global( ) , GRXSTSP ) ; // pop GRXSTSP
@@ -746,7 +771,9 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
746771 ep_out |= 1 << ep. address ( ) . index ( ) ;
747772 }
748773 EndpointBufferState :: DataSetup => {
749- ep_setup |= 1 << ep. address ( ) . index ( ) ;
774+ if core_id > 0x0000_1000 {
775+ ep_setup |= 1 << ep. address ( ) . index ( ) ;
776+ }
750777 }
751778 EndpointBufferState :: Empty => { }
752779 }
0 commit comments