Skip to content

Commit

Permalink
Peripheral ref/gpio (#323)
Browse files Browse the repository at this point in the history
* Implement Peripheral for all GPIO pins

* Update i2c & i2s to use the new gpio peripherals ref

* gpio pref: usb

* gpio pref: pulse control (RMT)

* gpio pref: spi

* gpio pref: uart

* gpio pref: ledc

* gpio pref: mcpwm

* fixup smartleds to use new pulse controller traits

* dump msrv

* bump rust-version in cargo tomls
  • Loading branch information
MabezDev authored Dec 19, 2022
1 parent 4598df6 commit 452fde2
Show file tree
Hide file tree
Showing 29 changed files with 274 additions and 194 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ jobs:
with:
profile: minimal
target: riscv32imc-unknown-none-elf
toolchain: "1.60.0"
toolchain: "1.65.0"
default: true
- uses: Swatinem/rust-cache@v1
- uses: actions-rs/cargo@v1
Expand Down Expand Up @@ -195,7 +195,7 @@ jobs:
default: true
ldproxy: false
buildtargets: ${{ matrix.chip_features.chip }}
version: "1.60.0"
version: "1.65.0"
- uses: Swatinem/rust-cache@v1
- uses: actions-rs/cargo@v1
with:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ There are a number of other crates within the [esp-rs organization] which can be

The **M**inimum **S**upported **R**ust **V**ersions are:

- `1.60.0` for RISC-V devices (**ESP32-C2**, **ESP32-C3**)
- `1.60.0` for Xtensa devices (**ESP32**, **ESP32-S2**, **ESP32-S3**)
- `1.65.0` for RISC-V devices (**ESP32-C2**, **ESP32-C3**)
- `1.65.0` for Xtensa devices (**ESP32**, **ESP32-S2**, **ESP32-S3**)

Note that targeting the Xtensa ISA currently requires the use of the [esp-rs/rust] compiler fork. The [esp-rs/rust-build] repository has pre-compiled release artifacts for most common platforms, and provides installation scripts to aid you in the process.

Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = [
"Björn Quentin <bjoern.quentin@mobile-j.de>",
]
edition = "2021"
rust-version = "1.60.0"
rust-version = "1.65.0"
description = "HAL implementations for peripherals common among Espressif devices; should not be used directly"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
Expand Down
34 changes: 34 additions & 0 deletions esp-hal-common/src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,40 @@ where
}
}

impl<MODE, RA, PINTYPE, const GPIONUM: u8> crate::peripheral::Peripheral
for GpioPin<MODE, RA, PINTYPE, GPIONUM>
where
RA: BankGpioRegisterAccess,
PINTYPE: PinType,
{
type P = GpioPin<MODE, RA, PINTYPE, GPIONUM>;

unsafe fn clone_unchecked(&mut self) -> Self::P {
core::ptr::read(self as *const _)
}
}

impl<MODE, RA, PINTYPE, const GPIONUM: u8> crate::peripheral::Peripheral
for &mut GpioPin<MODE, RA, PINTYPE, GPIONUM>
where
RA: BankGpioRegisterAccess,
PINTYPE: PinType,
{
type P = GpioPin<MODE, RA, PINTYPE, GPIONUM>;

unsafe fn clone_unchecked(&mut self) -> Self::P {
core::ptr::read(*self as *const _)
}
}

impl<MODE, RA, PINTYPE, const GPIONUM: u8> crate::peripheral::sealed::Sealed
for GpioPin<MODE, RA, PINTYPE, GPIONUM>
where
RA: BankGpioRegisterAccess,
PINTYPE: PinType,
{
}

impl<RA, PINTYPE, const GPIONUM: u8> From<GpioPin<Unknown, RA, PINTYPE, GPIONUM>>
for GpioPin<Input<Floating>, RA, PINTYPE, GPIONUM>
where
Expand Down
6 changes: 3 additions & 3 deletions esp-hal-common/src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,13 +266,13 @@ where
/// automatically disabled when this gets dropped.
pub fn new<SDA: OutputPin + InputPin, SCL: OutputPin + InputPin>(
i2c: impl Peripheral<P = T> + 'd,
mut sda: SDA,
mut scl: SCL,
sda: impl Peripheral<P = SDA> + 'd,
scl: impl Peripheral<P = SCL> + 'd,
frequency: HertzU32,
peripheral_clock_control: &mut PeripheralClockControl,
clocks: &Clocks,
) -> Self {
crate::into_ref!(i2c);
crate::into_ref!(i2c, sda, scl);
enable_peripheral(&i2c, peripheral_clock_control);

let mut i2c = I2C { peripheral: i2c };
Expand Down
98 changes: 67 additions & 31 deletions esp-hal-common/src/i2s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,29 @@ impl DataFormat {
}

/// Pins to use for I2S tx
pub struct PinsBclkWsDout<B: OutputPin, W: OutputPin, DO: OutputPin> {
pub bclk: B,
pub ws: W,
pub dout: DO,
pub struct PinsBclkWsDout<'d, B, W, DO> {
bclk: PeripheralRef<'d, B>,
ws: PeripheralRef<'d, W>,
dout: PeripheralRef<'d, DO>,
}

impl<B, W, DO> I2sTxPins for PinsBclkWsDout<B, W, DO>
impl<'d, B, W, DO> PinsBclkWsDout<'d, B, W, DO>
where
B: OutputPin,
W: OutputPin,
DO: OutputPin,
{
pub fn new(
bclk: impl Peripheral<P = B> + 'd,
ws: impl Peripheral<P = W> + 'd,
dout: impl Peripheral<P = DO> + 'd,
) -> Self {
crate::into_ref!(bclk, ws, dout);
Self { bclk, ws, dout }
}
}

impl<'d, B, W, DO> I2sTxPins for PinsBclkWsDout<'d, B, W, DO>
where
B: OutputPin,
W: OutputPin,
Expand All @@ -151,13 +167,29 @@ where
}

