Skip to content

Commit 4c6e0ae

Browse files
committed
Add example using RTIC
1 parent 5d348a8 commit 4c6e0ae

File tree

3 files changed

+153
-0
lines changed

3 files changed

+153
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ required-features = ["rt"]
202202
name = "usb_serial"
203203
required-features = ["usb_hs"]
204204

205+
[[example]]
206+
name = "usb_rtic"
207+
required-features = ["rt", "usb_hs"]
208+
205209
[[example]]
206210
name = "usb_passthrough"
207211
required-features = ["usb_hs", "rm0399"]

examples/usb_rtic.rs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
//! CDC-ACM serial port example using polling in a busy loop
2+
//!
3+
#![deny(warnings)]
4+
#![no_std]
5+
#![no_main]
6+
7+
#[macro_use]
8+
mod utilities;
9+
10+
#[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true)]
11+
mod app {
12+
use stm32h7xx_hal::gpio::gpioe::PE1;
13+
use stm32h7xx_hal::gpio::{Output, PushPull};
14+
use stm32h7xx_hal::hal::digital::v2::OutputPin;
15+
use stm32h7xx_hal::prelude::*;
16+
use stm32h7xx_hal::rcc::rec::UsbClkSel;
17+
use stm32h7xx_hal::usb_hs::{UsbBus, USB1};
18+
use usb_device::prelude::*;
19+
20+
static mut EP_MEMORY: [u32; 1024] = [0; 1024];
21+
use super::utilities;
22+
23+
#[shared]
24+
struct SharedResources {}
25+
#[local]
26+
struct LocalResources {
27+
usb: (
28+
UsbDevice<'static, UsbBus<USB1>>,
29+
usbd_serial::SerialPort<'static, UsbBus<USB1>>,
30+
),
31+
led: PE1<Output<PushPull>>,
32+
}
33+
34+
#[init]
35+
fn init(
36+
ctx: init::Context,
37+
) -> (SharedResources, LocalResources, init::Monotonics) {
38+
utilities::logger::init();
39+
let pwr = ctx.device.PWR.constrain();
40+
let pwrcfg = example_power!(pwr).freeze();
41+
42+
// RCC
43+
let rcc = ctx.device.RCC.constrain();
44+
let mut ccdr = rcc.sys_ck(80.mhz()).freeze(pwrcfg, &ctx.device.SYSCFG);
45+
46+
// 48MHz CLOCK
47+
let _ = ccdr.clocks.hsi48_ck().expect("HSI48 must run");
48+
ccdr.peripheral.kernel_usb_clk_mux(UsbClkSel::HSI48);
49+
50+
// If your hardware uses the internal USB voltage regulator in ON mode, you
51+
// should uncomment this block.
52+
// unsafe {
53+
// let pwr = &*stm32::PWR::ptr();
54+
// pwr.cr3.modify(|_, w| w.usbregen().set_bit());
55+
// while pwr.cr3.read().usb33rdy().bit_is_clear() {}
56+
// }
57+
58+
// IO
59+
#[cfg(any(feature = "rm0433", feature = "rm0399"))]
60+
let (pin_dm, pin_dp) = {
61+
let gpiob = ctx.device.GPIOB.split(ccdr.peripheral.GPIOB);
62+
(
63+
gpiob.pb14.into_alternate_af12(),
64+
gpiob.pb15.into_alternate_af12(),
65+
)
66+
};
67+
68+
#[cfg(any(feature = "rm0455", feature = "rm0468"))]
69+
let (pin_dm, pin_dp) = {
70+
let gpioa = ctx.device.GPIOA.split(ccdr.peripheral.GPIOA);
71+
(
72+
gpioa.pa11.into_alternate_af10(),
73+
gpioa.pa12.into_alternate_af10(),
74+
)
75+
};
76+
77+
let led = ctx.device.GPIOE.split(ccdr.peripheral.GPIOE).pe1;
78+
let usb = USB1::new(
79+
ctx.device.OTG1_HS_GLOBAL,
80+
ctx.device.OTG1_HS_DEVICE,
81+
ctx.device.OTG1_HS_PWRCLK,
82+
pin_dm,
83+
pin_dp,
84+
ccdr.peripheral.USB1OTG,
85+
&ccdr.clocks,
86+
);
87+
88+
let usb_bus = cortex_m::singleton!(
89+
: usb_device::class_prelude::UsbBusAllocator<UsbBus<USB1>> =
90+
UsbBus::new(usb, unsafe { &mut EP_MEMORY })
91+
)
92+
.unwrap();
93+
let serial = usbd_serial::SerialPort::new(usb_bus);
94+
let usb_dev = UsbDeviceBuilder::new(usb_bus, UsbVidPid(0x16c0, 0x27dd))
95+
.manufacturer("Fake company")
96+
.product("Serial port")
97+
.serial_number("TEST")
98+
.device_class(usbd_serial::USB_CLASS_CDC)
99+
.build();
100+
let usb = (usb_dev, serial);
101+
102+
(
103+
SharedResources {},
104+
LocalResources {
105+
usb,
106+
led: led.into_push_pull_output(),
107+
},
108+
init::Monotonics(),
109+
)
110+
}
111+
112+
#[task(binds = OTG_HS, local = [usb,led])]
113+
fn usb_event(mut ctx: usb_event::Context) {
114+
let (usb_dev, serial) = &mut ctx.local.usb;
115+
ctx.local.led.set_high().ok();
116+
117+
loop {
118+
if !usb_dev.poll(&mut [serial]) {
119+
ctx.local.led.set_low().ok();
120+
return;
121+
}
122+
123+
let mut buf = [0u8; 64];
124+
125+
match serial.read(&mut buf) {
126+
Ok(count) if count > 0 => {
127+
// Echo back in upper case
128+
for c in buf[0..count].iter_mut() {
129+
if 0x61 <= *c && *c <= 0x7a {
130+
*c &= !0x20;
131+
}
132+
}
133+
134+
let mut write_offset = 0;
135+
while write_offset < count {
136+
match serial.write(&buf[write_offset..count]) {
137+
Ok(len) if len > 0 => {
138+
write_offset += len;
139+
}
140+
_ => {}
141+
}
142+
}
143+
}
144+
_ => {}
145+
}
146+
}
147+
}
148+
}

src/usb_hs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//!
77
//! - [USB Serial Port](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/usb_serial.rs)
88
//! - [USB Passthrough Examples](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/usb_passthrough.rs)
9+
//! - [USB Serial Port with Interrupts and RTIC](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/usb_rtic.rs)
910
1011
use crate::rcc;
1112
use crate::stm32;

0 commit comments

Comments
 (0)