aboutsummaryrefslogtreecommitdiff
path: root/examples/stm32l1/src/bin/usb_serial.rs
diff options
context:
space:
mode:
authorshufps <[email protected]>2024-01-14 22:46:20 +0100
committershufps <[email protected]>2024-01-14 22:46:20 +0100
commitec4cffe28c314b8cb69998fe0b5ddafbf4e092e8 (patch)
tree2ead15d5325fc2292cbdda01ec810179a6cf8991 /examples/stm32l1/src/bin/usb_serial.rs
parent018c48cf1ce54effe73f2287cb78fabbdede215c (diff)
usb-serial with HSI
Diffstat (limited to 'examples/stm32l1/src/bin/usb_serial.rs')
-rw-r--r--examples/stm32l1/src/bin/usb_serial.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/examples/stm32l1/src/bin/usb_serial.rs b/examples/stm32l1/src/bin/usb_serial.rs
new file mode 100644
index 000000000..7b1e84cbc
--- /dev/null
+++ b/examples/stm32l1/src/bin/usb_serial.rs
@@ -0,0 +1,103 @@
1#![no_std]
2#![no_main]
3
4use defmt::{panic, *};
5use embassy_executor::Spawner;
6use embassy_stm32::usb::{self, Driver, Instance};
7use embassy_stm32::{bind_interrupts, peripherals};
8use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
9use embassy_usb::driver::EndpointError;
10use embassy_usb::Builder;
11use futures::future::join;
12use {defmt_rtt as _, panic_probe as _};
13
14bind_interrupts!(struct Irqs {
15 USB_LP => usb::InterruptHandler<peripherals::USB>;
16
17});
18
19#[embassy_executor::main]
20async fn main(_spawner: Spawner) {
21 let mut config = embassy_stm32::Config::default();
22 {
23 use embassy_stm32::rcc::*;
24 config.rcc.hsi = true;
25 config.rcc.pll = Some(Pll {
26 source: PllSource::HSI,
27 mul: PllMul::MUL6, // PLLVCO = 16*6 = 96Mhz
28 div: PllDiv::DIV3, // 32Mhz clock (16 * 6 / 3)
29 });
30 config.rcc.mux = ClockSrc::PLL1_R;
31 }
32
33 let p = embassy_stm32::init(config);
34
35 info!("Hello World!");
36
37 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
38
39 let mut config = embassy_usb::Config::new(0xc0de, 0xcafe);
40 config.manufacturer = Some("Embassy");
41 config.product = Some("USB-Serial Example");
42 config.serial_number = Some("123456");
43
44 config.device_class = 0xEF;
45 config.device_sub_class = 0x02;
46 config.device_protocol = 0x01;
47 config.composite_with_iads = true;
48
49 let mut device_descriptor = [0; 256];
50 let mut config_descriptor = [0; 256];
51 let mut bos_descriptor = [0; 256];
52 let mut control_buf = [0; 64];
53
54 let mut state = State::new();
55
56 let mut builder = Builder::new(
57 driver,
58 config,
59 &mut device_descriptor,
60 &mut config_descriptor,
61 &mut bos_descriptor,
62 &mut [], // no msos descriptors
63 &mut control_buf,
64 );
65
66 let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
67
68 let mut usb = builder.build();
69
70 let usb_fut = usb.run();
71
72 let echo_fut = async {
73 loop {
74 class.wait_connection().await;
75 info!("Connected");
76 let _ = echo(&mut class).await;
77 info!("Disconnected");
78 }
79 };
80
81 join(usb_fut, echo_fut).await;
82}
83
84struct Disconnected {}
85
86impl From<EndpointError> for Disconnected {
87 fn from(val: EndpointError) -> Self {
88 match val {
89 EndpointError::BufferOverflow => panic!("Buffer overflow"),
90 EndpointError::Disabled => Disconnected {},
91 }
92 }
93}
94
95async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> {
96 let mut buf = [0; 64];
97 loop {
98 let n = class.read_packet(&mut buf).await?;
99 let data = &buf[..n];
100 info!("data: {:x}", data);
101 class.write_packet(data).await?;
102 }
103}