/// Pins to use for I2S rx
pub struct PinsBclkWsDin<B: OutputPin, W: OutputPin, DI: InputPin> {
pub bclk: B,
pub ws: W,
pub din: DI,
pub struct PinsBclkWsDin<'d, B, W, DI> {
bclk: PeripheralRef<'d, B>,
ws: PeripheralRef<'d, W>,
din: PeripheralRef<'d, DI>,
}

impl<'d, B, W, DI> PinsBclkWsDin<'d, B, W, DI>
where
B: OutputPin,
W: OutputPin,
DI: InputPin,
{
pub fn new(
bclk: impl Peripheral<P = B> + 'd,
ws: impl Peripheral<P = W> + 'd,
din: impl Peripheral<P = DI> + 'd,
) -> Self {
crate::into_ref!(bclk, ws, din);
Self { bclk, ws, din }
}
}

impl<B, W, DI> I2sRxPins for PinsBclkWsDin<B, W, DI>
impl<'d, B, W, DI> I2sRxPins for PinsBclkWsDin<'d, B, W, DI>
where
B: OutputPin,
W: OutputPin,
Expand All @@ -183,12 +215,21 @@ where

/// MCLK pin to use
#[cfg(not(esp32))]
pub struct MclkPin<M: OutputPin> {
pub mclk: M,
pub struct MclkPin<'d, M: OutputPin> {
mclk: PeripheralRef<'d, M>,
}

#[cfg(not(esp32))]
impl<M> I2sMclkPin for MclkPin<M>
impl<'d, M: OutputPin> MclkPin<'d, M> {
pub fn new(pin: impl Peripheral<P = M> + 'd) -> Self {
Self {
mclk: pin.into_ref(),
}
}
}

#[cfg(not(esp32))]
impl<'d, M> I2sMclkPin for MclkPin<'d, M>
where
M: OutputPin,
{
Expand Down Expand Up @@ -225,7 +266,7 @@ where
buffer: BUFFER,
}

impl<T, P, TX, BUFFER> I2sWriteDmaTransfer<T, P, TX, BUFFER>
impl<'d, T, P, TX, BUFFER> I2sWriteDmaTransfer<T, P, TX, BUFFER>
where
T: RegisterAccess,
P: I2sTxPins,
Expand All @@ -244,7 +285,7 @@ where
}
}

impl<T, P, TX, BUFFER> DmaTransfer<BUFFER, I2sTx<T, P, TX>>
impl<'d, T, P, TX, BUFFER> DmaTransfer<BUFFER, I2sTx<T, P, TX>>
for I2sWriteDmaTransfer<T, P, TX, BUFFER>
where
T: RegisterAccess,
Expand Down Expand Up @@ -272,7 +313,7 @@ where
}
}

impl<T, P, TX, BUFFER> Drop for I2sWriteDmaTransfer<T, P, TX, BUFFER>
impl<'d, T, P, TX, BUFFER> Drop for I2sWriteDmaTransfer<T, P, TX, BUFFER>
where
T: RegisterAccess,
P: I2sTxPins,
Expand All @@ -289,7 +330,7 @@ pub trait I2sWrite<W> {
}

/// Initiate a DMA tx transfer
pub trait I2sWriteDma<T, P, TX, TXBUF>
pub trait I2sWriteDma<'d, T, P, TX, TXBUF>
where
T: RegisterAccess,
P: I2sTxPins,
Expand Down Expand Up @@ -329,7 +370,7 @@ where
buffer: BUFFER,
}

impl<T, P, RX, BUFFER> I2sReadDmaTransfer<T, P, RX, BUFFER>
impl<'d, T, P, RX, BUFFER> I2sReadDmaTransfer<T, P, RX, BUFFER>
where
T: RegisterAccess,
P: I2sRxPins,
Expand Down Expand Up @@ -369,7 +410,8 @@ where
}
}

