aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-05-06 04:01:54 +0200
committerDario Nieuwenhuis <[email protected]>2021-05-06 04:01:54 +0200
commit386e4bf0de6369a3338f56877a779e1e05b4dcc2 (patch)
tree4be33adc9cc29686fb867e33a40eda8521167d47
parentf5f98cdeab8e457911fe369e244c60855c951f43 (diff)
Remove unused files
-rw-r--r--embassy-stm32/src/can.rs120
-rw-r--r--embassy-stm32/src/f4/mod.rs2
-rw-r--r--embassy-stm32/src/f4/serial.rs357
-rw-r--r--embassy-stm32/src/f4/spi.rs475
-rw-r--r--embassy-stm32/src/interrupt.rs59
-rw-r--r--embassy-stm32/src/rtc.rs504
6 files changed, 0 insertions, 1517 deletions
diff --git a/embassy-stm32/src/can.rs b/embassy-stm32/src/can.rs
deleted file mode 100644
index f97e900ea..000000000
--- a/embassy-stm32/src/can.rs
+++ /dev/null
@@ -1,120 +0,0 @@
1//! Async low power Serial.
2//!
3//! The peripheral is autmatically enabled and disabled as required to save power.
4//! Lowest power consumption can only be guaranteed if the send receive futures
5//! are dropped correctly (e.g. not using `mem::forget()`).
6
7use bxcan;
8use bxcan::Interrupts;
9use core::future::Future;
10use embassy::interrupt::Interrupt;
11use embassy::util::InterruptFuture;
12use nb;
13use nb::block;
14
15use crate::interrupt;
16
17/// Interface to the Serial peripheral
18pub struct Can<T: Instance> {
19 can: bxcan::Can<T>,
20 tx_int: T::TInterrupt,
21 rx_int: T::RInterrupt,
22}
23
24impl<T: Instance> Can<T> {
25 pub fn new(mut can: bxcan::Can<T>, tx_int: T::TInterrupt, rx_int: T::RInterrupt) -> Self {
26 // Sync to the bus and start normal operation.
27 can.enable_interrupts(
28 Interrupts::TRANSMIT_MAILBOX_EMPTY | Interrupts::FIFO0_MESSAGE_PENDING,
29 );
30 block!(can.enable()).unwrap();
31
32 Can {
33 can: can,
34 tx_int: tx_int,
35 rx_int: rx_int,
36 }
37 }
38
39 /// Sends can frame.
40 ///
41 /// This method async-blocks until the frame is transmitted.
42 pub fn transmit<'a>(&'a mut self, frame: &'a bxcan::Frame) -> impl Future<Output = ()> + 'a {
43 async move {
44 let fut = InterruptFuture::new(&mut self.tx_int);
45 // Infallible
46 self.can.transmit(frame).unwrap();
47
48 fut.await;
49 }
50 }
51
52 /// Receive can frame.
53 ///
54 /// This method async-blocks until the frame is received.
55 pub fn receive<'a>(&'a mut self) -> impl Future<Output = bxcan::Frame> + 'a {
56 async move {
57 let mut frame: Option<bxcan::Frame>;
58
59 loop {
60 let fut = InterruptFuture::new(&mut self.rx_int);
61 frame = match self.can.receive() {
62 Ok(frame) => Some(frame),
63 Err(nb::Error::WouldBlock) => None,
64 Err(nb::Error::Other(_)) => None, // Ignore overrun errors.
65 };
66 if frame.is_some() {
67 break;
68 }
69 fut.await;
70 }
71
72 frame.unwrap()
73 }
74 }
75}
76
77mod private {
78 pub trait Sealed {}
79}
80
81pub trait Instance: bxcan::Instance + private::Sealed {
82 type TInterrupt: Interrupt;
83 type RInterrupt: Interrupt;
84}
85
86macro_rules! can {
87 ($($can:ident => ($tint:ident, $rint:ident),)+) => {
88 $(
89 impl private::Sealed for crate::hal::can::Can<crate::pac::$can> {}
90 impl Instance for crate::hal::can::Can<crate::pac::$can> {
91 type TInterrupt = interrupt::$tint;
92 type RInterrupt = interrupt::$rint;
93 }
94 )+
95 }
96}
97
98#[cfg(any(
99 feature = "stm32f401",
100 feature = "stm32f405",
101 feature = "stm32f407",
102 feature = "stm32f410",
103 feature = "stm32f411",
104 feature = "stm32f412",
105 feature = "stm32f413",
106 feature = "stm32f415",
107 feature = "stm32f417",
108 feature = "stm32f423",
109 feature = "stm32f427",
110 feature = "stm32f429",
111 feature = "stm32f437",
112 feature = "stm32f439",
113 feature = "stm32f446",
114 feature = "stm32f469",
115 feature = "stm32f479",
116))]
117can! {
118 CAN1 => (CAN1_TX, CAN1_RX0),
119 CAN2 => (CAN2_TX, CAN2_RX0),
120}
diff --git a/embassy-stm32/src/f4/mod.rs b/embassy-stm32/src/f4/mod.rs
deleted file mode 100644
index 9edde82ca..000000000
--- a/embassy-stm32/src/f4/mod.rs
+++ /dev/null
@@ -1,2 +0,0 @@
1pub mod serial;
2pub mod spi;
diff --git a/embassy-stm32/src/f4/serial.rs b/embassy-stm32/src/f4/serial.rs
deleted file mode 100644
index 78aaa8944..000000000
--- a/embassy-stm32/src/f4/serial.rs
+++ /dev/null
@@ -1,357 +0,0 @@
1//! Async Serial.
2
3use core::future::Future;
4use core::marker::PhantomData;
5use embassy::interrupt::Interrupt;
6use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write};
7use embassy::util::InterruptFuture;
8use futures::{select_biased, FutureExt};
9
10use crate::hal::{
11 dma,
12 dma::config::DmaConfig,
13 dma::traits::{Channel, DMASet, PeriAddress, Stream},
14 dma::{MemoryToPeripheral, PeripheralToMemory, Transfer},
15 rcc::Clocks,
16 serial,
17 serial::config::{Config as SerialConfig, DmaConfig as SerialDmaConfig},
18 serial::{Event as SerialEvent, Pins},
19};
20use crate::interrupt;
21use crate::pac;
22
23/// Interface to the Serial peripheral
24pub struct Serial<
25 USART: PeriAddress<MemSize = u8> + WithInterrupt,
26 TSTREAM: Stream + WithInterrupt,
27 RSTREAM: Stream + WithInterrupt,
28 CHANNEL: Channel,
29> {
30 tx_stream: Option<TSTREAM>,
31 rx_stream: Option<RSTREAM>,
32 usart: Option<USART>,
33 tx_int: TSTREAM::Interrupt,
34 rx_int: RSTREAM::Interrupt,
35 usart_int: USART::Interrupt,
36 channel: PhantomData<CHANNEL>,
37}
38
39// static mut INSTANCE: *const Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> = ptr::null_mut();
40
41impl<USART, TSTREAM, RSTREAM, CHANNEL> Serial<USART, TSTREAM, RSTREAM, CHANNEL>
42where
43 USART: serial::Instance
44 + PeriAddress<MemSize = u8>
45 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
46 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
47 + WithInterrupt,
48 TSTREAM: Stream + WithInterrupt,
49 RSTREAM: Stream + WithInterrupt,
50 CHANNEL: Channel,
51{
52 // Leaking futures is forbidden!
53 pub unsafe fn new<PINS>(
54 usart: USART,
55 streams: (TSTREAM, RSTREAM),
56 pins: PINS,
57 tx_int: TSTREAM::Interrupt,
58 rx_int: RSTREAM::Interrupt,
59 usart_int: USART::Interrupt,
60 mut config: SerialConfig,
61 clocks: Clocks,
62 ) -> Self
63 where
64 PINS: Pins<USART>,
65 {
66 config.dma = SerialDmaConfig::TxRx;
67
68 let (usart, _) = serial::Serial::new(usart, pins, config, clocks)
69 .unwrap()
70 .release();
71
72 let (tx_stream, rx_stream) = streams;
73
74 Serial {
75 tx_stream: Some(tx_stream),
76 rx_stream: Some(rx_stream),
77 usart: Some(usart),
78 tx_int: tx_int,
79 rx_int: rx_int,
80 usart_int: usart_int,
81 channel: PhantomData,
82 }
83 }
84}
85
86impl<USART, TSTREAM, RSTREAM, CHANNEL> Read for Serial<USART, TSTREAM, RSTREAM, CHANNEL>
87where
88 USART: serial::Instance
89 + PeriAddress<MemSize = u8>
90 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
91 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
92 + WithInterrupt
93 + 'static,
94 TSTREAM: Stream + WithInterrupt + 'static,
95 RSTREAM: Stream + WithInterrupt + 'static,
96 CHANNEL: Channel + 'static,
97{
98 type ReadFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
99
100 /// Receives serial data.
101 ///
102 /// The future is pending until the buffer is completely filled.
103 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
104 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) };
105
106 async move {
107 let rx_stream = self.rx_stream.take().unwrap();
108 let usart = self.usart.take().unwrap();
109
110 let mut rx_transfer = Transfer::init(
111 rx_stream,
112 usart,
113 static_buf,
114 None,
115 DmaConfig::default()
116 .transfer_complete_interrupt(true)
117 .memory_increment(true)
118 .double_buffer(false),
119 );
120
121 let fut = InterruptFuture::new(&mut self.rx_int);
122 rx_transfer.start(|_usart| {});
123 fut.await;
124
125 let (rx_stream, usart, _, _) = rx_transfer.free();
126 self.rx_stream.replace(rx_stream);
127 self.usart.replace(usart);
128
129 Ok(())
130 }
131 }
132}
133
134impl<USART, TSTREAM, RSTREAM, CHANNEL> Write for Serial<USART, TSTREAM, RSTREAM, CHANNEL>
135where
136 USART: serial::Instance
137 + PeriAddress<MemSize = u8>
138 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
139 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
140 + WithInterrupt
141 + 'static,
142 TSTREAM: Stream + WithInterrupt + 'static,
143 RSTREAM: Stream + WithInterrupt + 'static,
144 CHANNEL: Channel + 'static,
145{
146 type WriteFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
147
148 /// Sends serial data.
149 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
150 #[allow(mutable_transmutes)]
151 let static_buf = unsafe { core::mem::transmute::<&'a [u8], &'static mut [u8]>(buf) };
152
153 async move {
154 let tx_stream = self.tx_stream.take().unwrap();
155 let usart = self.usart.take().unwrap();
156
157 let mut tx_transfer = Transfer::init(
158 tx_stream,
159 usart,
160 static_buf,
161 None,
162 DmaConfig::default()
163 .transfer_complete_interrupt(true)
164 .memory_increment(true)
165 .double_buffer(false),
166 );
167
168 let fut = InterruptFuture::new(&mut self.tx_int);
169
170 tx_transfer.start(|_usart| {});
171 fut.await;
172
173 let (tx_stream, usart, _buf, _) = tx_transfer.free();
174
175 self.tx_stream.replace(tx_stream);
176 self.usart.replace(usart);
177
178 Ok(())
179 }
180 }
181}
182
183impl<USART, TSTREAM, RSTREAM, CHANNEL> ReadUntilIdle for Serial<USART, TSTREAM, RSTREAM, CHANNEL>
184where
185 USART: serial::Instance
186 + PeriAddress<MemSize = u8>
187 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
188 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
189 + WithInterrupt
190 + 'static,
191 TSTREAM: Stream + WithInterrupt + 'static,
192 RSTREAM: Stream + WithInterrupt + 'static,
193 CHANNEL: Channel + 'static,
194{
195 type ReadUntilIdleFuture<'a> = impl Future<Output = Result<usize, Error>> + 'a;
196
197 /// Receives serial data.
198 ///
199 /// The future is pending until either the buffer is completely full, or the RX line falls idle after receiving some data.
200 ///
201 /// Returns the number of bytes read.
202 fn read_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a> {
203 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) };
204
205 async move {
206 let rx_stream = self.rx_stream.take().unwrap();
207 let usart = self.usart.take().unwrap();
208
209 unsafe {
210 /* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */
211 (*USART::ptr()).cr1.modify(|_, w| w.idleie().set_bit());
212
213 /* __HAL_UART_CLEAR_IDLEFLAG(&uart->UartHandle); */
214 (*USART::ptr()).sr.read();
215 (*USART::ptr()).dr.read();
216 };
217
218 let mut rx_transfer = Transfer::init(
219 rx_stream,
220 usart,
221 static_buf,
222 None,
223 DmaConfig::default()
224 .transfer_complete_interrupt(true)
225 .memory_increment(true)
226 .double_buffer(false),
227 );
228
229 let total_bytes = RSTREAM::get_number_of_transfers() as usize;
230
231 let fut = InterruptFuture::new(&mut self.rx_int);
232 let fut_idle = InterruptFuture::new(&mut self.usart_int);
233
234 rx_transfer.start(|_usart| {});
235
236 futures::future::select(fut, fut_idle).await;
237
238 let (rx_stream, usart, _, _) = rx_transfer.free();
239
240 let remaining_bytes = RSTREAM::get_number_of_transfers() as usize;
241
242 unsafe {
243 (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit());
244 }
245 self.rx_stream.replace(rx_stream);
246 self.usart.replace(usart);
247
248 Ok(total_bytes - remaining_bytes)
249 }
250 }
251}
252
253mod private {
254 pub trait Sealed {}
255}
256
257pub trait WithInterrupt: private::Sealed {
258 type Interrupt: Interrupt;
259}
260
261macro_rules! dma {
262 ($($PER:ident => ($dma:ident, $stream:ident),)+) => {
263 $(
264 impl private::Sealed for dma::$stream<pac::$dma> {}
265 impl WithInterrupt for dma::$stream<pac::$dma> {
266 type Interrupt = interrupt::$PER;
267 }
268 )+
269 }
270 }
271
272macro_rules! usart {
273 ($($PER:ident => ($usart:ident),)+) => {
274 $(
275 impl private::Sealed for pac::$usart {}
276 impl WithInterrupt for pac::$usart {
277 type Interrupt = interrupt::$PER;
278 }
279 )+
280 }
281}
282
283dma! {
284 DMA2_STREAM0 => (DMA2, Stream0),
285 DMA2_STREAM1 => (DMA2, Stream1),
286 DMA2_STREAM2 => (DMA2, Stream2),
287 DMA2_STREAM3 => (DMA2, Stream3),
288 DMA2_STREAM4 => (DMA2, Stream4),
289 DMA2_STREAM5 => (DMA2, Stream5),
290 DMA2_STREAM6 => (DMA2, Stream6),
291 DMA2_STREAM7 => (DMA2, Stream7),
292 DMA1_STREAM0 => (DMA1, Stream0),
293 DMA1_STREAM1 => (DMA1, Stream1),
294 DMA1_STREAM2 => (DMA1, Stream2),
295 DMA1_STREAM3 => (DMA1, Stream3),
296 DMA1_STREAM4 => (DMA1, Stream4),
297 DMA1_STREAM5 => (DMA1, Stream5),
298 DMA1_STREAM6 => (DMA1, Stream6),
299}
300
301#[cfg(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411",))]
302usart! {
303 USART1 => (USART1),
304 USART2 => (USART2),
305 USART6 => (USART6),
306}
307
308#[cfg(any(feature = "stm32f405", feature = "stm32f407"))]
309usart! {
310 USART1 => (USART1),
311 USART2 => (USART2),
312 USART3 => (USART3),
313 USART6 => (USART6),
314
315 UART4 => (UART4),
316 UART5 => (UART5),
317}
318
319#[cfg(feature = "stm32f412")]
320usart! {
321 USART1 => (USART1),
322 USART2 => (USART2),
323 USART3 => (USART3),
324 USART6 => (USART6),
325}
326
327#[cfg(feature = "stm32f413")]
328usart! {
329 USART1 => (USART1),
330 USART2 => (USART2),
331 USART3 => (USART3),
332 USART6 => (USART6),
333 USART7 => (USART7),
334 USART8 => (USART8),
335
336 UART5 => (UART5),
337 UART9 => (UART9),
338 UART10 => (UART10),
339}
340
341#[cfg(any(
342 feature = "stm32f427",
343 feature = "stm32f429",
344 feature = "stm32f446",
345 feature = "stm32f469"
346))]
347usart! {
348 USART1 => (USART1),
349 USART2 => (USART2),
350 USART3 => (USART3),
351 USART6 => (USART6),
352
353 UART4 => (UART4),
354 UART5 => (UART5),
355// UART7 => (UART7),
356// UART8 => (UART8),
357}
diff --git a/embassy-stm32/src/f4/spi.rs b/embassy-stm32/src/f4/spi.rs
deleted file mode 100644
index 65bf7287a..000000000
--- a/embassy-stm32/src/f4/spi.rs
+++ /dev/null
@@ -1,475 +0,0 @@
1//! Async SPI
2
3use embassy::time;
4
5use core::{future::Future, marker::PhantomData, mem, ops::Deref, pin::Pin, ptr};
6use embassy::{interrupt::Interrupt, traits::spi::FullDuplex, util::InterruptFuture};
7use nb;
8
9pub use crate::hal::spi::{Mode, Phase, Polarity};
10use crate::hal::{
11 bb, dma,
12 dma::config::DmaConfig,
13 dma::traits::{Channel, DMASet, PeriAddress, Stream},
14 dma::{MemoryToPeripheral, PeripheralToMemory, Transfer},
15 rcc::Clocks,
16 spi::Pins,
17 time::Hertz,
18};
19use crate::interrupt;
20use crate::pac;
21use futures::future;
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25#[non_exhaustive]
26pub enum Error {
27 TxBufferTooLong,
28 RxBufferTooLong,
29 Overrun,
30 ModeFault,
31 Crc,
32}
33
34fn read_sr<T: Instance>(spi: &T) -> nb::Result<u8, Error> {
35 let sr = spi.sr.read();
36 Err(if sr.ovr().bit_is_set() {
37 nb::Error::Other(Error::Overrun)
38 } else if sr.modf().bit_is_set() {
39 nb::Error::Other(Error::ModeFault)
40 } else if sr.crcerr().bit_is_set() {
41 nb::Error::Other(Error::Crc)
42 } else if sr.rxne().bit_is_set() {
43 // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
44 // reading a half-word)
45 return Ok(unsafe { ptr::read_volatile(&spi.dr as *const _ as *const u8) });
46 } else {
47 nb::Error::WouldBlock
48 })
49}
50
51fn write_sr<T: Instance>(spi: &T, byte: u8) -> nb::Result<(), Error> {
52 let sr = spi.sr.read();
53 Err(if sr.ovr().bit_is_set() {
54 // Read from the DR to clear the OVR bit
55 let _ = spi.dr.read();
56 nb::Error::Other(Error::Overrun)
57 } else if sr.modf().bit_is_set() {
58 // Write to CR1 to clear MODF
59 spi.cr1.modify(|_r, w| w);
60 nb::Error::Other(Error::ModeFault)
61 } else if sr.crcerr().bit_is_set() {
62 // Clear the CRCERR bit
63 spi.sr.modify(|_r, w| {
64 w.crcerr().clear_bit();
65 w
66 });
67 nb::Error::Other(Error::Crc)
68 } else if sr.txe().bit_is_set() {
69 // NOTE(write_volatile) see note above
70 unsafe { ptr::write_volatile(&spi.dr as *const _ as *mut u8, byte) }
71 return Ok(());
72 } else {
73 nb::Error::WouldBlock
74 })
75}
76
77/// Interface to the Serial peripheral
78pub struct Spi<
79 SPI: PeriAddress<MemSize = u8> + WithInterrupt,
80 TSTREAM: Stream + WithInterrupt,
81 RSTREAM: Stream + WithInterrupt,
82 CHANNEL: Channel,
83> {
84 tx_stream: Option<TSTREAM>,
85 rx_stream: Option<RSTREAM>,
86 spi: Option<SPI>,
87 tx_int: TSTREAM::Interrupt,
88 rx_int: RSTREAM::Interrupt,
89 spi_int: SPI::Interrupt,
90 channel: PhantomData<CHANNEL>,
91}
92
93impl<SPI, TSTREAM, RSTREAM, CHANNEL> Spi<SPI, TSTREAM, RSTREAM, CHANNEL>
94where
95 SPI: Instance
96 + PeriAddress<MemSize = u8>
97 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
98 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
99 + WithInterrupt,
100 TSTREAM: Stream + WithInterrupt,
101 RSTREAM: Stream + WithInterrupt,
102 CHANNEL: Channel,
103{
104 // Leaking futures is forbidden!
105 pub unsafe fn new<PINS>(
106 spi: SPI,
107 streams: (TSTREAM, RSTREAM),
108 pins: PINS,
109 tx_int: TSTREAM::Interrupt,
110 rx_int: RSTREAM::Interrupt,
111 spi_int: SPI::Interrupt,
112 mode: Mode,
113 freq: Hertz,
114 clocks: Clocks,
115 ) -> Self
116 where
117 PINS: Pins<SPI>,
118 {
119 let (tx_stream, rx_stream) = streams;
120
121 // let spi1: crate::pac::SPI1 = unsafe { mem::transmute(()) };
122 // let mut hspi = crate::hal::spi::Spi::spi1(
123 // spi1,
124 // (
125 // crate::hal::spi::NoSck,
126 // crate::hal::spi::NoMiso,
127 // crate::hal::spi::NoMosi,
128 // ),
129 // mode,
130 // freq,
131 // clocks,
132 // );
133
134 unsafe { SPI::enable_clock() };
135
136 let clock = SPI::clock_speed(clocks);
137
138 // disable SS output
139 // spi.cr2
140 // .write(|w| w.ssoe().clear_bit().rxdmaen().set_bit().txdmaen().set_bit());
141 spi.cr2.write(|w| w.ssoe().clear_bit());
142
143 let br = match clock.0 / freq.0 {
144 0 => unreachable!(),
145 1..=2 => 0b000,
146 3..=5 => 0b001,
147 6..=11 => 0b010,
148 12..=23 => 0b011,
149 24..=47 => 0b100,
150 48..=95 => 0b101,
151 96..=191 => 0b110,
152 _ => 0b111,
153 };
154
155 // mstr: master configuration
156 // lsbfirst: MSB first
157 // ssm: enable software slave management (NSS pin free for other uses)
158 // ssi: set nss high = master mode
159 // dff: 8 bit frames
160 // bidimode: 2-line unidirectional
161 // spe: enable the SPI bus
162 spi.cr1.write(|w| {
163 w.cpha()
164 .bit(mode.phase == Phase::CaptureOnSecondTransition)
165 .cpol()
166 .bit(mode.polarity == Polarity::IdleHigh)
167 .mstr()
168 .set_bit()
169 .br()
170 .bits(br)
171 .lsbfirst()
172 .clear_bit()
173 .ssm()
174 .set_bit()
175 .ssi()
176 .set_bit()
177 .rxonly()
178 .clear_bit()
179 .dff()
180 .clear_bit()
181 .bidimode()
182 .clear_bit()
183 .spe()
184 .set_bit()
185 });
186
187 Self {
188 tx_stream: Some(tx_stream),
189 rx_stream: Some(rx_stream),
190 spi: Some(spi),
191 tx_int: tx_int,
192 rx_int: rx_int,
193 spi_int: spi_int,
194 channel: PhantomData,
195 }
196 }
197}
198
199impl<SPI, TSTREAM, RSTREAM, CHANNEL> FullDuplex<u8> for Spi<SPI, TSTREAM, RSTREAM, CHANNEL>
200where
201 SPI: Instance
202 + PeriAddress<MemSize = u8>
203 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
204 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
205 + WithInterrupt
206 + 'static,
207 TSTREAM: Stream + WithInterrupt + 'static,
208 RSTREAM: Stream + WithInterrupt + 'static,
209 CHANNEL: Channel + 'static,
210{
211 type Error = Error;
212
213 type WriteFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
214 type ReadFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
215 type WriteReadFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
216
217 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
218 #[allow(mutable_transmutes)]
219 let static_buf: &'static mut [u8] = unsafe { mem::transmute(buf) };
220
221 async move {
222 let rx_stream = self.rx_stream.take().unwrap();
223 let spi = self.spi.take().unwrap();
224
225 spi.cr2.modify(|_, w| w.errie().set_bit());
226
227 let mut rx_transfer = Transfer::init(
228 rx_stream,
229 spi,
230 static_buf,
231 None,
232 DmaConfig::default()
233 .transfer_complete_interrupt(true)
234 .memory_increment(true)
235 .double_buffer(false),
236 );
237
238 let fut = InterruptFuture::new(&mut self.rx_int);
239 let fut_err = InterruptFuture::new(&mut self.spi_int);
240
241 rx_transfer.start(|_spi| {});
242 future::select(fut, fut_err).await;
243
244 let (rx_stream, spi, _buf, _) = rx_transfer.free();
245
246 spi.cr2.modify(|_, w| w.errie().clear_bit());
247 self.rx_stream.replace(rx_stream);
248 self.spi.replace(spi);
249
250 Ok(())
251 }
252 }
253
254 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
255 #[allow(mutable_transmutes)]
256 let static_buf: &'static mut [u8] = unsafe { mem::transmute(buf) };
257
258 async move {
259 let tx_stream = self.tx_stream.take().unwrap();
260 let spi = self.spi.take().unwrap();
261
262 // let mut tx_transfer = Transfer::init(
263 // tx_stream,
264 // spi,
265 // static_buf,
266 // None,
267 // DmaConfig::default()
268 // .transfer_complete_interrupt(true)
269 // .memory_increment(true)
270 // .double_buffer(false),
271 // );
272 //
273 // let fut = InterruptFuture::new(&mut self.tx_int);
274 //
275 // tx_transfer.start(|_spi| {});
276 // fut.await;
277
278 // let (tx_stream, spi, _buf, _) = tx_transfer.free();
279
280 for i in 0..(static_buf.len() - 1) {
281 let byte = static_buf[i];
282 nb::block!(write_sr(&spi, byte));
283 }
284
285 self.tx_stream.replace(tx_stream);
286 self.spi.replace(spi);
287
288 Ok(())
289 }
290 }
291
292 fn read_write<'a>(
293 &'a mut self,
294 read_buf: &'a mut [u8],
295 write_buf: &'a [u8],
296 ) -> Self::WriteReadFuture<'a> {
297 #[allow(mutable_transmutes)]
298 let write_static_buf: &'static mut [u8] = unsafe { mem::transmute(write_buf) };
299 let read_static_buf: &'static mut [u8] = unsafe { mem::transmute(read_buf) };
300
301 async move {
302 let tx_stream = self.tx_stream.take().unwrap();
303 let rx_stream = self.rx_stream.take().unwrap();
304 let spi_tx = self.spi.take().unwrap();
305 let spi_rx: SPI = unsafe { mem::transmute_copy(&spi_tx) };
306
307 spi_rx
308 .cr2
309 .modify(|_, w| w.errie().set_bit().txeie().set_bit().rxneie().set_bit());
310
311 // let mut tx_transfer = Transfer::init(
312 // tx_stream,
313 // spi_tx,
314 // write_static_buf,
315 // None,
316 // DmaConfig::default()
317 // .transfer_complete_interrupt(true)
318 // .memory_increment(true)
319 // .double_buffer(false),
320 // );
321 //
322 // let mut rx_transfer = Transfer::init(
323 // rx_stream,
324 // spi_rx,
325 // read_static_buf,
326 // None,
327 // DmaConfig::default()
328 // .transfer_complete_interrupt(true)
329 // .memory_increment(true)
330 // .double_buffer(false),
331 // );
332 //
333 // let tx_fut = InterruptFuture::new(&mut self.tx_int);
334 // let rx_fut = InterruptFuture::new(&mut self.rx_int);
335 // let rx_fut_err = InterruptFuture::new(&mut self.spi_int);
336 //
337 // rx_transfer.start(|_spi| {});
338 // tx_transfer.start(|_spi| {});
339 //
340 // time::Timer::after(time::Duration::from_millis(500)).await;
341 //
342 // // tx_fut.await;
343 // // future::select(rx_fut, rx_fut_err).await;
344 //
345 // let (rx_stream, spi_rx, _buf, _) = rx_transfer.free();
346 // let (tx_stream, _, _buf, _) = tx_transfer.free();
347
348 for i in 0..(read_static_buf.len() - 1) {
349 let byte = write_static_buf[i];
350 loop {
351 let fut = InterruptFuture::new(&mut self.spi_int);
352 match write_sr(&spi_tx, byte) {
353 Ok(()) => break,
354 _ => {}
355 }
356 fut.await;
357 }
358
359 loop {
360 let fut = InterruptFuture::new(&mut self.spi_int);
361 match read_sr(&spi_tx) {
362 Ok(byte) => {
363 read_static_buf[i] = byte;
364 break;
365 }
366 _ => {}
367 }
368 fut.await;
369 }
370 }
371
372 spi_rx.cr2.modify(|_, w| {
373 w.errie()
374 .clear_bit()
375 .txeie()
376 .clear_bit()
377 .rxneie()
378 .clear_bit()
379 });
380 self.rx_stream.replace(rx_stream);
381 self.tx_stream.replace(tx_stream);
382 self.spi.replace(spi_rx);
383
384 Ok(())
385 }
386 }
387}
388
389mod private {
390 pub trait Sealed {}
391}
392
393pub trait WithInterrupt: private::Sealed {
394 type Interrupt: Interrupt;
395}
396
397pub trait Instance: Deref<Target = pac::spi1::RegisterBlock> + private::Sealed {
398 unsafe fn enable_clock();
399 fn clock_speed(clocks: Clocks) -> Hertz;
400}
401
402macro_rules! dma {
403 ($($PER:ident => ($dma:ident, $stream:ident),)+) => {
404 $(
405 impl private::Sealed for dma::$stream<pac::$dma> {}
406 impl WithInterrupt for dma::$stream<pac::$dma> {
407 type Interrupt = interrupt::$PER;
408 }
409 )+
410 }
411 }
412
413macro_rules! spi {
414 ($($PER:ident => ($SPI:ident, $pclkX:ident, $apbXenr:ident, $en:expr),)+) => {
415 $(
416 impl private::Sealed for pac::$SPI {}
417 impl Instance for pac::$SPI {
418 unsafe fn enable_clock() {
419 const EN_BIT: u8 = $en;
420 // NOTE(unsafe) self reference will only be used for atomic writes with no side effects.
421 let rcc = &(*pac::RCC::ptr());
422 // Enable clock.
423 bb::set(&rcc.$apbXenr, EN_BIT);
424 // Stall the pipeline to work around erratum 2.1.13 (DM00037591)
425 cortex_m::asm::dsb();
426 }
427
428 fn clock_speed(clocks: Clocks) -> Hertz {
429 clocks.$pclkX()
430 }
431 }
432 impl WithInterrupt for pac::$SPI {
433 type Interrupt = interrupt::$PER;
434 }
435 )+
436 }
437}
438
439dma! {
440 DMA2_STREAM0 => (DMA2, Stream0),
441 DMA2_STREAM1 => (DMA2, Stream1),
442 DMA2_STREAM2 => (DMA2, Stream2),
443 DMA2_STREAM3 => (DMA2, Stream3),
444 DMA2_STREAM4 => (DMA2, Stream4),
445 DMA2_STREAM5 => (DMA2, Stream5),
446 DMA2_STREAM6 => (DMA2, Stream6),
447 DMA2_STREAM7 => (DMA2, Stream7),
448 DMA1_STREAM0 => (DMA1, Stream0),
449 DMA1_STREAM1 => (DMA1, Stream1),
450 DMA1_STREAM2 => (DMA1, Stream2),
451 DMA1_STREAM3 => (DMA1, Stream3),
452 DMA1_STREAM4 => (DMA1, Stream4),
453 DMA1_STREAM5 => (DMA1, Stream5),
454 DMA1_STREAM6 => (DMA1, Stream6),
455}
456
457#[cfg(any(
458 feature = "stm32f401",
459 feature = "stm32f410",
460 feature = "stm32f411",
461 feature = "stm32f446",
462))]
463spi! {
464 SPI1 => (SPI1, pclk2, apb2enr, 12),
465 SPI2 => (SPI2, pclk1, apb2enr, 14),
466// SPI6 => (SPI6, pclk2, apb2enr, 21),
467 SPI4 => (SPI3, pclk2, apb2enr, 13),
468// SPI5 => (SPI3, pclk2, apb2enr, 20),
469}
470
471#[cfg(any(feature = "stm32f405", feature = "stm32f407"))]
472spi! {
473 SPI1 => (SPI1, pclk2, apb2enr, 12),
474 SPI3 => (SPI3, pclk1, apb2enr, 15),
475}
diff --git a/embassy-stm32/src/interrupt.rs b/embassy-stm32/src/interrupt.rs
deleted file mode 100644
index 214327300..000000000
--- a/embassy-stm32/src/interrupt.rs
+++ /dev/null
@@ -1,59 +0,0 @@
1use core::sync::atomic::{compiler_fence, Ordering};
2
3use crate::pac::NVIC_PRIO_BITS;
4
5// Re-exports
6pub use cortex_m::interrupt::{CriticalSection, Mutex};
7pub use embassy::interrupt::{declare, take, Interrupt};
8
9#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11#[repr(u8)]
12pub enum Priority {
13 Level0 = 0,
14 Level1 = 1,
15 Level2 = 2,
16 Level3 = 3,
17 Level4 = 4,
18 Level5 = 5,
19 Level6 = 6,
20 Level7 = 7,
21 Level8 = 8,
22 Level9 = 9,
23 Level10 = 10,
24 Level11 = 11,
25 Level12 = 12,
26 Level13 = 13,
27 Level14 = 14,
28 Level15 = 15,
29}
30
31impl From<u8> for Priority {
32 fn from(priority: u8) -> Self {
33 match priority >> (8 - NVIC_PRIO_BITS) {
34 0 => Self::Level0,
35 1 => Self::Level1,
36 2 => Self::Level2,
37 3 => Self::Level3,
38 4 => Self::Level4,
39 5 => Self::Level5,
40 6 => Self::Level6,
41 7 => Self::Level7,
42 8 => Self::Level8,
43 9 => Self::Level9,
44 10 => Self::Level10,
45 11 => Self::Level11,
46 12 => Self::Level12,
47 13 => Self::Level13,
48 14 => Self::Level14,
49 15 => Self::Level15,
50 _ => unreachable!(),
51 }
52 }
53}
54
55impl From<Priority> for u8 {
56 fn from(p: Priority) -> Self {
57 (p as u8) << (8 - NVIC_PRIO_BITS)
58 }
59}
diff --git a/embassy-stm32/src/rtc.rs b/embassy-stm32/src/rtc.rs
deleted file mode 100644
index b1abba325..000000000
--- a/embassy-stm32/src/rtc.rs
+++ /dev/null
@@ -1,504 +0,0 @@
1use crate::hal::bb;
2use crate::hal::rcc::Clocks;
3use core::cell::Cell;
4use core::convert::TryInto;
5use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
6
7use embassy::interrupt::InterruptExt;
8use embassy::time::{Clock, TICKS_PER_SECOND};
9
10use crate::interrupt;
11use crate::interrupt::{CriticalSection, Interrupt, Mutex};
12
13// RTC timekeeping works with something we call "periods", which are time intervals
14// of 2^15 ticks. The RTC counter value is 16 bits, so one "overflow cycle" is 2 periods.
15//
16// A `period` count is maintained in parallel to the RTC hardware `counter`, like this:
17// - `period` and `counter` start at 0
18// - `period` is incremented on overflow (at counter value 0)
19// - `period` is incremented "midway" between overflows (at counter value 0x8000)
20//
21// Therefore, when `period` is even, counter is in 0..0x7FFF. When odd, counter is in 0x8000..0xFFFF
22// This allows for now() to return the correct value even if it races an overflow.
23//
24// To get `now()`, `period` is read first, then `counter` is read. If the counter value matches
25// the expected range for the `period` parity, we're done. If it doesn't, this means that
26// a new period start has raced us between reading `period` and `counter`, so we assume the `counter` value
27// corresponds to the next period.
28//
29// `period` is a 32bit integer, so It overflows on 2^32 * 2^15 / 32768 seconds of uptime, which is 136 years.
30fn calc_now(period: u32, counter: u16) -> u64 {
31 ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64)
32}
33
34struct AlarmState {
35 timestamp: Cell<u64>,
36 callback: Cell<Option<(fn(*mut ()), *mut ())>>,
37}
38
39impl AlarmState {
40 fn new() -> Self {
41 Self {
42 timestamp: Cell::new(u64::MAX),
43 callback: Cell::new(None),
44 }
45 }
46}
47
48// TODO: This is sometimes wasteful, try to find a better way
49const ALARM_COUNT: usize = 3;
50
51/// RTC timer that can be used by the executor and to set alarms.
52///
53/// It can work with Timers 2, 3, 4, 5, 9 and 12. Timers 9 and 12 only have one alarm available,
54/// while the others have three each.
55/// This timer works internally with a unit of 2^15 ticks, which means that if a call to
56/// [`embassy::time::Clock::now`] is blocked for that amount of ticks the returned value will be
57/// wrong (an old value). The current default tick rate is 32768 ticks per second.
58pub struct RTC<T: Instance> {
59 rtc: T,
60 irq: T::Interrupt,
61
62 /// Number of 2^23 periods elapsed since boot.
63 period: AtomicU32,
64
65 /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled.
66 alarms: Mutex<[AlarmState; ALARM_COUNT]>,
67
68 clocks: Clocks,
69}
70
71impl<T: Instance> RTC<T> {
72 pub fn new(rtc: T, irq: T::Interrupt, clocks: Clocks) -> Self {
73 Self {
74 rtc,
75 irq,
76 period: AtomicU32::new(0),
77 alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]),
78 clocks,
79 }
80 }
81
82 pub fn start(&'static self) {
83 self.rtc.enable_clock();
84 self.rtc.stop_and_reset();
85
86 let multiplier = if T::ppre(&self.clocks) == 1 { 1 } else { 2 };
87 let freq = T::pclk(&self.clocks) * multiplier;
88 let psc = freq / TICKS_PER_SECOND as u32 - 1;
89 let psc: u16 = psc.try_into().unwrap();
90
91 self.rtc.set_psc_arr(psc, u16::MAX);
92 // Mid-way point
93 self.rtc.set_compare(0, 0x8000);
94 self.rtc.set_compare_interrupt(0, true);
95
96 self.irq.set_handler(|ptr| unsafe {
97 let this = &*(ptr as *const () as *const Self);
98 this.on_interrupt();
99 });
100 self.irq.set_handler_context(self as *const _ as *mut _);
101 self.irq.unpend();
102 self.irq.enable();
103
104 self.rtc.start();
105 }
106
107 fn on_interrupt(&self) {
108 if self.rtc.overflow_interrupt_status() {
109 self.rtc.overflow_clear_flag();
110 self.next_period();
111 }
112
113 // Half overflow
114 if self.rtc.compare_interrupt_status(0) {
115 self.rtc.compare_clear_flag(0);
116 self.next_period();
117 }
118
119 for n in 1..=ALARM_COUNT {
120 if self.rtc.compare_interrupt_status(n) {
121 self.rtc.compare_clear_flag(n);
122 interrupt::free(|cs| self.trigger_alarm(n, cs));
123 }
124 }
125 }
126
127 fn next_period(&self) {
128 interrupt::free(|cs| {
129 let period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
130 let t = (period as u64) << 15;
131
132 for n in 1..=ALARM_COUNT {
133 let alarm = &self.alarms.borrow(cs)[n - 1];
134 let at = alarm.timestamp.get();
135
136 let diff = at - t;
137 if diff < 0xc000 {
138 self.rtc.set_compare(n, at as u16);
139 self.rtc.set_compare_interrupt(n, true);
140 }
141 }
142 })
143 }
144
145 fn trigger_alarm(&self, n: usize, cs: &CriticalSection) {
146 self.rtc.set_compare_interrupt(n, false);
147
148 let alarm = &self.alarms.borrow(cs)[n - 1];
149 alarm.timestamp.set(u64::MAX);
150
151 // Call after clearing alarm, so the callback can set another alarm.
152 if let Some((f, ctx)) = alarm.callback.get() {
153 f(ctx);
154 }
155 }
156
157 fn set_alarm_callback(&self, n: usize, callback: fn(*mut ()), ctx: *mut ()) {
158 interrupt::free(|cs| {
159 let alarm = &self.alarms.borrow(cs)[n - 1];
160 alarm.callback.set(Some((callback, ctx)));
161 })
162 }
163
164 fn set_alarm(&self, n: usize, timestamp: u64) {
165 interrupt::free(|cs| {
166 let alarm = &self.alarms.borrow(cs)[n - 1];
167 alarm.timestamp.set(timestamp);
168
169 let t = self.now();
170 if timestamp <= t {
171 self.trigger_alarm(n, cs);
172 return;
173 }
174
175 let diff = timestamp - t;
176 if diff < 0xc000 {
177 let safe_timestamp = timestamp.max(t + 3);
178 self.rtc.set_compare(n, safe_timestamp as u16);
179 self.rtc.set_compare_interrupt(n, true);
180 } else {
181 self.rtc.set_compare_interrupt(n, false);
182 }
183 })
184 }
185
186 pub fn alarm1(&'static self) -> Alarm<T> {
187 Alarm { n: 1, rtc: self }
188 }
189 pub fn alarm2(&'static self) -> Option<Alarm<T>> {
190 if T::REAL_ALARM_COUNT >= 2 {
191 Some(Alarm { n: 2, rtc: self })
192 } else {
193 None
194 }
195 }
196 pub fn alarm3(&'static self) -> Option<Alarm<T>> {
197 if T::REAL_ALARM_COUNT >= 3 {
198 Some(Alarm { n: 3, rtc: self })
199 } else {
200 None
201 }
202 }
203}
204
205impl<T: Instance> embassy::time::Clock for RTC<T> {
206 fn now(&self) -> u64 {
207 let period = self.period.load(Ordering::Relaxed);
208 compiler_fence(Ordering::Acquire);
209 let counter = self.rtc.counter();
210 calc_now(period, counter)
211 }
212}
213
214pub struct Alarm<T: Instance> {
215 n: usize,
216 rtc: &'static RTC<T>,
217}
218
219impl<T: Instance> embassy::time::Alarm for Alarm<T> {
220 fn set_callback(&self, callback: fn(*mut ()), ctx: *mut ()) {
221 self.rtc.set_alarm_callback(self.n, callback, ctx);
222 }
223
224 fn set(&self, timestamp: u64) {
225 self.rtc.set_alarm(self.n, timestamp);
226 }
227
228 fn clear(&self) {
229 self.rtc.set_alarm(self.n, u64::MAX);
230 }
231}
232
233mod sealed {
234 pub trait Sealed {}
235}
236
237pub trait Instance: sealed::Sealed + Sized + 'static {
238 type Interrupt: Interrupt;
239 const REAL_ALARM_COUNT: usize;
240
241 fn enable_clock(&self);
242 fn set_compare(&self, n: usize, value: u16);
243 fn set_compare_interrupt(&self, n: usize, enable: bool);
244 fn compare_interrupt_status(&self, n: usize) -> bool;
245 fn compare_clear_flag(&self, n: usize);
246 fn overflow_interrupt_status(&self) -> bool;
247 fn overflow_clear_flag(&self);
248 // This method should ensure that the values are really updated before returning
249 fn set_psc_arr(&self, psc: u16, arr: u16);
250 fn stop_and_reset(&self);
251 fn start(&self);
252 fn counter(&self) -> u16;
253 fn ppre(clocks: &Clocks) -> u8;
254 fn pclk(clocks: &Clocks) -> u32;
255}
256
257#[allow(unused_macros)]
258macro_rules! impl_timer {
259 ($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 3) => {
260 mod $module {
261 use super::*;
262 use crate::hal::pac::{$TYPE, RCC};
263
264 impl sealed::Sealed for $TYPE {}
265
266 impl Instance for $TYPE {
267 type Interrupt = interrupt::$INT;
268 const REAL_ALARM_COUNT: usize = 3;
269
270 fn enable_clock(&self) {
271 // NOTE(unsafe) It will only be used for atomic operations
272 unsafe {
273 let rcc = &*RCC::ptr();
274
275 bb::set(&rcc.$apbenr, $enrbit);
276 bb::set(&rcc.$apbrstr, $rstrbit);
277 bb::clear(&rcc.$apbrstr, $rstrbit);
278 }
279 }
280
281 fn set_compare(&self, n: usize, value: u16) {
282 // NOTE(unsafe) these registers accept all the range of u16 values
283 match n {
284 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
285 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
286 2 => self.ccr3.write(|w| unsafe { w.bits(value.into()) }),
287 3 => self.ccr4.write(|w| unsafe { w.bits(value.into()) }),
288 _ => {}
289 }
290 }
291
292 fn set_compare_interrupt(&self, n: usize, enable: bool) {
293 if n > 3 {
294 return;
295 }
296 let bit = n as u8 + 1;
297 unsafe {
298 if enable {
299 bb::set(&self.dier, bit);
300 } else {
301 bb::clear(&self.dier, bit);
302 }
303 }
304 }
305
306 fn compare_interrupt_status(&self, n: usize) -> bool {
307 let status = self.sr.read();
308 match n {
309 0 => status.cc1if().bit_is_set(),
310 1 => status.cc2if().bit_is_set(),
311 2 => status.cc3if().bit_is_set(),
312 3 => status.cc4if().bit_is_set(),
313 _ => false,
314 }
315 }
316
317 fn compare_clear_flag(&self, n: usize) {
318 if n > 3 {
319 return;
320 }
321 let bit = n as u8 + 1;
322 unsafe {
323 bb::clear(&self.sr, bit);
324 }
325 }
326
327 fn overflow_interrupt_status(&self) -> bool {
328 self.sr.read().uif().bit_is_set()
329 }
330
331 fn overflow_clear_flag(&self) {
332 unsafe {
333 bb::clear(&self.sr, 0);
334 }
335 }
336
337 fn set_psc_arr(&self, psc: u16, arr: u16) {
338 // NOTE(unsafe) All u16 values are valid
339 self.psc.write(|w| unsafe { w.bits(psc.into()) });
340 self.arr.write(|w| unsafe { w.bits(arr.into()) });
341
342 unsafe {
343 // Set URS, generate update, clear URS
344 bb::set(&self.cr1, 2);
345 self.egr.write(|w| w.ug().set_bit());
346 bb::clear(&self.cr1, 2);
347 }
348 }
349
350 fn stop_and_reset(&self) {
351 unsafe {
352 bb::clear(&self.cr1, 0);
353 }
354 self.cnt.reset();
355 }
356
357 fn start(&self) {
358 unsafe { bb::set(&self.cr1, 0) }
359 }
360
361 fn counter(&self) -> u16 {
362 self.cnt.read().bits() as u16
363 }
364
365 fn ppre(clocks: &Clocks) -> u8 {
366 clocks.$ppre()
367 }
368
369 fn pclk(clocks: &Clocks) -> u32 {
370 clocks.$pclk().0
371 }
372 }
373 }
374 };
375
376 ($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 1) => {
377 mod $module {
378 use super::*;
379 use crate::hal::pac::{$TYPE, RCC};
380
381 impl sealed::Sealed for $TYPE {}
382
383 impl Instance for $TYPE {
384 type Interrupt = interrupt::$INT;
385 const REAL_ALARM_COUNT: usize = 1;
386
387 fn enable_clock(&self) {
388 // NOTE(unsafe) It will only be used for atomic operations
389 unsafe {
390 let rcc = &*RCC::ptr();
391
392 bb::set(&rcc.$apbenr, $enrbit);
393 bb::set(&rcc.$apbrstr, $rstrbit);
394 bb::clear(&rcc.$apbrstr, $rstrbit);
395 }
396 }
397
398 fn set_compare(&self, n: usize, value: u16) {
399 // NOTE(unsafe) these registers accept all the range of u16 values
400 match n {
401 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
402 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
403 _ => {}
404 }
405 }
406
407 fn set_compare_interrupt(&self, n: usize, enable: bool) {
408 if n > 1 {
409 return;
410 }
411 let bit = n as u8 + 1;
412 unsafe {
413 if enable {
414 bb::set(&self.dier, bit);
415 } else {
416 bb::clear(&self.dier, bit);
417 }
418 }
419 }
420
421 fn compare_interrupt_status(&self, n: usize) -> bool {
422 let status = self.sr.read();
423 match n {
424 0 => status.cc1if().bit_is_set(),
425 1 => status.cc2if().bit_is_set(),
426 _ => false,
427 }
428 }
429
430 fn compare_clear_flag(&self, n: usize) {
431 if n > 1 {
432 return;
433 }
434 let bit = n as u8 + 1;
435 unsafe {
436 bb::clear(&self.sr, bit);
437 }
438 }
439
440 fn overflow_interrupt_status(&self) -> bool {
441 self.sr.read().uif().bit_is_set()
442 }
443
444 fn overflow_clear_flag(&self) {
445 unsafe {
446 bb::clear(&self.sr, 0);
447 }
448 }
449
450 fn set_psc_arr(&self, psc: u16, arr: u16) {
451 // NOTE(unsafe) All u16 values are valid
452 self.psc.write(|w| unsafe { w.bits(psc.into()) });
453 self.arr.write(|w| unsafe { w.bits(arr.into()) });
454
455 unsafe {
456 // Set URS, generate update, clear URS
457 bb::set(&self.cr1, 2);
458 self.egr.write(|w| w.ug().set_bit());
459 bb::clear(&self.cr1, 2);
460 }
461 }
462
463 fn stop_and_reset(&self) {
464 unsafe {
465 bb::clear(&self.cr1, 0);
466 }
467 self.cnt.reset();
468 }
469
470 fn start(&self) {
471 unsafe { bb::set(&self.cr1, 0) }
472 }
473
474 fn counter(&self) -> u16 {
475 self.cnt.read().bits() as u16
476 }
477
478 fn ppre(clocks: &Clocks) -> u8 {
479 clocks.$ppre()
480 }
481
482 fn pclk(clocks: &Clocks) -> u32 {
483 clocks.$pclk().0
484 }
485 }
486 }
487 };
488}
489
490#[cfg(not(feature = "stm32f410"))]
491impl_timer!(tim2: (TIM2, TIM2, apb1enr, 0, apb1rstr, 0, ppre1, pclk1), 3);
492
493#[cfg(not(feature = "stm32f410"))]
494impl_timer!(tim3: (TIM3, TIM3, apb1enr, 1, apb1rstr, 1, ppre1, pclk1), 3);
495
496#[cfg(not(feature = "stm32f410"))]
497impl_timer!(tim4: (TIM4, TIM4, apb1enr, 2, apb1rstr, 2, ppre1, pclk1), 3);
498
499impl_timer!(tim5: (TIM5, TIM5, apb1enr, 3, apb1rstr, 3, ppre1, pclk1), 3);
500
501impl_timer!(tim9: (TIM9, TIM1_BRK_TIM9, apb2enr, 16, apb2rstr, 16, ppre2, pclk2), 1);
502
503#[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411")))]
504impl_timer!(tim12: (TIM12, TIM8_BRK_TIM12, apb1enr, 6, apb1rstr, 6, ppre1, pclk1), 1);