nrf: remove OptionalPin

This commit is contained in:
Dario Nieuwenhuis 2022-02-12 01:04:01 +01:00
parent 5ae4e20f86
commit 6de02bb23e
14 changed files with 327 additions and 169 deletions

View File

@ -27,8 +27,7 @@ use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStor
use embassy_hal_common::ring_buffer::RingBuffer; use embassy_hal_common::ring_buffer::RingBuffer;
use embassy_hal_common::{low_power_wait_until, unborrow}; use embassy_hal_common::{low_power_wait_until, unborrow};
use crate::gpio::sealed::Pin as _; use crate::gpio::Pin as GpioPin;
use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin};
use crate::pac; use crate::pac;
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
use crate::timer::Instance as TimerInstance; use crate::timer::Instance as TimerInstance;
@ -89,8 +88,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
irq: impl Unborrow<Target = U::Interrupt> + 'd, irq: impl Unborrow<Target = U::Interrupt> + 'd,
rxd: impl Unborrow<Target = impl GpioPin> + 'd, rxd: impl Unborrow<Target = impl GpioPin> + 'd,
txd: impl Unborrow<Target = impl GpioPin> + 'd, txd: impl Unborrow<Target = impl GpioPin> + 'd,
cts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, cts: impl Unborrow<Target = impl GpioPin> + 'd,
rts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, rts: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config, config: Config,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
@ -108,28 +107,19 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
txd.conf().write(|w| w.dir().output().drive().h0h1()); txd.conf().write(|w| w.dir().output().drive().h0h1());
r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
if let Some(pin) = rts.pin_mut() { cts.conf().write(|w| w.input().connect().drive().h0h1());
pin.set_high();
pin.conf().write(|w| w.dir().output().drive().h0h1());
}
r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
if let Some(pin) = cts.pin_mut() { rts.set_high();
pin.conf().write(|w| w.input().connect().drive().h0h1()); rts.conf().write(|w| w.dir().output().drive().h0h1());
}
r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
r.baudrate.write(|w| w.baudrate().variant(config.baudrate)); r.baudrate.write(|w| w.baudrate().variant(config.baudrate));
r.config.write(|w| w.parity().variant(config.parity)); r.config.write(|w| w.parity().variant(config.parity));
// Configure // Configure
let hardware_flow_control = match (rts.pin().is_some(), cts.pin().is_some()) {
(false, false) => false,
(true, true) => true,
_ => panic!("RTS and CTS pins must be either both set or none set."),
};
r.config.write(|w| { r.config.write(|w| {
w.hwfc().bit(hardware_flow_control); w.hwfc().bit(true);
w.parity().variant(config.parity); w.parity().variant(config.parity);
w w
}); });

View File

