aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-02-20 01:41:42 +0100
committerGitHub <[email protected]>2021-02-20 01:41:42 +0100
commit68a345eff88f94ae9f76040d625fe3516124815a (patch)
tree7268ca55cbcc8cdc72c55fd98858a65df18c7812
parent82846d164c3dcb70a493f0f8dc2fb73c25c1fe4e (diff)
parente16e3780fd16929eec3b1b62942c6dffcfe90711 (diff)
Merge pull request #49 from thalesfragoso/st-timer
Add STM timer
-rw-r--r--embassy-stm32f4-examples/.cargo/config2
-rw-r--r--embassy-stm32f4-examples/Cargo.toml4
-rw-r--r--embassy-stm32f4-examples/memory.x2
-rw-r--r--embassy-stm32f4-examples/src/bin/rtc_async.rs65
-rw-r--r--embassy-stm32f4/src/interrupt.rs771
-rw-r--r--embassy-stm32f4/src/lib.rs1
-rw-r--r--embassy-stm32f4/src/rtc.rs505
7 files changed, 1346 insertions, 4 deletions
diff --git a/embassy-stm32f4-examples/.cargo/config b/embassy-stm32f4-examples/.cargo/config
index 707494d68..836853988 100644
--- a/embassy-stm32f4-examples/.cargo/config
+++ b/embassy-stm32f4-examples/.cargo/config
@@ -1,5 +1,5 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2runner = "probe-run --chip STM32F411CEUx --defmt" 2runner = "probe-run --chip STM32F401CCUx --defmt"
3 3
4rustflags = [ 4rustflags = [
5 # LLD (shipped with the Rust toolchain) is used as the default linker 5 # LLD (shipped with the Rust toolchain) is used as the default linker
diff --git a/embassy-stm32f4-examples/Cargo.toml b/embassy-stm32f4-examples/Cargo.toml
index e81f85ff1..216964374 100644
--- a/embassy-stm32f4-examples/Cargo.toml
+++ b/embassy-stm32f4-examples/Cargo.toml
@@ -18,7 +18,7 @@ defmt-error = []
18 18
19[dependencies] 19[dependencies]
20embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } 20embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] }
21embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4", features = ["stm32f405"] } 21embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4", features = ["stm32f401"] }
22 22
23defmt = "0.1.3" 23defmt = "0.1.3"
24defmt-rtt = "0.1.0" 24defmt-rtt = "0.1.0"
@@ -27,6 +27,6 @@ cortex-m = "0.7.1"
27cortex-m-rt = "0.6.13" 27cortex-m-rt = "0.6.13"
28embedded-hal = { version = "0.2.4" } 28embedded-hal = { version = "0.2.4" }
29panic-probe = "0.1.0" 29panic-probe = "0.1.0"
30stm32f4xx-hal = { version = "0.8.3", features = ["rt", "stm32f405"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"} 30stm32f4xx-hal = { version = "0.8.3", features = ["rt", "stm32f401"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"}
31futures = { version = "0.3.8", default-features = false, features = ["async-await"] } 31futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
32rtt-target = { version = "0.3", features = ["cortex-m"] } 32rtt-target = { version = "0.3", features = ["cortex-m"] }
diff --git a/embassy-stm32f4-examples/memory.x b/embassy-stm32f4-examples/memory.x
index ee4d4d59c..efa700b8a 100644
--- a/embassy-stm32f4-examples/memory.x
+++ b/embassy-stm32f4-examples/memory.x
@@ -1,5 +1,5 @@
1MEMORY 1MEMORY
2{ 2{
3 FLASH : ORIGIN = 0x08000000, LENGTH = 64K 3 FLASH : ORIGIN = 0x08000000, LENGTH = 64K
4 RAM : ORIGIN = 0x20000000, LENGTH = 32K 4 RAM : ORIGIN = 0x20000000, LENGTH = 32K
5} 5}
diff --git a/embassy-stm32f4-examples/src/bin/rtc_async.rs b/embassy-stm32f4-examples/src/bin/rtc_async.rs
new file mode 100644
index 000000000..e53212263
--- /dev/null
+++ b/embassy-stm32f4-examples/src/bin/rtc_async.rs
@@ -0,0 +1,65 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5#[path = "../example_common.rs"]
6mod example_common;
7use example_common::*;
8
9use cortex_m_rt::entry;
10use defmt::panic;
11use embassy::executor::{task, Executor};
12use embassy::time::{Duration, Timer};
13use embassy::util::Forever;
14use embassy_stm32f4::{interrupt, pac, rtc};
15use stm32f4xx_hal::prelude::*;
16
17#[task]
18async fn run1() {
19 loop {
20 info!("BIG INFREQUENT TICK");
21 Timer::after(Duration::from_ticks(32768 * 2)).await;
22 }
23}
24
25#[task]
26async fn run2() {
27 loop {
28 info!("tick");
29 Timer::after(Duration::from_ticks(13000)).await;
30 }
31}
32
33static RTC: Forever<rtc::RTC<pac::TIM2>> = Forever::new();
34static ALARM: Forever<rtc::Alarm<pac::TIM2>> = Forever::new();
35static EXECUTOR: Forever<Executor> = Forever::new();
36
37#[entry]
38fn main() -> ! {
39 info!("Hello World!");
40
41 let p = unwrap!(pac::Peripherals::take());
42
43 p.RCC.ahb1enr.modify(|_, w| w.dma1en().enabled());
44 let rcc = p.RCC.constrain();
45 let clocks = rcc.cfgr.freeze();
46
47 p.DBGMCU.cr.modify(|_, w| {
48 w.dbg_sleep().set_bit();
49 w.dbg_standby().set_bit();
50 w.dbg_stop().set_bit()
51 });
52
53 let rtc = RTC.put(rtc::RTC::new(p.TIM2, interrupt::take!(TIM2), clocks));
54 rtc.start();
55
56 unsafe { embassy::time::set_clock(rtc) };
57
58 let alarm = ALARM.put(rtc.alarm1());
59 let executor = EXECUTOR.put(Executor::new());
60 executor.set_alarm(alarm);
61 executor.run(|spawner| {
62 unwrap!(spawner.spawn(run1()));
63 unwrap!(spawner.spawn(run2()));
64 });
65}
diff --git a/embassy-stm32f4/src/interrupt.rs b/embassy-stm32f4/src/interrupt.rs
index c75e4b82d..4ecc76254 100644
--- a/embassy-stm32f4/src/interrupt.rs
+++ b/embassy-stm32f4/src/interrupt.rs
@@ -94,6 +94,66 @@ where
94 } 94 }
95} 95}
96 96
97#[cfg(feature = "stm32f401")]
98mod irqs {
99 use super::*;
100 declare!(PVD);
101 declare!(TAMP_STAMP);
102 declare!(RTC_WKUP);
103 declare!(FLASH);
104 declare!(RCC);
105 declare!(EXTI0);
106 declare!(EXTI1);
107 declare!(EXTI2);
108 declare!(EXTI3);
109 declare!(EXTI4);
110 declare!(DMA1_STREAM0);
111 declare!(DMA1_STREAM1);
112 declare!(DMA1_STREAM2);
113 declare!(DMA1_STREAM3);
114 declare!(DMA1_STREAM4);
115 declare!(DMA1_STREAM5);
116 declare!(DMA1_STREAM6);
117 declare!(ADC);
118 declare!(EXTI9_5);
119 declare!(TIM1_BRK_TIM9);
120 declare!(TIM1_UP_TIM10);
121 declare!(TIM1_TRG_COM_TIM11);
122 declare!(TIM1_CC);
123 declare!(TIM2);
124 declare!(TIM3);
125 declare!(TIM4);
126 declare!(I2C1_EV);
127 declare!(I2C1_ER);
128 declare!(I2C2_EV);
129 declare!(I2C2_ER);
130 declare!(SPI1);
131 declare!(SPI2);
132 declare!(USART1);
133 declare!(USART2);
134 declare!(EXTI15_10);
135 declare!(RTC_ALARM);
136 declare!(OTG_FS_WKUP);
137 declare!(DMA1_STREAM7);
138 declare!(SDIO);
139 declare!(TIM5);
140 declare!(SPI3);
141 declare!(DMA2_STREAM0);
142 declare!(DMA2_STREAM1);
143 declare!(DMA2_STREAM2);
144 declare!(DMA2_STREAM3);
145 declare!(DMA2_STREAM4);
146 declare!(OTG_FS);
147 declare!(DMA2_STREAM5);
148 declare!(DMA2_STREAM6);
149 declare!(DMA2_STREAM7);
150 declare!(USART6);
151 declare!(I2C3_EV);
152 declare!(I2C3_ER);
153 declare!(FPU);
154 declare!(SPI4);
155}
156
97#[cfg(feature = "stm32f405")] 157#[cfg(feature = "stm32f405")]
98mod irqs { 158mod irqs {
99 use super::*; 159 use super::*;
@@ -190,6 +250,155 @@ mod irqs {
190 // declare!(DMA2D); 250 // declare!(DMA2D);
191} 251}
192 252
253#[cfg(feature = "stm32f407")]
254mod irqs {
255 use super::*;
256
257 declare!(WWDG);
258 declare!(PVD);
259 declare!(TAMP_STAMP);
260 declare!(RTC_WKUP);
261 declare!(RCC);
262 declare!(EXTI0);
263 declare!(EXTI1);
264 declare!(EXTI2);
265 declare!(EXTI3);
266 declare!(EXTI4);
267 declare!(DMA1_STREAM0);
268 declare!(DMA1_STREAM1);
269 declare!(DMA1_STREAM2);
270 declare!(DMA1_STREAM3);
271 declare!(DMA1_STREAM4);
272 declare!(DMA1_STREAM5);
273 declare!(DMA1_STREAM6);
274 declare!(ADC);
275 declare!(CAN1_TX);
276 declare!(CAN1_RX0);
277 declare!(CAN1_RX1);
278 declare!(CAN1_SCE);
279 declare!(EXTI9_5);
280 declare!(TIM1_BRK_TIM9);
281 declare!(TIM1_UP_TIM10);
282 declare!(TIM1_TRG_COM_TIM11);
283 declare!(TIM1_CC);
284 declare!(TIM2);
285 declare!(TIM3);
286 declare!(TIM4);
287 declare!(I2C1_EV);
288 declare!(I2C1_ER);
289 declare!(I2C2_EV);
290 declare!(I2C2_ER);
291 declare!(SPI1);
292 declare!(SPI2);
293 declare!(USART1);
294 declare!(USART2);
295 declare!(USART3);
296 declare!(EXTI15_10);
297 declare!(RTC_ALARM);
298 declare!(OTG_FS_WKUP);
299 declare!(TIM8_BRK_TIM12);
300 declare!(TIM8_UP_TIM13);
301 declare!(TIM8_TRG_COM_TIM14);
302 declare!(TIM8_CC);
303 declare!(DMA1_STREAM7);
304 declare!(FSMC);
305 declare!(SDIO);
306 declare!(TIM5);
307 declare!(SPI3);
308 declare!(UART4);
309 declare!(UART5);
310 declare!(TIM6_DAC);
311 declare!(TIM7);
312 declare!(DMA2_STREAM0);
313 declare!(DMA2_STREAM1);
314 declare!(DMA2_STREAM2);
315 declare!(DMA2_STREAM3);
316 declare!(DMA2_STREAM4);
317 declare!(ETH);
318 declare!(ETH_WKUP);
319 declare!(CAN2_TX);
320 declare!(CAN2_RX0);
321 declare!(CAN2_RX1);
322 declare!(CAN2_SCE);
323 declare!(OTG_FS);
324 declare!(DMA2_STREAM5);
325 declare!(DMA2_STREAM6);
326 declare!(DMA2_STREAM7);
327 declare!(USART6);
328 declare!(I2C3_EV);
329 declare!(I2C3_ER);
330 declare!(OTG_HS_EP1_OUT);
331 declare!(OTG_HS_EP1_IN);
332 declare!(OTG_HS_WKUP);
333 declare!(OTG_HS);
334 declare!(DCMI);
335 declare!(CRYP);
336 declare!(HASH_RNG);
337 declare!(FPU);
338 declare!(LCD_TFT);
339 declare!(LCD_TFT_1);
340}
341
342#[cfg(feature = "stm32f410")]
343mod irqs {
344 use super::*;
345
346 declare!(WWDG);
347 declare!(PVD);
348 declare!(TAMP_STAMP);
349 declare!(RTC_WKUP);
350 declare!(FLASH);
351 declare!(RCC);
352 declare!(EXTI0);
353 declare!(EXTI1);
354 declare!(EXTI2);
355 declare!(EXTI3);
356 declare!(EXTI4);
357 declare!(DMA1_STREAM0);
358 declare!(DMA1_STREAM1);
359 declare!(DMA1_STREAM2);
360 declare!(DMA1_STREAM3);
361 declare!(DMA1_STREAM4);
362 declare!(DMA1_STREAM5);
363 declare!(DMA1_STREAM6);
364 declare!(ADC);
365 declare!(EXTI9_5);
366 declare!(TIM1_BRK_TIM9);
367 declare!(PWM1_UP);
368 declare!(TIM1_TRG_COM_TIM11);
369 declare!(TIM1_CC);
370 declare!(I2C1_EV);
371 declare!(I2C1_ER);
372 declare!(I2C2_EV);
373 declare!(I2C2_ER);
374 declare!(SPI1);
375 declare!(SPI2);
376 declare!(USART1);
377 declare!(USART2);
378 declare!(EXTI15_10);
379 declare!(RTC_ALARM);
380 declare!(DMA1_STREAM7);
381 declare!(TIM5);
382 declare!(TIM6_DAC1);
383 declare!(DMA2_STREAM0);
384 declare!(DMA2_STREAM1);
385 declare!(DMA2_STREAM2);
386 declare!(DMA2_STREAM3);
387 declare!(DMA2_STREAM4);
388 declare!(EXTI19);
389 declare!(DMA2_STREAM5);
390 declare!(DMA2_STREAM6);
391 declare!(DMA2_STREAM7);
392 declare!(USART6);
393 declare!(EXTI20);
394 declare!(RNG);
395 declare!(FPU);
396 declare!(SPI5);
397 declare!(I2C4_EV);
398 declare!(I2C4_ER);
399 declare!(LPTIM1);
400}
401
193#[cfg(feature = "stm32f411")] 402#[cfg(feature = "stm32f411")]
194mod irqs { 403mod irqs {
195 use super::*; 404 use super::*;
@@ -253,4 +462,566 @@ mod irqs {
253 declare!(SPI5); 462 declare!(SPI5);
254} 463}
255 464
465#[cfg(feature = "stm32f412")]
466mod irqs {
467 use super::*;
468
469 declare!(WWDG);
470 declare!(PVD);
471 declare!(TAMP_STAMP);
472 declare!(RTC_WKUP);
473 declare!(FLASH);
474 declare!(RCC);
475 declare!(EXTI0);
476 declare!(EXTI1);
477 declare!(EXTI2);
478 declare!(EXTI3);
479 declare!(EXTI4);
480 declare!(DMA1_STREAM0);
481 declare!(DMA1_STREAM1);
482 declare!(DMA1_STREAM2);
483 declare!(DMA1_STREAM3);
484 declare!(DMA1_STREAM4);
485 declare!(DMA1_STREAM5);
486 declare!(DMA1_STREAM6);
487 declare!(ADC);
488 declare!(CAN1_TX);
489 declare!(CAN1_RX0);
490 declare!(CAN1_RX1);
491 declare!(CAN1_SCE);
492 declare!(EXTI9_5);
493 declare!(TIM1_BRK_TIM9);
494 declare!(TIM1_UP_TIM10);
495 declare!(TIM1_TRG_COM_TIM11);
496 declare!(TIM1_CC);
497 declare!(TIM2);
498 declare!(TIM3);
499 declare!(TIM4);
500 declare!(I2C1_EV);
501 declare!(I2C1_ER);
502 declare!(I2C2_EV);
503 declare!(I2C2_ER);
504 declare!(SPI1);
505 declare!(SPI2);
506 declare!(USART1);
507 declare!(USART2);
508 declare!(USART3);
509 declare!(EXTI15_10);
510 declare!(RTC_ALARM);
511 declare!(OTG_FS_WKUP);
512 declare!(TIM12);
513 declare!(TIM13);
514 declare!(TIM14);
515 declare!(TIM8_CC);
516 declare!(DMA1_STREAM7);
517 declare!(FSMC);
518 declare!(SDIO);
519 declare!(TIM5);
520 declare!(SPI3);
521 declare!(TIM6_DACUNDER);
522 declare!(TIM7);
523 declare!(DMA2_STREAM0);
524 declare!(DMA2_STREAM1);
525 declare!(DMA2_STREAM2);
526 declare!(DMA2_STREAM3);
527 declare!(DMA2_STREAM4);
528 declare!(DFSDM1_FLT0);
529 declare!(DFSDM1_FLT1);
530 declare!(CAN2_TX);
531 declare!(CAN2_RX0);
532 declare!(CAN2_RX1);
533 declare!(CAN2_SCE);
534 declare!(OTG_FS);
535 declare!(DMA2_STREAM5);
536 declare!(DMA2_STREAM6);
537 declare!(DMA2_STREAM7);
538 declare!(USART6);
539 declare!(I2C3_EV);
540 declare!(I2C3_ER);
541 declare!(HASH_RNG);
542 declare!(FPU);
543 declare!(SPI4);
544 declare!(SPI5);
545 declare!(QUAD_SPI);
546 declare!(I2CFMP1_EVENT);
547 declare!(I2CFMP1_ERROR);
548}
549
550#[cfg(feature = "stm32f413")]
551mod irqs {
552 use super::*;
553
554 declare!(PVD);
555 declare!(TAMP_STAMP);
556 declare!(RTC_WKUP);
557 declare!(FLASH);
558 declare!(RCC);
559 declare!(EXTI0);
560 declare!(EXTI1);
561 declare!(EXTI2);
562 declare!(EXTI3);
563 declare!(EXTI4);
564 declare!(DMA1_STREAM0);
565 declare!(DMA1_STREAM1);
566 declare!(DMA1_STREAM2);
567 declare!(DMA1_STREAM3);
568 declare!(DMA1_STREAM4);
569 declare!(DMA1_STREAM5);
570 declare!(DMA1_STREAM6);
571 declare!(ADC);
572 declare!(CAN1_TX);
573 declare!(CAN1_RX0);
574 declare!(CAN1_RX1);
575 declare!(CAN1_SCE);
576 declare!(EXTI9_5);
577 declare!(TIM1_BRK_TIM9);
578 declare!(TIM1_UP_TIM10);
579 declare!(TIM1_TRG_COM_TIM11);
580 declare!(TIM1_CC);
581 declare!(TIM2);
582 declare!(TIM3);
583 declare!(TIM4);
584 declare!(I2C1_EVT);
585 declare!(I2C1_ERR);
586 declare!(I2C2_EVT);
587 declare!(I2C2_ERR);
588 declare!(SPI1);
589 declare!(SPI2);
590 declare!(USART1);
591 declare!(USART2);
592 declare!(USART3);
593 declare!(EXTI15_10);
594 declare!(EXTI17_RTC_ALARM);
595 declare!(TIM8_BRK_TIM12);
596 declare!(TIM8_UP_TIM13);
597 declare!(TIM8_TRG_COM_TIM14);
598 declare!(TIM8_CC);
599 declare!(DMA1_STREAM7);
600 declare!(FSMC);
601 declare!(SDIO);
602 declare!(TIM5);
603 declare!(SPI3);
604 declare!(USART4);
605 declare!(UART5);
606 declare!(TIM6_GLB_IT_DAC1_DAC2);
607 declare!(TIM7);
608 declare!(DMA2_STREAM0);
609 declare!(DMA2_STREAM1);
610 declare!(DMA2_STREAM2);
611 declare!(DMA2_STREAM3);
612 declare!(DMA2_STREAM4);
613 declare!(DFSDM1_FLT0);
614 declare!(DFSDM1_FLT1);
615 declare!(CAN2_TX);
616 declare!(CAN2_RX0);
617 declare!(CAN2_RX1);
618 declare!(CAN2_SCE);
619 declare!(OTG_FS);
620 declare!(DMA2_STREAM5);
621 declare!(DMA2_STREAM6);
622 declare!(DMA2_STREAM7);
623 declare!(USART6);
624 declare!(I2C3_EV);
625 declare!(I2C3_ER);
626 declare!(CAN3_TX);
627 declare!(CAN3_RX0);
628 declare!(CAN3_RX1);
629 declare!(CAN3_SCE);
630 declare!(CRYPTO);
631 declare!(RNG);
632 declare!(FPU);
633 declare!(USART7);
634 declare!(USART8);
635 declare!(SPI4);
636 declare!(SPI5);
637 declare!(SAI1);
638 declare!(UART9);
639 declare!(UART10);
640 declare!(QUADSPI);
641 declare!(I2CFMP1EVENT);
642 declare!(I2CFMP1ERROR);
643 declare!(LPTIM1_OR_IT_EIT_23);
644 declare!(DFSDM2_FILTER1);
645 declare!(DFSDM2_FILTER2);
646 declare!(DFSDM2_FILTER3);
647 declare!(DFSDM2_FILTER4);
648}
649
650#[cfg(feature = "stm32f427")]
651mod irqs {
652 use super::*;
653
654 declare!(WWDG);
655 declare!(PVD);
656 declare!(TAMP_STAMP);
657 declare!(RTC_WKUP);
658 declare!(FLASH);
659 declare!(RCC);
660 declare!(EXTI0);
661 declare!(EXTI1);
662 declare!(EXTI2);
663 declare!(EXTI3);
664 declare!(EXTI4);
665 declare!(DMA1_STREAM0);
666 declare!(DMA1_STREAM1);
667 declare!(DMA1_STREAM2);
668 declare!(DMA1_STREAM3);
669 declare!(DMA1_STREAM4);
670 declare!(DMA1_STREAM5);
671 declare!(DMA1_STREAM6);
672 declare!(ADC);
673 declare!(CAN1_TX);
674 declare!(CAN1_RX0);
675 declare!(CAN1_RX1);
676 declare!(CAN1_SCE);
677 declare!(EXTI9_5);
678 declare!(TIM1_BRK_TIM9);
679 declare!(TIM1_UP_TIM10);
680 declare!(TIM1_TRG_COM_TIM11);
681 declare!(TIM1_CC);
682 declare!(TIM2);
683 declare!(TIM3);
684 declare!(TIM4);
685 declare!(I2C1_EV);
686 declare!(I2C1_ER);
687 declare!(I2C2_EV);
688 declare!(I2C2_ER);
689 declare!(SPI1);
690 declare!(SPI2);
691 declare!(USART1);
692 declare!(USART2);
693 declare!(USART3);
694 declare!(EXTI15_10);
695 declare!(RTC_ALARM);
696 declare!(OTG_FS_WKUP);
697 declare!(TIM8_BRK_TIM12);
698 declare!(TIM8_UP_TIM13);
699 declare!(TIM8_TRG_COM_TIM14);
700 declare!(TIM8_CC);
701 declare!(DMA1_STREAM7);
702 declare!(FMC);
703 declare!(SDIO);
704 declare!(TIM5);
705 declare!(SPI3);
706 declare!(UART4);
707 declare!(UART5);
708 declare!(TIM6_DAC);
709 declare!(TIM7);
710 declare!(DMA2_STREAM0);
711 declare!(DMA2_STREAM1);
712 declare!(DMA2_STREAM2);
713 declare!(DMA2_STREAM3);
714 declare!(DMA2_STREAM4);
715 declare!(ETH);
716 declare!(ETH_WKUP);
717 declare!(CAN2_TX);
718 declare!(CAN2_RX0);
719 declare!(CAN2_RX1);
720 declare!(CAN2_SCE);
721 declare!(OTG_FS);
722 declare!(DMA2_STREAM5);
723 declare!(DMA2_STREAM6);
724 declare!(DMA2_STREAM7);
725 declare!(USART6);
726 declare!(I2C3_EV);
727 declare!(I2C3_ER);
728 declare!(OTG_HS_EP1_OUT);
729 declare!(OTG_HS_EP1_IN);
730 declare!(OTG_HS_WKUP);
731 declare!(OTG_HS);
732 declare!(DCMI);
733 declare!(CRYP);
734 declare!(HASH_RNG);
735 declare!(FPU);
736 declare!(UART7);
737 declare!(UART8);
738 declare!(SPI4);
739 declare!(SPI5);
740 declare!(SPI6);
741 declare!(LCD_TFT);
742 declare!(LCD_TFT_1);
743}
744
745#[cfg(feature = "stm32f429")]
746mod irqs {
747 use super::*;
748
749 declare!(WWDG);
750 declare!(PVD);
751 declare!(TAMP_STAMP);
752 declare!(RTC_WKUP);
753 declare!(FLASH);
754 declare!(RCC);
755 declare!(EXTI0);
756 declare!(EXTI1);
757 declare!(EXTI2);
758 declare!(EXTI3);
759 declare!(EXTI4);
760 declare!(DMA1_STREAM0);
761 declare!(DMA1_STREAM1);
762 declare!(DMA1_STREAM2);
763 declare!(DMA1_STREAM3);
764 declare!(DMA1_STREAM4);
765 declare!(DMA1_STREAM5);
766 declare!(DMA1_STREAM6);
767 declare!(ADC);
768 declare!(CAN1_TX);
769 declare!(CAN1_RX0);
770 declare!(CAN1_RX1);
771 declare!(CAN1_SCE);
772 declare!(EXTI9_5);
773 declare!(TIM1_BRK_TIM9);
774 declare!(TIM1_UP_TIM10);
775 declare!(TIM1_TRG_COM_TIM11);
776 declare!(TIM1_CC);
777 declare!(TIM2);
778 declare!(TIM3);
779 declare!(TIM4);
780 declare!(I2C1_EV);
781 declare!(I2C1_ER);
782 declare!(I2C2_EV);
783 declare!(I2C2_ER);
784 declare!(SPI1);
785 declare!(SPI2);
786 declare!(USART1);
787 declare!(USART2);
788 declare!(USART3);
789 declare!(EXTI15_10);
790 declare!(RTC_ALARM);
791 declare!(OTG_FS_WKUP);
792 declare!(TIM8_BRK_TIM12);
793 declare!(TIM8_UP_TIM13);
794 declare!(TIM8_TRG_COM_TIM14);
795 declare!(TIM8_CC);
796 declare!(DMA1_STREAM7);
797 declare!(FMC);
798 declare!(SDIO);
799 declare!(TIM5);
800 declare!(SPI3);
801 declare!(UART4);
802 declare!(UART5);
803 declare!(TIM6_DAC);
804 declare!(TIM7);
805 declare!(DMA2_STREAM0);
806 declare!(DMA2_STREAM1);
807 declare!(DMA2_STREAM2);
808 declare!(DMA2_STREAM3);
809 declare!(DMA2_STREAM4);
810 declare!(ETH);
811 declare!(ETH_WKUP);
812 declare!(CAN2_TX);
813 declare!(CAN2_RX0);
814 declare!(CAN2_RX1);
815 declare!(CAN2_SCE);
816 declare!(OTG_FS);
817 declare!(DMA2_STREAM5);
818 declare!(DMA2_STREAM6);
819 declare!(DMA2_STREAM7);
820 declare!(USART6);
821 declare!(I2C3_EV);
822 declare!(I2C3_ER);
823 declare!(OTG_HS_EP1_OUT);
824 declare!(OTG_HS_EP1_IN);
825 declare!(OTG_HS_WKUP);
826 declare!(OTG_HS);
827 declare!(DCMI);
828 declare!(CRYP);
829 declare!(HASH_RNG);
830 declare!(FPU);
831 declare!(UART7);
832 declare!(UART8);
833 declare!(SPI4);
834 declare!(SPI5);
835 declare!(SPI6);
836 declare!(SAI1);
837 declare!(LCD_TFT);
838 declare!(LCD_TFT_1);
839 declare!(DMA2D);
840}
841
842#[cfg(feature = "stm32f446")]
843mod irqs {
844 use super::*;
845
846 declare!(WWDG);
847 declare!(TAMP_STAMP);
848 declare!(RTC_WKUP);
849 declare!(FLASH);
850 declare!(RCC);
851 declare!(EXTI0);
852 declare!(EXTI1);
853 declare!(EXTI2);
854 declare!(EXTI3);
855 declare!(EXTI4);
856 declare!(DMA1_STREAM0);
857 declare!(DMA1_STREAM1);
858 declare!(DMA1_STREAM2);
859 declare!(DMA1_STREAM3);
860 declare!(DMA1_STREAM4);
861 declare!(DMA1_STREAM5);
862 declare!(DMA1_STREAM6);
863 declare!(ADC);
864 declare!(CAN1_TX);
865 declare!(CAN1_RX0);
866 declare!(CAN1_RX1);
867 declare!(CAN1_SCE);
868 declare!(EXTI9_5);
869 declare!(TIM1_BRK_TIM9);
870 declare!(TIM1_UP_TIM10);
871 declare!(TIM1_TRG_COM_TIM11);
872 declare!(TIM1_CC);
873 declare!(TIM2);
874 declare!(TIM3);
875 declare!(TIM4);
876 declare!(I2C1_EV);
877 declare!(I2C1_ER);
878 declare!(I2C2_EV);
879 declare!(I2C2_ER);
880 declare!(SPI1);
881 declare!(SPI2);
882 declare!(USART1);
883 declare!(USART2);
884 declare!(USART3);
885 declare!(EXTI15_10);
886 declare!(RTC_ALARM);
887 declare!(OTG_FS_WKUP);
888 declare!(TIM8_BRK_TIM12);
889 declare!(TIM8_UP_TIM13);
890 declare!(TIM8_TRG_COM_TIM14);
891 declare!(TIM8_CC);
892 declare!(DMA1_STREAM7);
893 declare!(FMC);
894 declare!(SDIO);
895 declare!(TIM5);
896 declare!(SPI3);
897 declare!(UART4);
898 declare!(UART5);
899 declare!(TIM6_DAC);
900 declare!(TIM7);
901 declare!(DMA2_STREAM0);
902 declare!(DMA2_STREAM1);
903 declare!(DMA2_STREAM2);
904 declare!(DMA2_STREAM3);
905 declare!(DMA2_STREAM4);
906 declare!(ETH);
907 declare!(ETH_WKUP);
908 declare!(CAN2_TX);
909 declare!(CAN2_RX0);
910 declare!(CAN2_RX1);
911 declare!(CAN2_SCE);
912 declare!(OTG_FS);
913 declare!(DMA2_STREAM5);
914 declare!(DMA2_STREAM6);
915 declare!(DMA2_STREAM7);
916 declare!(USART6);
917 declare!(I2C3_EV);
918 declare!(I2C3_ER);
919 declare!(DCMI);
920 declare!(FPU);
921 declare!(UART7);
922 declare!(UART8);
923 declare!(SPI4);
924 declare!(LCD_TFT);
925 declare!(LCD_TFT_1);
926}
927
928#[cfg(feature = "stm32f469")]
929mod irqs {
930 use super::*;
931
932 declare!(WWDG);
933 declare!(PVD);
934 declare!(TAMP_STAMP);
935 declare!(RTC_WKUP);
936 declare!(FLASH);
937 declare!(RCC);
938 declare!(EXTI0);
939 declare!(EXTI1);
940 declare!(EXTI2);
941 declare!(EXTI3);
942 declare!(EXTI4);
943 declare!(DMA1_STREAM0);
944 declare!(DMA1_STREAM1);
945 declare!(DMA1_STREAM2);
946 declare!(DMA1_STREAM3);
947 declare!(DMA1_STREAM4);
948 declare!(DMA1_STREAM5);
949 declare!(DMA1_STREAM6);
950 declare!(ADC);
951 declare!(CAN1_TX);
952 declare!(CAN1_RX0);
953 declare!(CAN1_RX1);
954 declare!(CAN1_SCE);
955 declare!(EXTI9_5);
956 declare!(TIM1_BRK_TIM9);
957 declare!(TIM1_UP_TIM10);
958 declare!(TIM1_TRG_COM_TIM11);
959 declare!(TIM1_CC);
960 declare!(TIM2);
961 declare!(TIM3);
962 declare!(TIM4);
963 declare!(I2C1_EV);
964 declare!(I2C1_ER);
965 declare!(I2C2_EV);
966 declare!(I2C2_ER);
967 declare!(SPI1);
968 declare!(SPI2);
969 declare!(USART1);
970 declare!(USART2);
971 declare!(USART3);
972 declare!(EXTI15_10);
973 declare!(RTC_ALARM);
974 declare!(OTG_FS_WKUP);
975 declare!(TIM8_BRK_TIM12);
976 declare!(TIM8_UP_TIM13);
977 declare!(TIM8_TRG_COM_TIM14);
978 declare!(TIM8_CC);
979 declare!(DMA1_STREAM7);
980 declare!(FMC);
981 declare!(SDIO);
982 declare!(TIM5);
983 declare!(SPI3);
984 declare!(UART4);
985 declare!(UART5);
986 declare!(TIM6_DAC);
987 declare!(TIM7);
988 declare!(DMA2_STREAM0);
989 declare!(DMA2_STREAM1);
990 declare!(DMA2_STREAM2);
991 declare!(DMA2_STREAM3);
992 declare!(DMA2_STREAM4);
993 declare!(ETH);
994 declare!(ETH_WKUP);
995 declare!(CAN2_TX);
996 declare!(CAN2_RX0);
997 declare!(CAN2_RX1);
998 declare!(CAN2_SCE);
999 declare!(OTG_FS);
1000 declare!(DMA2_STREAM5);
1001 declare!(DMA2_STREAM6);
1002 declare!(DMA2_STREAM7);
1003 declare!(USART6);
1004 declare!(I2C3_EV);
1005 declare!(I2C3_ER);
1006 declare!(OTG_HS_EP1_OUT);
1007 declare!(OTG_HS_EP1_IN);
1008 declare!(OTG_HS_WKUP);
1009 declare!(OTG_HS);
1010 declare!(DCMI);
1011 declare!(CRYP);
1012 declare!(HASH_RNG);
1013 declare!(FPU);
1014 declare!(UART7);
1015 declare!(UART8);
1016 declare!(SPI4);
1017 declare!(SPI5);
1018 declare!(SPI6);
1019 declare!(SAI1);
1020 declare!(LCD_TFT);
1021 declare!(LCD_TFT_1);
1022 declare!(DMA2D);
1023 declare!(QUADSPI);
1024 declare!(DSIHOST);
1025}
1026
256pub use irqs::*; 1027pub use irqs::*;
diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs
index 02668b7eb..eb8530ea2 100644
--- a/embassy-stm32f4/src/lib.rs
+++ b/embassy-stm32f4/src/lib.rs
@@ -312,6 +312,7 @@ pub(crate) mod fmt;
312 312
313pub mod exti; 313pub mod exti;
314pub mod interrupt; 314pub mod interrupt;
315pub mod rtc;
315pub mod serial; 316pub mod serial;
316 317
317pub use cortex_m_rt::interrupt; 318pub use cortex_m_rt::interrupt;
diff --git a/embassy-stm32f4/src/rtc.rs b/embassy-stm32f4/src/rtc.rs
new file mode 100644
index 000000000..283442712
--- /dev/null
+++ b/embassy-stm32f4/src/rtc.rs
@@ -0,0 +1,505 @@
1use core::cell::Cell;
2use core::convert::TryInto;
3use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
4
5use embassy::time::{Clock, TICKS_PER_SECOND};
6use stm32f4xx_hal::bb;
7use stm32f4xx_hal::rcc::Clocks;
8
9use crate::interrupt;
10use crate::interrupt::{CriticalSection, Mutex, OwnedInterrupt};
11
12// RTC timekeeping works with something we call "periods", which are time intervals
13// of 2^15 ticks. The RTC counter value is 16 bits, so one "overflow cycle" is 2 periods.
14//
15// A `period` count is maintained in parallel to the RTC hardware `counter`, like this:
16// - `period` and `counter` start at 0
17// - `period` is incremented on overflow (at counter value 0)
18// - `period` is incremented "midway" between overflows (at counter value 0x8000)
19//
20// Therefore, when `period` is even, counter is in 0..0x7FFF. When odd, counter is in 0x8000..0xFFFF
21// This allows for now() to return the correct value even if it races an overflow.
22//
23// To get `now()`, `period` is read first, then `counter` is read. If the counter value matches
24// the expected range for the `period` parity, we're done. If it doesn't, this means that
25// a new period start has raced us between reading `period` and `counter`, so we assume the `counter` value
26// corresponds to the next period.
27//
28// `period` is a 32bit integer, so It overflows on 2^32 * 2^15 / 32768 seconds of uptime, which is 136 years.
29fn calc_now(period: u32, counter: u16) -> u64 {
30 ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64)
31}
32
33struct AlarmState {
34 timestamp: Cell<u64>,
35 callback: Cell<Option<(fn(*mut ()), *mut ())>>,
36}
37
38impl AlarmState {
39 fn new() -> Self {
40 Self {
41 timestamp: Cell::new(u64::MAX),
42 callback: Cell::new(None),
43 }
44 }
45}
46
47// TODO: This is sometimes wasteful, try to find a better way
48const ALARM_COUNT: usize = 3;
49
50/// RTC timer that can be used by the executor and to set alarms.
51///
52/// It can work with Timers 2, 3, 4, 5, 9 and 12. Timers 9 and 12 only have one alarm available,
53/// while the others have three each.
54/// This timer works internally with a unit of 2^15 ticks, which means that if a call to
55/// [`embassy::time::Clock::now`] is blocked for that amount of ticks the returned value will be
56/// wrong (an old value). The current default tick rate is 32768 ticks per second.
57pub struct RTC<T: Instance> {
58 rtc: T,
59 irq: T::Interrupt,
60
61 /// Number of 2^23 periods elapsed since boot.
62 period: AtomicU32,
63
64 /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled.
65 alarms: Mutex<[AlarmState; ALARM_COUNT]>,
66
67 clocks: Clocks,
68}
69
70impl<T: Instance> RTC<T> {
71 pub fn new(rtc: T, irq: T::Interrupt, clocks: Clocks) -> Self {
72 Self {
73 rtc,
74 irq,
75 period: AtomicU32::new(0),
76 alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]),
77 clocks,
78 }
79 }
80
81 pub fn start(&'static self) {
82 self.rtc.enable_clock();
83 self.rtc.stop_and_reset();
84
85 let multiplier = if T::ppre(&self.clocks) == 1 { 1 } else { 2 };
86 let freq = T::pclk(&self.clocks) * multiplier;
87 let psc = freq / TICKS_PER_SECOND as u32 - 1;
88 let psc: u16 = psc.try_into().unwrap();
89
90 self.rtc.set_psc_arr(psc, u16::MAX);
91 // Mid-way point
92 self.rtc.set_compare(0, 0x8000);
93 self.rtc.set_compare_interrupt(0, true);
94
95 self.irq.set_handler(
96 |ptr| unsafe {
97 let this = &*(ptr as *const () as *const Self);
98 this.on_interrupt();
99 },
100 self as *const _ as *mut _,
101 );
102 self.irq.unpend();
103 self.irq.enable();
104
105 self.rtc.start();
106 }
107
108 fn on_interrupt(&self) {
109 if self.rtc.overflow_interrupt_status() {
110 self.rtc.overflow_clear_flag();
111 self.next_period();
112 }
113
114 // Half overflow
115 if self.rtc.compare_interrupt_status(0) {
116 self.rtc.compare_clear_flag(0);
117 self.next_period();
118 }
119
120 for n in 1..=ALARM_COUNT {
121 if self.rtc.compare_interrupt_status(n) {
122 self.rtc.compare_clear_flag(n);
123 interrupt::free(|cs| self.trigger_alarm(n, cs));
124 }
125 }
126 }
127
128 fn next_period(&self) {
129 interrupt::free(|cs| {
130 let period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
131 let t = (period as u64) << 15;
132
133 for n in 1..=ALARM_COUNT {
134 let alarm = &self.alarms.borrow(cs)[n - 1];
135 let at = alarm.timestamp.get();
136
137 let diff = at - t;
138 if diff < 0xc000 {
139 self.rtc.set_compare(n, at as u16);
140 self.rtc.set_compare_interrupt(n, true);
141 }
142 }
143 })
144 }
145
146 fn trigger_alarm(&self, n: usize, cs: &CriticalSection) {
147 self.rtc.set_compare_interrupt(n, false);
148
149 let alarm = &self.alarms.borrow(cs)[n - 1];
150 alarm.timestamp.set(u64::MAX);
151
152 // Call after clearing alarm, so the callback can set another alarm.
153 if let Some((f, ctx)) = alarm.callback.get() {
154 f(ctx);
155 }
156 }
157
158 fn set_alarm_callback(&self, n: usize, callback: fn(*mut ()), ctx: *mut ()) {
159 interrupt::free(|cs| {
160 let alarm = &self.alarms.borrow(cs)[n - 1];
161 alarm.callback.set(Some((callback, ctx)));
162 })
163 }
164
165 fn set_alarm(&self, n: usize, timestamp: u64) {
166 interrupt::free(|cs| {
167 let alarm = &self.alarms.borrow(cs)[n - 1];
168 alarm.timestamp.set(timestamp);
169
170 let t = self.now();
171 if timestamp <= t {
172 self.trigger_alarm(n, cs);
173 return;
174 }
175
176 let diff = timestamp - t;
177 if diff < 0xc000 {
178 let safe_timestamp = timestamp.max(t + 3);
179 self.rtc.set_compare(n, safe_timestamp as u16);
180 self.rtc.set_compare_interrupt(n, true);
181 } else {
182 self.rtc.set_compare_interrupt(n, false);
183 }
184 })
185 }
186
187 pub fn alarm1(&'static self) -> Alarm<T> {
188 Alarm { n: 1, rtc: self }
189 }
190 pub fn alarm2(&'static self) -> Option<Alarm<T>> {
191 if T::REAL_ALARM_COUNT >= 2 {
192 Some(Alarm { n: 2, rtc: self })
193 } else {
194 None
195 }
196 }
197 pub fn alarm3(&'static self) -> Option<Alarm<T>> {
198 if T::REAL_ALARM_COUNT >= 3 {
199 Some(Alarm { n: 3, rtc: self })
200 } else {
201 None
202 }
203 }
204}
205
206impl<T: Instance> embassy::time::Clock for RTC<T> {
207 fn now(&self) -> u64 {
208 let period = self.period.load(Ordering::Relaxed);
209 compiler_fence(Ordering::Acquire);
210 let counter = self.rtc.counter();
211 calc_now(period, counter)
212 }
213}
214
215pub struct Alarm<T: Instance> {
216 n: usize,
217 rtc: &'static RTC<T>,
218}
219
220impl<T: Instance> embassy::time::Alarm for Alarm<T> {
221 fn set_callback(&self, callback: fn(*mut ()), ctx: *mut ()) {
222 self.rtc.set_alarm_callback(self.n, callback, ctx);
223 }
224
225 fn set(&self, timestamp: u64) {
226 self.rtc.set_alarm(self.n, timestamp);
227 }
228
229 fn clear(&self) {
230 self.rtc.set_alarm(self.n, u64::MAX);
231 }
232}
233
234mod sealed {
235 pub trait Sealed {}
236}
237
238pub trait Instance: sealed::Sealed + Sized + 'static {
239 type Interrupt: OwnedInterrupt;
240 const REAL_ALARM_COUNT: usize;
241
242 fn enable_clock(&self);
243 fn set_compare(&self, n: usize, value: u16);
244 fn set_compare_interrupt(&self, n: usize, enable: bool);
245 fn compare_interrupt_status(&self, n: usize) -> bool;
246 fn compare_clear_flag(&self, n: usize);
247 fn overflow_interrupt_status(&self) -> bool;
248 fn overflow_clear_flag(&self);
249 // This method should ensure that the values are really updated before returning
250 fn set_psc_arr(&self, psc: u16, arr: u16);
251 fn stop_and_reset(&self);
252 fn start(&self);
253 fn counter(&self) -> u16;
254 fn ppre(clocks: &Clocks) -> u8;
255 fn pclk(clocks: &Clocks) -> u32;
256}
257
258#[allow(unused_macros)]
259macro_rules! impl_timer {
260 ($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 3) => {
261 mod $module {
262 use super::*;
263 use stm32f4xx_hal::pac::{$TYPE, RCC};
264
265 impl sealed::Sealed for $TYPE {}
266
267 impl Instance for $TYPE {
268 type Interrupt = interrupt::$INT;
269 const REAL_ALARM_COUNT: usize = 3;
270
271 fn enable_clock(&self) {
272 // NOTE(unsafe) It will only be used for atomic operations
273 unsafe {
274 let rcc = &*RCC::ptr();
275
276 bb::set(&rcc.$apbenr, $enrbit);
277 bb::set(&rcc.$apbrstr, $rstrbit);
278 bb::clear(&rcc.$apbrstr, $rstrbit);
279 }
280 }
281
282 fn set_compare(&self, n: usize, value: u16) {
283 // NOTE(unsafe) these registers accept all the range of u16 values
284 match n {
285 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
286 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
287 2 => self.ccr3.write(|w| unsafe { w.bits(value.into()) }),
288 3 => self.ccr4.write(|w| unsafe { w.bits(value.into()) }),
289 _ => {}
290 }
291 }
292
293 fn set_compare_interrupt(&self, n: usize, enable: bool) {
294 if n > 3 {
295 return;
296 }
297 let bit = n as u8 + 1;
298 unsafe {
299 if enable {
300 bb::set(&self.dier, bit);
301 } else {
302 bb::clear(&self.dier, bit);
303 }
304 }
305 }
306
307 fn compare_interrupt_status(&self, n: usize) -> bool {
308 let status = self.sr.read();
309 match n {
310 0 => status.cc1if().bit_is_set(),
311 1 => status.cc2if().bit_is_set(),
312 2 => status.cc3if().bit_is_set(),
313 3 => status.cc4if().bit_is_set(),
314 _ => false,
315 }
316 }
317
318 fn compare_clear_flag(&self, n: usize) {
319 if n > 3 {
320 return;
321 }
322 let bit = n as u8 + 1;
323 unsafe {
324 bb::clear(&self.sr, bit);
325 }
326 }
327
328 fn overflow_interrupt_status(&self) -> bool {
329 self.sr.read().uif().bit_is_set()
330 }
331
332 fn overflow_clear_flag(&self) {
333 unsafe {
334 bb::clear(&self.sr, 0);
335 }
336 }
337
338 fn set_psc_arr(&self, psc: u16, arr: u16) {
339 // NOTE(unsafe) All u16 values are valid
340 self.psc.write(|w| unsafe { w.bits(psc.into()) });
341 self.arr.write(|w| unsafe { w.bits(arr.into()) });
342
343 unsafe {
344 // Set URS, generate update, clear URS
345 bb::set(&self.cr1, 2);
346 self.egr.write(|w| w.ug().set_bit());
347 bb::clear(&self.cr1, 2);
348 }
349 }
350
351 fn stop_and_reset(&self) {
352 unsafe {
353 bb::clear(&self.cr1, 0);
354 }
355 self.cnt.reset();
356 }
357
358 fn start(&self) {
359 unsafe { bb::set(&self.cr1, 0) }
360 }
361
362 fn counter(&self) -> u16 {
363 self.cnt.read().bits() as u16
364 }
365
366 fn ppre(clocks: &Clocks) -> u8 {
367 clocks.$ppre()
368 }
369
370 fn pclk(clocks: &Clocks) -> u32 {
371 clocks.$pclk().0
372 }
373 }
374 }
375 };
376
377 ($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 1) => {
378 mod $module {
379 use super::*;
380 use stm32f4xx_hal::pac::{$TYPE, RCC};
381
382 impl sealed::Sealed for $TYPE {}
383
384 impl Instance for $TYPE {
385 type Interrupt = interrupt::$INT;
386 const REAL_ALARM_COUNT: usize = 1;
387
388 fn enable_clock(&self) {
389 // NOTE(unsafe) It will only be used for atomic operations
390 unsafe {
391 let rcc = &*RCC::ptr();
392
393 bb::set(&rcc.$apbenr, $enrbit);
394 bb::set(&rcc.$apbrstr, $rstrbit);
395 bb::clear(&rcc.$apbrstr, $rstrbit);
396 }
397 }
398
399 fn set_compare(&self, n: usize, value: u16) {
400 // NOTE(unsafe) these registers accept all the range of u16 values
401 match n {
402 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
403 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
404 _ => {}
405 }
406 }
407
408 fn set_compare_interrupt(&self, n: usize, enable: bool) {
409 if n > 1 {
410 return;
411 }
412 let bit = n as u8 + 1;
413 unsafe {
414 if enable {
415 bb::set(&self.dier, bit);
416 } else {
417 bb::clear(&self.dier, bit);
418 }
419 }
420 }
421
422 fn compare_interrupt_status(&self, n: usize) -> bool {
423 let status = self.sr.read();
424 match n {
425 0 => status.cc1if().bit_is_set(),
426 1 => status.cc2if().bit_is_set(),
427 _ => false,
428 }
429 }
430
431 fn compare_clear_flag(&self, n: usize) {
432 if n > 1 {
433 return;
434 }
435 let bit = n as u8 + 1;
436 unsafe {
437 bb::clear(&self.sr, bit);
438 }
439 }
440
441 fn overflow_interrupt_status(&self) -> bool {
442 self.sr.read().uif().bit_is_set()
443 }
444
445 fn overflow_clear_flag(&self) {
446 unsafe {
447 bb::clear(&self.sr, 0);
448 }
449 }
450
451 fn set_psc_arr(&self, psc: u16, arr: u16) {
452 // NOTE(unsafe) All u16 values are valid
453 self.psc.write(|w| unsafe { w.bits(psc.into()) });
454 self.arr.write(|w| unsafe { w.bits(arr.into()) });
455
456 unsafe {
457 // Set URS, generate update, clear URS
458 bb::set(&self.cr1, 2);
459 self.egr.write(|w| w.ug().set_bit());
460 bb::clear(&self.cr1, 2);
461 }
462 }
463
464 fn stop_and_reset(&self) {
465 unsafe {
466 bb::clear(&self.cr1, 0);
467 }
468 self.cnt.reset();
469 }
470
471 fn start(&self) {
472 unsafe { bb::set(&self.cr1, 0) }
473 }
474
475 fn counter(&self) -> u16 {
476 self.cnt.read().bits() as u16
477 }
478
479 fn ppre(clocks: &Clocks) -> u8 {
480 clocks.$ppre()
481 }
482
483 fn pclk(clocks: &Clocks) -> u32 {
484 clocks.$pclk().0
485 }
486 }
487 }
488 };
489}
490
491#[cfg(not(feature = "stm32f410"))]
492impl_timer!(tim2: (TIM2, TIM2Interrupt, apb1enr, 0, apb1rstr, 0, ppre1, pclk1), 3);
493
494#[cfg(not(feature = "stm32f410"))]
495impl_timer!(tim3: (TIM3, TIM3Interrupt, apb1enr, 1, apb1rstr, 1, ppre1, pclk1), 3);
496
497#[cfg(not(feature = "stm32f410"))]
498impl_timer!(tim4: (TIM4, TIM4Interrupt, apb1enr, 2, apb1rstr, 2, ppre1, pclk1), 3);
499
500impl_timer!(tim5: (TIM5, TIM5Interrupt, apb1enr, 3, apb1rstr, 3, ppre1, pclk1), 3);
501
502impl_timer!(tim9: (TIM9, TIM1_BRK_TIM9Interrupt, apb2enr, 16, apb2rstr, 16, ppre2, pclk2), 1);
503
504#[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411")))]
505impl_timer!(tim12: (TIM12, TIM8_BRK_TIM12Interrupt, apb1enr, 6, apb1rstr, 6, ppre1, pclk1), 1);