Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

explicit PINS order, alias defaults #472

Merged
merged 1 commit into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- Explicit order for PINS, more smart aliases for peripherals
- Add `AFn` type aliases for `Alternate<n>`
- CI updates + cache
- Add missing `embedded-hal 1.0` for `DynamicPin`
Expand Down
19 changes: 12 additions & 7 deletions src/can.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ mod can3 {
}

pub trait CanExt: Sized + Instance {
fn can<PINS: Pins<Self>>(self, pins: PINS) -> Can<Self, PINS>;
fn can<TX, RX>(self, pins: (TX, RX)) -> Can<Self, (TX, RX)>
where
(TX, RX): Pins<Self>;
fn tx<TX>(self, tx_pin: TX) -> Can<Self, (TX, NoPin)>
where
(TX, NoPin): Pins<Self>;
Expand All @@ -68,7 +70,10 @@ pub trait CanExt: Sized + Instance {
}

impl<CAN: Instance> CanExt for CAN {
fn can<PINS: Pins<Self>>(self, pins: PINS) -> Can<Self, PINS> {
fn can<TX, RX>(self, pins: (TX, RX)) -> Can<Self, (TX, RX)>
where
(TX, RX): Pins<Self>,
{
Can::new(self, pins)
}
fn tx<TX>(self, tx_pin: TX) -> Can<Self, (TX, NoPin)>
Expand All @@ -91,13 +96,13 @@ pub struct Can<CAN, PINS> {
pins: PINS,
}

impl<CAN, PINS> Can<CAN, PINS>
impl<CAN, TX, RX> Can<CAN, (TX, RX)>
where
CAN: Instance,
PINS: Pins<CAN>,
(TX, RX): Pins<CAN>,
{
/// Creates a CAN interface.
pub fn new(can: CAN, mut pins: PINS) -> Self {
pub fn new(can: CAN, mut pins: (TX, RX)) -> Self {
unsafe {
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
let rcc = &(*crate::pac::RCC::ptr());
Expand All @@ -110,10 +115,10 @@ where
Can { can, pins }
}

pub fn release(mut self) -> (CAN, PINS) {
pub fn release(mut self) -> (CAN, (TX, RX)) {
self.pins.restore_mode();

(self.can, self.pins)
(self.can, (self.pins.0, self.pins.1))
}
}

Expand Down
27 changes: 16 additions & 11 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,31 +140,36 @@ impl Instance for pac::I2C3 {}
pub type I2c3<PINS> = I2c<pac::I2C3, PINS>;

pub trait I2cExt: Sized + Instance {
fn i2c<PINS: Pins<Self>>(
fn i2c<SCL, SDA>(
self,
pins: PINS,
pins: (SCL, SDA),
mode: impl Into<Mode>,
clocks: &Clocks,
) -> I2c<Self, PINS>;
) -> I2c<Self, (SCL, SDA)>
where
(SCL, SDA): Pins<Self>;
}

impl<I2C: Instance> I2cExt for I2C {
fn i2c<PINS: Pins<Self>>(
fn i2c<SCL, SDA>(
self,
pins: PINS,
pins: (SCL, SDA),
mode: impl Into<Mode>,
clocks: &Clocks,
) -> I2c<Self, PINS> {
) -> I2c<Self, (SCL, SDA)>
where
(SCL, SDA): Pins<Self>,
{
I2c::new(self, pins, mode, clocks)
}
}

impl<I2C, PINS> I2c<I2C, PINS>
impl<I2C, SCL, SDA> I2c<I2C, (SCL, SDA)>
where
I2C: Instance,
PINS: Pins<I2C>,
(SCL, SDA): Pins<I2C>,
{
pub fn new(i2c: I2C, mut pins: PINS, mode: impl Into<Mode>, clocks: &Clocks) -> Self {
pub fn new(i2c: I2C, mut pins: (SCL, SDA), mode: impl Into<Mode>, clocks: &Clocks) -> Self {
unsafe {
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
let rcc = &(*RCC::ptr());
Expand All @@ -181,10 +186,10 @@ where
i2c
}

pub fn release(mut self) -> (I2C, PINS) {
pub fn release(mut self) -> (I2C, (SCL, SDA)) {
self.pins.restore_mode();

(self.i2c, self.pins)
(self.i2c, (self.pins.0, self.pins.1))
}
}

Expand Down
32 changes: 24 additions & 8 deletions src/i2s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,32 +103,45 @@ macro_rules! i2s {
}

pub trait I2sExt: Sized + Instance {
fn i2s<PINS: Pins<Self>>(self, pins: PINS, clocks: &Clocks) -> I2s<Self, PINS>;
fn i2s<WS, CK, MCLK, SD>(
self,
pins: (WS, CK, MCLK, SD),
clocks: &Clocks,
) -> I2s<Self, (WS, CK, MCLK, SD)>
where
(WS, CK, MCLK, SD): Pins<Self>;
}

impl<SPI: Instance> I2sExt for SPI {
fn i2s<PINS: Pins<Self>>(self, pins: PINS, clocks: &Clocks) -> I2s<Self, PINS> {
fn i2s<WS, CK, MCLK, SD>(
self,
pins: (WS, CK, MCLK, SD),
clocks: &Clocks,
) -> I2s<Self, (WS, CK, MCLK, SD)>
where
(WS, CK, MCLK, SD): Pins<Self>,
{
I2s::new(self, pins, clocks)
}
}

impl<SPI, PINS> I2s<SPI, PINS>
impl<SPI, WS, CK, MCLK, SD> I2s<SPI, (WS, CK, MCLK, SD)>
where
SPI: Instance,
PINS: Pins<SPI>,
(WS, CK, MCLK, SD): Pins<SPI>,
{
/// Creates an I2s object around an SPI peripheral and pins
///
/// This function enables and resets the SPI peripheral, but does not configure it.
///
/// The returned I2s object implements [stm32_i2s_v12x::Instance], so it can be used
/// The returned I2s object implements `stm32_i2s_v12x::Instance`, so it can be used
/// to configure the peripheral and communicate.
///
/// # Panics
///
/// This function panics if the I2S clock input (from the I2S PLL or similar)
/// is not configured.
pub fn new(spi: SPI, mut pins: PINS, clocks: &Clocks) -> Self {
pub fn new(spi: SPI, mut pins: (WS, CK, MCLK, SD), clocks: &Clocks) -> Self {
let input_clock = SPI::i2s_freq(clocks);
unsafe {
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
Expand All @@ -147,10 +160,13 @@ where
}
}

pub fn release(mut self) -> (SPI, PINS) {
pub fn release(mut self) -> (SPI, (WS, CK, MCLK, SD)) {
self.pins.restore_mode();

(self.spi, self.pins)
(
self.spi,
(self.pins.0, self.pins.1, self.pins.2, self.pins.3),
)
}
}

Expand Down
29 changes: 14 additions & 15 deletions src/qei.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ use crate::{pac::RCC, rcc, timer::General};
pub trait Pins<TIM> {}
use crate::timer::CPin;

pub trait QeiExt<PINS>: Sized {
fn qei(self, pins: PINS) -> Qei<Self, PINS>;
pub trait QeiExt: Sized {
fn qei<PC1, PC2>(self, pins: (PC1, PC2)) -> Qei<Self, (PC1, PC2)>
where
(PC1, PC2): Pins<Self>;
}

impl<TIM, PINS> QeiExt<PINS> for TIM
where
TIM: Instance,
PINS: Pins<TIM>,
{
fn qei(self, pins: PINS) -> Qei<Self, PINS> {
impl<TIM: Instance> QeiExt for TIM {
fn qei<PC1, PC2>(self, pins: (PC1, PC2)) -> Qei<Self, (PC1, PC2)>
where
(PC1, PC2): Pins<Self>,
{
Qei::new(self, pins)
}
}
Expand All @@ -31,12 +32,12 @@ pub struct Qei<TIM, PINS> {
pins: PINS,
}

impl<TIM: Instance, PINS> Qei<TIM, PINS>
impl<TIM: Instance, PC1, PC2> Qei<TIM, (PC1, PC2)>
where
PINS: Pins<TIM>,
(PC1, PC2): Pins<TIM>,
{
/// Configures a TIM peripheral as a quadrature encoder interface input
pub fn new(mut tim: TIM, pins: PINS) -> Self {
pub fn new(mut tim: TIM, pins: (PC1, PC2)) -> Self {
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
let rcc = unsafe { &(*RCC::ptr()) };
// Enable and reset clock.
Expand All @@ -47,12 +48,10 @@ where

Qei { tim, pins }
}
}

impl<TIM: Instance, PINS> Qei<TIM, PINS> {
/// Releases the TIM peripheral and QEI pins
pub fn release(self) -> (TIM, PINS) {
(self.tim, self.pins)
pub fn release(self) -> (TIM, (PC1, PC2)) {
(self.tim, (self.pins.0, self.pins.1))
}
}

Expand Down
Loading