aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDerek Hageman <[email protected]>2024-01-04 07:53:31 -0700
committerDerek Hageman <[email protected]>2024-01-05 07:57:35 -0700
commitd34910dbc88d4d4b7cf907b17dd6ed4fd7e2f39c (patch)
tree2407e6f6771b0954a0727fc7349827ea491e6315 /examples
parent801a36c7b4e476388e55c842dec09d7ef2607a5a (diff)
stm32: Add G0 USB example
Add a USB CDC ACM example using STM32G0 USB and CRS.
Diffstat (limited to 'examples')
-rw-r--r--examples/stm32g0/.cargo/config.toml4
-rw-r--r--examples/stm32g0/Cargo.toml6
-rw-r--r--examples/stm32g0/src/bin/usb_serial.rs99
3 files changed, 105 insertions, 4 deletions
diff --git a/examples/stm32g0/.cargo/config.toml b/examples/stm32g0/.cargo/config.toml
index 35cca5412..f395d8920 100644
--- a/examples/stm32g0/.cargo/config.toml
+++ b/examples/stm32g0/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace STM32G071C8Rx with your chip as listed in `probe-rs chip list` 2# replace STM32G0B1RETx with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip STM32G071RBTx" 3runner = "probe-rs run --chip STM32G0B1RETx"
4 4
5[build] 5[build]
6target = "thumbv6m-none-eabi" 6target = "thumbv6m-none-eabi"
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml
index 0abc0a638..7ad36952f 100644
--- a/examples/stm32g0/Cargo.toml
+++ b/examples/stm32g0/Cargo.toml
@@ -5,11 +5,13 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32g071rb to your chip name, if necessary. 8# Change stm32g0b1re to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g0b1re", "memory-x", "unstable-pac", "exti"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
13 15
14defmt = "0.3" 16defmt = "0.3"
15defmt-rtt = "0.4" 17defmt-rtt = "0.4"
diff --git a/examples/stm32g0/src/bin/usb_serial.rs b/examples/stm32g0/src/bin/usb_serial.rs
new file mode 100644
index 000000000..f5aaa5624
--- /dev/null
+++ b/examples/stm32g0/src/bin/usb_serial.rs
@@ -0,0 +1,99 @@
1#![no_std]
2#![no_main]
3
4use defmt::{panic, *};
5use embassy_executor::Spawner;
6use embassy_futures::join::join;
7use embassy_stm32::rcc::{Hsi48Config, UsbSrc};
8use embassy_stm32::usb::{Driver, Instance};
9use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
11use embassy_usb::driver::EndpointError;
12use embassy_usb::Builder;
13use {defmt_rtt as _, panic_probe as _};
14
15bind_interrupts!(struct Irqs {
16 USB_UCPD1_2 => usb::InterruptHandler<peripherals::USB>;
17});
18
19#[embassy_executor::main]
20async fn main(_spawner: Spawner) {
21 let mut config = Config::default();
22 config.rcc.usb_src = Some(UsbSrc::Hsi48(Hsi48Config {
23 sync_from_usb: true,
24 ..Default::default()
25 }));
26 let p = embassy_stm32::init(config);
27
28 info!("Hello World!");
29
30 // Create the driver, from the HAL.
31 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
32
33 // Create embassy-usb Config
34 let config = embassy_usb::Config::new(0xc0de, 0xcafe);
35 //config.max_packet_size_0 = 64;
36
37 // Create embassy-usb DeviceBuilder using the driver and config.
38 // It needs some buffers for building the descriptors.
39 let mut device_descriptor = [0; 256];
40 let mut config_descriptor = [0; 256];
41 let mut bos_descriptor = [0; 256];
42 let mut control_buf = [0; 7];
43
44 let mut state = State::new();
45
46 let mut builder = Builder::new(
47 driver,
48 config,
49 &mut device_descriptor,
50 &mut config_descriptor,
51 &mut bos_descriptor,
52 &mut [], // no msos descriptors
53 &mut control_buf,
54 );
55
56 // Create classes on the builder.
57 let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
58
59 // Build the builder.
60 let mut usb = builder.build();
61
62 // Run the USB device.
63 let usb_fut = usb.run();
64
65 // Do stuff with the class!
66 let echo_fut = async {
67 loop {
68 class.wait_connection().await;
69 info!("Connected");
70 let _ = echo(&mut class).await;
71 info!("Disconnected");
72 }
73 };
74
75 // Run everything concurrently.
76 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
77 join(usb_fut, echo_fut).await;
78}
79
80struct Disconnected {}
81
82impl From<EndpointError> for Disconnected {
83 fn from(val: EndpointError) -> Self {
84 match val {
85 EndpointError::BufferOverflow => panic!("Buffer overflow"),
86 EndpointError::Disabled => Disconnected {},
87 }
88 }
89}
90
91async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> {
92 let mut buf = [0; 64];
93 loop {
94 let n = class.read_packet(&mut buf).await?;
95 let data = &buf[..n];
96 info!("data: {:x}", data);
97 class.write_packet(data).await?;
98 }
99}