aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-04-14 15:34:58 +0200
committerDario Nieuwenhuis <[email protected]>2021-04-20 02:44:55 +0200
commitef4d9d243e4e833b3f52c8a1e651877116386894 (patch)
tree6f414bc39408cde99604acafd8f57887c36fd03e
parent170536b0730d8ab7c2bdce4d3167aca7b70d2cd2 (diff)
wip usart
-rw-r--r--embassy-stm32-examples/src/bin/usart.rs130
-rw-r--r--embassy-stm32/src/chip/f429.rs11
-rw-r--r--embassy-stm32/src/lib.rs1
-rw-r--r--embassy-stm32/src/usart.rs64
4 files changed, 204 insertions, 2 deletions
diff --git a/embassy-stm32-examples/src/bin/usart.rs b/embassy-stm32-examples/src/bin/usart.rs
new file mode 100644
index 000000000..c218b8ced
--- /dev/null
+++ b/embassy-stm32-examples/src/bin/usart.rs
@@ -0,0 +1,130 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(min_type_alias_impl_trait)]
5#![feature(impl_trait_in_bindings)]
6#![feature(type_alias_impl_trait)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use embassy::executor::Executor;
11use embassy::time::Clock;
12use embassy::util::Forever;
13use embassy_stm32::exti::{self, ExtiInput};
14use embassy_stm32::gpio::{Input, Pull};
15use embassy_traits::gpio::{WaitForFallingEdge, WaitForRisingEdge};
16use example_common::*;
17
18use cortex_m_rt::entry;
19use pac::{interrupt, NVIC};
20use stm32f4::stm32f429 as pac;
21
22#[embassy::task]
23async fn main_task() {
24 let p = embassy_stm32::Peripherals::take().unwrap();
25 let button = Input::new(p.PC13, Pull::Down);
26 let mut button = ExtiInput::new(button, p.EXTI13);
27
28 info!("Press the USER button...");
29
30 loop {
31 button.wait_for_rising_edge().await;
32 info!("Pressed!");
33 button.wait_for_falling_edge().await;
34 info!("Released!");
35 }
36}
37
38struct ZeroClock;
39
40impl Clock for ZeroClock {
41 fn now(&self) -> u64 {
42 0
43 }
44}
45
46static EXECUTOR: Forever<Executor> = Forever::new();
47
48#[entry]
49fn main() -> ! {
50 info!("Hello World!");
51
52 let pp = pac::Peripherals::take().unwrap();
53
54 pp.DBGMCU.cr.modify(|_, w| {
55 w.dbg_sleep().set_bit();
56 w.dbg_standby().set_bit();
57 w.dbg_stop().set_bit()
58 });
59 pp.RCC.ahb1enr.modify(|_, w| w.dma1en().enabled());
60
61 pp.RCC.ahb1enr.modify(|_, w| {
62 w.gpioaen().enabled();
63 w.gpioben().enabled();
64 w.gpiocen().enabled();
65 w.gpioden().enabled();
66 w.gpioeen().enabled();
67 w.gpiofen().enabled();
68 w
69 });
70 pp.RCC.apb2enr.modify(|_, w| {
71 w.usart1en().enabled();
72 w.syscfgen().enabled();
73 w
74 });
75
76 unsafe { embassy::time::set_clock(&ZeroClock) };
77
78 unsafe {
79 NVIC::unmask(interrupt::EXTI0);
80 NVIC::unmask(interrupt::EXTI1);
81 NVIC::unmask(interrupt::EXTI2);
82 NVIC::unmask(interrupt::EXTI3);
83 NVIC::unmask(interrupt::EXTI4);
84 NVIC::unmask(interrupt::EXTI9_5);
85 NVIC::unmask(interrupt::EXTI15_10);
86 }
87
88 let executor = EXECUTOR.put(Executor::new());
89
90 executor.run(|spawner| {
91 unwrap!(spawner.spawn(main_task()));
92 })
93}
94
95// TODO for now irq handling is done by user code using the old pac, until we figure out how interrupts work in the metapac
96
97#[interrupt]
98unsafe fn EXTI0() {
99 exti::on_irq()
100}
101
102#[interrupt]
103unsafe fn EXTI1() {
104 exti::on_irq()
105}
106
107#[interrupt]
108unsafe fn EXTI2() {
109 exti::on_irq()
110}
111
112#[interrupt]
113unsafe fn EXTI3() {
114 exti::on_irq()
115}
116
117#[interrupt]
118unsafe fn EXTI4() {
119 exti::on_irq()
120}
121
122#[interrupt]
123unsafe fn EXTI9_5() {
124 exti::on_irq()
125}
126
127#[interrupt]
128unsafe fn EXTI15_10() {
129 exti::on_irq()
130}
diff --git a/embassy-stm32/src/chip/f429.rs b/embassy-stm32/src/chip/f429.rs
index db68faa5a..1209b9237 100644
--- a/embassy-stm32/src/chip/f429.rs
+++ b/embassy-stm32/src/chip/f429.rs
@@ -1,5 +1,6 @@
1use embassy_extras::peripherals; 1use embassy_extras::peripherals;
2 2
3#[rustfmt::skip]
3peripherals!( 4peripherals!(
4 // GPIO Port A 5 // GPIO Port A
5 PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, 6 PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15,
@@ -10,6 +11,12 @@ peripherals!(
10 // todo more ports 11 // todo more ports
11 12
12 // EXTI 13 // EXTI
13 EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5, EXTI6, EXTI7, EXTI8, EXTI9, EXTI10, EXTI11, EXTI12, 14 EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5, EXTI6, EXTI7, EXTI8, EXTI9, EXTI10, EXTI11, EXTI12, EXTI13, EXTI14, EXTI15,
14 EXTI13, EXTI14, EXTI15, 15
16 // USART
17 USART1,
18 USART2,
19 USART3,
20 USART6,
21
15); 22);
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index da266f75d..8fe53840f 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -32,5 +32,6 @@ pub mod exti;
32pub mod gpio; 32pub mod gpio;
33//pub mod rtc; 33//pub mod rtc;
34//pub mod interrupt; 34//pub mod interrupt;
35pub mod usart;
35 36
36pub(crate) use stm32_metapac as pac; 37pub(crate) use stm32_metapac as pac;
diff --git a/embassy-stm32/src/usart.rs b/embassy-stm32/src/usart.rs
new file mode 100644
index 000000000..ad1376941
--- /dev/null
+++ b/embassy-stm32/src/usart.rs
@@ -0,0 +1,64 @@
1use embassy::util::PeripheralBorrow;
2
3use crate::pac::usart_v1::{regs, vals, Usart};
4use crate::peripherals;
5
6mod sealed {
7 use super::*;
8 pub trait Instance {
9 fn regs(&self) -> Usart;
10 }
11}
12
13#[non_exhaustive]
14pub struct Config {
15 pub baudrate: u32,
16 pub data_bits: u8,
17 pub stop_bits: u8,
18}
19
20impl Default for Config {
21 fn default() -> Self {
22 Self {
23 baudrate: 115200,
24 data_bits: 8,
25 stop_bits: 1,
26 }
27 }
28}
29
30pub struct Uart<'d, T: Instance> {
31 inner: T,
32 phantom: PhantomData<&'d mut T>,
33}
34
35impl<'d, T: Instance> Uart<'d, T> {
36 pub fn new(
37 inner: impl PeripheralBorrow<Target = T>,
38 tx: impl PeripheralBorrow<Target = impl TxPin<T>>,
39 rx: impl PeripheralBorrow<Target = impl RxPin<T>>,
40 cts: impl PeripheralBorrow<Target = impl CtsPin<T>>,
41 rts: impl PeripheralBorrow<Target = impl RtsPin<T>>,
42 config: Config,
43 ) -> Self {
44 unborrow!(inner, tx, rx, cts, rts);
45 }
46}
47
48pub trait Instance: sealed::Instance {}
49
50macro_rules! impl_instance {
51 ($type:ident, $addr:expr) => {
52 impl sealed::Instance for peripherals::$type {
53 fn regs(&self) -> Usart {
54 Usart($addr as _)
55 }
56 }
57 impl Instance for peripherals::$type {}
58 };
59}
60
61impl_instance!(USART1, 0x40011000);
62impl_instance!(USART2, 0x40004400);
63impl_instance!(USART3, 0x40004800);
64impl_instance!(USART6, 0x40011400);