Skip to content

Commit

Permalink
Merge pull request #266 from braun-embedded/usart-settings
Browse files Browse the repository at this point in the history
Add support for changing USART settings
  • Loading branch information
hannobraun authored Aug 3, 2020
2 parents e11be33 + d6e5c87 commit 275107a
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 63 deletions.
10 changes: 7 additions & 3 deletions examples/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ fn main() -> ! {
let (u0_rxd, _) = swm.movable_functions.u0_rxd.assign(rx_pin, &mut handle);
let (u0_txd, _) = swm.movable_functions.u0_txd.assign(tx_pin, &mut handle);

let mut serial =
p.USART0
.enable(&clock_config, &mut syscon.handle, u0_rxd, u0_txd);
let mut serial = p.USART0.enable(
&clock_config,
&mut syscon.handle,
u0_rxd,
u0_txd,
usart::Settings::default(),
);

let adc_clock = AdcClock::new_default();
let mut adc = p.ADC.enable(&adc_clock, &mut syscon.handle);
Expand Down
10 changes: 7 additions & 3 deletions examples/i2c_eeprom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,13 @@ fn main() -> ! {
let (u0_rxd, _) = swm.movable_functions.u0_rxd.assign(rx_pin, &mut handle);
let (u0_txd, _) = swm.movable_functions.u0_txd.assign(tx_pin, &mut handle);

let mut serial =
p.USART0
.enable(&clock_config, &mut syscon.handle, u0_rxd, u0_txd);
let mut serial = p.USART0.enable(
&clock_config,
&mut syscon.handle,
u0_rxd,
u0_txd,
usart::Settings::default(),
);

serial
.bwrite_all(b"Initializing I2C...\n")
Expand Down
1 change: 1 addition & 0 deletions examples/i2c_vl53l0x.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ fn main() -> ! {
&mut syscon.handle,
u0_rxd,
u0_txd,
usart::Settings::default(),
);

serial
Expand Down
10 changes: 7 additions & 3 deletions examples/pmu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ fn main() -> ! {
.u0_txd
.assign(p.pins.pio0_4.into_swm_pin(), &mut swm.handle);

let mut serial =
p.USART0
.enable(&clock_config, &mut syscon.handle, u0_rxd, u0_txd);
let mut serial = p.USART0.enable(
&clock_config,
&mut syscon.handle,
u0_rxd,
u0_txd,
usart::Settings::default(),
);

let _ = pmu.low_power_clock.enable(&mut pmu.handle);

Expand Down
10 changes: 7 additions & 3 deletions examples/usart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,13 @@ fn main() -> ! {
let (u0_txd, _) = swm.movable_functions.u0_txd.assign(tx_pin, &mut handle);

// Enable USART0
let mut serial =
p.USART0
.enable(&clock_config, &mut syscon.handle, u0_rxd, u0_txd);
let mut serial = p.USART0.enable(
&clock_config,
&mut syscon.handle,
u0_rxd,
u0_txd,
usart::Settings::default(),
);

// Send a string via USART0, blocking until it has been sent
serial
Expand Down
10 changes: 7 additions & 3 deletions examples/usart_dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ fn main() -> ! {
.u0_txd
.assign(p.pins.pio0_25.into_swm_pin(), &mut swm_handle);

let mut serial =
p.USART0
.enable(&clock_config, &mut syscon.handle, u0_rxd, u0_txd);
let mut serial = p.USART0.enable(
&clock_config,
&mut syscon.handle,
u0_rxd,
u0_txd,
usart::Settings::default(),
);

let mut rx_channel = dma.channels.channel0;
let mut tx_channel = dma.channels.channel1;
Expand Down
5 changes: 5 additions & 0 deletions src/usart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
//! &mut syscon.handle,
//! u0_rxd,
//! u0_txd,
//! usart::Settings::default(),
//! );
//!
//! // Use a blocking method to write a string
Expand All @@ -71,12 +72,16 @@ mod clock;
mod instances;
mod peripheral;
mod rx;
mod settings;
mod tx;

pub mod state;

pub use self::{
clock::{Clock, ClockSource},
instances::Instance,
peripheral::USART,
rx::{Error, Rx},
settings::Settings,
tx::Tx,
};
50 changes: 25 additions & 25 deletions src/usart/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use embedded_hal::{
use void::Void;

use crate::{
init_state,
init_state::Disabled,
pac::NVIC,
pins,
swm::{self, FunctionTrait},
Expand All @@ -18,6 +18,8 @@ use super::{
clock::{Clock, ClockSource},
instances::Instance,
rx::{Error, Rx},
settings::Settings,
state::{Enabled, Word},
tx::Tx,
};

Expand All @@ -43,18 +45,17 @@ use super::{
/// [`embedded_hal::serial::Read`]: #impl-Read%3Cu8%3E
/// [`embedded_hal::serial::Write`]: #impl-Write%3Cu8%3E
/// [`embedded_hal::blocking::serial::Write`]: #impl-Write
pub struct USART<I, State = init_state::Enabled> {
pub struct USART<I, State> {
/// The USART Receiver
pub rx: Rx<I, State>,

/// The USART Transmitter
pub tx: Tx<I, State>,

usart: I,
_state: State,
}

impl<I> USART<I, init_state::Disabled>
impl<I> USART<I, Disabled>
where
I: Instance,
{
Expand All @@ -64,7 +65,6 @@ where
tx: Tx::new(),

usart,
_state: init_state::Disabled,
}
}

Expand All @@ -91,19 +91,21 @@ where
/// [`Enabled`]: ../init_state/struct.Enabled.html
/// [`BaudRate`]: struct.BaudRate.html
/// [module documentation]: index.html
pub fn enable<RxPin, TxPin, CLOCK>(
pub fn enable<RxPin, TxPin, CLOCK, W>(
self,
clock: &Clock<CLOCK>,
syscon: &mut syscon::Handle,
_: swm::Function<I::Rx, swm::state::Assigned<RxPin>>,
_: swm::Function<I::Tx, swm::state::Assigned<TxPin>>,
) -> USART<I, init_state::Enabled>
settings: Settings<W>,
) -> USART<I, Enabled<W>>
where
RxPin: pins::Trait,
TxPin: pins::Trait,
I::Rx: FunctionTrait<RxPin>,
I::Tx: FunctionTrait<TxPin>,
CLOCK: ClockSource,
W: Word,
{
syscon.enable_clock(&self.usart);

Expand All @@ -123,14 +125,12 @@ where
self.usart.cfg.modify(|_, w| {
w.enable().enabled();
w.datalen().bit_8();
w.paritysel().no_parity();
w.stoplen().bit_1();
w.ctsen().disabled();
w.syncen().asynchronous_mode();
w.loop_().normal();
w.autoaddr().disabled();
w.rxpol().standard();
w.txpol().standard()
settings.apply(w);
w
});

self.usart.ctl.modify(|_, w| {
Expand All @@ -144,14 +144,14 @@ where
rx: Rx::new(), // can't use `self.rx`, due to state
tx: Tx::new(), // can't use `self.tx`, due to state
usart: self.usart,
_state: init_state::Enabled(()),
}
}
}

impl<I> USART<I, init_state::Enabled>
impl<I, W> USART<I, Enabled<W>>
where
I: Instance,
W: Word,
{
/// Disable the USART
///
Expand All @@ -164,17 +164,13 @@ where
///
/// [`Enabled`]: ../init_state/struct.Enabled.html
/// [`Disabled`]: ../init_state/struct.Disabled.html
pub fn disable(
self,
syscon: &mut syscon::Handle,
) -> USART<I, init_state::Disabled> {
pub fn disable(self, syscon: &mut syscon::Handle) -> USART<I, Disabled> {
syscon.disable_clock(&self.usart);

USART {
rx: Rx::new(), // can't use `self.rx`, due to state
tx: Tx::new(), // can't use `self.tx`, due to state
usart: self.usart,
_state: init_state::Disabled,
}
}

Expand Down Expand Up @@ -262,26 +258,28 @@ where
}
}

impl<I> Read<u8> for USART<I, init_state::Enabled>
impl<I, W> Read<W> for USART<I, Enabled<W>>
where
I: Instance,
W: Word,
{
type Error = Error;

/// Reads a single word from the serial interface
fn read(&mut self) -> nb::Result<u8, Self::Error> {
fn read(&mut self) -> nb::Result<W, Self::Error> {
self.rx.read()
}
}

impl<I> Write<u8> for USART<I, init_state::Enabled>
impl<I, W> Write<W> for USART<I, Enabled<W>>
where
I: Instance,
W: Word,
{
type Error = Void;

/// Writes a single word to the serial interface
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
fn write(&mut self, word: W) -> nb::Result<(), Self::Error> {
self.tx.write(word)
}

Expand All @@ -291,12 +289,14 @@ where
}
}

impl<I> BlockingWriteDefault<u8> for USART<I, init_state::Enabled> where
I: Instance
impl<I, W> BlockingWriteDefault<W> for USART<I, Enabled<W>>
where
I: Instance,
W: Word,
{
}

impl<I> fmt::Write for USART<I, init_state::Enabled>
impl<I> fmt::Write for USART<I, Enabled<u8>>
where
Self: BlockingWriteDefault<u8>,
I: Instance,
Expand Down
31 changes: 19 additions & 12 deletions src/usart/rx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ use void::Void;
use crate::{
dma::{self, transfer::state::Ready},
embedded_hal::serial::Read,
init_state::Enabled,
init_state,
pac::dma0::channel::xfercfg::SRCINC_A,
};

use super::instances::Instance;
use super::{
instances::Instance,
state::{Enabled, Word},
};

/// USART receiver
///
Expand All @@ -18,7 +21,7 @@ use super::instances::Instance;
///
///
/// [`embedded_hal::serial::Read`]: #impl-Read%3Cu8%3E
pub struct Rx<I, State = Enabled> {
pub struct Rx<I, State> {
_instance: PhantomData<I>,
_state: PhantomData<State>,
}
Expand All @@ -35,9 +38,10 @@ where
}
}

impl<I> Rx<I, Enabled>
impl<I, W> Rx<I, Enabled<W>>
where
I: Instance,
W: Word,
{
/// Enable the RXRDY interrupt
///
Expand All @@ -60,7 +64,12 @@ where

usart.intenclr.write(|w| w.rxrdyclr().set_bit());
}
}

impl<I> Rx<I, Enabled<u8>>
where
I: Instance,
{
/// Reads until the provided buffer is full, using DMA
///
/// # Panics
Expand All @@ -69,19 +78,20 @@ where
pub fn read_all(
self,
buffer: &'static mut [u8],
channel: dma::Channel<I::RxChannel, Enabled>,
channel: dma::Channel<I::RxChannel, init_state::Enabled>,
) -> dma::Transfer<Ready, I::RxChannel, Self, &'static mut [u8]> {
dma::Transfer::new(channel, self, buffer)
}
}

impl<I> Read<u8> for Rx<I, Enabled>
impl<I, W> Read<W> for Rx<I, Enabled<W>>
where
I: Instance,
W: Word,
{
type Error = Error;

fn read(&mut self) -> nb::Result<u8, Self::Error> {
fn read(&mut self) -> nb::Result<W, Self::Error> {
// Sound, as we're only reading from `stat`, and `rxdatastat` is
// exclusively accessed by this method.
let usart = unsafe { &*I::REGISTERS };
Expand All @@ -106,10 +116,7 @@ where
} else if rx_dat_stat.rxnoise().bit_is_set() {
Err(nb::Error::Other(Error::Noise))
} else {
// `bits` returns `u16`, but at most 9 bits are used. We've
// configured UART to use only 8 bits, so we can safely cast to
// `u8`.
Ok(rx_dat_stat.rxdat().bits() as u8)
Ok(Word::from_u16(rx_dat_stat.rxdat().bits()))
}
} else {
Err(nb::Error::WouldBlock)
Expand All @@ -119,7 +126,7 @@ where

impl<I, State> crate::private::Sealed for Rx<I, State> {}

impl<I> dma::Source for Rx<I, Enabled>
impl<I> dma::Source for Rx<I, Enabled<u8>>
where
I: Instance,
{
Expand Down
Loading

0 comments on commit 275107a

Please sign in to comment.