Skip to content

Commit 81b92b9

Browse files
authored
Merge pull request #25 from stm32-rs/gd32v-ng
Add support for GD32VF103 chips
2 parents 8cbeb70 + 33798d6 commit 81b92b9

File tree

3 files changed

+63
-29
lines changed

3 files changed

+63
-29
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
88
## [Unreleased]
99

1010

11+
### Added
12+
13+
* Support for GD32VF103 chips (#25)
14+
1115
### Changed
1216

1317
* Use `critical-section` crate for critical sections.

src/bus.rs

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/endpoint.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,18 @@ impl EndpointOut {
189189
}
190190
}
191191

192-
pub fn deconfigure(&self, _cs: CriticalSection<'_>) {
192+
pub fn deconfigure(&self, _cs: CriticalSection<'_>, core_id: u32) {
193193
let regs = self.usb.endpoint_out(self.index() as usize);
194194

195-
// deactivating endpoint
196-
modify_reg!(endpoint_out, regs, DOEPCTL, USBAEP: 0);
195+
// GD32VF103 doesn't support endpoint deactivation after reset, so skip this.
196+
if core_id > 0x0000_1000 {
197+
// deactivating endpoint
198+
modify_reg!(endpoint_out, regs, DOEPCTL, USBAEP: 0);
197199

198-
// disabling endpoint
199-
if read_reg!(endpoint_out, regs, DOEPCTL, EPENA) != 0 && self.index() != 0 {
200-
modify_reg!(endpoint_out, regs, DOEPCTL, EPDIS: 1)
200+
// disabling endpoint
201+
if read_reg!(endpoint_out, regs, DOEPCTL, EPENA) != 0 && self.index() != 0 {
202+
modify_reg!(endpoint_out, regs, DOEPCTL, EPDIS: 1)
203+
}
201204
}
202205

203206
// clean EP interrupts

0 commit comments

Comments
 (0)