Skip to content

Commit

Permalink
Fix UART pad definitions (#607)
Browse files Browse the repository at this point in the history
* Fix sercom::uart valid pad definitions

The pad definitions in sercom::uart didn't take into
account that the XCK pad would be unavailable for use,
even if asynchronous mode isn't unavailable. Especially,
implement the same `impl_rxpotxpo` macro system for thumbv7em
targets as the one already in use for thumbv6m targets. Additionnally,
reject pad combinations where XCK would conflict on thumbv6m targets.

* Bump HAL to 0.15.1

* Bump HAL to 0.15.1
  • Loading branch information
jbeaurivage authored May 8, 2022
1 parent 49f8724 commit e241dc0
Show file tree
Hide file tree
Showing 16 changed files with 257 additions and 162 deletions.
3 changes: 3 additions & 0 deletions boards/feather_m0/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Unreleased

# v0.12.1

- Update to `atsamd-hal` version `0.15.1`
- Update .cargo/config

# v0.12.0
Expand Down
4 changes: 2 additions & 2 deletions boards/feather_m0/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "feather_m0"
version = "0.12.0"
version = "0.12.1"
authors = ["Ben Bergman <[email protected]>"]
description = "Board Support crate for the Adafruit Feather M0"
keywords = ["no-std", "arm", "cortex-m", "embedded-hal"]
Expand All @@ -21,7 +21,7 @@ optional = true

[dependencies.atsamd-hal]
path = "../../hal"
version = "0.15"
version = "0.15.1"
default-features = false

[dependencies.usb-device]
Expand Down
3 changes: 3 additions & 0 deletions boards/feather_m4/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Unreleased

# v0.10.1

- Update to `atsamd-hal` version `0.15.1`
- Make use of `bsp_peripherals` macro

# v0.10.0
Expand Down
4 changes: 2 additions & 2 deletions boards/feather_m4/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "feather_m4"
version = "0.10.0"
version = "0.10.1"
edition = "2021"
authors = ["Theodore DeRego <[email protected]>"]
description = "Board Support crate for the Adafruit Feather M4"
Expand All @@ -21,7 +21,7 @@ optional = true

[dependencies.atsamd-hal]
path = "../../hal"
version = "0.15"
version = "0.15.1"
default-features = false

[dependencies.usb-device]
Expand Down
6 changes: 6 additions & 0 deletions boards/metro_m0/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Unreleased

# v0.12.1

- Update to `atsamd-hal` version `0.15.1`

# v0.12.0

- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs
- Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API
- Add an `i2c` example
Expand Down
4 changes: 2 additions & 2 deletions boards/metro_m0/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "metro_m0"
version = "0.12.0"
version = "0.12.1"
authors = ["Wez Furlong <[email protected]>"]
description = "Board Support crate for the Adafruit Metro M0"
keywords = ["no-std", "arm", "cortex-m", "embedded-hal"]
Expand All @@ -20,7 +20,7 @@ optional = true

[dependencies.atsamd-hal]
path = "../../hal"
version = "0.15"
version = "0.15.1"
default-features = false

[dependencies.usb-device]
Expand Down
3 changes: 3 additions & 0 deletions boards/metro_m4/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Unreleased

# v0.11.1

- Update to `atsamd-hal` version `0.15.1`
- Make use of `bsp_peripherals` macro

# v0.11.0
Expand Down
4 changes: 2 additions & 2 deletions boards/metro_m4/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "metro_m4"
version = "0.11.0"
version = "0.11.1"
authors = ["Paul Sajna <[email protected]>", "Wez Furlong <[email protected]>"]
description = "Board Support crate for the Adafruit Metro M4"
keywords = ["no-std", "arm", "cortex-m", "embedded-hal"]
Expand All @@ -20,7 +20,7 @@ optional = true

[dependencies.atsamd-hal]
path = "../../hal"
version = "0.15"
version = "0.15.1"
default-features = false

[dependencies.usb-device]
Expand Down
4 changes: 4 additions & 0 deletions boards/samd11_bare/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Unreleased

# v0.8.1
- Update to `atsamd-hal` version `0.15.1`

# v0.8.0
- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs
- Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API
- Add an `i2c` example
Expand Down
4 changes: 2 additions & 2 deletions boards/samd11_bare/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "samd11_bare"
version = "0.8.0"
version = "0.8.1"
authors = ["Jesse Braham <[email protected]>"]
description = "Support crate for the ATSAMD11C"
keywords = ["no-std", "arm", "cortex-m", "embedded-hal"]
Expand All @@ -19,7 +19,7 @@ optional = true

[dependencies.atsamd-hal]
path = "../../hal"
version = "0.15"
version = "0.15.1"
default-features = false

[dev-dependencies]
Expand Down
6 changes: 6 additions & 0 deletions boards/wio_terminal/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Unreleased

# v0.6.1

- Update to `atsamd-hal` version `0.15.1`

# v0.6.0

- Fix removed deprecated modules from HAL
- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs
- Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API
Expand Down
4 changes: 2 additions & 2 deletions boards/wio_terminal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wio_terminal"
version = "0.6.0"
version = "0.6.1"
authors = [
"Jesse Braham <[email protected]>",
"Tom <[email protected]>"
Expand Down Expand Up @@ -45,7 +45,7 @@ seeed-erpc = { version = "0.1.1", optional = true }

[dependencies.atsamd-hal]
path = "../../hal"
version = "0.15"
version = "0.15.1"
default-features = false

[dev-dependencies]
Expand Down
3 changes: 3 additions & 0 deletions hal/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Unreleased Changes

# v0.15.1

- Fix `sercom::uart` pad definitions to reject pads conflicting with XCK.
- Add support for L-Variant of the SAMD21D

# v0.15.0
Expand Down
2 changes: 1 addition & 1 deletion hal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "atsamd-hal"
version = "0.15.0"
version = "0.15.1"
authors = [
"Wez Furlong <[email protected]>",
"Paul Sajna <[email protected]>",
Expand Down
163 changes: 83 additions & 80 deletions hal/src/sercom/uart/pads_thumbv6m.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! UART pad definitions for thumbv6m targets
use core::marker::PhantomData;

use super::{AnyConfig, Capability, CharSize, Config, Duplex, Rx, Tx};
use crate::sercom::*;
use crate::typelevel::{NoneT, Sealed};
use crate::{
sercom::*,
typelevel::{NoneT, Sealed},
};
use core::marker::PhantomData;

#[cfg(not(feature = "samd11"))]
use crate::gpio::AnyPin;
Expand Down Expand Up @@ -55,58 +56,60 @@ where
//=============================================================================

/// Filter [`PadNum`] permutations and implement [`RxpoTxpo`]
#[rustfmt::skip]
macro_rules! impl_rxpotxpo {
// This is the entry pattern. Start by checking RTS and CTS.
($RX:ident, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@check_rts_cts, $RX, $TX, $RTS, $CTS); };

// Check whether RTS and CTS form a valid pair.
// They both must be the correct pad or absent.
(@check_rts_cts, $RX:ident, $TX:ident, NoneT, NoneT) => { impl_rxpotxpo!(@rxpo, $RX, $TX, NoneT, NoneT); };
(@check_rts_cts, $RX:ident, $TX:ident, Pad2, NoneT) => { impl_rxpotxpo!(@rxpo, $RX, $TX, Pad2, NoneT); };
(@check_rts_cts, $RX:ident, $TX:ident, NoneT, Pad3) => { impl_rxpotxpo!(@rxpo, $RX, $TX, NoneT, Pad3); };
(@check_rts_cts, $RX:ident, $TX:ident, Pad2, Pad3) => { impl_rxpotxpo!(@rxpo, $RX, $TX, Pad2, Pad3); };

// If RTS and CTS are not valid, fall through to this pattern.
(@check_rts_cts, $RX:ident, $TX:ident, $RTS:ident, $CTS:ident) => { };

// Assign RXPO based on RX.
// Our options are exhaustive, so no fall through pattern is needed.
(@rxpo, NoneT, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, NoneT, $TX, $RTS, $CTS, 0); };
(@rxpo, Pad0, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, Pad0, $TX, $RTS, $CTS, 0); };
(@rxpo, Pad1, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, Pad1, $TX, $RTS, $CTS, 1); };
(@rxpo, Pad2, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, Pad2, $TX, $RTS, $CTS, 2); };
(@rxpo, Pad3, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, Pad3, $TX, $RTS, $CTS, 3); };

