Peripheral ref/gpio (#323)

* 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
This commit is contained in:
Scott Mabin 2022-12-19 14:40:29 +00:00 committed by GitHub
parent 4598df6ed6
commit 452fde2c12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 274 additions and 194 deletions

View File

@ -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
@ -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:

View File

@ -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.

View File

@ -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"

View File

@ -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

View File

@ -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 };

View File

@ -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,
@ -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<B, W, DI> I2sRxPins for PinsBclkWsDin<B, W, 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<'d, B, W, DI> I2sRxPins for PinsBclkWsDin<'d, B, W, DI>
where
B: OutputPin,
W: OutputPin,
@ -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,
{
@ -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,
@ -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,
@ -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,
@ -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,
@ -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,
@ -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,
@ -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,
@ -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,
@ -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,
@ -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,
@ -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)
}
}
@ -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)
}
}

View File

@ -8,6 +8,7 @@ use super::{
};
use crate::{
gpio::{types::OutputSignal, OutputPin},
peripheral::{Peripheral, PeripheralRef},
peripherals::ledc::RegisterBlock,
};
@ -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>,
{
@ -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,

View File

@ -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)
}

View File

@ -2,6 +2,7 @@ use core::marker::PhantomData;
use crate::{
mcpwm::{timer::Timer, PwmPeripheral},
peripheral::{Peripheral, PeripheralRef},
OutputPin,
};
@ -52,31 +53,34 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
}
/// Use the A output with the given pin and configuration
pub fn with_pin_a<Pin: OutputPin>(
pub fn with_pin_a<'d, Pin: OutputPin>(
self,
pin: Pin,
pin: impl Peripheral<P = Pin> + 'd,
config: PwmPinConfig<true>,
) -> PwmPin<Pin, PWM, OP, true> {
) -> PwmPin<'d, Pin, PWM, OP, true> {
PwmPin::new(pin, config)
}
/// Use the B output with the given pin and configuration
pub fn with_pin_b<Pin: OutputPin>(
pub fn with_pin_b<'d, Pin: OutputPin>(
self,
pin: Pin,
pin: impl Peripheral<P = Pin> + 'd,
config: PwmPinConfig<false>,
) -> PwmPin<Pin, PWM, OP, false> {
) -> PwmPin<'d, Pin, PWM, OP, false> {
PwmPin::new(pin, config)
}
/// Use both the A and the B output with the given pins and configurations
pub fn with_pins<PinA: OutputPin, PinB: OutputPin>(
pub fn with_pins<'d, PinA: OutputPin, PinB: OutputPin>(
self,
pin_a: PinA,
pin_a: impl Peripheral<P = PinA> + 'd,
config_a: PwmPinConfig<true>,
pin_b: PinB,
pin_b: impl Peripheral<P = PinB> + 'd,
config_b: PwmPinConfig<false>,
) -> (PwmPin<PinA, PWM, OP, true>, PwmPin<PinB, PWM, OP, false>) {
) -> (
PwmPin<'d, PinA, PWM, OP, true>,
PwmPin<'d, PinB, PWM, OP, false>,
) {
(PwmPin::new(pin_a, config_a), PwmPin::new(pin_b, config_b))
}
}
@ -110,15 +114,16 @@ impl<const IS_A: bool> PwmPinConfig<IS_A> {
}
/// A pin driven by an MCPWM operator
pub struct PwmPin<Pin, PWM, const OP: u8, const IS_A: bool> {
_pin: Pin,
pub struct PwmPin<'d, Pin, PWM, const OP: u8, const IS_A: bool> {
_pin: PeripheralRef<'d, Pin>,
phantom: PhantomData<PWM>,
}
impl<Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
PwmPin<Pin, PWM, OP, IS_A>
impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
PwmPin<'d, Pin, PWM, OP, IS_A>
{
fn new(mut pin: Pin, config: PwmPinConfig<IS_A>) -> Self {
fn new(pin: impl Peripheral<P = Pin> + 'd, config: PwmPinConfig<IS_A>) -> Self {
crate::into_ref!(pin);
let output_signal = PWM::output_signal::<OP, IS_A>();
pin.enable_output(true)
.connect_peripheral_to_output(output_signal);

View File

@ -4,9 +4,9 @@ pub use esp_synopsys_usb_otg::UsbBus;
use esp_synopsys_usb_otg::UsbPeripheral;
use crate::{
peripheral::PeripheralRef,
peripheral::{Peripheral, PeripheralRef},
peripherals,
system::{Peripheral, PeripheralClockControl},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
types::InputSignal,
};
@ -26,9 +26,9 @@ where
M: UsbDm + Send + Sync,
{
_usb0: PeripheralRef<'d, peripherals::USB0>,
_usb_sel: S,
_usb_dp: P,
_usb_dm: M,
_usb_sel: PeripheralRef<'d, S>,
_usb_dp: PeripheralRef<'d, P>,
_usb_dm: PeripheralRef<'d, M>,
}
impl<'d, S, P, M> USB<'d, S, P, M>
@ -38,13 +38,14 @@ where
M: UsbDm + Send + Sync,
{
pub fn new(
usb0: impl crate::peripheral::Peripheral<P = peripherals::USB0> + 'd,
usb_sel: S,
usb_dp: P,
usb_dm: M,
usb0: impl Peripheral<P = peripherals::USB0> + 'd,
usb_sel: impl Peripheral<P = S> + 'd,
usb_dp: impl Peripheral<P = P> + 'd,
usb_dm: impl Peripheral<P = M> + 'd,
peripheral_clock_control: &mut PeripheralClockControl,
) -> Self {
peripheral_clock_control.enable(Peripheral::Usb);
crate::into_ref!(usb_sel, usb_dp, usb_dm);
peripheral_clock_control.enable(PeripheralEnable::Usb);
Self {
_usb0: usb0.into_ref(),
_usb_sel: usb_sel,

View File

@ -301,7 +301,8 @@ mod peripheral_macros {
macro_rules! into_ref {
($($name:ident),*) => {
$(
let $name = $name.into_ref();
#[allow(unused_mut)]
let mut $name = $name.into_ref();
)*
}
}

View File

@ -211,7 +211,12 @@ impl From<PulseCode> for u32 {
}
/// Functionality that every OutputChannel must support
pub trait OutputChannel<CC> {
pub trait OutputChannel {
/// Output channel type
type ConfiguredChannel<'d, P>
where
P: OutputPin + 'd;
/// Set the logical level that the connected pin is pulled to
/// while the channel is idle
fn set_idle_output_level(&mut self, level: bool) -> &mut Self;
@ -231,11 +236,10 @@ pub trait OutputChannel<CC> {
fn set_clock_source(&mut self, source: ClockSource) -> &mut Self;
/// Assign a pin that should be driven by this channel
///
/// (Note that we only take a reference here, so the ownership remains with
/// the calling entity. The configured pin thus can be re-configured
/// independently.)
fn assign_pin<RmtPin: OutputPin>(self, pin: RmtPin) -> CC;
fn assign_pin<'d, P: OutputPin>(
self,
pin: impl Peripheral<P = P> + 'd,
) -> Self::ConfiguredChannel<'d, P>;
}
/// Functionality that is allowed only on `ConfiguredChannel`
@ -359,11 +363,12 @@ macro_rules! channel_instance {
paste!(
#[doc = "Wrapper for`" $cxi "` object."]
pub struct [<Configured $cxi>] {
pub struct [<Configured $cxi>]<'d, P> {
channel: $cxi,
_pin: PeripheralRef<'d, P>
}
impl ConfiguredChannel for [<Configured $cxi>] {
impl<'d, P: OutputPin> ConfiguredChannel for [<Configured $cxi>]<'d, P> {
/// Send a pulse sequence in a blocking fashion
fn send_pulse_sequence<const N: usize>(
&mut self,
@ -651,7 +656,11 @@ macro_rules! output_channel {
) => {
paste!(
impl OutputChannel<[<Configured $cxi>]> for $cxi {
impl OutputChannel for $cxi {
type ConfiguredChannel<'d, P> = [<Configured $cxi>]<'d, P>
where P: OutputPin + 'd;
/// Set the logical level that the connected pin is pulled to
/// while the channel is idle
#[inline(always)]
@ -737,16 +746,18 @@ macro_rules! output_channel {
}
/// Assign a pin that should be driven by this channel
fn assign_pin<RmtPin: OutputPin >(
fn assign_pin<'d, RmtPin: OutputPin >(
self,
mut pin: RmtPin,
) -> [<Configured $cxi>] {
pin: impl Peripheral<P = RmtPin> + 'd
) -> [<Configured $cxi>]<'d, RmtPin> {
crate::into_ref!(pin);
// Configure Pin as output anc connect to signal
pin.set_to_push_pull_output()
.connect_peripheral_to_output($output_signal);
[<Configured $cxi>] {
channel: self,
_pin: pin
}
}
}

View File

@ -115,16 +115,16 @@ where
/// Constructs an SPI instance in 8bit dataframe mode.
pub fn new<SCK: OutputPin, MOSI: OutputPin, MISO: InputPin, CS: OutputPin>(
spi: impl Peripheral<P = T> + 'd,
mut sck: SCK,
mut mosi: MOSI,
mut miso: MISO,
mut cs: CS,
sck: impl Peripheral<P = SCK> + 'd,
mosi: impl Peripheral<P = MOSI> + 'd,
miso: impl Peripheral<P = MISO> + 'd,
cs: impl Peripheral<P = CS> + 'd,
frequency: HertzU32,
mode: SpiMode,
peripheral_clock_control: &mut PeripheralClockControl,
clocks: &Clocks,
) -> Self {
crate::into_ref!(spi);
crate::into_ref!(spi, sck, mosi, miso, cs);
sck.set_to_push_pull_output()
.connect_peripheral_to_output(spi.sclk_signal());
@ -143,15 +143,15 @@ where
/// Constructs an SPI instance in 8bit dataframe mode without CS pin.
pub fn new_no_cs<SCK: OutputPin, MOSI: OutputPin, MISO: InputPin>(
spi: impl Peripheral<P = T> + 'd,
mut sck: SCK,
mut mosi: MOSI,
mut miso: MISO,
sck: impl Peripheral<P = SCK> + 'd,
mosi: impl Peripheral<P = MOSI> + 'd,
miso: impl Peripheral<P = MISO> + 'd,
frequency: HertzU32,
mode: SpiMode,
peripheral_clock_control: &mut PeripheralClockControl,
clocks: &Clocks,
) -> Self {
crate::into_ref!(spi);
crate::into_ref!(spi, sck, mosi, miso);
sck.set_to_push_pull_output()
.connect_peripheral_to_output(spi.sclk_signal());
@ -168,14 +168,14 @@ where
/// pin.
pub fn new_no_cs_no_miso<SCK: OutputPin, MOSI: OutputPin>(
spi: impl Peripheral<P = T> + 'd,
mut sck: SCK,
mut mosi: MOSI,
sck: impl Peripheral<P = SCK> + 'd,
mosi: impl Peripheral<P = MOSI> + 'd,
frequency: HertzU32,
mode: SpiMode,
peripheral_clock_control: &mut PeripheralClockControl,
clocks: &Clocks,
) -> Self {
crate::into_ref!(spi);
crate::into_ref!(spi, sck, mosi);
sck.set_to_push_pull_output()
.connect_peripheral_to_output(spi.sclk_signal());
@ -191,13 +191,13 @@ where
/// waveforms…)
pub fn new_mosi_only<MOSI: OutputPin>(
spi: impl Peripheral<P = T> + 'd,
mut mosi: MOSI,
mosi: impl Peripheral<P = MOSI> + 'd,
frequency: HertzU32,
mode: SpiMode,
peripheral_clock_control: &mut PeripheralClockControl,
clocks: &Clocks,
) -> Self {
crate::into_ref!(spi);
crate::into_ref!(spi, mosi);
mosi.set_to_push_pull_output()
.connect_peripheral_to_output(spi.mosi_signal());

View File

@ -144,16 +144,22 @@ pub trait UartPins {
}
/// All pins offered by UART
pub struct AllPins<TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> {
pub tx: Option<TX>,
pub rx: Option<RX>,
pub cts: Option<CTS>,
pub rts: Option<RTS>,
pub struct AllPins<'d, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> {
pub(crate) tx: Option<PeripheralRef<'d, TX>>,
pub(crate) rx: Option<PeripheralRef<'d, RX>>,
pub(crate) cts: Option<PeripheralRef<'d, CTS>>,
pub(crate) rts: Option<PeripheralRef<'d, RTS>>,
}
/// Tx and Rx pins
impl<TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> AllPins<TX, RX, CTS, RTS> {
pub fn new(tx: TX, rx: RX, cts: CTS, rts: RTS) -> AllPins<TX, RX, CTS, RTS> {
impl<'d, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> AllPins<'d, TX, RX, CTS, RTS> {
pub fn new(
tx: impl Peripheral<P = TX> + 'd,
rx: impl Peripheral<P = RX> + 'd,
cts: impl Peripheral<P = CTS> + 'd,
rts: impl Peripheral<P = RTS> + 'd,
) -> AllPins<'d, TX, RX, CTS, RTS> {
crate::into_ref!(tx, rx, cts, rts);
AllPins {
tx: Some(tx),
rx: Some(rx),
@ -164,7 +170,7 @@ impl<TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> AllPins<TX, RX,
}
impl<TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> UartPins
for AllPins<TX, RX, CTS, RTS>
for AllPins<'_, TX, RX, CTS, RTS>
{
fn configure_pins(
&mut self,
@ -193,13 +199,17 @@ impl<TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> UartPins
}
}
pub struct TxRxPins<TX: OutputPin, RX: InputPin> {
pub tx: Option<TX>,
pub rx: Option<RX>,
pub struct TxRxPins<'d, TX: OutputPin, RX: InputPin> {
pub tx: Option<PeripheralRef<'d, TX>>,
pub rx: Option<PeripheralRef<'d, RX>>,
}
impl<TX: OutputPin, RX: InputPin> TxRxPins<TX, RX> {
pub fn new_tx_rx(tx: TX, rx: RX) -> TxRxPins<TX, RX> {
impl<'d, TX: OutputPin, RX: InputPin> TxRxPins<'d, TX, RX> {
pub fn new_tx_rx(
tx: impl Peripheral<P = TX> + 'd,
rx: impl Peripheral<P = RX> + 'd,
) -> TxRxPins<'d, TX, RX> {
crate::into_ref!(tx, rx);
TxRxPins {
tx: Some(tx),
rx: Some(rx),
@ -207,7 +217,7 @@ impl<TX: OutputPin, RX: InputPin> TxRxPins<TX, RX> {
}
}
impl<TX: OutputPin, RX: InputPin> UartPins for TxRxPins<TX, RX> {
impl<TX: OutputPin, RX: InputPin> UartPins for TxRxPins<'_, TX, RX> {
fn configure_pins(
&mut self,
tx_signal: OutputSignal,

View File

@ -11,7 +11,7 @@
//! in a sequence in a single RMT send operation) might be required!_
#![deny(missing_docs)]
use core::{marker::PhantomData, slice::IterMut};
use core::slice::IterMut;
use fugit::NanosDuration;
use smart_leds_trait::{SmartLedsWrite, RGB8};
@ -20,6 +20,7 @@ use smart_leds_trait::{SmartLedsWrite, RGB8};
use crate::pulse_control::ClockSource;
use crate::{
gpio::OutputPin,
peripheral::Peripheral,
pulse_control::{ConfiguredChannel, OutputChannel, PulseCode, RepeatMode, TransmissionError},
};
@ -75,30 +76,28 @@ macro_rules! smartLedAdapter {
// * channels (r,g,b -> 3)
// * pulses per channel 8)
// ) + 1 additional pulse for the end delimiter
SmartLedsAdapter::<_, _, { $buffer_size * 24 + 1 }>
SmartLedsAdapter::<_, { $buffer_size * 24 + 1 }>
};
}
/// Adapter taking an RMT channel and a specific pin and providing RGB LED
/// interaction functionality using the `smart-leds` crate
pub struct SmartLedsAdapter<CHANNEL, PIN, const BUFFER_SIZE: usize> {
pub struct SmartLedsAdapter<CHANNEL, const BUFFER_SIZE: usize> {
channel: CHANNEL,
rmt_buffer: [u32; BUFFER_SIZE],
_pin: PhantomData<PIN>,
}
impl<CHANNEL, PIN, const BUFFER_SIZE: usize> SmartLedsAdapter<CHANNEL, PIN, BUFFER_SIZE>
impl<'d, CHANNEL, const BUFFER_SIZE: usize> SmartLedsAdapter<CHANNEL, BUFFER_SIZE>
where
CHANNEL: ConfiguredChannel,
PIN: OutputPin,
{
/// Create a new adapter object that drives the pin using the RMT channel.
pub fn new<UnconfiguredChannel>(
pub fn new<UnconfiguredChannel, O: OutputPin + 'd>(
mut channel: UnconfiguredChannel,
pin: PIN,
) -> SmartLedsAdapter<CHANNEL, PIN, BUFFER_SIZE>
pin: impl Peripheral<P = O> + 'd,
) -> SmartLedsAdapter<CHANNEL, BUFFER_SIZE>
where
UnconfiguredChannel: OutputChannel<CHANNEL>,
UnconfiguredChannel: OutputChannel<ConfiguredChannel<'d, O> = CHANNEL>,
{
#[cfg(any(esp32c3, esp32s3))]
channel
@ -119,7 +118,6 @@ where
Self {
channel,
rmt_buffer: [0; BUFFER_SIZE],
_pin: PhantomData,
}
}
@ -127,15 +125,9 @@ where
value: RGB8,
mut_iter: &mut IterMut<u32>,
) -> Result<(), LedAdapterError> {
SmartLedsAdapter::<CHANNEL, PIN, BUFFER_SIZE>::convert_rgb_channel_to_pulses(
value.g, mut_iter,
)?;
SmartLedsAdapter::<CHANNEL, PIN, BUFFER_SIZE>::convert_rgb_channel_to_pulses(
value.r, mut_iter,
)?;
SmartLedsAdapter::<CHANNEL, PIN, BUFFER_SIZE>::convert_rgb_channel_to_pulses(
value.b, mut_iter,
)?;
SmartLedsAdapter::<CHANNEL, BUFFER_SIZE>::convert_rgb_channel_to_pulses(value.g, mut_iter)?;
SmartLedsAdapter::<CHANNEL, BUFFER_SIZE>::convert_rgb_channel_to_pulses(value.r, mut_iter)?;
SmartLedsAdapter::<CHANNEL, BUFFER_SIZE>::convert_rgb_channel_to_pulses(value.b, mut_iter)?;
Ok(())
}
@ -168,11 +160,9 @@ where
}
}
impl<CHANNEL, PIN, const BUFFER_SIZE: usize> SmartLedsWrite
for SmartLedsAdapter<CHANNEL, PIN, BUFFER_SIZE>
impl<CHANNEL, const BUFFER_SIZE: usize> SmartLedsWrite for SmartLedsAdapter<CHANNEL, BUFFER_SIZE>
where
CHANNEL: ConfiguredChannel,
PIN: OutputPin,
{
type Error = LedAdapterError;
type Color = RGB8;
@ -192,7 +182,7 @@ where
// This will result in an `BufferSizeExceeded` error in case
// the iterator provides more elements than the buffer can take.
for item in iterator {
SmartLedsAdapter::<CHANNEL, PIN, BUFFER_SIZE>::convert_rgb_to_pulse(
SmartLedsAdapter::<CHANNEL, BUFFER_SIZE>::convert_rgb_to_pulse(
item.into(),
&mut seq_iter,
)?;

View File

@ -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 = "Procedural macros for ESP-HAL"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"

View File

@ -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 for ESP32 microcontrollers"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"

View File

@ -66,11 +66,11 @@ fn main() -> ! {
&clocks,
);
let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin {
bclk: io.pins.gpio12,
ws: io.pins.gpio13,
din: io.pins.gpio17,
});
let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin::new(
io.pins.gpio12,
io.pins.gpio13,
io.pins.gpio17,
));
let buffer = dma_buffer();

View File

@ -89,11 +89,11 @@ fn main() -> ! {
&clocks,
);
let i2s_tx = i2s.i2s_tx.with_pins(PinsBclkWsDout {
bclk: io.pins.gpio12,
ws: io.pins.gpio13,
dout: io.pins.gpio14,
});
let i2s_tx = i2s.i2s_tx.with_pins(PinsBclkWsDout::new(
io.pins.gpio12,
io.pins.gpio13,
io.pins.gpio14,
));
let data =
unsafe { core::slice::from_raw_parts(&SINE as *const _ as *const u8, SINE.len() * 2) };

View File

@ -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 for ESP32-C2 microcontrollers"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"

View File

@ -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 for ESP32-C3 microcontrollers"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"

View File

@ -57,9 +57,7 @@ fn main() -> ! {
let i2s = I2s::new(
peripherals.I2S,
MclkPin {
mclk: io.pins.gpio4,
},
MclkPin::new(io.pins.gpio4),
Standard::Philips,
DataFormat::Data16Channel16,
44100u32.Hz(),
@ -73,11 +71,11 @@ fn main() -> ! {
&clocks,
);
let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin {
bclk: io.pins.gpio1,
ws: io.pins.gpio2,
din: io.pins.gpio5,
});
let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin::new(
io.pins.gpio1,
io.pins.gpio2,
io.pins.gpio5,
));
let buffer = dma_buffer();

View File

@ -80,9 +80,7 @@ fn main() -> ! {
let i2s = I2s::new(
peripherals.I2S,
MclkPin {
mclk: io.pins.gpio4,
},
MclkPin::new(io.pins.gpio4),
Standard::Philips,
DataFormat::Data16Channel16,
44100u32.Hz(),
@ -96,11 +94,11 @@ fn main() -> ! {
&clocks,
);
let i2s_tx = i2s.i2s_tx.with_pins(PinsBclkWsDout {
bclk: io.pins.gpio1,
ws: io.pins.gpio2,
dout: io.pins.gpio3,
});
let i2s_tx = i2s.i2s_tx.with_pins(PinsBclkWsDout::new(
io.pins.gpio1,
io.pins.gpio2,
io.pins.gpio3,
));
let data =
unsafe { core::slice::from_raw_parts(&SINE as *const _ as *const u8, SINE.len() * 2) };

View File

@ -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 for ESP32-S2 microcontrollers"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"

View File

@ -66,11 +66,11 @@ fn main() -> ! {
&clocks,
);
let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin {
bclk: io.pins.gpio1,
ws: io.pins.gpio2,
din: io.pins.gpio5,
});
let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin::new(
io.pins.gpio1,
io.pins.gpio2,
io.pins.gpio5,
));
let buffer = dma_buffer();

View File

@ -76,9 +76,7 @@ fn main() -> ! {
let i2s = I2s::new(
peripherals.I2S,
MclkPin {
mclk: io.pins.gpio4,
},
MclkPin::new(io.pins.gpio4),
Standard::Philips,
DataFormat::Data16Channel16,
44100u32.Hz(),
@ -92,11 +90,11 @@ fn main() -> ! {
&clocks,
);
let i2s_tx = i2s.i2s_tx.with_pins(PinsBclkWsDout {
bclk: io.pins.gpio1,
ws: io.pins.gpio2,
dout: io.pins.gpio3,
});
let i2s_tx = i2s.i2s_tx.with_pins(PinsBclkWsDout::new(
io.pins.gpio1,
io.pins.gpio2,
io.pins.gpio3,
));
let data =
unsafe { core::slice::from_raw_parts(&SINE as *const _ as *const u8, SINE.len() * 2) };

View File

@ -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 for ESP32-S3 microcontrollers"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"

View File

@ -57,9 +57,7 @@ fn main() -> ! {
let i2s = I2s::new(
peripherals.I2S0,
MclkPin {
mclk: io.pins.gpio4,
},
MclkPin::new(io.pins.gpio4),
Standard::Philips,
DataFormat::Data16Channel16,
44100u32.Hz(),
@ -73,11 +71,11 @@ fn main() -> ! {
&clocks,
);
let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin {
bclk: io.pins.gpio1,
ws: io.pins.gpio2,
din: io.pins.gpio5,
});
let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin::new(
io.pins.gpio1,
io.pins.gpio2,
io.pins.gpio5,
));
let buffer = dma_buffer();

View File

@ -80,9 +80,7 @@ fn main() -> ! {
let i2s = I2s::new(
peripherals.I2S0,
MclkPin {
mclk: io.pins.gpio4,
},
MclkPin::new(io.pins.gpio4),
Standard::Philips,
DataFormat::Data16Channel16,
44100u32.Hz(),
@ -96,11 +94,11 @@ fn main() -> ! {
&clocks,
);
let i2s_tx = i2s.i2s_tx.with_pins(PinsBclkWsDout {
bclk: io.pins.gpio1,
ws: io.pins.gpio2,
dout: io.pins.gpio3,
});
let i2s_tx = i2s.i2s_tx.with_pins(PinsBclkWsDout::new(
io.pins.gpio1,
io.pins.gpio2,
io.pins.gpio3,
));
let data =
unsafe { core::slice::from_raw_parts(&SINE as *const _ as *const u8, SINE.len() * 2) };