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

Use sealed traits instead of unsafe markers on traits #45

Merged
merged 3 commits into from
Jan 10, 2024
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
109 changes: 75 additions & 34 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ use embedded_time::rate::Hertz;

use crate::{clock::Clocks, pac};

use self::private::Sealed;

/// I2C error
#[derive(Debug, Eq, PartialEq)]
pub enum Error {
Expand Down Expand Up @@ -54,40 +56,40 @@ impl embedded_hal::i2c::Error for Error {
}
}

/// SDA pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait SdaPin<I2C> {}

/// SCL pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait SclPin<I2C> {}

/// I2C pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait Pins<I2C> {}

unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin0<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin1<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin2<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin3<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin4<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin5<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin6<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin7<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin8<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin9<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin10<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin11<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin12<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin13<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin14<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin15<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin16<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin17<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin18<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin19<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin20<MODE> {}
unsafe impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin21<MODE> {}
unsafe impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin22<MODE> {}

unsafe impl<SCL, SDA> Pins<I2C> for (SCL, SDA)
/// SDA pins
pub trait SdaPin<I2C>: Sealed {}

/// SCL pins
pub trait SclPin<I2C>: Sealed {}

/// I2C pins
pub trait Pins<I2C>: Sealed {}

impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin0<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin1<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin2<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin3<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin4<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin5<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin6<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin7<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin8<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin9<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin10<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin11<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin12<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin13<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin14<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin15<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin16<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin17<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin18<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin19<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin20<MODE> {}
impl<MODE> SdaPin<pac::I2C> for crate::gpio::Pin21<MODE> {}
impl<MODE> SclPin<pac::I2C> for crate::gpio::Pin22<MODE> {}

impl<SCL, SDA> Pins<I2C> for (SCL, SDA)
where
SCL: SclPin<I2C>,
SDA: SdaPin<I2C>,
Expand Down Expand Up @@ -358,3 +360,42 @@ where
i2cAlpha::I2c::write(self, addr, bytes)
}
}

// Prevent users from implementing the i2c pin traits
mod private {
use super::{SclPin, SdaPin};
use crate::gpio;
use bl602_pac::I2C;

pub trait Sealed {}
impl<SCL, SDA> Sealed for (SCL, SDA)
where
SCL: SclPin<I2C>,
SDA: SdaPin<I2C>,
{
}

impl<MODE> Sealed for gpio::Pin0<MODE> {}
impl<MODE> Sealed for gpio::Pin1<MODE> {}
impl<MODE> Sealed for gpio::Pin2<MODE> {}
impl<MODE> Sealed for gpio::Pin3<MODE> {}
impl<MODE> Sealed for gpio::Pin4<MODE> {}
impl<MODE> Sealed for gpio::Pin5<MODE> {}
impl<MODE> Sealed for gpio::Pin6<MODE> {}
impl<MODE> Sealed for gpio::Pin7<MODE> {}
impl<MODE> Sealed for gpio::Pin8<MODE> {}
impl<MODE> Sealed for gpio::Pin9<MODE> {}
impl<MODE> Sealed for gpio::Pin10<MODE> {}
impl<MODE> Sealed for gpio::Pin11<MODE> {}
impl<MODE> Sealed for gpio::Pin12<MODE> {}
impl<MODE> Sealed for gpio::Pin13<MODE> {}
impl<MODE> Sealed for gpio::Pin14<MODE> {}
impl<MODE> Sealed for gpio::Pin15<MODE> {}
impl<MODE> Sealed for gpio::Pin16<MODE> {}
impl<MODE> Sealed for gpio::Pin17<MODE> {}
impl<MODE> Sealed for gpio::Pin18<MODE> {}
impl<MODE> Sealed for gpio::Pin19<MODE> {}
impl<MODE> Sealed for gpio::Pin20<MODE> {}
impl<MODE> Sealed for gpio::Pin21<MODE> {}
impl<MODE> Sealed for gpio::Pin22<MODE> {}
}
74 changes: 54 additions & 20 deletions src/serial.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Serial communication
use self::private::Sealed;
use crate::clock::Clocks;
use crate::pac;
use core::fmt;
Expand Down Expand Up @@ -348,28 +349,28 @@ where
}
}

