Skip to content

Commit

Permalink
Force swm to be enabled on lpc845, fix lpc-rs#183
Browse files Browse the repository at this point in the history
  • Loading branch information
david-sawatzke committed Jan 10, 2020
1 parent ae3f278 commit 9bd8339
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 29 deletions.
18 changes: 5 additions & 13 deletions examples/usart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,11 @@ use lpc8xx_hal::pac::syscon::frg::frgclksel::SEL_A;
fn main() -> ! {
let p = Peripherals::take().unwrap();

let mut swm = p.SWM.split();
let swm = p.SWM.split();
let mut syscon = p.SYSCON.split();

// TODO
//
// For some reason, the clock for swm need to be enabled, even though
// it should be enabled from the start
swm.handle = swm
.handle
.disable(&mut syscon.handle)
.enable(&mut syscon.handle);
#[cfg(feature = "845")]
let mut handle = swm.handle.enable(&mut syscon.handle); // SWM isn't initialized by default on LPC845.

#[cfg(feature = "82x")]
// Set baud rate to 115200 baud
Expand Down Expand Up @@ -99,10 +93,8 @@ fn main() -> ! {
// LPC845-BRK development boards, they're connected to the integrated USB to
// Serial converter. So by using the pins, we can use them to communicate
// with a host PC, without additional hardware.
let (u0_rxd, _) =
swm.movable_functions.u0_rxd.assign(rx_pin, &mut swm.handle);
let (u0_txd, _) =
swm.movable_functions.u0_txd.assign(tx_pin, &mut swm.handle);
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);

// Enable USART0
let serial =
Expand Down
24 changes: 22 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,24 @@ pub struct Peripherals {
pub PMU: PMU,

/// Switch matrix
pub SWM: SWM,
///
/// By default, the switch matrix is enabled on the LPC82x and disabled on
/// the LPC845.
///
/// The reference manual for the LPC845 suggests otherwise, but it seems to
/// be wrong.
#[cfg(feature = "82x")]
pub SWM: SWM<init_state::Enabled>,

/// Switch matrix
///
/// By default, the switch matrix is enabled on the LPC82x and disabled on
/// the LPC845.
///
/// The reference manual for the LPC845 suggests otherwise, but it seems to
/// be wrong.
#[cfg(feature = "845")]
pub SWM: SWM<init_state::Disabled>,

/// System configuration
pub SYSCON: SYSCON,
Expand Down Expand Up @@ -512,7 +529,10 @@ impl Peripherals {
#[cfg(feature = "82x")]
I2C0: I2C::new(p.I2C0),
PMU: PMU::new(p.PMU),
SWM: SWM::new(p.SWM0),
#[cfg(feature = "82x")]
SWM: unsafe { SWM::new_enabled(p.SWM0) },
#[cfg(feature = "845")]
SWM: unsafe { SWM::new(p.SWM0) },
SYSCON: SYSCON::new(p.SYSCON),
USART0: USART::new(p.USART0),
USART1: USART::new(p.USART1),
Expand Down
64 changes: 50 additions & 14 deletions src/swm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,59 @@ use self::pin_state::PinState;
/// [`swm::Parts`]: struct.Parts.html
/// [`Peripherals`]: ../struct.Peripherals.html
/// [module documentation]: index.html
pub struct SWM {
pub struct SWM<State = init_state::Enabled> {
swm: pac::SWM0,
state: State,
}

impl SWM {
pub(crate) fn new(swm: pac::SWM0) -> Self {
SWM { swm }
impl SWM<init_state::Disabled> {
/// Create a disabled SWM peripheral
///
/// This method creates an `SWM` instance that it assumes is in the
/// [`Disabled`] state. As it's only possible to enable a [`Disabled`] `SWM`
/// instance, it's also safe to pass an already [`Enabled`] instance.
///
/// # Safety
///
/// This method creates an `SWM` instance that it assumes is in the default
/// state. It's up to the caller to verify this assumption.
///
/// [`Disabled`]: ../init_state/struct.Enabled.html
/// [`Enabled`]: ../init_state/struct.Enabled.html
pub unsafe fn new(swm: pac::SWM0) -> Self {
SWM {
swm,
state: init_state::Disabled,
}
}
}

impl SWM<init_state::Enabled> {
/// Create a enabled SWM peripheral
///
/// # Safety
///
/// This method creates an `SWM` instance that it assumes is already in the
/// default [`Enabled`] state. It's up to the caller to verify this assumption.
///
/// [`Enabled`]: ../init_state/struct.Enabled.html
pub unsafe fn new_enabled(swm: pac::SWM0) -> Self {
SWM {
swm,
state: init_state::Enabled(()),
}
}
}

impl<STATE> SWM<STATE> {
/// Splits the SWM API into its component parts
///
/// This is the regular way to access the SWM API. It exists as an explicit
/// step, as it's no longer possible to gain access to the raw peripheral
/// using [`SWM::free`] after you've called this method.
pub fn split(self) -> Parts {
pub fn split(self) -> Parts<STATE> {
Parts {
handle: Handle::new(self.swm),
handle: Handle::new(self.swm, self.state),
pins: Pins::new(),
movable_functions: MovableFunctions::new(),
fixed_functions: FixedFunctions::new(),
Expand Down Expand Up @@ -76,9 +112,9 @@ impl SWM {
/// [module documentation] for more information.
///
/// [module documentation]: index.html
pub struct Parts {
pub struct Parts<STATE> {
/// Handle to the switch matrix
pub handle: Handle<init_state::Enabled>,
pub handle: Handle<STATE>,

/// Pins that can be used for GPIO or other functions
pub pins: Pins,
Expand All @@ -105,12 +141,9 @@ pub struct Handle<State = init_state::Enabled> {
_state: State,
}

impl Handle<init_state::Enabled> {
pub(crate) fn new(swm: pac::SWM0) -> Self {
Handle {
swm,
_state: init_state::Enabled(()),
}
impl<STATE> Handle<STATE> {
pub(crate) fn new(swm: pac::SWM0, state: STATE) -> Self {
Handle { swm, _state: state }
}
}

Expand Down Expand Up @@ -142,6 +175,9 @@ impl Handle<init_state::Disabled> {
impl Handle<init_state::Enabled> {
/// Disable the switch matrix
///
/// The switch matrix retains it's configuration while disabled, but
/// doesn't allow modifications
///
/// This method is only available, if `SWM` is in the [`Enabled`] state.
/// Code that attempts to call this method when the peripheral is already
/// disabled will not compile.
Expand Down

0 comments on commit 9bd8339

Please sign in to comment.