aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32f4/src/serial.rs90
1 files changed, 55 insertions, 35 deletions
diff --git a/embassy-stm32f4/src/serial.rs b/embassy-stm32f4/src/serial.rs
index 7efb4a0bb..cc55ef325 100644
--- a/embassy-stm32f4/src/serial.rs
+++ b/embassy-stm32f4/src/serial.rs
@@ -5,6 +5,8 @@
5//! are dropped correctly (e.g. not using `mem::forget()`). 5//! are dropped correctly (e.g. not using `mem::forget()`).
6 6
7use core::future::Future; 7use core::future::Future;
8use core::ptr;
9use core::sync::atomic::{self, Ordering};
8use core::task::{Context, Poll}; 10use core::task::{Context, Poll};
9 11
10use embassy::interrupt::OwnedInterrupt; 12use embassy::interrupt::OwnedInterrupt;
@@ -33,31 +35,32 @@ use crate::pac::{DMA2, USART1};
33 35
34/// Interface to the Serial peripheral 36/// Interface to the Serial peripheral
35pub struct Serial<USART: PeriAddress<MemSize = u8>, TSTREAM: Stream, RSTREAM: Stream> { 37pub struct Serial<USART: PeriAddress<MemSize = u8>, TSTREAM: Stream, RSTREAM: Stream> {
36 // tx_transfer: Transfer<Stream7<DMA2>, Channel4, USART1, MemoryToPeripheral, &mut [u8; 20]>,
37 // rx_transfer: Transfer<Stream2<DMA2>, Channel4, USART1, PeripheralToMemory, &mut [u8; 20]>,
38 tx_stream: Option<TSTREAM>, 38 tx_stream: Option<TSTREAM>,
39 rx_stream: Option<RSTREAM>, 39 rx_stream: Option<RSTREAM>,
40 usart: Option<USART>, 40 usart: Option<USART>,
41 tx_int: interrupt::DMA2_STREAM7Interrupt,
42 rx_int: interrupt::DMA2_STREAM2Interrupt,
43 usart_int: interrupt::USART1Interrupt,
41} 44}
42 45
43struct State { 46struct State {
44 tx_done: Signal<()>, 47 tx_int: Signal<()>,
45 rx_done: Signal<()>, 48 rx_int: Signal<()>,
46 dma_done: Signal<()>,
47} 49}
48 50
49static STATE: State = State { 51static STATE: State = State {
50 tx_done: Signal::new(), 52 tx_int: Signal::new(),
51 rx_done: Signal::new(), 53 rx_int: Signal::new(),
52 dma_done: Signal::new(),
53}; 54};
54 55
56static mut INSTANCE: *const Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> = ptr::null_mut();
57
55impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { 58impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
56 pub fn new( 59 pub fn new(
57 txd: PA9<Alternate<AF7>>, 60 txd: PA9<Alternate<AF7>>,
58 rxd: PA10<Alternate<AF7>>, 61 rxd: PA10<Alternate<AF7>>,
59 tx_int: interrupt::DMA2_STREAM2Interrupt, 62 tx_int: interrupt::DMA2_STREAM7Interrupt,
60 rx_int: interrupt::DMA2_STREAM7Interrupt, 63 rx_int: interrupt::DMA2_STREAM2Interrupt,
61 usart_int: interrupt::USART1Interrupt, 64 usart_int: interrupt::USART1Interrupt,
62 dma: DMA2, 65 dma: DMA2,
63 usart: USART1, 66 usart: USART1,
@@ -80,20 +83,14 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
80 .unwrap(); 83 .unwrap();
81 84
82 serial.listen(SerialEvent::Idle); 85 serial.listen(SerialEvent::Idle);
83 serial.listen(SerialEvent::Txe); 86 // serial.listen(SerialEvent::Txe);
84 87
85 let (usart, _) = serial.release(); 88 let (usart, _) = serial.release();
86 89
87 // Register ISR 90 // Register ISR
88 tx_int.set_handler(Self::on_tx_irq); 91 tx_int.set_handler(Self::on_tx_irq);
89 tx_int.unpend();
90 tx_int.enable();
91
92 rx_int.set_handler(Self::on_rx_irq); 92 rx_int.set_handler(Self::on_rx_irq);
93 rx_int.unpend(); 93 usart_int.set_handler(Self::on_rx_irq);
94 rx_int.enable();
95
96 // usart_int.set_handler(Self::on_usart_irq);
97 // usart_int.unpend(); 94 // usart_int.unpend();
98 // usart_int.enable(); 95 // usart_int.enable();
99 96
@@ -103,40 +100,56 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
103 tx_stream: Some(streams.7), 100 tx_stream: Some(streams.7),
104 rx_stream: Some(streams.2), 101 rx_stream: Some(streams.2),
105 usart: Some(usart), 102 usart: Some(usart),
103 tx_int: tx_int,
104 rx_int: rx_int,
105 usart_int: usart_int,
106 } 106 }
107 } 107 }
108 108
109 unsafe fn on_tx_irq() { 109 unsafe fn on_tx_irq() {
110 STATE.tx_done.signal(()); 110 let s = &(*INSTANCE);
111
112 s.tx_int.disable();
113
114 STATE.tx_int.signal(());
111 } 115 }
112 116
113 unsafe fn on_rx_irq() { 117 unsafe fn on_rx_irq() {
114 STATE.rx_done.signal(()); 118 let s = &(*INSTANCE);
119
120 atomic::compiler_fence(Ordering::Acquire);
121 s.rx_int.disable();
122 s.usart_int.disable();
123 atomic::compiler_fence(Ordering::Release);
124
125 STATE.rx_int.signal(());
115 } 126 }
116 127
117 unsafe fn on_usart_irq() { 128 unsafe fn on_usart_irq() {
118 /* 129 let s = &(*INSTANCE);
119 TODO: Signal tx_done if txe
120 */
121 130
122 /* 131 atomic::compiler_fence(Ordering::Acquire);
123 TODO: Signal rx_done if idle 132 s.rx_int.disable();
124 */ 133 s.usart_int.disable();
134 atomic::compiler_fence(Ordering::Release);
125 135
126 // STATE.rx_done.signal(()); 136 STATE.rx_int.signal(());
127 } 137 }
138
128 /// Sends serial data. 139 /// Sends serial data.
129 /// 140 ///
130 /// `tx_buffer` is marked as static as per `embedded-dma` requirements. 141 /// `tx_buffer` is marked as static as per `embedded-dma` requirements.
131 /// It it safe to use a buffer with a non static lifetime if memory is not 142 /// It it safe to use a buffer with a non static lifetime if memory is not
132 /// reused until the future has finished. 143 /// reused until the future has finished.
133 pub fn send<'a, B>(&'a mut self, tx_buffer: B) -> impl Future<Output = ()> + 'a 144 pub fn send<'a, B: 'a>(&'a mut self, tx_buffer: B) -> impl Future<Output = ()> + 'a
134 where 145 where
135 B: WriteBuffer<Word = u8> + 'static, 146 B: StaticWriteBuffer<Word = u8>,
136 { 147 {
148 unsafe { INSTANCE = self };
149
137 let tx_stream = self.tx_stream.take().unwrap(); 150 let tx_stream = self.tx_stream.take().unwrap();
138 let usart = self.usart.take().unwrap(); 151 let usart = self.usart.take().unwrap();
139 STATE.tx_done.reset(); 152 STATE.tx_int.reset();
140 153
141 async move { 154 async move {
142 let mut tx_transfer = Transfer::init( 155 let mut tx_transfer = Transfer::init(
@@ -150,9 +163,11 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
150 .double_buffer(false), 163 .double_buffer(false),
151 ); 164 );
152 165
166 self.tx_int.unpend();
167 self.tx_int.enable();
153 tx_transfer.start(|_usart| {}); 168 tx_transfer.start(|_usart| {});
154 169
155 STATE.tx_done.wait().await; 170 STATE.tx_int.wait().await;
156 171
157 let (tx_stream, usart, _buf, _) = tx_transfer.free(); 172 let (tx_stream, usart, _buf, _) = tx_transfer.free();
158 self.tx_stream.replace(tx_stream); 173 self.tx_stream.replace(tx_stream);
@@ -170,13 +185,15 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
170 /// `rx_buffer` is marked as static as per `embedded-dma` requirements. 185 /// `rx_buffer` is marked as static as per `embedded-dma` requirements.
171 /// It it safe to use a buffer with a non static lifetime if memory is not 186 /// It it safe to use a buffer with a non static lifetime if memory is not
172 /// reused until the future has finished. 187 /// reused until the future has finished.
173 pub fn receive<'a, B>(&'a mut self, rx_buffer: B) -> impl Future<Output = B> + 'a 188 pub fn receive<'a, B: 'a>(&'a mut self, rx_buffer: B) -> impl Future<Output = B> + 'a
174 where 189 where
175 B: WriteBuffer<Word = u8> + 'static + Unpin, 190 B: StaticWriteBuffer<Word = u8> + Unpin,
176 { 191 {
192 unsafe { INSTANCE = self };
193
177 let rx_stream = self.rx_stream.take().unwrap(); 194 let rx_stream = self.rx_stream.take().unwrap();
178 let usart = self.usart.take().unwrap(); 195 let usart = self.usart.take().unwrap();
179 STATE.rx_done.reset(); 196 STATE.rx_int.reset();
180 197
181 async move { 198 async move {
182 let mut rx_transfer = Transfer::init( 199 let mut rx_transfer = Transfer::init(
@@ -190,9 +207,12 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
190 .double_buffer(false), 207 .double_buffer(false),
191 ); 208 );
192 209
210 self.rx_int.unpend();
211 self.rx_int.enable();
212
193 rx_transfer.start(|_usart| {}); 213 rx_transfer.start(|_usart| {});
194 214
195 STATE.rx_done.wait().await; 215 STATE.rx_int.wait().await;
196 216
197 let (rx_stream, usart, buf, _) = rx_transfer.free(); 217 let (rx_stream, usart, buf, _) = rx_transfer.free();
198 self.rx_stream.replace(rx_stream); 218 self.rx_stream.replace(rx_stream);