/// Serial transmit pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait TxPin<UART> {}
/// Serial receive pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait RxPin<UART> {}
/// Serial rts pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait RtsPin<UART> {}
/// Serial cts pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait CtsPin<UART> {}
/// Serial transmit pins
pub trait TxPin<UART>: Sealed {}
/// Serial receive pins
pub trait RxPin<UART>: Sealed {}
/// Serial rts pins
pub trait RtsPin<UART>: Sealed {}
/// Serial cts pins
pub trait CtsPin<UART>: Sealed {}

macro_rules! impl_uart_pin {
($(($UartSigi: ident, $UartMuxi: ident),)+) => {
use crate::gpio::*;
$(
unsafe impl<PIN: UartPin<$UartSigi>> TxPin<pac::UART0> for (PIN, $UartMuxi<Uart0Tx>) {}
unsafe impl<PIN: UartPin<$UartSigi>> RxPin<pac::UART0> for (PIN, $UartMuxi<Uart0Rx>) {}
unsafe impl<PIN: UartPin<$UartSigi>> RtsPin<pac::UART0> for (PIN, $UartMuxi<Uart0Rts>) {}
unsafe impl<PIN: UartPin<$UartSigi>> CtsPin<pac::UART0> for (PIN, $UartMuxi<Uart0Cts>) {}

unsafe impl<PIN: UartPin<$UartSigi>> TxPin<pac::UART1> for (PIN, $UartMuxi<Uart1Tx>) {}
unsafe impl<PIN: UartPin<$UartSigi>> RxPin<pac::UART1> for (PIN, $UartMuxi<Uart1Rx>) {}
unsafe impl<PIN: UartPin<$UartSigi>> RtsPin<pac::UART1> for (PIN, $UartMuxi<Uart1Rts>) {}
unsafe impl<PIN: UartPin<$UartSigi>> CtsPin<pac::UART1> for (PIN, $UartMuxi<Uart1Cts>) {}
impl<PIN: UartPin<$UartSigi>> TxPin<pac::UART0> for (PIN, $UartMuxi<Uart0Tx>) {}
impl<PIN: UartPin<$UartSigi>> RxPin<pac::UART0> for (PIN, $UartMuxi<Uart0Rx>) {}
impl<PIN: UartPin<$UartSigi>> RtsPin<pac::UART0> for (PIN, $UartMuxi<Uart0Rts>) {}
impl<PIN: UartPin<$UartSigi>> CtsPin<pac::UART0> for (PIN, $UartMuxi<Uart0Cts>) {}

impl<PIN: UartPin<$UartSigi>> TxPin<pac::UART1> for (PIN, $UartMuxi<Uart1Tx>) {}
impl<PIN: UartPin<$UartSigi>> RxPin<pac::UART1> for (PIN, $UartMuxi<Uart1Rx>) {}
impl<PIN: UartPin<$UartSigi>> RtsPin<pac::UART1> for (PIN, $UartMuxi<Uart1Rts>) {}
impl<PIN: UartPin<$UartSigi>> CtsPin<pac::UART1> for (PIN, $UartMuxi<Uart1Cts>) {}
)+
};
}
Expand All @@ -386,14 +387,14 @@ impl_uart_pin!(
);

/// Serial pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait Pins<UART> {
pub trait Pins<UART>: Sealed {
const HAS_TX: bool;
const HAS_RX: bool;
const HAS_RTS: bool;
const HAS_CTS: bool;
}

unsafe impl<UART, TX, RX> Pins<UART> for (TX, RX)
impl<UART, TX, RX> Pins<UART> for (TX, RX)
where
TX: TxPin<UART>,
RX: RxPin<UART>,
Expand All @@ -404,7 +405,7 @@ where
const HAS_CTS: bool = false;
}

unsafe impl<UART, TX, RX, RTS, CTS> Pins<UART> for (TX, RX, RTS, CTS)
impl<UART, TX, RX, RTS, CTS> Pins<UART> for (TX, RX, RTS, CTS)
where
TX: TxPin<UART>,
RX: RxPin<UART>,
Expand All @@ -416,3 +417,36 @@ where
const HAS_RTS: bool = true;
const HAS_CTS: bool = true;
}