impl<T, P, RX, BUFFER> DmaTransfer<BUFFER, I2sRx<T, P, RX>> for I2sReadDmaTransfer<T, P, RX, BUFFER>
impl<'d, T, P, RX, BUFFER> DmaTransfer<BUFFER, I2sRx<T, P, RX>>
for I2sReadDmaTransfer<T, P, RX, BUFFER>
where
T: RegisterAccess,
P: I2sRxPins,
Expand Down Expand Up @@ -413,7 +455,7 @@ pub trait I2sRead<W> {
}

/// Initate a DMA rx transfer
pub trait I2sReadDma<T, P, RX, RXBUF>
pub trait I2sReadDma<'d, T, P, RX, RXBUF>
where
T: RegisterAccess,
P: I2sRxPins,
Expand Down Expand Up @@ -739,7 +781,7 @@ where
}
}

impl<T, P, TX, TXBUF> I2sWriteDma<T, P, TX, TXBUF> for I2sTx<T, P, TX>
impl<'d, T, P, TX, TXBUF> I2sWriteDma<'d, T, P, TX, TXBUF> for I2sTx<T, P, TX>
where
T: RegisterAccess,
P: I2sTxPins,
Expand Down Expand Up @@ -772,7 +814,7 @@ where
rx_channel: RX,
}

impl<T, P, RX> I2sRx<T, P, RX>
impl<'d, T, P, RX> I2sRx<T, P, RX>
where
T: RegisterAccess,
P: I2sRxPins,
Expand Down Expand Up @@ -885,7 +927,7 @@ where
}
}

impl<T, P, RX, RXBUF> I2sReadDma<T, P, RX, RXBUF> for I2sRx<T, P, RX>
impl<'d, T, P, RX, RXBUF> I2sReadDma<'d, T, P, RX, RXBUF> for I2sRx<T, P, RX>
where
T: RegisterAccess,
P: I2sRxPins,
Expand Down Expand Up @@ -962,13 +1004,10 @@ mod private {
T: RegisterAccess + Clone,
TX: Tx,
{
pub fn with_pins<P>(self, mut pins: P) -> I2sTx<T, P, TX>
pub fn with_pins<P>(self, pins: P) -> I2sTx<T, P, TX>
where
P: I2sTxPins,
{
let mut register_access = self.register_access.clone();
pins.configure(&mut register_access);

I2sTx::new(self.register_access, pins, self.tx_channel)
}
}
Expand All @@ -987,13 +1026,10 @@ mod private {
T: RegisterAccess + Clone,
RX: Rx,
{
pub fn with_pins<P>(self, mut pins: P) -> I2sRx<T, P, RX>
pub fn with_pins<P>(self, pins: P) -> I2sRx<T, P, RX>
where
P: I2sRxPins,
{
let mut register_access = self.register_access.clone();
pins.configure(&mut register_access);

I2sRx::new(self.register_access, pins, self.rx_channel)
}
}
Expand Down
8 changes: 5 additions & 3 deletions esp-hal-common/src/ledc/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use super::{
};
use crate::{
gpio::{types::OutputSignal, OutputPin},
peripheral::{Peripheral, PeripheralRef},
peripherals::ledc::RegisterBlock,
};

Expand Down Expand Up @@ -50,7 +51,7 @@ pub mod config {
}

/// Channel interface
pub trait ChannelIFace<'a, S: TimerSpeed + 'a, O: OutputPin>
pub trait ChannelIFace<'a, S: TimerSpeed + 'a, O: OutputPin + 'a>
where
Channel<'a, S, O>: ChannelHW<O>,
{
Expand All @@ -76,12 +77,13 @@ pub struct Channel<'a, S: TimerSpeed, O: OutputPin> {
ledc: &'a RegisterBlock,
timer: Option<&'a dyn TimerIFace<S>>,
number: Number,
output_pin: O,
output_pin: PeripheralRef<'a, O>,
}

impl<'a, S: TimerSpeed, O: OutputPin> Channel<'a, S, O> {
/// Return a new channel
pub fn new(number: Number, output_pin: O) -> Self {
pub fn new(number: Number, output_pin: impl Peripheral<P = O> + 'a) -> Self {
crate::into_ref!(output_pin);
let ledc = unsafe { &*crate::peripherals::LEDC::ptr() };
Channel {
ledc,
Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/src/ledc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl<'d> LEDC<'d> {
pub fn get_channel<S: TimerSpeed, O: OutputPin>(
&self,
number: channel::Number,
output_pin: O,
output_pin: impl Peripheral<P = O> + 'd,
) -> Channel<S, O> {
Channel::new(number, output_pin)
}
Expand Down
Loading

0 comments on commit 452fde2

Please sign in to comment.