wip usart

This commit is contained in:
Dario Nieuwenhuis 2021-04-14 15:34:58 +02:00
parent 170536b073
commit ef4d9d243e
4 changed files with 204 additions and 2 deletions

View File

@ -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<Executor> = 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()
}

View File

@ -1,5 +1,6 @@
use embassy_extras::peripherals; use embassy_extras::peripherals;
#[rustfmt::skip]
peripherals!( peripherals!(
// GPIO Port A // GPIO Port A
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15,
@ -10,6 +11,12 @@ peripherals!(
// todo more ports // todo more ports
// EXTI // EXTI
EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5, EXTI6, EXTI7, EXTI8, EXTI9, EXTI10, EXTI11, EXTI12, EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5, EXTI6, EXTI7, EXTI8, EXTI9, EXTI10, EXTI11, EXTI12, EXTI13, EXTI14, EXTI15,
EXTI13, EXTI14, EXTI15,
// USART
USART1,
USART2,
USART3,
USART6,
); );

View File

@ -32,5 +32,6 @@ pub mod exti;
pub mod gpio; pub mod gpio;
//pub mod rtc; //pub mod rtc;
//pub mod interrupt; //pub mod interrupt;
pub mod usart;
pub(crate) use stm32_metapac as pac; pub(crate) use stm32_metapac as pac;

View File

@ -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<Target = T>,
tx: impl PeripheralBorrow<Target = impl TxPin<T>>,
rx: impl PeripheralBorrow<Target = impl RxPin<T>>,
cts: impl PeripheralBorrow<Target = impl CtsPin<T>>,
rts: impl PeripheralBorrow<Target = impl RtsPin<T>>,
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);