// Prevent users from implementing the Serial pin traits
mod private {
use crate::gpio;

pub trait Sealed {}
impl<TX, RX> Sealed for (TX, RX) {}
impl<TX, RX, RTS, CTS> Sealed for (TX, RX, RTS, CTS) {}

impl<MODE> Sealed for gpio::Pin0<MODE> {}
impl<MODE> Sealed for gpio::Pin1<MODE> {}
impl<MODE> Sealed for gpio::Pin2<MODE> {}
impl<MODE> Sealed for gpio::Pin3<MODE> {}
impl<MODE> Sealed for gpio::Pin4<MODE> {}
impl<MODE> Sealed for gpio::Pin5<MODE> {}
impl<MODE> Sealed for gpio::Pin6<MODE> {}
impl<MODE> Sealed for gpio::Pin7<MODE> {}
impl<MODE> Sealed for gpio::Pin8<MODE> {}
impl<MODE> Sealed for gpio::Pin9<MODE> {}
impl<MODE> Sealed for gpio::Pin10<MODE> {}
impl<MODE> Sealed for gpio::Pin11<MODE> {}
impl<MODE> Sealed for gpio::Pin12<MODE> {}
impl<MODE> Sealed for gpio::Pin13<MODE> {}
impl<MODE> Sealed for gpio::Pin14<MODE> {}
impl<MODE> Sealed for gpio::Pin15<MODE> {}
impl<MODE> Sealed for gpio::Pin16<MODE> {}
impl<MODE> Sealed for gpio::Pin17<MODE> {}
impl<MODE> Sealed for gpio::Pin18<MODE> {}
impl<MODE> Sealed for gpio::Pin19<MODE> {}
impl<MODE> Sealed for gpio::Pin20<MODE> {}
impl<MODE> Sealed for gpio::Pin21<MODE> {}
impl<MODE> Sealed for gpio::Pin22<MODE> {}
}
133 changes: 92 additions & 41 deletions src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,46 +65,46 @@ pub enum SpiBitFormat {
MsbFirst,
}

/// MISO pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait MisoPin<SPI> {}

/// MOSI pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait MosiPin<SPI> {}

/// SS pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait SsPin<SPI> {}

/// SCLK pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait SclkPin<SPI> {}

/// Spi pins - DO NOT IMPLEMENT THIS TRAIT
pub unsafe trait Pins<SPI> {}

unsafe impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin0<MODE> {}
unsafe impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin1<MODE> {}
unsafe impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin2<MODE> {}
unsafe impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin3<MODE> {}
unsafe impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin4<MODE> {}
unsafe impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin5<MODE> {}
unsafe impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin6<MODE> {}
unsafe impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin7<MODE> {}
unsafe impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin8<MODE> {}
unsafe impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin9<MODE> {}
unsafe impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin10<MODE> {}
unsafe impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin11<MODE> {}
unsafe impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin12<MODE> {}
unsafe impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin13<MODE> {}
unsafe impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin14<MODE> {}
unsafe impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin15<MODE> {}
unsafe impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin16<MODE> {}
unsafe impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin17<MODE> {}
unsafe impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin18<MODE> {}
unsafe impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin19<MODE> {}
unsafe impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin20<MODE> {}
unsafe impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin21<MODE> {}
unsafe impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin22<MODE> {}

unsafe impl<MISO, MOSI, SS, SCLK> Pins<SPI> for (MISO, MOSI, SS, SCLK)
/// MISO pins
pub trait MisoPin<SPI>: private::Sealed {}

/// MOSI pins
pub trait MosiPin<SPI>: private::Sealed {}

/// SS pins
pub trait SsPin<SPI>: private::Sealed {}

/// SCLK pins
pub trait SclkPin<SPI>: private::Sealed {}

/// Spi pins
pub trait Pins<SPI>: private::Sealed {}

impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin0<MODE> {}
impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin1<MODE> {}
impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin2<MODE> {}
impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin3<MODE> {}
impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin4<MODE> {}
impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin5<MODE> {}
impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin6<MODE> {}
impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin7<MODE> {}
impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin8<MODE> {}
impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin9<MODE> {}
impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin10<MODE> {}
impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin11<MODE> {}
impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin12<MODE> {}
impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin13<MODE> {}
impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin14<MODE> {}
impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin15<MODE> {}
impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin16<MODE> {}
impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin17<MODE> {}
impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin18<MODE> {}
impl<MODE> SclkPin<pac::SPI> for crate::gpio::Pin19<MODE> {}
impl<MODE> MisoPin<pac::SPI> for crate::gpio::Pin20<MODE> {}
impl<MODE> MosiPin<pac::SPI> for crate::gpio::Pin21<MODE> {}
impl<MODE> SsPin<pac::SPI> for crate::gpio::Pin22<MODE> {}

impl<MISO, MOSI, SS, SCLK> Pins<SPI> for (MISO, MOSI, SS, SCLK)
where
MISO: MisoPin<SPI>,
MOSI: MosiPin<SPI>,
Expand All @@ -113,14 +113,65 @@ where
{
}

unsafe impl<MISO, MOSI, SCLK> Pins<SPI> for (MISO, MOSI, SCLK)
impl<MISO, MOSI, SCLK> Pins<SPI> for (MISO, MOSI, SCLK)
where
MISO: MisoPin<SPI>,
MOSI: MosiPin<SPI>,
SCLK: SclkPin<SPI>,
{
}

// Prevent users from implementing the SPI pin traits
mod private {
use bl602_pac::SPI;

use crate::gpio;

use super::{MisoPin, MosiPin, SclkPin, SsPin};

pub trait Sealed {}
impl<MISO, MOSI, SCLK> Sealed for (MISO, MOSI, SCLK)
where
MISO: MisoPin<SPI>,
MOSI: MosiPin<SPI>,
SCLK: SclkPin<SPI>,
{
}

impl<MISO, MOSI, SS, SCLK> Sealed for (MISO, MOSI, SS, SCLK)
where
MISO: MisoPin<SPI>,
MOSI: MosiPin<SPI>,
SS: SsPin<SPI>,
SCLK: SclkPin<SPI>,
{
}

impl<MODE> Sealed for gpio::Pin0<MODE> {}
impl<MODE> Sealed for gpio::Pin1<MODE> {}
impl<MODE> Sealed for gpio::Pin2<MODE> {}
impl<MODE> Sealed for gpio::Pin3<MODE> {}
impl<MODE> Sealed for gpio::Pin4<MODE> {}
impl<MODE> Sealed for gpio::Pin5<MODE> {}
impl<MODE> Sealed for gpio::Pin6<MODE> {}
impl<MODE> Sealed for gpio::Pin7<MODE> {}
impl<MODE> Sealed for gpio::Pin8<MODE> {}
impl<MODE> Sealed for gpio::Pin9<MODE> {}
impl<MODE> Sealed for gpio::Pin10<MODE> {}
impl<MODE> Sealed for gpio::Pin11<MODE> {}
impl<MODE> Sealed for gpio::Pin12<MODE> {}
impl<MODE> Sealed for gpio::Pin13<MODE> {}
impl<MODE> Sealed for gpio::Pin14<MODE> {}
impl<MODE> Sealed for gpio::Pin15<MODE> {}
impl<MODE> Sealed for gpio::Pin16<MODE> {}
impl<MODE> Sealed for gpio::Pin17<MODE> {}
impl<MODE> Sealed for gpio::Pin18<MODE> {}
impl<MODE> Sealed for gpio::Pin19<MODE> {}
impl<MODE> Sealed for gpio::Pin20<MODE> {}
impl<MODE> Sealed for gpio::Pin21<MODE> {}
impl<MODE> Sealed for gpio::Pin22<MODE> {}
}

/// A Serial Peripheral Interface
pub struct Spi<SPI, PINS> {
spi: SPI,
Expand Down
Loading