// Assign TXPO based on RX and RTS
(@txpo, $RX:ident, NoneT, NoneT, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, NoneT, NoneT, $CTS, $RXPO, 0); };
(@txpo, $RX:ident, NoneT, Pad2, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, NoneT, Pad2, $CTS, $RXPO, 2); };
(@txpo, $RX:ident, Pad0, NoneT, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, Pad0, NoneT, $CTS, $RXPO, 0); };
(@txpo, $RX:ident, Pad2, NoneT, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, Pad2, NoneT, $CTS, $RXPO, 1); };
(@txpo, $RX:ident, Pad0, Pad2, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, Pad0, Pad2, $CTS, $RXPO, 2); };

// If TX is not valid, fall through to this pattern.
(@txpo, $RX:ident, $TX:ident, $RTS:ident, $CTS:ident, $RXPO:literal) => { };

// Filter any remaining permutations that conflict.
(@filter, NoneT, NoneT, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => { };
(@filter, Pad0, Pad0, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => { };
(@filter, Pad2, Pad2, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => { };
(@filter, Pad2, $TX:ident, Pad2, $CTS:ident, $RXPO:literal, $TXPO:literal) => { };
(@filter, Pad3, $TX:ident, $RTS:ident, Pad3, $RXPO:literal, $TXPO:literal) => { };
(@filter, $RX:ident, Pad2, Pad2, $CTS:ident, $RXPO:literal, $TXPO:literal) => { };
macro_rules! impl_rxpotxpo {
// This is the entry pattern. Start by checking RTS and CTS.
($RX:ident, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@check_rts_cts, $RX, $TX, $RTS, $CTS); };

// Check whether RTS and CTS form a valid pair.
// They both must be the correct pad or absent.
(@check_rts_cts, $RX:ident, $TX:ident, NoneT, NoneT) => { impl_rxpotxpo!(@rxpo, $RX, $TX, NoneT, NoneT); };
(@check_rts_cts, $RX:ident, $TX:ident, Pad2, NoneT) => { impl_rxpotxpo!(@rxpo, $RX, $TX, Pad2, NoneT); };
(@check_rts_cts, $RX:ident, $TX:ident, NoneT, Pad3) => { impl_rxpotxpo!(@rxpo, $RX, $TX, NoneT, Pad3); };
(@check_rts_cts, $RX:ident, $TX:ident, Pad2, Pad3) => { impl_rxpotxpo!(@rxpo, $RX, $TX, Pad2, Pad3); };

// If RTS and CTS are not valid, fall through to this pattern.
(@check_rts_cts, $RX:ident, $TX:ident, $RTS:ident, $CTS:ident) => { };

// Assign RXPO based on RX.
// Our options are exhaustive, so no fall through pattern is needed.
(@rxpo, NoneT, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, NoneT, $TX, $RTS, $CTS, 0); };
(@rxpo, Pad0, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, Pad0, $TX, $RTS, $CTS, 0); };
(@rxpo, Pad1, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, Pad1, $TX, $RTS, $CTS, 1); };
(@rxpo, Pad2, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, Pad2, $TX, $RTS, $CTS, 2); };
(@rxpo, Pad3, $TX:ident, $RTS:ident, $CTS:ident) => { impl_rxpotxpo!(@txpo, Pad3, $TX, $RTS, $CTS, 3); };

