diff options
| -rw-r--r-- | embassy-stm32-examples/src/bin/usart.rs | 130 | ||||
| -rw-r--r-- | embassy-stm32/src/chip/f429.rs | 11 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/usart.rs | 64 |
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"] | ||
| 9 | mod example_common; | ||
| 10 | use embassy::executor::Executor; | ||
| 11 | use embassy::time::Clock; | ||
| 12 | use embassy::util::Forever; | ||
| 13 | use embassy_stm32::exti::{self, ExtiInput}; | ||
| 14 | use embassy_stm32::gpio::{Input, Pull}; | ||
| 15 | use embassy_traits::gpio::{WaitForFallingEdge, WaitForRisingEdge}; | ||
| 16 | use example_common::*; | ||
| 17 | |||
| 18 | use cortex_m_rt::entry; | ||
| 19 | use pac::{interrupt, NVIC}; | ||
| 20 | use stm32f4::stm32f429 as pac; | ||
| 21 | |||
| 22 | #[embassy::task] | ||
| 23 | async 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 | |||
| 38 | struct ZeroClock; | ||
| 39 | |||
| 40 | impl Clock for ZeroClock { | ||
| 41 | fn now(&self) -> u64 { | ||
| 42 | 0 | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | static EXECUTOR: Forever<Executor> = Forever::new(); | ||
| 47 | |||
| 48 | #[entry] | ||
| 49 | fn 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] | ||
| 98 | unsafe fn EXTI0() { | ||
| 99 | exti::on_irq() | ||
| 100 | } | ||
| 101 | |||
| 102 | #[interrupt] | ||
| 103 | unsafe fn EXTI1() { | ||
| 104 | exti::on_irq() | ||
| 105 | } | ||
| 106 | |||
| 107 | #[interrupt] | ||
| 108 | unsafe fn EXTI2() { | ||
| 109 | exti::on_irq() | ||
| 110 | } | ||
| 111 | |||
| 112 | #[interrupt] | ||
| 113 | unsafe fn EXTI3() { | ||
| 114 | exti::on_irq() | ||
| 115 | } | ||
| 116 | |||
| 117 | #[interrupt] | ||
| 118 | unsafe fn EXTI4() { | ||
| 119 | exti::on_irq() | ||
| 120 | } | ||
| 121 | |||
| 122 | #[interrupt] | ||
| 123 | unsafe fn EXTI9_5() { | ||
| 124 | exti::on_irq() | ||
| 125 | } | ||
| 126 | |||
| 127 | #[interrupt] | ||
| 128 | unsafe 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 @@ | |||
| 1 | use embassy_extras::peripherals; | 1 | use embassy_extras::peripherals; |
| 2 | 2 | ||
| 3 | #[rustfmt::skip] | ||
| 3 | peripherals!( | 4 | peripherals!( |
| 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; | |||
| 32 | pub mod gpio; | 32 | pub mod gpio; |
| 33 | //pub mod rtc; | 33 | //pub mod rtc; |
| 34 | //pub mod interrupt; | 34 | //pub mod interrupt; |
| 35 | pub mod usart; | ||
| 35 | 36 | ||
| 36 | pub(crate) use stm32_metapac as pac; | 37 | pub(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 @@ | |||
| 1 | use embassy::util::PeripheralBorrow; | ||
| 2 | |||
| 3 | use crate::pac::usart_v1::{regs, vals, Usart}; | ||
| 4 | use crate::peripherals; | ||
| 5 | |||
| 6 | mod sealed { | ||
| 7 | use super::*; | ||
| 8 | pub trait Instance { | ||
| 9 | fn regs(&self) -> Usart; | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | #[non_exhaustive] | ||
| 14 | pub struct Config { | ||
| 15 | pub baudrate: u32, | ||
| 16 | pub data_bits: u8, | ||
| 17 | pub stop_bits: u8, | ||
| 18 | } | ||
| 19 | |||
| 20 | impl Default for Config { | ||
| 21 | fn default() -> Self { | ||
| 22 | Self { | ||
| 23 | baudrate: 115200, | ||
| 24 | data_bits: 8, | ||
| 25 | stop_bits: 1, | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | pub struct Uart<'d, T: Instance> { | ||
| 31 | inner: T, | ||
| 32 | phantom: PhantomData<&'d mut T>, | ||
| 33 | } | ||
| 34 | |||
| 35 | impl<'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 | |||
| 48 | pub trait Instance: sealed::Instance {} | ||
| 49 | |||
| 50 | macro_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 | |||
| 61 | impl_instance!(USART1, 0x40011000); | ||
| 62 | impl_instance!(USART2, 0x40004400); | ||
| 63 | impl_instance!(USART3, 0x40004800); | ||
| 64 | impl_instance!(USART6, 0x40011400); | ||
