mspm0: blocking uart driver
This commit is contained in:
@@ -39,6 +39,7 @@ embedded-hal = { version = "1.0" }
|
||||
embedded-hal-async = { version = "1.0" }
|
||||
|
||||
defmt = { version = "0.3", optional = true }
|
||||
fixed = "1.29"
|
||||
log = { version = "0.4.14", optional = true }
|
||||
cortex-m-rt = ">=0.6.15,<0.8"
|
||||
cortex-m = "0.7.6"
|
||||
|
||||
@@ -381,7 +381,7 @@ fn generate_peripheral_instances() -> TokenStream {
|
||||
// Will be filled in when uart implementation is finished
|
||||
let _ = peri;
|
||||
let tokens = match peripheral.kind {
|
||||
// "uart" => Some(quote! { impl_uart_instance!(#peri); }),
|
||||
"uart" => Some(quote! { impl_uart_instance!(#peri); }),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@@ -412,10 +412,10 @@ fn generate_pin_trait_impls() -> TokenStream {
|
||||
let _ = pf;
|
||||
|
||||
let tokens = match key {
|
||||
// ("uart", "TX") => Some(quote! { impl_uart_tx_pin!(#peri, #pin_name, #pf); }),
|
||||
// ("uart", "RX") => Some(quote! { impl_uart_rx_pin!(#peri, #pin_name, #pf); }),
|
||||
// ("uart", "CTS") => Some(quote! { impl_uart_cts_pin!(#peri, #pin_name, #pf); }),
|
||||
// ("uart", "RTS") => Some(quote! { impl_uart_rts_pin!(#peri, #pin_name, #pf); }),
|
||||
("uart", "TX") => Some(quote! { impl_uart_tx_pin!(#peri, #pin_name, #pf); }),
|
||||
("uart", "RX") => Some(quote! { impl_uart_rx_pin!(#peri, #pin_name, #pf); }),
|
||||
("uart", "CTS") => Some(quote! { impl_uart_cts_pin!(#peri, #pin_name, #pf); }),
|
||||
("uart", "RTS") => Some(quote! { impl_uart_rts_pin!(#peri, #pin_name, #pf); }),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
||||
@@ -836,6 +836,31 @@ impl<'d> embedded_hal_async::digital::Wait for OutputOpenDrain<'d> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct PfType {
|
||||
pull: Pull,
|
||||
input: bool,
|
||||
invert: bool,
|
||||
}
|
||||
|
||||
impl PfType {
|
||||
pub const fn input(pull: Pull, invert: bool) -> Self {
|
||||
Self {
|
||||
pull,
|
||||
input: true,
|
||||
invert,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn output(pull: Pull, invert: bool) -> Self {
|
||||
Self {
|
||||
pull,
|
||||
input: false,
|
||||
invert,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The pin function to disconnect peripherals from the pin.
|
||||
///
|
||||
/// This is also the pin function used to connect to analog peripherals, such as an ADC.
|
||||
@@ -907,6 +932,40 @@ pub(crate) trait SealedPin {
|
||||
(self.pin_port() % 32) as usize
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_as_analog(&self) {
|
||||
let pincm = pac::IOMUX.pincm(self._pin_cm() as usize);
|
||||
|
||||
pincm.modify(|w| {
|
||||
w.set_pf(DISCONNECT_PF);
|
||||
w.set_pipu(false);
|
||||
w.set_pipd(false);
|
||||
});
|
||||
}
|
||||
|
||||
fn update_pf(&self, ty: PfType) {
|
||||
let pincm = pac::IOMUX.pincm(self._pin_cm() as usize);
|
||||
let pf = pincm.read().pf();
|
||||
|
||||
set_pf(self._pin_cm() as usize, pf, ty);
|
||||
}
|
||||
|
||||
fn set_as_pf(&self, pf: u8, ty: PfType) {
|
||||
set_pf(self._pin_cm() as usize, pf, ty)
|
||||
}
|
||||
|
||||
/// Set the pin as "disconnected", ie doing nothing and consuming the lowest
|
||||
/// amount of power possible.
|
||||
///
|
||||
/// This is currently the same as [`Self::set_as_analog()`] but is semantically different
|
||||
/// really. Drivers should `set_as_disconnected()` pins when dropped.
|
||||
///
|
||||
/// Note that this also disables the internal weak pull-up and pull-down resistors.
|
||||
#[inline]
|
||||
fn set_as_disconnected(&self) {
|
||||
self.set_as_analog();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn block(&self) -> gpio::Gpio {
|
||||
match self.pin_port() / 32 {
|
||||
@@ -920,6 +979,18 @@ pub(crate) trait SealedPin {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn set_pf(pincm: usize, pf: u8, ty: PfType) {
|
||||
pac::IOMUX.pincm(pincm).modify(|w| {
|
||||
w.set_pf(pf);
|
||||
w.set_pc(true);
|
||||
w.set_pipu(ty.pull == Pull::Up);
|
||||
w.set_pipd(ty.pull == Pull::Down);
|
||||
w.set_inena(ty.input);
|
||||
w.set_inv(ty.invert);
|
||||
});
|
||||
}
|
||||
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
struct InputFuture<'d> {
|
||||
pin: Peri<'d, AnyPin>,
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
// This mod MUST go first, so that the others see its macros.
|
||||
pub(crate) mod fmt;
|
||||
|
||||
// This must be declared early as well for
|
||||
mod macros;
|
||||
|
||||
pub mod gpio;
|
||||
pub mod timer;
|
||||
pub mod uart;
|
||||
|
||||
/// Operating modes for peripherals.
|
||||
pub mod mode {
|
||||
|
||||
9
embassy-mspm0/src/macros.rs
Normal file
9
embassy-mspm0/src/macros.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
#![macro_use]
|
||||
|
||||
macro_rules! new_pin {
|
||||
($name: ident, $pf_type: expr) => {{
|
||||
let pin = $name;
|
||||
pin.set_as_pf(pin.pf_num(), $pf_type);
|
||||
Some(pin.into())
|
||||
}};
|
||||
}
|
||||
1085
embassy-mspm0/src/uart.rs
Normal file
1085
embassy-mspm0/src/uart.rs
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user