From ef4d9d243e4e833b3f52c8a1e651877116386894 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 14 Apr 2021 15:34:58 +0200 Subject: [PATCH] wip usart --- embassy-stm32-examples/src/bin/usart.rs | 130 ++++++++++++++++++++++++ embassy-stm32/src/chip/f429.rs | 11 +- embassy-stm32/src/lib.rs | 1 + embassy-stm32/src/usart.rs | 64 ++++++++++++ 4 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 embassy-stm32-examples/src/bin/usart.rs create mode 100644 embassy-stm32/src/usart.rs diff --git a/embassy-stm32-examples/src/bin/usart.rs b/embassy-stm32-examples/src/bin/usart.rs new file mode 100644 index 00000000..c218b8ce --- /dev/null +++ b/embassy-stm32-examples/src/bin/usart.rs @@ -0,0 +1,130 @@ +#![no_std] +#![no_main] +#![feature(trait_alias)] +#![feature(min_type_alias_impl_trait)] +#![feature(impl_trait_in_bindings)] +#![feature(type_alias_impl_trait)] + +#[path = "../example_common.rs"] +mod example_common; +use embassy::executor::Executor; +use embassy::time::Clock; +use embassy::util::Forever; +use embassy_stm32::exti::{self, ExtiInput}; +use embassy_stm32::gpio::{Input, Pull}; +use embassy_traits::gpio::{WaitForFallingEdge, WaitForRisingEdge}; +use example_common::*; + +use cortex_m_rt::entry; +use pac::{interrupt, NVIC}; +use stm32f4::stm32f429 as pac; + +#[embassy::task] +async fn main_task() { + let p = embassy_stm32::Peripherals::take().unwrap(); + let button = Input::new(p.PC13, Pull::Down); + let mut button = ExtiInput::new(button, p.EXTI13); + + info!("Press the USER button..."); + + loop { + button.wait_for_rising_edge().await; + info!("Pressed!"); + button.wait_for_falling_edge().await; + info!("Released!"); + } +} + +struct ZeroClock; + +impl Clock for ZeroClock { + fn now(&self) -> u64 { + 0 + } +} + +static EXECUTOR: Forever = Forever::new(); + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let pp = pac::Peripherals::take().unwrap(); + + pp.DBGMCU.cr.modify(|_, w| { + w.dbg_sleep().set_bit(); + w.dbg_standby().set_bit(); + w.dbg_stop().set_bit() + }); + pp.RCC.ahb1enr.modify(|_, w| w.dma1en().enabled()); + + pp.RCC.ahb1enr.modify(|_, w| { + w.gpioaen().enabled(); + w.gpioben().enabled(); + w.gpiocen().enabled(); + w.gpioden().enabled(); + w.gpioeen().enabled(); + w.gpiofen().enabled(); + w + }); + pp.RCC.apb2enr.modify(|_, w| { + w.usart1en().enabled(); + w.syscfgen().enabled(); + w + }); + + unsafe { embassy::time::set_clock(&ZeroClock) }; + + unsafe { + NVIC::unmask(interrupt::EXTI0); + NVIC::unmask(interrupt::EXTI1); + NVIC::unmask(interrupt::EXTI2); + NVIC::unmask(interrupt::EXTI3); + NVIC::unmask(interrupt::EXTI4); + NVIC::unmask(interrupt::EXTI9_5); + NVIC::unmask(interrupt::EXTI15_10); + } + + let executor = EXECUTOR.put(Executor::new()); + + executor.run(|spawner| { + unwrap!(spawner.spawn(main_task())); + }) +} + +// TODO for now irq handling is done by user code using the old pac, until we figure out how interrupts work in the metapac + +#[interrupt] +unsafe fn EXTI0() { + exti::on_irq() +} + +#[interrupt] +unsafe fn EXTI1() { + exti::on_irq() +} + +#[interrupt] +unsafe fn EXTI2() { + exti::on_irq() +} + +#[interrupt] +unsafe fn EXTI3() { + exti::on_irq() +} + +#[interrupt] +unsafe fn EXTI4() { + exti::on_irq() +} + +#[interrupt] +unsafe fn EXTI9_5() { + exti::on_irq() +} + +#[interrupt] +unsafe fn EXTI15_10() { + exti::on_irq() +} diff --git a/embassy-stm32/src/chip/f429.rs b/embassy-stm32/src/chip/f429.rs index db68faa5..1209b923 100644 --- a/embassy-stm32/src/chip/f429.rs +++ b/embassy-stm32/src/chip/f429.rs @@ -1,5 +1,6 @@ use embassy_extras::peripherals; +#[rustfmt::skip] peripherals!( // GPIO Port A PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, @@ -10,6 +11,12 @@ peripherals!( // todo more ports // EXTI - EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5, EXTI6, EXTI7, EXTI8, EXTI9, EXTI10, EXTI11, EXTI12, - EXTI13, EXTI14, EXTI15, + EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5, EXTI6, EXTI7, EXTI8, EXTI9, EXTI10, EXTI11, EXTI12, EXTI13, EXTI14, EXTI15, + + // USART + USART1, + USART2, + USART3, + USART6, + ); diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index da266f75..8fe53840 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -32,5 +32,6 @@ pub mod exti; pub mod gpio; //pub mod rtc; //pub mod interrupt; +pub mod usart; 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 00000000..ad137694 --- /dev/null +++ b/embassy-stm32/src/usart.rs @@ -0,0 +1,64 @@ +use embassy::util::PeripheralBorrow; + +use crate::pac::usart_v1::{regs, vals, Usart}; +use crate::peripherals; + +mod sealed { + use super::*; + pub trait Instance { + fn regs(&self) -> Usart; + } +} + +#[non_exhaustive] +pub struct Config { + pub baudrate: u32, + pub data_bits: u8, + pub stop_bits: u8, +} + +impl Default for Config { + fn default() -> Self { + Self { + baudrate: 115200, + data_bits: 8, + stop_bits: 1, + } + } +} + +pub struct Uart<'d, T: Instance> { + inner: T, + phantom: PhantomData<&'d mut T>, +} + +impl<'d, T: Instance> Uart<'d, T> { + pub fn new( + inner: impl PeripheralBorrow, + tx: impl PeripheralBorrow>, + rx: impl PeripheralBorrow>, + cts: impl PeripheralBorrow>, + rts: impl PeripheralBorrow>, + config: Config, + ) -> Self { + unborrow!(inner, tx, rx, cts, rts); + } +} + +pub trait Instance: sealed::Instance {} + +macro_rules! impl_instance { + ($type:ident, $addr:expr) => { + impl sealed::Instance for peripherals::$type { + fn regs(&self) -> Usart { + Usart($addr as _) + } + } + impl Instance for peripherals::$type {} + }; +} + +impl_instance!(USART1, 0x40011000); +impl_instance!(USART2, 0x40004400); +impl_instance!(USART3, 0x40004800); +impl_instance!(USART6, 0x40011400);