diff options
| author | xoviat <[email protected]> | 2020-12-31 17:59:01 -0600 |
|---|---|---|
| committer | xoviat <[email protected]> | 2020-12-31 17:59:01 -0600 |
| commit | d5cb9bebaa6d33bffa63211ed53ddf8a80ad975b (patch) | |
| tree | b564a0d4f0235675460399cfe43487022d682a21 | |
| parent | cc8d1628597d449e3b2e2e1545af25fc47b0a8a5 (diff) | |
implement on irqs
| -rw-r--r-- | embassy-stm32f4/src/lib.rs | 56 | ||||
| -rw-r--r-- | embassy-stm32f4/src/serial.rs | 59 |
2 files changed, 65 insertions, 50 deletions
diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs index 40a40ef4b..2a5a34a2a 100644 --- a/embassy-stm32f4/src/lib.rs +++ b/embassy-stm32f4/src/lib.rs | |||
| @@ -329,34 +329,34 @@ pub use stm32f4xx_hal::stm32 as pac; | |||
| 329 | /// | 329 | /// |
| 330 | /// [`Waker`]: core::task::Waker | 330 | /// [`Waker`]: core::task::Waker |
| 331 | /// [`Future::poll`]: core::future::Future::poll | 331 | /// [`Future::poll`]: core::future::Future::poll |
| 332 | macro_rules! waker_interrupt { | 332 | // macro_rules! waker_interrupt { |
| 333 | ($INT:ident, $waker:expr) => {{ | 333 | // ($INT:ident, $waker:expr) => {{ |
| 334 | use core::sync::atomic::{self, Ordering}; | 334 | // use core::sync::atomic::{self, Ordering}; |
| 335 | use core::task::Waker; | 335 | // use core::task::Waker; |
| 336 | use stm32f4xx_hal::pac::{interrupt, Interrupt, NVIC}; | 336 | // use stm32f4xx_hal::pac::{interrupt, Interrupt, NVIC}; |
| 337 | 337 | // | |
| 338 | static mut WAKER: Option<Waker> = None; | 338 | // static mut WAKER: Option<Waker> = None; |
| 339 | 339 | // | |
| 340 | #[interrupt] | 340 | // #[interrupt] |
| 341 | fn $INT() { | 341 | // fn $INT() { |
| 342 | // Safety: This context is disabled while the lower priority context accesses WAKER | 342 | // // Safety: This context is disabled while the lower priority context accesses WAKER |
| 343 | if let Some(waker) = unsafe { WAKER.as_ref() } { | 343 | // if let Some(waker) = unsafe { WAKER.as_ref() } { |
| 344 | waker.wake_by_ref(); | 344 | // waker.wake_by_ref(); |
| 345 | 345 | // | |
| 346 | NVIC::mask(Interrupt::$INT); | 346 | // NVIC::mask(Interrupt::$INT); |
| 347 | } | 347 | // } |
| 348 | } | 348 | // } |
| 349 | 349 | // | |
| 350 | NVIC::mask(Interrupt::$INT); | 350 | // NVIC::mask(Interrupt::$INT); |
| 351 | atomic::compiler_fence(Ordering::Acquire); | 351 | // atomic::compiler_fence(Ordering::Acquire); |
| 352 | // Safety: The other relevant context, the interrupt, is disabled | 352 | // // Safety: The other relevant context, the interrupt, is disabled |
| 353 | unsafe { WAKER = Some($waker) } | 353 | // unsafe { WAKER = Some($waker) } |
| 354 | NVIC::unpend(Interrupt::$INT); | 354 | // NVIC::unpend(Interrupt::$INT); |
| 355 | atomic::compiler_fence(Ordering::Release); | 355 | // atomic::compiler_fence(Ordering::Release); |
| 356 | // Safety: This is the end of a mask-based critical section | 356 | // // Safety: This is the end of a mask-based critical section |
| 357 | unsafe { NVIC::unmask(Interrupt::$INT) } | 357 | // unsafe { NVIC::unmask(Interrupt::$INT) } |
| 358 | }}; | 358 | // }}; |
| 359 | } | 359 | // } |
| 360 | 360 | ||
| 361 | // This mod MUST go first, so that the others see its macros. | 361 | // This mod MUST go first, so that the others see its macros. |
| 362 | pub(crate) mod fmt; | 362 | pub(crate) mod fmt; |
diff --git a/embassy-stm32f4/src/serial.rs b/embassy-stm32f4/src/serial.rs index 5042566db..5c3e3f1ac 100644 --- a/embassy-stm32f4/src/serial.rs +++ b/embassy-stm32f4/src/serial.rs | |||
| @@ -4,31 +4,20 @@ | |||
| 4 | //! Lowest power consumption can only be guaranteed if the send receive futures | 4 | //! Lowest power consumption can only be guaranteed if the send receive futures |
| 5 | //! are dropped correctly (e.g. not using `mem::forget()`). | 5 | //! are dropped correctly (e.g. not using `mem::forget()`). |
| 6 | 6 | ||
| 7 | use core::cell::UnsafeCell; | ||
| 8 | use core::cmp::min; | ||
| 9 | use core::future::Future; | 7 | use core::future::Future; |
| 10 | use core::marker::PhantomPinned; | ||
| 11 | use core::ops::Deref; | ||
| 12 | use core::pin::Pin; | ||
| 13 | use core::ptr; | ||
| 14 | use core::sync::atomic::{compiler_fence, Ordering}; | ||
| 15 | use core::task::{Context, Poll}; | 8 | use core::task::{Context, Poll}; |
| 16 | use cortex_m::singleton; | ||
| 17 | 9 | ||
| 10 | use embassy::interrupt::OwnedInterrupt; | ||
| 18 | use embassy::util::Signal; | 11 | use embassy::util::Signal; |
| 19 | use embedded_dma::{StaticReadBuffer, StaticWriteBuffer, WriteBuffer}; | 12 | use embedded_dma::{StaticReadBuffer, StaticWriteBuffer, WriteBuffer}; |
| 20 | 13 | ||
| 21 | use crate::fmt::assert; | ||
| 22 | use crate::hal::dma::config::DmaConfig; | 14 | use crate::hal::dma::config::DmaConfig; |
| 23 | use crate::hal::dma::traits::{PeriAddress, Stream}; | 15 | use crate::hal::dma::traits::{PeriAddress, Stream}; |
| 24 | use crate::hal::dma::{ | 16 | use crate::hal::dma::{ |
| 25 | Channel4, Channel7, MemoryToPeripheral, PeripheralToMemory, Stream2, Stream7, StreamsTuple, | 17 | Channel4, MemoryToPeripheral, PeripheralToMemory, Stream2, Stream7, StreamsTuple, Transfer, |
| 26 | Transfer, | ||
| 27 | }; | 18 | }; |
| 28 | use crate::hal::gpio::gpioa::{PA10, PA9}; | 19 | use crate::hal::gpio::gpioa::{PA10, PA9}; |
| 29 | use crate::hal::gpio::{Alternate, AF10, AF7, AF9}; | 20 | use crate::hal::gpio::{Alternate, AF7}; |
| 30 | use crate::hal::gpio::{Floating, Input, Output, PushPull}; | ||
| 31 | use crate::hal::pac; | ||
| 32 | use crate::hal::prelude::*; | 21 | use crate::hal::prelude::*; |
| 33 | use crate::hal::rcc::Clocks; | 22 | use crate::hal::rcc::Clocks; |
| 34 | use crate::hal::serial::config::{ | 23 | use crate::hal::serial::config::{ |
| @@ -42,8 +31,6 @@ use crate::interrupt; | |||
| 42 | use crate::pac::Interrupt; | 31 | use crate::pac::Interrupt; |
| 43 | use crate::pac::{DMA2, USART1}; | 32 | use crate::pac::{DMA2, USART1}; |
| 44 | 33 | ||
| 45 | use embedded_hal::digital::v2::OutputPin; | ||
| 46 | |||
| 47 | /// Interface to the Serial peripheral | 34 | /// Interface to the Serial peripheral |
| 48 | pub struct Serial<USART: PeriAddress<MemSize = u8>, TSTREAM: Stream, RSTREAM: Stream> { | 35 | pub struct Serial<USART: PeriAddress<MemSize = u8>, TSTREAM: Stream, RSTREAM: Stream> { |
| 49 | // tx_transfer: Transfer<Stream7<DMA2>, Channel4, USART1, MemoryToPeripheral, &mut [u8; 20]>, | 36 | // tx_transfer: Transfer<Stream7<DMA2>, Channel4, USART1, MemoryToPeripheral, &mut [u8; 20]>, |
| @@ -55,7 +42,7 @@ pub struct Serial<USART: PeriAddress<MemSize = u8>, TSTREAM: Stream, RSTREAM: St | |||
| 55 | 42 | ||
| 56 | struct State { | 43 | struct State { |
| 57 | tx_done: Signal<()>, | 44 | tx_done: Signal<()>, |
| 58 | rx_done: Signal<u32>, | 45 | rx_done: Signal<()>, |
| 59 | } | 46 | } |
| 60 | 47 | ||
| 61 | static STATE: State = State { | 48 | static STATE: State = State { |
| @@ -93,6 +80,15 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | |||
| 93 | 80 | ||
| 94 | // serial.listen(SerialEvent::Idle); | 81 | // serial.listen(SerialEvent::Idle); |
| 95 | 82 | ||
| 83 | // Register ISR | ||
| 84 | tx_int.set_handler(Self::on_tx_irq); | ||
| 85 | tx_int.unpend(); | ||
| 86 | tx_int.enable(); | ||
| 87 | |||
| 88 | rx_int.set_handler(Self::on_rx_irq); | ||
| 89 | rx_int.unpend(); | ||
| 90 | rx_int.enable(); | ||
| 91 | |||
| 96 | let streams = StreamsTuple::new(dma); | 92 | let streams = StreamsTuple::new(dma); |
| 97 | 93 | ||
| 98 | Serial { | 94 | Serial { |
| @@ -102,6 +98,13 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | |||
| 102 | } | 98 | } |
| 103 | } | 99 | } |
| 104 | 100 | ||
| 101 | unsafe fn on_tx_irq() { | ||
| 102 | STATE.tx_done.signal(()); | ||
| 103 | } | ||
| 104 | |||
| 105 | unsafe fn on_rx_irq() { | ||
| 106 | STATE.rx_done.signal(()); | ||
| 107 | } | ||
| 105 | /// Sends serial data. | 108 | /// Sends serial data. |
| 106 | /// | 109 | /// |
| 107 | /// `tx_buffer` is marked as static as per `embedded-dma` requirements. | 110 | /// `tx_buffer` is marked as static as per `embedded-dma` requirements. |
| @@ -127,6 +130,8 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | |||
| 127 | .double_buffer(false), | 130 | .double_buffer(false), |
| 128 | ); | 131 | ); |
| 129 | 132 | ||
| 133 | STATE.tx_done.reset(); | ||
| 134 | |||
| 130 | SendFuture { | 135 | SendFuture { |
| 131 | Serial: self, | 136 | Serial: self, |
| 132 | tx_transfer: Some(tx_transfer), | 137 | tx_transfer: Some(tx_transfer), |
| @@ -166,6 +171,8 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | |||
| 166 | .double_buffer(false), | 171 | .double_buffer(false), |
| 167 | ); | 172 | ); |
| 168 | 173 | ||
| 174 | STATE.rx_done.reset(); | ||
| 175 | |||
| 169 | ReceiveFuture { | 176 | ReceiveFuture { |
| 170 | Serial: self, | 177 | Serial: self, |
| 171 | rx_transfer: Some(rx_transfer), | 178 | rx_transfer: Some(rx_transfer), |
| @@ -213,11 +220,12 @@ where | |||
| 213 | 220 | ||
| 214 | Poll::Ready(()) | 221 | Poll::Ready(()) |
| 215 | } else { | 222 | } else { |
| 216 | waker_interrupt!(DMA2_STREAM7, cx.waker().clone()); | 223 | // waker_interrupt!(DMA2_STREAM7, cx.waker().clone()); |
| 217 | taken.start(|usart| {}); | 224 | taken.start(|_usart| {}); |
| 218 | tx_transfer.replace(taken); | 225 | tx_transfer.replace(taken); |
| 219 | 226 | ||
| 220 | Poll::Pending | 227 | // Poll::Pending |
| 228 | STATE.tx_done.poll_wait(cx) | ||
| 221 | } | 229 | } |
| 222 | } | 230 | } |
| 223 | } | 231 | } |
| @@ -263,11 +271,18 @@ where | |||
| 263 | 271 | ||
| 264 | Poll::Ready(buf) | 272 | Poll::Ready(buf) |
| 265 | } else { | 273 | } else { |
| 266 | waker_interrupt!(DMA2_STREAM2, cx.waker().clone()); | 274 | // waker_interrupt!(DMA2_STREAM2, cx.waker().clone()); |
| 267 | 275 | ||
| 268 | taken.start(|usart| {}); | 276 | taken.start(|_usart| {}); |
| 269 | rx_transfer.replace(taken); | 277 | rx_transfer.replace(taken); |
| 270 | 278 | ||
| 279 | STATE.rx_done.poll_wait(cx); | ||
| 280 | |||
| 281 | /* | ||
| 282 | Note: we have to do this because rx_transfer owns the buffer and we can't | ||
| 283 | access it until the transfer is completed. Therefore we can't pass | ||
| 284 | the buffer to poll_wait, but we still need to be woken. | ||
| 285 | */ | ||
| 271 | Poll::Pending | 286 | Poll::Pending |
| 272 | } | 287 | } |
| 273 | } | 288 | } |