// Assign TXPO based on TX and RTS
(@txpo, $RX:ident, NoneT, NoneT, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, NoneT, NoneT, $CTS, $RXPO, 0); };
(@txpo, $RX:ident, NoneT, Pad2, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, NoneT, Pad2, $CTS, $RXPO, 2); };
(@txpo, $RX:ident, Pad0, NoneT, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, Pad0, NoneT, $CTS, $RXPO, 0); };
(@txpo, $RX:ident, Pad2, NoneT, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, Pad2, NoneT, $CTS, $RXPO, 1); };
(@txpo, $RX:ident, Pad0, Pad2, $CTS:ident, $RXPO:literal) => { impl_rxpotxpo!(@filter, $RX, Pad0, Pad2, $CTS, $RXPO, 2); };

// If TX is not valid, fall through to this pattern.
(@txpo, $RX:ident, $TX:ident, $RTS:ident, $CTS:ident, $RXPO:literal) => { };

// Filter any remaining permutations that conflict.
(@filter, NoneT, NoneT, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => { }; // RX and TX both NoneT
(@filter, Pad0, Pad0, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => { }; // RX and TX both Pad0
(@filter, Pad2, Pad2, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => { }; // RX and TX both Pad2
(@filter, Pad2, $TX:ident, Pad2, $CTS:ident, $RXPO:literal, $TXPO:literal) => { }; // RX can't share a pad with RTS
(@filter, Pad3, $TX:ident, $RTS:ident, Pad3, $RXPO:literal, $TXPO:literal) => { }; // RX can't share a pad with CTS
(@filter, Pad1, $TX:ident, $RTS:ident, $CTS:ident, 0, $TXPO:literal) => { }; // RX can't be Pad1 when TXPO is 0 because of XCK conflict
(@filter, Pad3, $TX:ident, $RTS:ident, $CTS:ident, 1, $TXPO:literal) => { }; // RX can't be Pad3 when TXPO is 1 because of XCK conflict

// If there are no conflicts, fall through to this pattern
(@filter, $RX:ident, $TX:ident, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => { impl_rxpotxpo!(@implement, $RX, $TX, $RTS, $CTS, $RXPO, $TXPO); };

// If there are no conflicts, fall through to this pattern and implement RxpoTxpo
(@implement, $RX:ident, $TX:ident, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => {
impl RxpoTxpo for ($RX, $TX, $RTS, $CTS) {
const RXPO: u8 = $RXPO;
const TXPO: u8 = $TXPO;
}
};
}
(@filter, $RX:ident, $TX:ident, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => {
impl_rxpotxpo!(@implement, $RX, $TX, $RTS, $CTS, $RXPO, $TXPO);
};

// If there are no conflicts, fall through to this pattern and implement RxpoTxpo
(@implement, $RX:ident, $TX:ident, $RTS:ident, $CTS:ident, $RXPO:literal, $TXPO:literal) => {
impl RxpoTxpo for ($RX, $TX, $RTS, $CTS) {
const RXPO: u8 = $RXPO;
const TXPO: u8 = $TXPO;
}
};
}

/// Try to implement [`RxpoTxpo`] on all possible 4-tuple permutations of
/// [`OptionalPadNum`]s.
Expand All @@ -121,32 +124,32 @@ where
/// The final, optional `[]` token tree exists to temporarily store the entire
/// list before pushing it down for the next permutation element.
macro_rules! padnum_permutations {
// If we have built up four [`PadNum`]s, try to implement [`RxpoTxpo`].
// Ignore the remaining list of [`PadNum`]s.
(
( $RX:ident $TX:ident $RTS:ident $CTS:ident ) [ $( $Pads:ident )* ]
) => {
impl_rxpotxpo!($RX, $TX, $RTS, $CTS);
};
// If we only have one list of [`PadNum`]s, duplicate it, to save it for the
// next permutation element.
(
( $($Perm:ident)* ) [ $($Pads:ident)+ ]
) => {
padnum_permutations!( ( $($Perm)* ) [ $($Pads)+ ] [ $($Pads)+ ] );
};
(
( $($Perm:ident)* ) [ $Head:ident $($Tail:ident)* ] [ $($Pads:ident)+ ]
) => {
// Append the first [`PadNum`] from the list, then push down to the next
// permutation element.
padnum_permutations!( ( $($Perm)* $Head ) [ $($Pads)+ ] );

// Loop through the remaining [`PadNum`]s to do the same thing for each.
padnum_permutations!( ( $($Perm)* ) [ $($Tail)* ] [ $($Pads)+ ] );
};
// Once the list of [`PadNum`]s is empty, we're done with this element.
( ( $($Perm:ident)* ) [ ] [ $($Pads:ident)+ ] ) => { };
// If we have built up four [`PadNum`]s, try to implement [`RxpoTxpo`].
// Ignore the remaining list of [`PadNum`]s.
(
( $RX:ident $TX:ident $RTS:ident $CTS:ident ) [ $( $Pads:ident )* ]
) => {
impl_rxpotxpo!($RX, $TX, $RTS, $CTS);
};
// If we only have one list of [`PadNum`]s, duplicate it, to save it for the
// next permutation element.
(
( $($Perm:ident)* ) [ $($Pads:ident)+ ]
) => {
padnum_permutations!( ( $($Perm)* ) [ $($Pads)+ ] [ $($Pads)+ ] );
};
(
( $($Perm:ident)* ) [ $Head:ident $($Tail:ident)* ] [ $($Pads:ident)+ ]
) => {
// Append the first [`PadNum`] from the list, then push down to the next
// permutation element.
padnum_permutations!( ( $($Perm)* $Head ) [ $($Pads)+ ] );

// Loop through the remaining [`PadNum`]s to do the same thing for each.
padnum_permutations!( ( $($Perm)* ) [ $($Tail)* ] [ $($Pads)+ ] );
};
// Once the list of [`PadNum`]s is empty, we're done with this element.
( ( $($Perm:ident)* ) [ ] [ $($Pads:ident)+ ] ) => { };
}

padnum_permutations!( () [NoneT Pad0 Pad1 Pad2 Pad3] );
Expand Down
Loading

0 comments on commit e241dc0

Please sign in to comment.