diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-03-06 00:11:25 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-03-06 00:11:25 +0100 |
| commit | bfd777b91ec2931d2d05ddd2d8d5444e3fc7dbfb (patch) | |
| tree | 92a999a0ebe6b7b0746a36ea5354b282baad9f83 | |
| parent | f8172316cd6a44bf5b6dc596ea24248c2a279224 (diff) | |
| parent | beca7f4d9bba3c37ae2bfa110f07df5d97e2fe3a (diff) | |
Merge pull request #25 from xoviat/implement-uart
impl. generics on serial
| -rw-r--r-- | embassy-stm32f4-examples/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32f4-examples/src/bin/serial.rs | 23 | ||||
| -rw-r--r-- | embassy-stm32f4/src/serial.rs | 214 |
3 files changed, 157 insertions, 84 deletions
diff --git a/embassy-stm32f4-examples/Cargo.toml b/embassy-stm32f4-examples/Cargo.toml index 16581f4fd..94f24c75e 100644 --- a/embassy-stm32f4-examples/Cargo.toml +++ b/embassy-stm32f4-examples/Cargo.toml | |||
| @@ -19,7 +19,7 @@ defmt-error = [] | |||
| 19 | [dependencies] | 19 | [dependencies] |
| 20 | embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } | 20 | embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } |
| 21 | embassy-traits = { version = "0.1.0", path = "../embassy-traits", features = ["defmt"] } | 21 | embassy-traits = { version = "0.1.0", path = "../embassy-traits", features = ["defmt"] } |
| 22 | embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4", features = ["stm32f401"] } | 22 | embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4", features = ["stm32f405"] } |
| 23 | 23 | ||
| 24 | defmt = "0.2.0" | 24 | defmt = "0.2.0" |
| 25 | defmt-rtt = "0.2.0" | 25 | defmt-rtt = "0.2.0" |
| @@ -28,6 +28,6 @@ cortex-m = "0.7.1" | |||
| 28 | cortex-m-rt = "0.6.13" | 28 | cortex-m-rt = "0.6.13" |
| 29 | embedded-hal = { version = "0.2.4" } | 29 | embedded-hal = { version = "0.2.4" } |
| 30 | panic-probe = "0.1.0" | 30 | panic-probe = "0.1.0" |
| 31 | stm32f4xx-hal = { version = "0.8.3", features = ["rt", "stm32f401"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"} | 31 | stm32f4xx-hal = { version = "0.8.3", features = ["rt", "stm32f405"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"} |
| 32 | futures = { version = "0.3.8", default-features = false, features = ["async-await"] } | 32 | futures = { version = "0.3.8", default-features = false, features = ["async-await"] } |
| 33 | rtt-target = { version = "0.3", features = ["cortex-m"] } | 33 | rtt-target = { version = "0.3", features = ["cortex-m"] } |
diff --git a/embassy-stm32f4-examples/src/bin/serial.rs b/embassy-stm32f4-examples/src/bin/serial.rs index 72fd1a2f9..6351f7284 100644 --- a/embassy-stm32f4-examples/src/bin/serial.rs +++ b/embassy-stm32f4-examples/src/bin/serial.rs | |||
| @@ -14,6 +14,7 @@ use embassy::traits::uart::Uart; | |||
| 14 | use embassy::util::Forever; | 14 | use embassy::util::Forever; |
| 15 | use embassy_stm32f4::interrupt; | 15 | use embassy_stm32f4::interrupt; |
| 16 | use embassy_stm32f4::serial; | 16 | use embassy_stm32f4::serial; |
| 17 | use stm32f4xx_hal::dma::StreamsTuple; | ||
| 17 | use stm32f4xx_hal::prelude::*; | 18 | use stm32f4xx_hal::prelude::*; |
| 18 | use stm32f4xx_hal::serial::config::Config; | 19 | use stm32f4xx_hal::serial::config::Config; |
| 19 | use stm32f4xx_hal::stm32; | 20 | use stm32f4xx_hal::stm32; |
| @@ -38,10 +39,12 @@ async fn run(dp: stm32::Peripherals, _cp: cortex_m::Peripherals) { | |||
| 38 | .pclk1(24.mhz()) | 39 | .pclk1(24.mhz()) |
| 39 | .freeze(); | 40 | .freeze(); |
| 40 | 41 | ||
| 42 | let streams = StreamsTuple::new(dp.DMA2); | ||
| 43 | |||
| 41 | let mut serial = unsafe { | 44 | let mut serial = unsafe { |
| 42 | serial::Serial::new( | 45 | serial::Serial::new( |
| 43 | dp.USART1, | 46 | dp.USART1, |
| 44 | dp.DMA2, | 47 | (streams.7, streams.2), |
| 45 | ( | 48 | ( |
| 46 | gpioa.pa9.into_alternate_af7(), | 49 | gpioa.pa9.into_alternate_af7(), |
| 47 | gpioa.pa10.into_alternate_af7(), | 50 | gpioa.pa10.into_alternate_af7(), |
| @@ -53,6 +56,24 @@ async fn run(dp: stm32::Peripherals, _cp: cortex_m::Peripherals) { | |||
| 53 | clocks, | 56 | clocks, |
| 54 | ) | 57 | ) |
| 55 | }; | 58 | }; |
| 59 | |||
| 60 | let streams = StreamsTuple::new(dp.DMA1); | ||
| 61 | |||
| 62 | let mut serial = unsafe { | ||
| 63 | serial::Serial::new( | ||
| 64 | dp.USART2, | ||
| 65 | (streams.6, streams.5), | ||
| 66 | ( | ||
| 67 | gpioa.pa2.into_alternate_af7(), | ||
| 68 | gpioa.pa3.into_alternate_af7(), | ||
| 69 | ), | ||
| 70 | interrupt::take!(DMA1_STREAM6), | ||
| 71 | interrupt::take!(DMA1_STREAM5), | ||
| 72 | interrupt::take!(USART2), | ||
| 73 | Config::default().baudrate(9600.bps()), | ||
| 74 | clocks, | ||
| 75 | ) | ||
| 76 | }; | ||
| 56 | let buf = singleton!(: [u8; 30] = [0; 30]).unwrap(); | 77 | let buf = singleton!(: [u8; 30] = [0; 30]).unwrap(); |
| 57 | 78 | ||
| 58 | buf[5] = 0x01; | 79 | buf[5] = 0x01; |
diff --git a/embassy-stm32f4/src/serial.rs b/embassy-stm32f4/src/serial.rs index 8a90e9fa3..36ca5af56 100644 --- a/embassy-stm32f4/src/serial.rs +++ b/embassy-stm32f4/src/serial.rs | |||
| @@ -8,129 +8,120 @@ use core::future::Future; | |||
| 8 | use core::ptr; | 8 | use core::ptr; |
| 9 | use core::sync::atomic::{self, Ordering}; | 9 | use core::sync::atomic::{self, Ordering}; |
| 10 | 10 | ||
| 11 | use embassy::interrupt::InterruptExt; | 11 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 12 | use embassy::traits::uart::{Error, Uart}; | 12 | use embassy::traits::uart::{Error, Uart}; |
| 13 | use embassy::util::Signal; | 13 | use embassy::util::InterruptFuture; |
| 14 | 14 | ||
| 15 | use crate::hal::dma; | ||
| 15 | use crate::hal::dma::config::DmaConfig; | 16 | use crate::hal::dma::config::DmaConfig; |
| 16 | use crate::hal::dma::traits::{PeriAddress, Stream}; | 17 | use crate::hal::dma::traits::{PeriAddress, Stream}; |
| 17 | use crate::hal::dma::{Stream2, Stream7, StreamsTuple, Transfer}; | 18 | use crate::hal::dma::{MemoryToPeripheral, PeripheralToMemory, Transfer}; |
| 18 | use crate::hal::rcc::Clocks; | 19 | use crate::hal::rcc::Clocks; |
| 20 | use crate::hal::serial; | ||
| 19 | use crate::hal::serial::config::{Config as SerialConfig, DmaConfig as SerialDmaConfig}; | 21 | use crate::hal::serial::config::{Config as SerialConfig, DmaConfig as SerialDmaConfig}; |
| 20 | use crate::hal::serial::Pins; | 22 | use crate::hal::serial::Pins; |
| 21 | use crate::hal::serial::{Event as SerialEvent, Serial as HalSerial}; | 23 | use crate::hal::serial::{Event as SerialEvent, Serial as HalSerial}; |
| 22 | use crate::interrupt; | 24 | use crate::interrupt; |
| 23 | use crate::pac::{DMA2, USART1}; | 25 | use crate::pac; |
| 24 | 26 | ||
| 25 | /// Interface to the Serial peripheral | 27 | /// Interface to the Serial peripheral |
| 26 | pub struct Serial<USART: PeriAddress<MemSize = u8>, TSTREAM: Stream, RSTREAM: Stream> { | 28 | pub struct Serial< |
| 29 | USART: PeriAddress<MemSize = u8>, | ||
| 30 | TSTREAM: Stream, | ||
| 31 | RSTREAM: Stream, | ||
| 32 | CHANNEL: dma::traits::Channel, | ||
| 33 | TINT: Interrupt, | ||
| 34 | RINT: Interrupt, | ||
| 35 | UINT: Interrupt, | ||
| 36 | > { | ||
| 27 | tx_stream: Option<TSTREAM>, | 37 | tx_stream: Option<TSTREAM>, |
| 28 | rx_stream: Option<RSTREAM>, | 38 | rx_stream: Option<RSTREAM>, |
| 29 | usart: Option<USART>, | 39 | usart: Option<USART>, |
| 30 | tx_int: interrupt::DMA2_STREAM7, | 40 | tx_int: TINT, |
| 31 | rx_int: interrupt::DMA2_STREAM2, | 41 | rx_int: RINT, |
| 32 | usart_int: interrupt::USART1, | 42 | usart_int: UINT, |
| 43 | channel: core::marker::PhantomData<CHANNEL>, | ||
| 33 | } | 44 | } |
| 34 | 45 | ||
| 35 | struct State { | 46 | // static mut INSTANCE: *const Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> = ptr::null_mut(); |
| 36 | tx_int: Signal<()>, | 47 | |
| 37 | rx_int: Signal<()>, | 48 | impl<USART, TSTREAM, RSTREAM, CHANNEL, TINT, RINT, UINT> |
| 38 | } | 49 | Serial<USART, TSTREAM, RSTREAM, CHANNEL, TINT, RINT, UINT> |
| 39 | 50 | where | |
| 40 | static STATE: State = State { | 51 | USART: serial::Instance |
| 41 | tx_int: Signal::new(), | 52 | + dma::traits::PeriAddress<MemSize = u8> |
| 42 | rx_int: Signal::new(), | 53 | + dma::traits::DMASet<TSTREAM, CHANNEL, MemoryToPeripheral> |
| 43 | }; | 54 | + dma::traits::DMASet<RSTREAM, CHANNEL, PeripheralToMemory> |
| 44 | 55 | + WithInterrupt<Instance = UINT>, | |
| 45 | static mut INSTANCE: *const Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> = ptr::null_mut(); | 56 | TSTREAM: Stream + WithInterrupt<Instance = TINT>, |
| 46 | 57 | RSTREAM: Stream + WithInterrupt<Instance = RINT>, | |
| 47 | impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | 58 | CHANNEL: dma::traits::Channel, |
| 59 | TINT: Interrupt, | ||
| 60 | RINT: Interrupt, | ||
| 61 | UINT: Interrupt, | ||
| 62 | { | ||
| 48 | // Leaking futures is forbidden! | 63 | // Leaking futures is forbidden! |
| 49 | pub unsafe fn new<PINS>( | 64 | pub unsafe fn new<PINS>( |
| 50 | usart: USART1, | 65 | usart: USART, |
| 51 | dma: DMA2, | 66 | streams: (TSTREAM, RSTREAM), |
| 52 | pins: PINS, | 67 | pins: PINS, |
| 53 | tx_int: interrupt::DMA2_STREAM7, | 68 | tx_int: TINT, |
| 54 | rx_int: interrupt::DMA2_STREAM2, | 69 | rx_int: RINT, |
| 55 | usart_int: interrupt::USART1, | 70 | usart_int: UINT, |
| 56 | mut config: SerialConfig, | 71 | mut config: SerialConfig, |
| 57 | clocks: Clocks, | 72 | clocks: Clocks, |
| 58 | ) -> Self | 73 | ) -> Self |
| 59 | where | 74 | where |
| 60 | PINS: Pins<USART1>, | 75 | PINS: Pins<USART>, |
| 61 | { | 76 | { |
| 62 | config.dma = SerialDmaConfig::TxRx; | 77 | config.dma = SerialDmaConfig::TxRx; |
| 63 | let mut serial = HalSerial::usart1(usart, pins, config, clocks).unwrap(); | 78 | let mut serial = HalSerial::new(usart, pins, config, clocks).unwrap(); |
| 64 | 79 | ||
| 65 | serial.listen(SerialEvent::Idle); | 80 | serial.listen(SerialEvent::Idle); |
| 66 | // serial.listen(SerialEvent::Txe); | 81 | // serial.listen(SerialEvent::Txe); |
| 67 | 82 | ||
| 68 | let (usart, _) = serial.release(); | 83 | let (usart, _) = serial.release(); |
| 69 | 84 | ||
| 70 | // Register ISR | 85 | let (tx_stream, rx_stream) = streams; |
| 71 | tx_int.set_handler(Self::on_tx_irq); | ||
| 72 | rx_int.set_handler(Self::on_rx_irq); | ||
| 73 | usart_int.set_handler(Self::on_rx_irq); | ||
| 74 | // usart_int.unpend(); | ||
| 75 | // usart_int.enable(); | ||
| 76 | |||
| 77 | let streams = StreamsTuple::new(dma); | ||
| 78 | 86 | ||
| 79 | Serial { | 87 | Serial { |
| 80 | tx_stream: Some(streams.7), | 88 | tx_stream: Some(tx_stream), |
| 81 | rx_stream: Some(streams.2), | 89 | rx_stream: Some(rx_stream), |
| 82 | usart: Some(usart), | 90 | usart: Some(usart), |
| 83 | tx_int: tx_int, | 91 | tx_int: tx_int, |
| 84 | rx_int: rx_int, | 92 | rx_int: rx_int, |
| 85 | usart_int: usart_int, | 93 | usart_int: usart_int, |
| 94 | channel: core::marker::PhantomData, | ||
| 86 | } | 95 | } |
| 87 | } | 96 | } |
| 88 | |||
| 89 | unsafe fn on_tx_irq(_ctx: *mut ()) { | ||
| 90 | let s = &(*INSTANCE); | ||
| 91 | |||
| 92 | s.tx_int.disable(); | ||
| 93 | |||
| 94 | STATE.tx_int.signal(()); | ||
| 95 | } | ||
| 96 | |||
| 97 | unsafe fn on_rx_irq(_ctx: *mut ()) { | ||
| 98 | let s = &(*INSTANCE); | ||
| 99 | |||
| 100 | atomic::compiler_fence(Ordering::Acquire); | ||
| 101 | s.rx_int.disable(); | ||
| 102 | s.usart_int.disable(); | ||
| 103 | atomic::compiler_fence(Ordering::Release); | ||
| 104 | |||
| 105 | STATE.rx_int.signal(()); | ||
| 106 | } | ||
| 107 | |||
| 108 | unsafe fn on_usart_irq(_ctx: *mut ()) { | ||
| 109 | let s = &(*INSTANCE); | ||
| 110 | |||
| 111 | atomic::compiler_fence(Ordering::Acquire); | ||
| 112 | s.rx_int.disable(); | ||
| 113 | s.usart_int.disable(); | ||
| 114 | atomic::compiler_fence(Ordering::Release); | ||
| 115 | |||
| 116 | STATE.rx_int.signal(()); | ||
| 117 | } | ||
| 118 | } | 97 | } |
| 119 | 98 | ||
| 120 | impl Uart for Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | 99 | impl<USART, TSTREAM, RSTREAM, CHANNEL, TINT, RINT, UINT> Uart |
| 100 | for Serial<USART, TSTREAM, RSTREAM, CHANNEL, TINT, RINT, UINT> | ||
| 101 | where | ||
| 102 | USART: serial::Instance | ||
| 103 | + dma::traits::PeriAddress<MemSize = u8> | ||
| 104 | + dma::traits::DMASet<TSTREAM, CHANNEL, MemoryToPeripheral> | ||
| 105 | + dma::traits::DMASet<RSTREAM, CHANNEL, PeripheralToMemory> | ||
| 106 | + WithInterrupt<Instance = UINT> | ||
| 107 | + 'static, | ||
| 108 | TSTREAM: Stream + WithInterrupt<Instance = TINT> + 'static, | ||
| 109 | RSTREAM: Stream + WithInterrupt<Instance = RINT> + 'static, | ||
| 110 | CHANNEL: dma::traits::Channel + 'static, | ||
| 111 | TINT: Interrupt + 'static, | ||
| 112 | RINT: Interrupt + 'static, | ||
| 113 | UINT: Interrupt + 'static, | ||
| 114 | { | ||
| 121 | type SendFuture<'a> = impl Future<Output = Result<(), Error>> + 'a; | 115 | type SendFuture<'a> = impl Future<Output = Result<(), Error>> + 'a; |
| 122 | type ReceiveFuture<'a> = impl Future<Output = Result<(), Error>> + 'a; | 116 | type ReceiveFuture<'a> = impl Future<Output = Result<(), Error>> + 'a; |
| 123 | 117 | ||
| 124 | /// Sends serial data. | 118 | /// Sends serial data. |
| 125 | fn send<'a>(&'a mut self, buf: &'a [u8]) -> Self::SendFuture<'a> { | 119 | fn send<'a>(&'a mut self, buf: &'a [u8]) -> Self::SendFuture<'a> { |
| 126 | unsafe { INSTANCE = self }; | ||
| 127 | |||
| 128 | #[allow(mutable_transmutes)] | 120 | #[allow(mutable_transmutes)] |
| 129 | let static_buf = unsafe { core::mem::transmute::<&'a [u8], &'static mut [u8]>(buf) }; | 121 | let static_buf = unsafe { core::mem::transmute::<&'a [u8], &'static mut [u8]>(buf) }; |
| 130 | 122 | ||
| 131 | let tx_stream = self.tx_stream.take().unwrap(); | 123 | let tx_stream = self.tx_stream.take().unwrap(); |
| 132 | let usart = self.usart.take().unwrap(); | 124 | let usart = self.usart.take().unwrap(); |
| 133 | STATE.tx_int.reset(); | ||
| 134 | 125 | ||
| 135 | async move { | 126 | async move { |
| 136 | let mut tx_transfer = Transfer::init( | 127 | let mut tx_transfer = Transfer::init( |
| @@ -144,11 +135,11 @@ impl Uart for Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | |||
| 144 | .double_buffer(false), | 135 | .double_buffer(false), |
| 145 | ); | 136 | ); |
| 146 | 137 | ||
| 147 | self.tx_int.unpend(); | 138 | let fut = InterruptFuture::new(&mut self.tx_int); |
| 148 | self.tx_int.enable(); | 139 | |
| 149 | tx_transfer.start(|_usart| {}); | 140 | tx_transfer.start(|_usart| {}); |
| 150 | 141 | ||
| 151 | STATE.tx_int.wait().await; | 142 | fut.await; |
| 152 | 143 | ||
| 153 | let (tx_stream, usart, _buf, _) = tx_transfer.free(); | 144 | let (tx_stream, usart, _buf, _) = tx_transfer.free(); |
| 154 | self.tx_stream.replace(tx_stream); | 145 | self.tx_stream.replace(tx_stream); |
| @@ -165,12 +156,11 @@ impl Uart for Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | |||
| 165 | /// unfinished transfers after a timeout to prevent lockup when no more data | 156 | /// unfinished transfers after a timeout to prevent lockup when no more data |
| 166 | /// is incoming. | 157 | /// is incoming. |
| 167 | fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a> { | 158 | fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a> { |
| 168 | unsafe { INSTANCE = self }; | ||
| 169 | |||
| 170 | let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) }; | 159 | let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) }; |
| 160 | |||
| 171 | let rx_stream = self.rx_stream.take().unwrap(); | 161 | let rx_stream = self.rx_stream.take().unwrap(); |
| 172 | let usart = self.usart.take().unwrap(); | 162 | let usart = self.usart.take().unwrap(); |
| 173 | STATE.rx_int.reset(); | 163 | |
| 174 | async move { | 164 | async move { |
| 175 | let mut rx_transfer = Transfer::init( | 165 | let mut rx_transfer = Transfer::init( |
| 176 | rx_stream, | 166 | rx_stream, |
| @@ -182,14 +172,76 @@ impl Uart for Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { | |||
| 182 | .memory_increment(true) | 172 | .memory_increment(true) |
| 183 | .double_buffer(false), | 173 | .double_buffer(false), |
| 184 | ); | 174 | ); |
| 185 | self.rx_int.unpend(); | 175 | |
| 186 | self.rx_int.enable(); | 176 | let fut = InterruptFuture::new(&mut self.rx_int); |
| 177 | |||
| 187 | rx_transfer.start(|_usart| {}); | 178 | rx_transfer.start(|_usart| {}); |
| 188 | STATE.rx_int.wait().await; | 179 | fut.await; |
| 180 | |||
| 189 | let (rx_stream, usart, _, _) = rx_transfer.free(); | 181 | let (rx_stream, usart, _, _) = rx_transfer.free(); |
| 190 | self.rx_stream.replace(rx_stream); | 182 | self.rx_stream.replace(rx_stream); |
| 191 | self.usart.replace(usart); | 183 | self.usart.replace(usart); |
| 184 | |||
| 192 | Ok(()) | 185 | Ok(()) |
| 193 | } | 186 | } |
| 194 | } | 187 | } |
| 195 | } | 188 | } |
| 189 | |||
| 190 | mod private { | ||
| 191 | pub trait Sealed {} | ||
| 192 | } | ||
| 193 | |||
| 194 | pub trait WithInterrupt: private::Sealed { | ||
| 195 | type Instance; | ||
| 196 | } | ||
| 197 | |||
| 198 | macro_rules! dma { | ||
| 199 | ($($PER:ident => ($dma:ident, $stream:ident),)+) => { | ||
| 200 | $( | ||
| 201 | impl private::Sealed for dma::$stream<pac::$dma> {} | ||
| 202 | impl WithInterrupt for dma::$stream<pac::$dma> { | ||
| 203 | type Instance = interrupt::$PER; | ||
| 204 | } | ||
| 205 | )+ | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | macro_rules! usart { | ||
| 210 | ($($PER:ident => ($usart:ident),)+) => { | ||
| 211 | $( | ||
| 212 | impl private::Sealed for pac::$usart {} | ||
| 213 | impl WithInterrupt for pac::$usart { | ||
| 214 | type Instance = interrupt::$PER; | ||
| 215 | } | ||
| 216 | )+ | ||
| 217 | } | ||
| 218 | } | ||
| 219 | |||
| 220 | #[cfg(any(feature = "stm32f405",))] | ||
| 221 | dma! { | ||
| 222 | DMA2_STREAM0 => (DMA2, Stream0), | ||
| 223 | DMA2_STREAM1 => (DMA2, Stream1), | ||
| 224 | DMA2_STREAM2 => (DMA2, Stream2), | ||
| 225 | DMA2_STREAM3 => (DMA2, Stream3), | ||
| 226 | DMA2_STREAM4 => (DMA2, Stream4), | ||
| 227 | DMA2_STREAM5 => (DMA2, Stream5), | ||
| 228 | DMA2_STREAM6 => (DMA2, Stream6), | ||
| 229 | DMA2_STREAM7 => (DMA2, Stream7), | ||
| 230 | DMA1_STREAM0 => (DMA1, Stream0), | ||
| 231 | DMA1_STREAM1 => (DMA1, Stream1), | ||
| 232 | DMA1_STREAM2 => (DMA1, Stream2), | ||
| 233 | DMA1_STREAM3 => (DMA1, Stream3), | ||
| 234 | DMA1_STREAM4 => (DMA1, Stream4), | ||
| 235 | DMA1_STREAM5 => (DMA1, Stream5), | ||
| 236 | DMA1_STREAM6 => (DMA1, Stream6), | ||
| 237 | } | ||
| 238 | |||
| 239 | #[cfg(any(feature = "stm32f405",))] | ||
| 240 | usart! { | ||
| 241 | USART1 => (USART1), | ||
| 242 | USART2 => (USART2), | ||
| 243 | USART3 => (USART3), | ||
| 244 | UART4 => (UART4), | ||
| 245 | UART5 => (UART5), | ||
| 246 | USART6 => (USART6), | ||
| 247 | } | ||
