aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32f4-examples/src/bin/usb_serial.rs85
-rw-r--r--embassy-stm32f4/src/usb.rs136
-rw-r--r--embassy-stm32f4/src/usb_serial.rs28
3 files changed, 200 insertions, 49 deletions
diff --git a/embassy-stm32f4-examples/src/bin/usb_serial.rs b/embassy-stm32f4-examples/src/bin/usb_serial.rs
index d2ccb4b21..cf04c772e 100644
--- a/embassy-stm32f4-examples/src/bin/usb_serial.rs
+++ b/embassy-stm32f4-examples/src/bin/usb_serial.rs
@@ -10,12 +10,11 @@ use cortex_m_rt::entry;
10use defmt::panic; 10use defmt::panic;
11use embassy::executor::{task, Executor}; 11use embassy::executor::{task, Executor};
12use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; 12use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
13use embassy::time::{Duration, Timer};
14use embassy::util::Forever; 13use embassy::util::Forever;
15use embassy_stm32f4::interrupt::OwnedInterrupt; 14use embassy_stm32f4::interrupt::OwnedInterrupt;
16use embassy_stm32f4::usb::Usb; 15use embassy_stm32f4::usb::Usb;
17use embassy_stm32f4::usb_serial::UsbSerial; 16use embassy_stm32f4::usb_serial::UsbSerial;
18use embassy_stm32f4::{interrupt, pac, rtc}; 17use embassy_stm32f4::{interrupt, pac};
19use futures::future::{select, Either}; 18use futures::future::{select, Either};
20use futures::pin_mut; 19use futures::pin_mut;
21use stm32f4xx_hal::otg_fs::{UsbBus, USB}; 20use stm32f4xx_hal::otg_fs::{UsbBus, USB};
@@ -27,44 +26,81 @@ use usb_device::prelude::*;
27async fn run1(bus: &'static mut UsbBusAllocator<UsbBus<USB>>) { 26async fn run1(bus: &'static mut UsbBusAllocator<UsbBus<USB>>) {
28 info!("Async task"); 27 info!("Async task");
29 28
30 let mut read_buf = [0u8; 128]; 29 let mut read_buf1 = [0u8; 128];
31 let mut write_buf = [0u8; 128]; 30 let mut write_buf1 = [0u8; 128];
32 let serial = UsbSerial::new(bus, &mut read_buf, &mut write_buf); 31 let serial1 = UsbSerial::new(bus, &mut read_buf1, &mut write_buf1);
32
33 let mut read_buf2 = [0u8; 128];
34 let mut write_buf2 = [0u8; 128];
35 let serial2 = UsbSerial::new(bus, &mut read_buf2, &mut write_buf2);
33 36
34 let device = UsbDeviceBuilder::new(bus, UsbVidPid(0x16c0, 0x27dd)) 37 let device = UsbDeviceBuilder::new(bus, UsbVidPid(0x16c0, 0x27dd))
35 .manufacturer("Fake company") 38 .manufacturer("Fake company")
36 .product("Serial port") 39 .product("Serial port")
37 .serial_number("TEST") 40 .serial_number("TEST")
38 .device_class(0x02) 41 //.device_class(0x02)
39 .build(); 42 .build();
40 43
41 let irq = interrupt::take!(OTG_FS); 44 let irq = interrupt::take!(OTG_FS);
42 irq.set_priority(interrupt::Priority::Level3); 45 irq.set_priority(interrupt::Priority::Level3);
43 46
44 let usb = Usb::new(device, serial, irq); 47 let usb = Usb::new(device, (serial1, serial2), irq);
45 pin_mut!(usb); 48 pin_mut!(usb);
46 49
47 let (mut read_interface, mut write_interface) = usb.as_mut().into_ref().take_serial(); 50 let (mut read_interface1, mut write_interface1) = usb.as_ref().take_serial_0();
51 let (mut read_interface2, mut write_interface2) = usb.as_ref().take_serial_1();
48 52
49 let mut buf = [0u8; 5]; 53 let mut buf1 = [0u8; 64];
50 loop { 54 let mut buf2 = [0u8; 64];
51 let recv_fut = read_interface.read(&mut buf);
52 let timeout = Timer::after(Duration::from_ticks(32768 * 3));
53 55
54 match select(recv_fut, timeout).await { 56 loop {
55 Either::Left((recv, _)) => { 57 let mut n1 = 0;
56 let recv = unwrap!(recv); 58 let mut n2 = 0;
57 unwrap!(write_interface.write_all(&buf[..recv]).await); 59 let left = {
58 } 60 let read_line1 = async {
59 Either::Right(_) => { 61 loop {
60 unwrap!(write_interface.write_all(b"Hello\r\n").await); 62 let byte = unwrap!(read_interface1.read_byte().await);
63 unwrap!(write_interface1.write_byte(byte).await);
64 buf1[n1] = byte;
65
66 n1 += 1;
67 if byte == b'\n' || n1 == buf1.len() {
68 break;
69 }
70 }
71 };
72 pin_mut!(read_line1);
73
74 let read_line2 = async {
75 loop {
76 let byte = unwrap!(read_interface2.read_byte().await);
77 unwrap!(write_interface2.write_byte(byte).await);
78 buf2[n2] = byte;
79
80 n2 += 1;
81 if byte == b'\n' || n2 == buf2.len() {
82 break;
83 }
84 }
85 };
86 pin_mut!(read_line2);
87
88 match select(read_line1, read_line2).await {
89 Either::Left(_) => true,
90 Either::Right(_) => false,
61 } 91 }
92 };
93
94 if left {
95 unwrap!(write_interface2.write_all(b"\r\n").await);
96 unwrap!(write_interface2.write_all(&buf1[..n1]).await);
97 } else {
98 unwrap!(write_interface1.write_all(b"\r\n").await);
99 unwrap!(write_interface1.write_all(&buf2[..n2]).await);
62 } 100 }
63 } 101 }
64} 102}
65 103
66static RTC: Forever<rtc::RTC<pac::TIM2>> = Forever::new();
67static ALARM: Forever<rtc::Alarm<pac::TIM2>> = Forever::new();
68static EXECUTOR: Forever<Executor> = Forever::new(); 104static EXECUTOR: Forever<Executor> = Forever::new();
69static USB_BUS: Forever<UsbBusAllocator<UsbBus<USB>>> = Forever::new(); 105static USB_BUS: Forever<UsbBusAllocator<UsbBus<USB>>> = Forever::new();
70 106
@@ -91,14 +127,7 @@ fn main() -> ! {
91 w.dbg_stop().set_bit() 127 w.dbg_stop().set_bit()
92 }); 128 });
93 129
94 let rtc = RTC.put(rtc::RTC::new(p.TIM2, interrupt::take!(TIM2), clocks));
95 rtc.start();
96
97 unsafe { embassy::time::set_clock(rtc) };
98
99 let alarm = ALARM.put(rtc.alarm1());
100 let executor = EXECUTOR.put(Executor::new()); 130 let executor = EXECUTOR.put(Executor::new());
101 executor.set_alarm(alarm);
102 131
103 let gpioa = p.GPIOA.split(); 132 let gpioa = p.GPIOA.split();
104 let usb = USB { 133 let usb = USB {
diff --git a/embassy-stm32f4/src/usb.rs b/embassy-stm32f4/src/usb.rs
index 613b9ecb7..9e7411562 100644
--- a/embassy-stm32f4/src/usb.rs
+++ b/embassy-stm32f4/src/usb.rs
@@ -10,12 +10,20 @@ use crate::interrupt;
10use crate::usb_serial::{ReadInterface, UsbSerial, WriteInterface}; 10use crate::usb_serial::{ReadInterface, UsbSerial, WriteInterface};
11use crate::util::peripheral::{PeripheralMutex, PeripheralState}; 11use crate::util::peripheral::{PeripheralMutex, PeripheralState};
12 12
13pub struct State<'bus, B: UsbBus, T: ClassSet<B>> { 13pub struct State<'bus, B, T>
14where
15 B: UsbBus,
16 T: ClassSet<B>,
17{
14 device: UsbDevice<'bus, B>, 18 device: UsbDevice<'bus, B>,
15 pub(crate) classes: T, 19 pub(crate) classes: T,
16} 20}
17 21
18pub struct Usb<'bus, B: UsbBus, T: ClassSet<B>> { 22pub struct Usb<'bus, B, T>
23where
24 B: UsbBus,
25 T: ClassSet<B>,
26{
19 // Don't you dare moving out `PeripheralMutex` 27 // Don't you dare moving out `PeripheralMutex`
20 inner: RefCell<PeripheralMutex<State<'bus, B, T>>>, 28 inner: RefCell<PeripheralMutex<State<'bus, B, T>>>,
21} 29}
@@ -53,24 +61,54 @@ where
53impl<'bus, 'c, B, T> Usb<'bus, B, T> 61impl<'bus, 'c, B, T> Usb<'bus, B, T>
54where 62where
55 B: UsbBus, 63 B: UsbBus,
56 T: ClassSet<B> + SerialState<'bus, 'c, B>, 64 T: ClassSet<B> + SerialState<'bus, 'c, B, Index0>,
57{ 65{
58 pub fn take_serial<'a>( 66 pub fn take_serial_0<'a>(
59 self: Pin<&'a Self>, 67 self: Pin<&'a Self>,
60 ) -> ( 68 ) -> (
61 ReadInterface<'a, 'bus, 'c, B, T>, 69 ReadInterface<'a, 'bus, 'c, Index0, B, T>,
62 WriteInterface<'a, 'bus, 'c, B, T>, 70 WriteInterface<'a, 'bus, 'c, Index0, B, T>,
63 ) { 71 ) {
64 let this = self.get_ref(); 72 let this = self.get_ref();
65 73
66 let r = ReadInterface { 74 let r = ReadInterface {
67 inner: &this.inner, 75 inner: &this.inner,
68 _buf_lifetime: PhantomData, 76 _buf_lifetime: PhantomData,
77 _index: PhantomData,
69 }; 78 };
70 79
71 let w = WriteInterface { 80 let w = WriteInterface {
72 inner: &this.inner, 81 inner: &this.inner,
73 _buf_lifetime: PhantomData, 82 _buf_lifetime: PhantomData,
83 _index: PhantomData,
84 };
85 (r, w)
86 }
87}
88
89impl<'bus, 'c, B, T> Usb<'bus, B, T>
90where
91 B: UsbBus,
92 T: ClassSet<B> + SerialState<'bus, 'c, B, Index1>,
93{
94 pub fn take_serial_1<'a>(
95 self: Pin<&'a Self>,
96 ) -> (
97 ReadInterface<'a, 'bus, 'c, Index1, B, T>,
98 WriteInterface<'a, 'bus, 'c, Index1, B, T>,
99 ) {
100 let this = self.get_ref();
101
102 let r = ReadInterface {
103 inner: &this.inner,
104 _buf_lifetime: PhantomData,
105 _index: PhantomData,
106 };
107
108 let w = WriteInterface {
109 inner: &this.inner,
110 _buf_lifetime: PhantomData,
111 _index: PhantomData,
74 }; 112 };
75 (r, w) 113 (r, w)
76 } 114 }
@@ -95,23 +133,56 @@ pub trait IntoClassSet<B: UsbBus, C: ClassSet<B>> {
95 fn into_class_set(self) -> C; 133 fn into_class_set(self) -> C;
96} 134}
97 135
98pub struct ClassSet1<B: UsbBus, T: UsbClass<B>> { 136pub struct ClassSet1<B, C1>
99 class: T, 137where
138 B: UsbBus,
139 C1: UsbClass<B>,
140{
141 class: C1,
100 _bus: PhantomData<B>, 142 _bus: PhantomData<B>,
101} 143}
102 144
103impl<B, T> ClassSet<B> for ClassSet1<B, T> 145pub struct ClassSet2<B, C1, C2>
104where 146where
105 B: UsbBus, 147 B: UsbBus,
106 T: UsbClass<B>, 148 C1: UsbClass<B>,
149 C2: UsbClass<B>,
150{
151 class1: C1,
152 class2: C2,
153 _bus: PhantomData<B>,
154}
155
156pub struct Index0;
157pub struct Index1;
158
159impl<B, C1> ClassSet<B> for ClassSet1<B, C1>
160where
161 B: UsbBus,
162 C1: UsbClass<B>,
107{ 163{
108 fn poll_all(&mut self, device: &mut UsbDevice<'_, B>) -> bool { 164 fn poll_all(&mut self, device: &mut UsbDevice<'_, B>) -> bool {
109 device.poll(&mut [&mut self.class]) 165 device.poll(&mut [&mut self.class])
110 } 166 }
111} 167}
112 168
113impl<B: UsbBus, T: UsbClass<B>> IntoClassSet<B, ClassSet1<B, T>> for T { 169impl<B, C1, C2> ClassSet<B> for ClassSet2<B, C1, C2>
114 fn into_class_set(self) -> ClassSet1<B, T> { 170where
171 B: UsbBus,
172 C1: UsbClass<B>,
173 C2: UsbClass<B>,
174{
175 fn poll_all(&mut self, device: &mut UsbDevice<'_, B>) -> bool {
176 device.poll(&mut [&mut self.class1, &mut self.class2])
177 }
178}
179
180impl<B, C1> IntoClassSet<B, ClassSet1<B, C1>> for C1
181where
182 B: UsbBus,
183 C1: UsbClass<B>,
184{
185 fn into_class_set(self) -> ClassSet1<B, C1> {
115 ClassSet1 { 186 ClassSet1 {
116 class: self, 187 class: self,
117 _bus: PhantomData, 188 _bus: PhantomData,
@@ -119,12 +190,49 @@ impl<B: UsbBus, T: UsbClass<B>> IntoClassSet<B, ClassSet1<B, T>> for T {
119 } 190 }
120} 191}
121 192
122pub trait SerialState<'bus, 'a, B: UsbBus> { 193impl<B, C1, C2> IntoClassSet<B, ClassSet2<B, C1, C2>> for (C1, C2)
194where
195 B: UsbBus,
196 C1: UsbClass<B>,
197 C2: UsbClass<B>,
198{
199 fn into_class_set(self) -> ClassSet2<B, C1, C2> {
200 ClassSet2 {
201 class1: self.0,
202 class2: self.1,
203 _bus: PhantomData,
204 }
205 }
206}
207
208pub trait SerialState<'bus, 'a, B: UsbBus, I> {
123 fn get_serial(&mut self) -> &mut UsbSerial<'bus, 'a, B>; 209 fn get_serial(&mut self) -> &mut UsbSerial<'bus, 'a, B>;
124} 210}
125 211
126impl<'bus, 'a, B: UsbBus> SerialState<'bus, 'a, B> for ClassSet1<B, UsbSerial<'bus, 'a, B>> { 212impl<'bus, 'a, B: UsbBus> SerialState<'bus, 'a, B, Index0>
213 for ClassSet1<B, UsbSerial<'bus, 'a, B>>
214{
127 fn get_serial(&mut self) -> &mut UsbSerial<'bus, 'a, B> { 215 fn get_serial(&mut self) -> &mut UsbSerial<'bus, 'a, B> {
128 &mut self.class 216 &mut self.class
129 } 217 }
130} 218}
219
220impl<'bus, 'a, B, C2> SerialState<'bus, 'a, B, Index0> for ClassSet2<B, UsbSerial<'bus, 'a, B>, C2>
221where
222 B: UsbBus,
223 C2: UsbClass<B>,
224{
225 fn get_serial(&mut self) -> &mut UsbSerial<'bus, 'a, B> {
226 &mut self.class1
227 }
228}
229
230impl<'bus, 'a, B, C1> SerialState<'bus, 'a, B, Index1> for ClassSet2<B, C1, UsbSerial<'bus, 'a, B>>
231where
232 B: UsbBus,
233 C1: UsbClass<B>,
234{
235 fn get_serial(&mut self) -> &mut UsbSerial<'bus, 'a, B> {
236 &mut self.class2
237 }
238}
diff --git a/embassy-stm32f4/src/usb_serial.rs b/embassy-stm32f4/src/usb_serial.rs
index 284d7e5f6..bacc886d8 100644
--- a/embassy-stm32f4/src/usb_serial.rs
+++ b/embassy-stm32f4/src/usb_serial.rs
@@ -1,5 +1,5 @@
1use core::cell::RefCell; 1use core::cell::RefCell;
2use core::marker::{PhantomData, PhantomPinned}; 2use core::marker::{PhantomData, Unpin};
3use core::pin::Pin; 3use core::pin::Pin;
4use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
5 5
@@ -14,26 +14,39 @@ use crate::usb::{ClassSet, SerialState, State};
14use crate::util::peripheral::PeripheralMutex; 14use crate::util::peripheral::PeripheralMutex;
15use crate::util::ring_buffer::RingBuffer; 15use crate::util::ring_buffer::RingBuffer;
16 16
17pub struct ReadInterface<'a, 'bus, 'c, B: UsbBus, T: SerialState<'bus, 'c, B> + ClassSet<B>> { 17pub struct ReadInterface<'a, 'bus, 'c, I, B, T>
18where
19 I: Unpin,
20 B: UsbBus,
21 T: SerialState<'bus, 'c, B, I> + ClassSet<B>,
22{
18 // Don't you dare moving out `PeripheralMutex` 23 // Don't you dare moving out `PeripheralMutex`
19 pub(crate) inner: &'a RefCell<PeripheralMutex<State<'bus, B, T>>>, 24 pub(crate) inner: &'a RefCell<PeripheralMutex<State<'bus, B, T>>>,
20 pub(crate) _buf_lifetime: PhantomData<&'c T>, 25 pub(crate) _buf_lifetime: PhantomData<&'c T>,
26 pub(crate) _index: PhantomData<I>,
21} 27}
22 28
23/// Write interface for USB CDC_ACM 29/// Write interface for USB CDC_ACM
24/// 30///
25/// This interface is buffered, meaning that after the write returns the bytes might not be fully 31/// This interface is buffered, meaning that after the write returns the bytes might not be fully
26/// on the wire just yet 32/// on the wire just yet
27pub struct WriteInterface<'a, 'bus, 'c, B: UsbBus, T: SerialState<'bus, 'c, B> + ClassSet<B>> { 33pub struct WriteInterface<'a, 'bus, 'c, I, B, T>
34where
35 I: Unpin,
36 B: UsbBus,
37 T: SerialState<'bus, 'c, B, I> + ClassSet<B>,
38{
28 // Don't you dare moving out `PeripheralMutex` 39 // Don't you dare moving out `PeripheralMutex`
29 pub(crate) inner: &'a RefCell<PeripheralMutex<State<'bus, B, T>>>, 40 pub(crate) inner: &'a RefCell<PeripheralMutex<State<'bus, B, T>>>,
30 pub(crate) _buf_lifetime: PhantomData<&'c T>, 41 pub(crate) _buf_lifetime: PhantomData<&'c T>,
42 pub(crate) _index: PhantomData<I>,
31} 43}
32 44
33impl<'a, 'bus, 'c, B, T> AsyncBufRead for ReadInterface<'a, 'bus, 'c, B, T> 45impl<'a, 'bus, 'c, I, B, T> AsyncBufRead for ReadInterface<'a, 'bus, 'c, I, B, T>
34where 46where
47 I: Unpin,
35 B: UsbBus, 48 B: UsbBus,
36 T: SerialState<'bus, 'c, B> + ClassSet<B>, 49 T: SerialState<'bus, 'c, B, I> + ClassSet<B>,
37{ 50{
38 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> { 51 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
39 let this = self.get_mut(); 52 let this = self.get_mut();
@@ -68,10 +81,11 @@ where
68 } 81 }
69} 82}
70 83
71impl<'a, 'bus, 'c, B, T> AsyncWrite for WriteInterface<'a, 'bus, 'c, B, T> 84impl<'a, 'bus, 'c, I, B, T> AsyncWrite for WriteInterface<'a, 'bus, 'c, I, B, T>
72where 85where
86 I: Unpin,
73 B: UsbBus, 87 B: UsbBus,
74 T: SerialState<'bus, 'c, B> + ClassSet<B>, 88 T: SerialState<'bus, 'c, B, I> + ClassSet<B>,
75{ 89{
76 fn poll_write( 90 fn poll_write(
77 self: Pin<&mut Self>, 91 self: Pin<&mut Self>,