@ -287,8 +287,6 @@ pub(crate) mod sealed {
unsafe { self.block().outclr.write(|w| w.bits(1u32 << self._pin())) } unsafe { self.block().outclr.write(|w| w.bits(1u32 << self._pin())) }
} }
} }
pub trait OptionalPin {}
} }
pub trait Pin: Unborrow<Target = Self> + sealed::Pin + Sized + 'static { pub trait Pin: Unborrow<Target = Self> + sealed::Pin + Sized + 'static {
@ -346,59 +344,17 @@ impl sealed::Pin for AnyPin {
// ==================== // ====================
pub trait OptionalPin: Unborrow<Target = Self> + sealed::OptionalPin + Sized { pub(crate) trait PselBits {
type Pin: Pin; fn psel_bits(&self) -> u32;
fn pin(&self) -> Option<&Self::Pin>; }
fn pin_mut(&mut self) -> Option<&mut Self::Pin>;
impl PselBits for Option<AnyPin> {
#[inline] #[inline]
fn psel_bits(&self) -> u32 { fn psel_bits(&self) -> u32 {
self.pin().map_or(1u32 << 31, Pin::psel_bits) self.as_ref().map_or(1u32 << 31, Pin::psel_bits)
}
/// Convert from concrete pin type PX_XX to type erased `Option<AnyPin>`.
#[inline]
fn degrade_optional(mut self) -> Option<AnyPin> {
self.pin_mut()
.map(|pin| unsafe { core::ptr::read(pin) }.degrade())
} }
} }
impl<T: Pin> sealed::OptionalPin for T {}
impl<T: Pin> OptionalPin for T {
type Pin = T;
#[inline]
fn pin(&self) -> Option<&T> {
Some(self)
}
#[inline]
fn pin_mut(&mut self) -> Option<&mut T> {
Some(self)
}
}
#[derive(Clone, Copy, Debug)]
pub struct NoPin;
unsafe_impl_unborrow!(NoPin);
impl sealed::OptionalPin for NoPin {}
impl OptionalPin for NoPin {
type Pin = AnyPin;
#[inline]
fn pin(&self) -> Option<&AnyPin> {
None
}
#[inline]
fn pin_mut(&mut self) -> Option<&mut AnyPin> {
None
}
}
// ====================
pub(crate) fn deconfigure_pin(psel_bits: u32) { pub(crate) fn deconfigure_pin(psel_bits: u32) {
if psel_bits & 0x8000_0000 != 0 { if psel_bits & 0x8000_0000 != 0 {
return; return;

View File

@ -6,7 +6,7 @@ use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{AnyPin, OptionalPin as GpioOptionalPin}; use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::Interrupt; use crate::interrupt::Interrupt;
use crate::pac; use crate::pac;
use crate::ppi::{Event, Task}; use crate::ppi::{Event, Task};
@ -48,47 +48,104 @@ pub enum Error {
const MAX_SEQUENCE_LEN: usize = 32767; const MAX_SEQUENCE_LEN: usize = 32767;
impl<'d, T: Instance> SequencePwm<'d, T> { impl<'d, T: Instance> SequencePwm<'d, T> {
/// Creates the interface to a `SequencePwm`. /// Create a new 1-channel PWM
///
/// Must be started by calling `start`
///
/// # Safety
///
/// The returned API is safe unless you use `mem::forget` (or similar safe
/// mechanisms) on stack allocated buffers which which have been passed to
/// [`new()`](SequencePwm::new).
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new( pub fn new_1ch(
_pwm: impl Unborrow<Target = T> + 'd, pwm: impl Unborrow<Target = T> + 'd,
ch0: impl Unborrow<Target = impl GpioOptionalPin> + 'd, ch0: impl Unborrow<Target = impl GpioPin> + 'd,
ch1: impl Unborrow<Target = impl GpioOptionalPin> + 'd, config: Config,
ch2: impl Unborrow<Target = impl GpioOptionalPin> + 'd, ) -> Result<Self, Error> {
ch3: impl Unborrow<Target = impl GpioOptionalPin> + 'd, unborrow!(ch0);
Self::new_inner(pwm, Some(ch0.degrade()), None, None, None, config)
}
/// Create a new 2-channel PWM
#[allow(unused_unsafe)]
pub fn new_2ch(
pwm: impl Unborrow<Target = T> + 'd,
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config,
) -> Result<Self, Error> {
unborrow!(ch0, ch1);
Self::new_inner(
pwm,
Some(ch0.degrade()),
Some(ch1.degrade()),
None,
None,
config,
)
}
/// Create a new 3-channel PWM
#[allow(unused_unsafe)]
pub fn new_3ch(
pwm: impl Unborrow<Target = T> + 'd,
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config,
) -> Result<Self, Error> {
unborrow!(ch0, ch1, ch2);
Self::new_inner(
pwm,
Some(ch0.degrade()),
Some(ch1.degrade()),
Some(ch2.degrade()),
None,
config,
)
}
/// Create a new 4-channel PWM
#[allow(unused_unsafe)]
pub fn new_4ch(
pwm: impl Unborrow<Target = T> + 'd,
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
ch3: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config, config: Config,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
unborrow!(ch0, ch1, ch2, ch3); unborrow!(ch0, ch1, ch2, ch3);
Self::new_inner(
pwm,
Some(ch0.degrade()),
Some(ch1.degrade()),
Some(ch2.degrade()),
Some(ch3.degrade()),
config,
)
}
fn new_inner(
_pwm: impl Unborrow<Target = T> + 'd,
ch0: Option<AnyPin>,
ch1: Option<AnyPin>,
ch2: Option<AnyPin>,
ch3: Option<AnyPin>,
config: Config,
) -> Result<Self, Error> {
let r = T::regs(); let r = T::regs();
if let Some(pin) = ch0.pin_mut() { if let Some(pin) = &ch0 {
pin.set_low(); pin.set_low();
pin.conf().write(|w| w.dir().output()); pin.conf().write(|w| w.dir().output());
} }
if let Some(pin) = ch1.pin_mut() { if let Some(pin) = &ch1 {
pin.set_low(); pin.set_low();
pin.conf().write(|w| w.dir().output()); pin.conf().write(|w| w.dir().output());
} }
if let Some(pin) = ch2.pin_mut() { if let Some(pin) = &ch2 {
pin.set_low(); pin.set_low();
pin.conf().write(|w| w.dir().output()); pin.conf().write(|w| w.dir().output());
} }
if let Some(pin) = ch3.pin_mut() { if let Some(pin) = &ch3 {
pin.set_low(); pin.set_low();
pin.conf().write(|w| w.dir().output()); pin.conf().write(|w| w.dir().output());
} }
// if NoPin provided writes disconnected (top bit 1) 0x80000000 else
// writes pin number ex 13 (0x0D) which is connected (top bit 0)
r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) }); r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) });
r.psel.out[1].write(|w| unsafe { w.bits(ch1.psel_bits()) }); r.psel.out[1].write(|w| unsafe { w.bits(ch1.psel_bits()) });
r.psel.out[2].write(|w| unsafe { w.bits(ch2.psel_bits()) }); r.psel.out[2].write(|w| unsafe { w.bits(ch2.psel_bits()) });
@ -121,10 +178,10 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
Ok(Self { Ok(Self {
phantom: PhantomData, phantom: PhantomData,
ch0: ch0.degrade_optional(), ch0,
ch1: ch1.degrade_optional(), ch1,
ch2: ch2.degrade_optional(), ch2,
ch3: ch3.degrade_optional(), ch3,
}) })
} }
@ -545,41 +602,86 @@ pub enum CounterMode {
} }
impl<'d, T: Instance> SimplePwm<'d, T> { impl<'d, T: Instance> SimplePwm<'d, T> {
/// Creates the interface to a `SimplePwm` /// Create a new 1-channel PWM
///
/// Enables the peripheral, defaults the freq to 1Mhz, max_duty 1000, duty
/// 0, up mode, and pins low. Must be started by calling `set_duty`
///
/// # Safety
///
/// The returned API is safe unless you use `mem::forget` (or similar safe
/// mechanisms) on stack allocated buffers which which have been passed to
/// [`new()`](SimplePwm::new).
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new( pub fn new_1ch(
_pwm: impl Unborrow<Target = T> + 'd, pwm: impl Unborrow<Target = T> + 'd,
ch0: impl Unborrow<Target = impl GpioOptionalPin> + 'd, ch0: impl Unborrow<Target = impl GpioPin> + 'd,
ch1: impl Unborrow<Target = impl GpioOptionalPin> + 'd, ) -> Self {
ch2: impl Unborrow<Target = impl GpioOptionalPin> + 'd, unborrow!(ch0);
ch3: impl Unborrow<Target = impl GpioOptionalPin> + 'd, Self::new_inner(pwm, Some(ch0.degrade()), None, None, None)
}
/// Create a new 2-channel PWM
#[allow(unused_unsafe)]
pub fn new_2ch(
pwm: impl Unborrow<Target = T> + 'd,
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
) -> Self {
unborrow!(ch0, ch1);
Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None)
}
/// Create a new 3-channel PWM
#[allow(unused_unsafe)]
pub fn new_3ch(
pwm: impl Unborrow<Target = T> + 'd,
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
) -> Self {
unborrow!(ch0, ch1, ch2);
Self::new_inner(
pwm,
Some(ch0.degrade()),
Some(ch1.degrade()),
Some(ch2.degrade()),
None,
)
}
/// Create a new 4-channel PWM
#[allow(unused_unsafe)]
pub fn new_4ch(
pwm: impl Unborrow<Target = T> + 'd,
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
ch3: impl Unborrow<Target = impl GpioPin> + 'd,
) -> Self { ) -> Self {
unborrow!(ch0, ch1, ch2, ch3); unborrow!(ch0, ch1, ch2, ch3);
Self::new_inner(
pwm,
Some(ch0.degrade()),
Some(ch1.degrade()),
Some(ch2.degrade()),
Some(ch3.degrade()),
)
}
fn new_inner(
_pwm: impl Unborrow<Target = T> + 'd,
ch0: Option<AnyPin>,
ch1: Option<AnyPin>,
ch2: Option<AnyPin>,
ch3: Option<AnyPin>,
) -> Self {
let r = T::regs(); let r = T::regs();
if let Some(pin) = ch0.pin_mut() { if let Some(pin) = &ch0 {
pin.set_low(); pin.set_low();
pin.conf().write(|w| w.dir().output()); pin.conf().write(|w| w.dir().output());
} }
if let Some(pin) = ch1.pin_mut() { if let Some(pin) = &ch1 {
pin.set_low(); pin.set_low();
pin.conf().write(|w| w.dir().output()); pin.conf().write(|w| w.dir().output());
} }
if let Some(pin) = ch2.pin_mut() { if let Some(pin) = &ch2 {
pin.set_low(); pin.set_low();
pin.conf().write(|w| w.dir().output()); pin.conf().write(|w| w.dir().output());
} }
if let Some(pin) = ch3.pin_mut() { if let Some(pin) = &ch3 {
pin.set_low(); pin.set_low();
pin.conf().write(|w| w.dir().output()); pin.conf().write(|w| w.dir().output());
} }
@ -593,10 +695,10 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
let pwm = Self { let pwm = Self {
phantom: PhantomData, phantom: PhantomData,
ch0: ch0.degrade_optional(), ch0,
ch1: ch1.degrade_optional(), ch1,
ch2: ch2.degrade_optional(), ch2,
ch3: ch3.degrade_optional(), ch3,
duty: [0; 4], duty: [0; 4],
}; };

View File

@ -8,9 +8,9 @@ use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::gpio;
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{OptionalPin, Pin as GpioPin}; use crate::gpio::{self, AnyPin};
use crate::gpio::{Pin as GpioPin, PselBits};
use crate::interrupt::Interrupt; use crate::interrupt::Interrupt;
use crate::util::{slice_ptr_parts, slice_ptr_parts_mut}; use crate::util::{slice_ptr_parts, slice_ptr_parts_mut};
use crate::{pac, util::slice_in_ram_or}; use crate::{pac, util::slice_in_ram_or};
@ -51,36 +51,77 @@ impl Default for Config {
impl<'d, T: Instance> Spim<'d, T> { impl<'d, T: Instance> Spim<'d, T> {
pub fn new( pub fn new(
_spim: impl Unborrow<Target = T> + 'd, spim: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
sck: impl Unborrow<Target = impl GpioPin> + 'd, sck: impl Unborrow<Target = impl GpioPin> + 'd,
miso: impl Unborrow<Target = impl OptionalPin> + 'd, miso: impl Unborrow<Target = impl GpioPin> + 'd,
mosi: impl Unborrow<Target = impl OptionalPin> + 'd, mosi: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(irq, sck, miso, mosi); unborrow!(sck, miso, mosi);
Self::new_inner(
spim,
irq,
sck.degrade(),
Some(miso.degrade()),
Some(mosi.degrade()),
config,
)
}
pub fn new_txonly(
spim: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
sck: impl Unborrow<Target = impl GpioPin> + 'd,
mosi: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config,
) -> Self {
unborrow!(sck, mosi);
Self::new_inner(spim, irq, sck.degrade(), None, Some(mosi.degrade()), config)
}
pub fn new_rxonly(
spim: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
sck: impl Unborrow<Target = impl GpioPin> + 'd,
miso: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config,
) -> Self {
unborrow!(sck, miso);
Self::new_inner(spim, irq, sck.degrade(), Some(miso.degrade()), None, config)
}
fn new_inner(
_spim: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
sck: AnyPin,
miso: Option<AnyPin>,
mosi: Option<AnyPin>,
config: Config,
) -> Self {
unborrow!(irq);
let r = T::regs(); let r = T::regs();
// Configure pins // Configure pins
sck.conf().write(|w| w.dir().output().drive().h0h1()); sck.conf().write(|w| w.dir().output().drive().h0h1());
if let Some(mosi) = mosi.pin_mut() { if let Some(mosi) = &mosi {
mosi.conf().write(|w| w.dir().output().drive().h0h1()); mosi.conf().write(|w| w.dir().output().drive().h0h1());
} }
if let Some(miso) = miso.pin_mut() { if let Some(miso) = &miso {
miso.conf().write(|w| w.input().connect().drive().h0h1()); miso.conf().write(|w| w.input().connect().drive().h0h1());
} }
match config.mode.polarity { match config.mode.polarity {
Polarity::IdleHigh => { Polarity::IdleHigh => {
sck.set_high(); sck.set_high();
if let Some(mosi) = mosi.pin_mut() { if let Some(mosi) = &mosi {
mosi.set_high(); mosi.set_high();
} }
} }
Polarity::IdleLow => { Polarity::IdleLow => {
sck.set_low(); sck.set_low();
if let Some(mosi) = mosi.pin_mut() { if let Some(mosi) = &mosi {
mosi.set_low(); mosi.set_low();
} }
} }

View File

@ -24,7 +24,7 @@ use futures::future::poll_fn;
use crate::chip::EASY_DMA_SIZE; use crate::chip::EASY_DMA_SIZE;
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{self, OptionalPin as GpioOptionalPin, Pin as GpioPin}; use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::Interrupt; use crate::interrupt::Interrupt;
use crate::pac; use crate::pac;
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
@ -80,18 +80,50 @@ pub struct UarteRx<'d, T: Instance> {
} }
impl<'d, T: Instance> Uarte<'d, T> { impl<'d, T: Instance> Uarte<'d, T> {
/// Creates the interface to a UARTE instance. /// Create a new UARTE without hardware flow control
/// Sets the baud rate, parity and assigns the pins to the UARTE peripheral.
pub fn new( pub fn new(
_uarte: impl Unborrow<Target = T> + 'd, uarte: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
rxd: impl Unborrow<Target = impl GpioPin> + 'd, rxd: impl Unborrow<Target = impl GpioPin> + 'd,
txd: impl Unborrow<Target = impl GpioPin> + 'd, txd: impl Unborrow<Target = impl GpioPin> + 'd,
cts: impl Unborrow<Target = impl GpioOptionalPin> + 'd,
rts: impl Unborrow<Target = impl GpioOptionalPin> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(irq, rxd, txd, cts, rts); unborrow!(rxd, txd);
Self::new_inner(uarte, irq, rxd.degrade(), txd.degrade(), None, None, config)
}
/// Create a new UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts(
uarte: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
txd: impl Unborrow<Target = impl GpioPin> + 'd,
cts: impl Unborrow<Target = impl GpioPin> + 'd,
rts: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config,
) -> Self {
unborrow!(rxd, txd, cts, rts);
Self::new_inner(
uarte,
irq,
rxd.degrade(),
txd.degrade(),
Some(cts.degrade()),
Some(rts.degrade()),
config,
)
}
fn new_inner(
_uarte: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
rxd: AnyPin,
txd: AnyPin,
cts: Option<AnyPin>,
rts: Option<AnyPin>,
config: Config,
) -> Self {
unborrow!(irq);
let r = T::regs(); let r = T::regs();
@ -102,19 +134,19 @@ impl<'d, T: Instance> Uarte<'d, T> {
txd.conf().write(|w| w.dir().output().drive().h0h1()); txd.conf().write(|w| w.dir().output().drive().h0h1());
r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
if let Some(pin) = rts.pin_mut() { if let Some(pin) = &cts {
pin.set_high(); pin.conf().write(|w| w.input().connect().drive().h0h1());
pin.conf().write(|w| w.dir().output().drive().h0h1());
} }
r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
if let Some(pin) = cts.pin_mut() { if let Some(pin) = &rts {
pin.conf().write(|w| w.input().connect().drive().h0h1()); pin.set_high();
pin.conf().write(|w| w.dir().output().drive().h0h1());
} }
r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
// Configure // Configure
let hardware_flow_control = match (rts.pin().is_some(), cts.pin().is_some()) { let hardware_flow_control = match (rts.is_some(), cts.is_some()) {
(false, false) => false, (false, false) => false,
(true, true) => true, (true, true) => true,
_ => panic!("RTS and CTS pins must be either both set or none set."), _ => panic!("RTS and CTS pins must be either both set or none set."),
@ -491,8 +523,7 @@ pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> {
} }
impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
/// Creates the interface to a UARTE instance. /// Create a new UARTE without hardware flow control
/// Sets the baud rate, parity and assigns the pins to the UARTE peripheral.
pub fn new( pub fn new(
uarte: impl Unborrow<Target = U> + 'd, uarte: impl Unborrow<Target = U> + 'd,
timer: impl Unborrow<Target = T> + 'd, timer: impl Unborrow<Target = T> + 'd,
@ -501,12 +532,65 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
irq: impl Unborrow<Target = U::Interrupt> + 'd, irq: impl Unborrow<Target = U::Interrupt> + 'd,
rxd: impl Unborrow<Target = impl GpioPin> + 'd, rxd: impl Unborrow<Target = impl GpioPin> + 'd,
txd: impl Unborrow<Target = impl GpioPin> + 'd, txd: impl Unborrow<Target = impl GpioPin> + 'd,
cts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, config: Config,
rts: impl Unborrow<Target = impl GpioOptionalPin> + 'd, ) -> Self {
unborrow!(rxd, txd);
Self::new_inner(
uarte,
timer,
ppi_ch1,
ppi_ch2,
irq,
rxd.degrade(),
txd.degrade(),
None,
None,
config,
)
}
/// Create a new UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts(
uarte: impl Unborrow<Target = U> + 'd,
timer: impl Unborrow<Target = T> + 'd,
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
irq: impl Unborrow<Target = U::Interrupt> + 'd,
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
txd: impl Unborrow<Target = impl GpioPin> + 'd,
cts: impl Unborrow<Target = impl GpioPin> + 'd,
rts: impl Unborrow<Target = impl GpioPin> + 'd,
config: Config,
) -> Self {
unborrow!(rxd, txd, cts, rts);
Self::new_inner(
uarte,
timer,
ppi_ch1,
ppi_ch2,
irq,
rxd.degrade(),
txd.degrade(),
Some(cts.degrade()),
Some(rts.degrade()),
config,
)
}
fn new_inner(
uarte: impl Unborrow<Target = U> + 'd,
timer: impl Unborrow<Target = T> + 'd,
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
irq: impl Unborrow<Target = U::Interrupt> + 'd,
rxd: AnyPin,
txd: AnyPin,
cts: Option<AnyPin>,
rts: Option<AnyPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
let baudrate = config.baudrate; let baudrate = config.baudrate;
let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config); let uarte = Uarte::new_inner(uarte, irq, rxd, txd, cts, rts, config);
let mut timer = Timer::new(timer); let mut timer = Timer::new(timer);
unborrow!(ppi_ch1, ppi_ch2); unborrow!(ppi_ch1, ppi_ch2);

View File

@ -85,7 +85,7 @@ static DUTY: [u16; 1024] = [
#[embassy::main] #[embassy::main]
async fn main(_spawner: Spawner, p: Peripherals) { async fn main(_spawner: Spawner, p: Peripherals) {
let mut pwm = SimplePwm::new(p.PWM0, p.P0_13, p.P0_14, p.P0_16, p.P0_15); let mut pwm = SimplePwm::new_4ch(p.PWM0, p.P0_13, p.P0_14, p.P0_16, p.P0_15);
pwm.set_prescaler(Prescaler::Div1); pwm.set_prescaler(Prescaler::Div1);
pwm.set_max_duty(32767); pwm.set_max_duty(32767);
info!("pwm initialized!"); info!("pwm initialized!");

View File

@ -7,7 +7,6 @@ mod example_common;
use defmt::*; use defmt::*;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy::time::{Duration, Timer}; use embassy::time::{Duration, Timer};
use embassy_nrf::gpio::NoPin;
use embassy_nrf::pwm::{ use embassy_nrf::pwm::{
Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, Sequencer, Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, Sequencer,
StartSequence, StartSequence,
@ -29,9 +28,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
seq_config.refresh = 624; seq_config.refresh = 624;
// thus our sequence takes 5 * 5000ms or 25 seconds // thus our sequence takes 5 * 5000ms or 25 seconds
let mut pwm = unwrap!(SequencePwm::new( let mut pwm = unwrap!(SequencePwm::new_1ch(p.PWM0, p.P0_13, config));
p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config,
));
let sequence_0 = Sequence::new(&seq_words_0, seq_config.clone()); let sequence_0 = Sequence::new(&seq_words_0, seq_config.clone());
let sequence_1 = Sequence::new(&seq_words_1, seq_config); let sequence_1 = Sequence::new(&seq_words_1, seq_config);

View File

@ -7,7 +7,6 @@ mod example_common;
use defmt::*; use defmt::*;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy::time::{Duration, Timer}; use embassy::time::{Duration, Timer};
use embassy_nrf::gpio::NoPin;
use embassy_nrf::pwm::{ use embassy_nrf::pwm::{
Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer, Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer,
}; };
@ -27,9 +26,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
seq_config.refresh = 624; seq_config.refresh = 624;
// thus our sequence takes 5 * 5000ms or 25 seconds // thus our sequence takes 5 * 5000ms or 25 seconds
let mut pwm = unwrap!(SequencePwm::new( let mut pwm = unwrap!(SequencePwm::new_1ch(p.PWM0, p.P0_13, config,));
p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config,
));
let sequencer = SingleSequencer::new(&mut pwm, &seq_words, seq_config); let sequencer = SingleSequencer::new(&mut pwm, &seq_words, seq_config);
unwrap!(sequencer.start(SingleSequenceMode::Times(1))); unwrap!(sequencer.start(SingleSequenceMode::Times(1)));

View File

@ -8,7 +8,7 @@ mod example_common;
use core::future::pending; use core::future::pending;
use defmt::*; use defmt::*;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy_nrf::gpio::{Input, NoPin, Pull}; use embassy_nrf::gpio::{Input, Pull};
use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
use embassy_nrf::ppi::Ppi; use embassy_nrf::ppi::Ppi;
use embassy_nrf::pwm::{ use embassy_nrf::pwm::{
@ -29,9 +29,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
let mut seq_config = SequenceConfig::default(); let mut seq_config = SequenceConfig::default();
seq_config.refresh = 30; seq_config.refresh = 30;
let mut pwm = unwrap!(SequencePwm::new( let mut pwm = unwrap!(SequencePwm::new_1ch(p.PWM0, p.P0_13, config));
p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config,
));
// pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work
// so its going to have to start running in order load the configuration // so its going to have to start running in order load the configuration

View File

@ -7,7 +7,6 @@ mod example_common;
use defmt::*; use defmt::*;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy::time::{Duration, Timer}; use embassy::time::{Duration, Timer};
use embassy_nrf::gpio::NoPin;
use embassy_nrf::pwm::{ use embassy_nrf::pwm::{
Config, Prescaler, SequenceConfig, SequenceLoad, SequencePwm, SingleSequenceMode, Config, Prescaler, SequenceConfig, SequenceLoad, SequencePwm, SingleSequenceMode,
SingleSequencer, SingleSequencer,
@ -35,9 +34,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
config.sequence_load = SequenceLoad::Common; config.sequence_load = SequenceLoad::Common;
config.prescaler = Prescaler::Div1; config.prescaler = Prescaler::Div1;
config.max_duty = 20; // 1.25us (1s / 16Mhz * 20) config.max_duty = 20; // 1.25us (1s / 16Mhz * 20)
let mut pwm = unwrap!(SequencePwm::new( let mut pwm = unwrap!(SequencePwm::new_1ch(p.PWM0, p.P1_05, config));
p.PWM0, p.P1_05, NoPin, NoPin, NoPin, config,
));
// Declare the bits of 24 bits in a buffer we'll be // Declare the bits of 24 bits in a buffer we'll be
// mutating later. // mutating later.

View File

@ -7,13 +7,12 @@ mod example_common;
use defmt::*; use defmt::*;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy::time::{Duration, Timer}; use embassy::time::{Duration, Timer};
use embassy_nrf::gpio::NoPin;
use embassy_nrf::pwm::{Prescaler, SimplePwm}; use embassy_nrf::pwm::{Prescaler, SimplePwm};
use embassy_nrf::Peripherals; use embassy_nrf::Peripherals;
#[embassy::main] #[embassy::main]
async fn main(_spawner: Spawner, p: Peripherals) { async fn main(_spawner: Spawner, p: Peripherals) {
let mut pwm = SimplePwm::new(p.PWM0, p.P0_05, NoPin, NoPin, NoPin); let mut pwm = SimplePwm::new_1ch(p.PWM0, p.P0_05);
// sg90 microervo requires 50hz or 20ms period // sg90 microervo requires 50hz or 20ms period
// set_period can only set down to 125khz so we cant use it directly // set_period can only set down to 125khz so we cant use it directly
// Div128 is 125khz or 0.000008s or 0.008ms, 20/0.008 is 2500 is top // Div128 is 125khz or 0.000008s or 0.008ms, 20/0.008 is 2500 is top

View File

@ -7,7 +7,6 @@ mod example_common;
use example_common::*; use example_common::*;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy_nrf::gpio::NoPin;
use embassy_nrf::{interrupt, uarte, Peripherals}; use embassy_nrf::{interrupt, uarte, Peripherals};
#[embassy::main] #[embassy::main]
@ -17,7 +16,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
config.baudrate = uarte::Baudrate::BAUD115200; config.baudrate = uarte::Baudrate::BAUD115200;
let irq = interrupt::take!(UARTE0_UART0); let irq = interrupt::take!(UARTE0_UART0);
let mut uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, NoPin, NoPin, config); let mut uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
info!("uarte initialized!"); info!("uarte initialized!");

View File

@ -7,7 +7,6 @@ mod example_common;
use example_common::*; use example_common::*;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy_nrf::gpio::NoPin;
use embassy_nrf::{interrupt, uarte, Peripherals}; use embassy_nrf::{interrupt, uarte, Peripherals};
#[embassy::main] #[embassy::main]
@ -18,7 +17,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
let irq = interrupt::take!(UARTE0_UART0); let irq = interrupt::take!(UARTE0_UART0);
let mut uart = uarte::UarteWithIdle::new( let mut uart = uarte::UarteWithIdle::new(
p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, NoPin, NoPin, config, p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, config,
); );
info!("uarte initialized!"); info!("uarte initialized!");

View File

@ -10,7 +10,6 @@ use embassy::blocking_mutex::kind::Noop;
use embassy::channel::mpsc::{self, Channel, Sender}; use embassy::channel::mpsc::{self, Channel, Sender};
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy::util::Forever; use embassy::util::Forever;
use embassy_nrf::gpio::NoPin;
use embassy_nrf::peripherals::UARTE0; use embassy_nrf::peripherals::UARTE0;
use embassy_nrf::uarte::UarteRx; use embassy_nrf::uarte::UarteRx;
use embassy_nrf::{interrupt, uarte, Peripherals}; use embassy_nrf::{interrupt, uarte, Peripherals};
@ -24,7 +23,7 @@ async fn main(spawner: Spawner, p: Peripherals) {
config.baudrate = uarte::Baudrate::BAUD115200; config.baudrate = uarte::Baudrate::BAUD115200;
let irq = interrupt::take!(UARTE0_UART0); let irq = interrupt::take!(UARTE0_UART0);
let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, NoPin, NoPin, config); let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
let (mut tx, rx) = uart.split(); let (mut tx, rx) = uart.split();
let c = CHANNEL.put(Channel::new()); let c = CHANNEL.put(Channel::new());