aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorPhilip A Reimer <[email protected]>2022-04-09 14:25:29 -0600
committerPhilip A Reimer <[email protected]>2022-04-09 14:55:03 -0600
commitd8860c0b800fc00b88ae6564c4ddf92f619e4ce6 (patch)
treee1dcd24f0d427243fc1fbc8e711c84859b2a5c9c /examples
parentcd6250986a590983930158cc17aa7dbfd25f81ea (diff)
add stm32l4 hsi48 and usb example
Diffstat (limited to 'examples')
-rw-r--r--examples/stm32l4/Cargo.toml4
-rw-r--r--examples/stm32l4/src/bin/usb_uart.rs115
2 files changed, 118 insertions, 1 deletions
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index 0709a8f5b..5838d01db 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -10,7 +10,7 @@ resolver = "2"
10[dependencies] 10[dependencies]
11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] }
12embassy-traits = { version = "0.1.0", path = "../../embassy-traits" } 12embassy-traits = { version = "0.1.0", path = "../../embassy-traits" }
13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits"] } 13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits", "usb-otg"] }
14 14
15defmt = "0.3" 15defmt = "0.3"
16defmt-rtt = "0.3" 16defmt-rtt = "0.3"
@@ -24,4 +24,6 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
24heapless = { version = "0.7.5", default-features = false } 24heapless = { version = "0.7.5", default-features = false }
25 25
26micromath = "2.0.0" 26micromath = "2.0.0"
27usb-device = "0.2"
28usbd-serial = "0.1.1"
27 29
diff --git a/examples/stm32l4/src/bin/usb_uart.rs b/examples/stm32l4/src/bin/usb_uart.rs
new file mode 100644
index 000000000..878309550
--- /dev/null
+++ b/examples/stm32l4/src/bin/usb_uart.rs
@@ -0,0 +1,115 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt_rtt as _; // global logger
6use panic_probe as _;
7
8use defmt::{info, unwrap};
9use defmt_rtt as _; // global logger
10use embassy::interrupt::InterruptExt;
11use futures::pin_mut;
12use panic_probe as _; // print out panic messages
13
14use embassy::executor::Spawner;
15use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
16use embassy_stm32::pac::pwr::vals::Usv;
17use embassy_stm32::pac::{PWR, RCC};
18use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv};
19use embassy_stm32::usb_otg::{State, Usb, UsbBus, UsbOtg, UsbSerial};
20use embassy_stm32::{interrupt, Config, Peripherals};
21use usb_device::device::{UsbDeviceBuilder, UsbVidPid};
22
23static mut EP_MEMORY: [u32; 2048] = [0; 2048];
24
25// USB requires at least 48 MHz clock
26fn config() -> Config {
27 let mut config = Config::default();
28 // set up a 80Mhz clock
29 config.rcc.mux = ClockSrc::PLL(
30 PLLSource::HSI16,
31 PLLClkDiv::Div2,
32 PLLSrcDiv::Div2,
33 PLLMul::Mul20,
34 None,
35 );
36 // enable HSI48 clock for USB
37 config.rcc.hsi48 = true;
38 config
39}
40
41#[embassy::main(config = "config()")]
42async fn main(_spawner: Spawner, p: Peripherals) {
43 // Enable PWR peripheral
44 unsafe { RCC.apb1enr1().modify(|w| w.set_pwren(true)) };
45 unsafe { PWR.cr2().modify(|w| w.set_usv(Usv::VALID)) }
46
47 let mut rx_buffer = [0u8; 64];
48 // we send back input + cr + lf
49 let mut tx_buffer = [0u8; 66];
50
51 let peri = UsbOtg::new_fs(p.USB_OTG_FS, p.PA12, p.PA11);
52 let usb_bus = UsbBus::new(peri, unsafe { &mut EP_MEMORY });
53
54 let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer);
55
56 let device = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
57 .manufacturer("Fake company")
58 .product("Serial port")
59 .serial_number("TEST")
60 .device_class(0x02)
61 .build();
62
63 let irq = interrupt::take!(OTG_FS);
64 irq.set_priority(interrupt::Priority::P3);
65
66 let mut state = State::new();
67 let usb = unsafe { Usb::new(&mut state, device, serial, irq) };
68 pin_mut!(usb);
69
70 let (mut reader, mut writer) = usb.as_ref().take_serial_0();
71
72 info!("usb initialized!");
73
74 unwrap!(
75 writer
76 .write_all(b"\r\nInput returned upper cased on CR+LF\r\n")
77 .await
78 );
79
80 let mut buf = [0u8; 64];
81 loop {
82 let mut n = 0;
83
84 async {
85 loop {
86 let char = unwrap!(reader.read_byte().await);
87
88 if char == b'\r' || char == b'\n' {
89 break;
90 }
91
92 buf[n] = char;
93 n += 1;
94
95 // stop if we're out of room
96 if n == buf.len() {
97 break;
98 }
99 }
100 }
101 .await;
102
103 if n > 0 {
104 for char in buf[..n].iter_mut() {
105 // upper case
106 if 0x61 <= *char && *char <= 0x7a {
107 *char &= !0x20;
108 }
109 }
110 unwrap!(writer.write_all(&buf[..n]).await);
111 unwrap!(writer.write_all(b"\r\n").await);
112 unwrap!(writer.flush().await);
113 }
114 }
115}