mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
parent
a754e411b1
commit
d914a0301f
@ -14,11 +14,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Add burst transfer support to DMA buffers (#2336)
|
- Add burst transfer support to DMA buffers (#2336)
|
||||||
- `AnyPin` now implements `From<GpioPin<N>>`. (#2326)
|
- `AnyPin` now implements `From<GpioPin<N>>`. (#2326)
|
||||||
- Added `AnySpi` and `AnySpiDmaChannel`. (#2334)
|
- Added `AnySpi` and `AnySpiDmaChannel`. (#2334)
|
||||||
|
- Added `AnyI2s` and `AnyI2sDmaChannel`. (#2367)
|
||||||
- `Pins::steal()` to unsafely obtain GPIO. (#2335)
|
- `Pins::steal()` to unsafely obtain GPIO. (#2335)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Peripheral type erasure for SPI (#2334)
|
- Peripheral type erasure for SPI (#2334)
|
||||||
|
- Peripheral type erasure for I2S (#2367)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ You no longer have to specify the peripheral instance in the driver's type for t
|
|||||||
peripherals:
|
peripherals:
|
||||||
|
|
||||||
- SPI (both master and slave)
|
- SPI (both master and slave)
|
||||||
|
- I2S
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
-Spi<'static, SPI2, FullDuplexMode>
|
-Spi<'static, SPI2, FullDuplexMode>
|
||||||
@ -36,6 +37,9 @@ peripherals:
|
|||||||
|
|
||||||
-SpiDma<'static, SPI2, HalfDuplexMode, Blocking>
|
-SpiDma<'static, SPI2, HalfDuplexMode, Blocking>
|
||||||
+SpiDma<'static, HalfDuplexMode, Blocking>
|
+SpiDma<'static, HalfDuplexMode, Blocking>
|
||||||
|
|
||||||
|
-I2sTx<'static, I2S0, Async>
|
||||||
|
+I2sTx<'static, Async>
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that you may still specify the instance if you need to. To do this, we provide `_typed`
|
Note that you may still specify the instance if you need to. To do this, we provide `_typed`
|
||||||
|
@ -787,6 +787,15 @@ macro_rules! ImplI2sChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DmaChannelConvert<AnyI2sDmaChannel> for [<I2s $num DmaChannel>] {
|
||||||
|
fn degrade_rx(rx: I2sDmaRxChannelImpl<Self>) -> I2sDmaRxChannelImpl<AnyI2sDmaChannelInner> {
|
||||||
|
I2sDmaRxChannelImpl(rx.0.into())
|
||||||
|
}
|
||||||
|
fn degrade_tx(tx: I2sDmaTxChannelImpl<Self>) -> I2sDmaTxChannelImpl<AnyI2sDmaChannelInner> {
|
||||||
|
I2sDmaTxChannelImpl(tx.0.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[doc = concat!("Creates a channel for I2S", $num)]
|
#[doc = concat!("Creates a channel for I2S", $num)]
|
||||||
pub struct [<I2s $num DmaChannelCreator>] {}
|
pub struct [<I2s $num DmaChannelCreator>] {}
|
||||||
|
|
||||||
@ -942,3 +951,41 @@ impl PdmaChannel for AnySpiDmaChannelInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A marker for I2S-compatible type-erased DMA channels.
|
||||||
|
pub struct AnyI2sDmaChannel;
|
||||||
|
|
||||||
|
impl crate::private::Sealed for AnyI2sDmaChannel {}
|
||||||
|
|
||||||
|
impl DmaChannel for AnyI2sDmaChannel {
|
||||||
|
type Rx = I2sDmaRxChannelImpl<AnyI2sDmaChannelInner>;
|
||||||
|
type Tx = I2sDmaTxChannelImpl<AnyI2sDmaChannelInner>;
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::any_enum! {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub enum AnyI2sDmaChannelInner {
|
||||||
|
I2s0(I2s0DmaChannel),
|
||||||
|
#[cfg(i2s1)]
|
||||||
|
I2s1(I2s1DmaChannel),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::private::Sealed for AnyI2sDmaChannelInner {}
|
||||||
|
|
||||||
|
impl PdmaChannel for AnyI2sDmaChannelInner {
|
||||||
|
type RegisterBlock = I2sRegisterBlock;
|
||||||
|
|
||||||
|
delegate::delegate! {
|
||||||
|
to match self {
|
||||||
|
AnyI2sDmaChannelInner::I2s0(channel) => channel,
|
||||||
|
#[cfg(i2s1)]
|
||||||
|
AnyI2sDmaChannelInner::I2s1(channel) => channel,
|
||||||
|
} {
|
||||||
|
fn register_block(&self) -> &I2sRegisterBlock;
|
||||||
|
fn tx_waker(&self) -> &'static AtomicWaker;
|
||||||
|
fn rx_waker(&self) -> &'static AtomicWaker;
|
||||||
|
fn is_compatible_with(&self, peripheral: &impl PeripheralMarker) -> bool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -92,6 +92,7 @@ use crate::{
|
|||||||
DescriptorChain,
|
DescriptorChain,
|
||||||
DmaChannelConvert,
|
DmaChannelConvert,
|
||||||
DmaDescriptor,
|
DmaDescriptor,
|
||||||
|
DmaEligible,
|
||||||
DmaError,
|
DmaError,
|
||||||
DmaTransferRx,
|
DmaTransferRx,
|
||||||
DmaTransferRxCircular,
|
DmaTransferRxCircular,
|
||||||
@ -252,26 +253,26 @@ impl DataFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Instance of the I2S peripheral driver
|
/// Instance of the I2S peripheral driver
|
||||||
pub struct I2s<'d, T, DmaMode>
|
pub struct I2s<'d, DmaMode, T = AnyI2s>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
/// Handles the reception (RX) side of the I2S peripheral.
|
/// Handles the reception (RX) side of the I2S peripheral.
|
||||||
pub i2s_rx: RxCreator<'d, T, DmaMode>,
|
pub i2s_rx: RxCreator<'d, DmaMode, T>,
|
||||||
/// Handles the transmission (TX) side of the I2S peripheral.
|
/// Handles the transmission (TX) side of the I2S peripheral.
|
||||||
pub i2s_tx: TxCreator<'d, T, DmaMode>,
|
pub i2s_tx: TxCreator<'d, DmaMode, T>,
|
||||||
phantom: PhantomData<DmaMode>,
|
phantom: PhantomData<DmaMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> I2s<'d, T, DmaMode>
|
impl<'d, DmaMode, T> I2s<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn new_internal<CH>(
|
fn new_internal<CH>(
|
||||||
i2s: impl Peripheral<P = T> + 'd,
|
i2s: PeripheralRef<'d, T>,
|
||||||
standard: Standard,
|
standard: Standard,
|
||||||
data_format: DataFormat,
|
data_format: DataFormat,
|
||||||
sample_rate: impl Into<fugit::HertzU32>,
|
sample_rate: impl Into<fugit::HertzU32>,
|
||||||
@ -282,7 +283,6 @@ where
|
|||||||
where
|
where
|
||||||
CH: DmaChannelConvert<T::Dma>,
|
CH: DmaChannelConvert<T::Dma>,
|
||||||
{
|
{
|
||||||
crate::into_ref!(i2s);
|
|
||||||
channel.runtime_ensure_compatible(&i2s);
|
channel.runtime_ensure_compatible(&i2s);
|
||||||
// on ESP32-C3 / ESP32-S3 and later RX and TX are independent and
|
// on ESP32-C3 / ESP32-S3 and later RX and TX are independent and
|
||||||
// could be configured totally independently but for now handle all
|
// could be configured totally independently but for now handle all
|
||||||
@ -314,7 +314,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> I2s<'d, T, DmaMode>
|
impl<'d, DmaMode, T> I2s<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -352,14 +352,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, I, DmaMode> crate::private::Sealed for I2s<'d, I, DmaMode>
|
impl<'d, DmaMode, I> crate::private::Sealed for I2s<'d, DmaMode, I>
|
||||||
where
|
where
|
||||||
I: RegisterAccess,
|
I: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, I, DmaMode> InterruptConfigurable for I2s<'d, I, DmaMode>
|
impl<'d, DmaMode, I> InterruptConfigurable for I2s<'d, DmaMode, I>
|
||||||
where
|
where
|
||||||
I: RegisterAccess,
|
I: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -369,7 +369,38 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> I2s<'d, T, DmaMode>
|
impl<'d, DmaMode> I2s<'d, DmaMode>
|
||||||
|
where
|
||||||
|
DmaMode: Mode,
|
||||||
|
{
|
||||||
|
/// Construct a new I2S peripheral driver instance for the first I2S
|
||||||
|
/// peripheral
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn new<CH>(
|
||||||
|
i2s: impl Peripheral<P = impl RegisterAccess> + 'd,
|
||||||
|
standard: Standard,
|
||||||
|
data_format: DataFormat,
|
||||||
|
sample_rate: impl Into<fugit::HertzU32>,
|
||||||
|
channel: Channel<'d, CH, DmaMode>,
|
||||||
|
rx_descriptors: &'static mut [DmaDescriptor],
|
||||||
|
tx_descriptors: &'static mut [DmaDescriptor],
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
CH: DmaChannelConvert<<AnyI2s as DmaEligible>::Dma>,
|
||||||
|
{
|
||||||
|
Self::new_typed(
|
||||||
|
i2s.map_into(),
|
||||||
|
standard,
|
||||||
|
data_format,
|
||||||
|
sample_rate,
|
||||||
|
channel,
|
||||||
|
rx_descriptors,
|
||||||
|
tx_descriptors,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, DmaMode, T> I2s<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -377,7 +408,7 @@ where
|
|||||||
/// Construct a new I2S peripheral driver instance for the first I2S
|
/// Construct a new I2S peripheral driver instance for the first I2S
|
||||||
/// peripheral
|
/// peripheral
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new<CH>(
|
pub fn new_typed<CH>(
|
||||||
i2s: impl Peripheral<P = T> + 'd,
|
i2s: impl Peripheral<P = T> + 'd,
|
||||||
standard: Standard,
|
standard: Standard,
|
||||||
data_format: DataFormat,
|
data_format: DataFormat,
|
||||||
@ -388,8 +419,8 @@ where
|
|||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<T::Dma>,
|
CH: DmaChannelConvert<T::Dma>,
|
||||||
DmaMode: Mode,
|
|
||||||
{
|
{
|
||||||
|
crate::into_ref!(i2s);
|
||||||
Self::new_internal(
|
Self::new_internal(
|
||||||
i2s,
|
i2s,
|
||||||
standard,
|
standard,
|
||||||
@ -412,7 +443,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// I2S TX channel
|
/// I2S TX channel
|
||||||
pub struct I2sTx<'d, T, DmaMode>
|
pub struct I2sTx<'d, DmaMode, T = AnyI2s>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
@ -422,7 +453,7 @@ where
|
|||||||
phantom: PhantomData<DmaMode>,
|
phantom: PhantomData<DmaMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> core::fmt::Debug for I2sTx<'d, T, DmaMode>
|
impl<'d, DmaMode, T> core::fmt::Debug for I2sTx<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -432,7 +463,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> DmaSupport for I2sTx<'d, T, DmaMode>
|
impl<'d, DmaMode, T> DmaSupport for I2sTx<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -446,7 +477,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> DmaSupportTx for I2sTx<'d, T, DmaMode>
|
impl<'d, DmaMode, T> DmaSupportTx for I2sTx<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -462,7 +493,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> I2sTx<'d, T, DmaMode>
|
impl<'d, DmaMode, T> I2sTx<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -544,7 +575,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// I2S RX channel
|
/// I2S RX channel
|
||||||
pub struct I2sRx<'d, T, DmaMode>
|
pub struct I2sRx<'d, DmaMode, T = AnyI2s>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -555,7 +586,7 @@ where
|
|||||||
phantom: PhantomData<DmaMode>,
|
phantom: PhantomData<DmaMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> core::fmt::Debug for I2sRx<'d, T, DmaMode>
|
impl<'d, DmaMode, T> core::fmt::Debug for I2sRx<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -565,7 +596,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> DmaSupport for I2sRx<'d, T, DmaMode>
|
impl<'d, DmaMode, T> DmaSupport for I2sRx<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -579,7 +610,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> DmaSupportRx for I2sRx<'d, T, DmaMode>
|
impl<'d, DmaMode, T> DmaSupportRx for I2sRx<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -595,7 +626,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> I2sRx<'d, T, DmaMode>
|
impl<'d, DmaMode, T> I2sRx<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -728,7 +759,7 @@ mod private {
|
|||||||
Mode,
|
Mode,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TxCreator<'d, T, DmaMode>
|
pub struct TxCreator<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -739,12 +770,12 @@ mod private {
|
|||||||
pub(crate) phantom: PhantomData<DmaMode>,
|
pub(crate) phantom: PhantomData<DmaMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> TxCreator<'d, T, DmaMode>
|
impl<'d, DmaMode, T> TxCreator<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
pub fn build(self) -> I2sTx<'d, T, DmaMode> {
|
pub fn build(self) -> I2sTx<'d, DmaMode, T> {
|
||||||
I2sTx {
|
I2sTx {
|
||||||
i2s: self.i2s,
|
i2s: self.i2s,
|
||||||
tx_channel: self.tx_channel,
|
tx_channel: self.tx_channel,
|
||||||
@ -787,7 +818,7 @@ mod private {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RxCreator<'d, T, DmaMode>
|
pub struct RxCreator<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -798,12 +829,12 @@ mod private {
|
|||||||
pub(crate) phantom: PhantomData<DmaMode>,
|
pub(crate) phantom: PhantomData<DmaMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, DmaMode> RxCreator<'d, T, DmaMode>
|
impl<'d, DmaMode, T> RxCreator<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
pub fn build(self) -> I2sRx<'d, T, DmaMode> {
|
pub fn build(self) -> I2sRx<'d, DmaMode, T> {
|
||||||
I2sRx {
|
I2sRx {
|
||||||
i2s: self.i2s,
|
i2s: self.i2s,
|
||||||
rx_channel: self.rx_channel,
|
rx_channel: self.rx_channel,
|
||||||
@ -847,7 +878,11 @@ mod private {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait RegBlock:
|
pub trait RegBlock:
|
||||||
crate::peripheral::Peripheral<P = Self> + PeripheralMarker + DmaEligible
|
crate::peripheral::Peripheral<P = Self>
|
||||||
|
+ PeripheralMarker
|
||||||
|
+ DmaEligible
|
||||||
|
+ Into<super::AnyI2s>
|
||||||
|
+ 'static
|
||||||
{
|
{
|
||||||
fn register_block(&self) -> &RegisterBlock;
|
fn register_block(&self) -> &RegisterBlock;
|
||||||
}
|
}
|
||||||
@ -1559,7 +1594,6 @@ mod private {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(i2s0)]
|
|
||||||
impl Signals for crate::peripherals::I2S0 {
|
impl Signals for crate::peripherals::I2S0 {
|
||||||
fn mclk_signal(&self) -> OutputSignal {
|
fn mclk_signal(&self) -> OutputSignal {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
@ -1709,6 +1743,48 @@ mod private {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RegBlock for super::AnyI2s {
|
||||||
|
delegate::delegate! {
|
||||||
|
to match &self.0 {
|
||||||
|
super::AnyI2sInner::I2s0(i2s) => i2s,
|
||||||
|
#[cfg(i2s1)]
|
||||||
|
super::AnyI2sInner::I2s1(i2s) => i2s,
|
||||||
|
} {
|
||||||
|
fn register_block(&self) -> &RegisterBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegisterAccessPrivate for super::AnyI2s {
|
||||||
|
delegate::delegate! {
|
||||||
|
to match &self.0 {
|
||||||
|
super::AnyI2sInner::I2s0(i2s) => i2s,
|
||||||
|
#[cfg(i2s1)]
|
||||||
|
super::AnyI2sInner::I2s1(i2s) => i2s,
|
||||||
|
} {
|
||||||
|
fn set_interrupt_handler(&self, handler: InterruptHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Signals for super::AnyI2s {
|
||||||
|
delegate::delegate! {
|
||||||
|
to match &self.0 {
|
||||||
|
super::AnyI2sInner::I2s0(i2s) => i2s,
|
||||||
|
#[cfg(i2s1)]
|
||||||
|
super::AnyI2sInner::I2s1(i2s) => i2s,
|
||||||
|
} {
|
||||||
|
fn mclk_signal(&self) -> OutputSignal;
|
||||||
|
fn bclk_signal(&self) -> OutputSignal;
|
||||||
|
fn ws_signal(&self) -> OutputSignal;
|
||||||
|
fn dout_signal(&self) -> OutputSignal;
|
||||||
|
fn bclk_rx_signal(&self) -> OutputSignal;
|
||||||
|
fn ws_rx_signal(&self) -> OutputSignal;
|
||||||
|
fn din_signal(&self) -> InputSignal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct I2sClockDividers {
|
pub struct I2sClockDividers {
|
||||||
mclk_divider: u32,
|
mclk_divider: u32,
|
||||||
bclk_divider: u32,
|
bclk_divider: u32,
|
||||||
@ -1801,7 +1877,7 @@ pub mod asynch {
|
|||||||
Async,
|
Async,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'d, T> I2sTx<'d, T, Async>
|
impl<'d, T> I2sTx<'d, Async, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
@ -1831,7 +1907,7 @@ pub mod asynch {
|
|||||||
pub fn write_dma_circular_async<TXBUF: ReadBuffer>(
|
pub fn write_dma_circular_async<TXBUF: ReadBuffer>(
|
||||||
mut self,
|
mut self,
|
||||||
words: TXBUF,
|
words: TXBUF,
|
||||||
) -> Result<I2sWriteDmaTransferAsync<'d, T, TXBUF>, Error> {
|
) -> Result<I2sWriteDmaTransferAsync<'d, TXBUF, T>, Error> {
|
||||||
let (ptr, len) = unsafe { words.read_buffer() };
|
let (ptr, len) = unsafe { words.read_buffer() };
|
||||||
|
|
||||||
// Reset TX unit and TX FIFO
|
// Reset TX unit and TX FIFO
|
||||||
@ -1862,16 +1938,16 @@ pub mod asynch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An in-progress async circular DMA write transfer.
|
/// An in-progress async circular DMA write transfer.
|
||||||
pub struct I2sWriteDmaTransferAsync<'d, T, BUFFER>
|
pub struct I2sWriteDmaTransferAsync<'d, BUFFER, T = super::AnyI2s>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
i2s_tx: I2sTx<'d, T, Async>,
|
i2s_tx: I2sTx<'d, Async, T>,
|
||||||
state: TxCircularState,
|
state: TxCircularState,
|
||||||
_buffer: BUFFER,
|
_buffer: BUFFER,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, BUFFER> I2sWriteDmaTransferAsync<'d, T, BUFFER>
|
impl<'d, T, BUFFER> I2sWriteDmaTransferAsync<'d, BUFFER, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
@ -1911,7 +1987,7 @@ pub mod asynch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T> I2sRx<'d, T, Async>
|
impl<'d, T> I2sRx<'d, Async, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
@ -1949,7 +2025,7 @@ pub mod asynch {
|
|||||||
pub fn read_dma_circular_async<RXBUF>(
|
pub fn read_dma_circular_async<RXBUF>(
|
||||||
mut self,
|
mut self,
|
||||||
mut words: RXBUF,
|
mut words: RXBUF,
|
||||||
) -> Result<I2sReadDmaTransferAsync<'d, T, RXBUF>, Error>
|
) -> Result<I2sReadDmaTransferAsync<'d, RXBUF, T>, Error>
|
||||||
where
|
where
|
||||||
RXBUF: WriteBuffer,
|
RXBUF: WriteBuffer,
|
||||||
{
|
{
|
||||||
@ -1985,16 +2061,16 @@ pub mod asynch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An in-progress async circular DMA read transfer.
|
/// An in-progress async circular DMA read transfer.
|
||||||
pub struct I2sReadDmaTransferAsync<'d, T, BUFFER>
|
pub struct I2sReadDmaTransferAsync<'d, BUFFER, T = super::AnyI2s>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
i2s_rx: I2sRx<'d, T, Async>,
|
i2s_rx: I2sRx<'d, Async, T>,
|
||||||
state: RxCircularState,
|
state: RxCircularState,
|
||||||
_buffer: BUFFER,
|
_buffer: BUFFER,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, BUFFER> I2sReadDmaTransferAsync<'d, T, BUFFER>
|
impl<'d, T, BUFFER> I2sReadDmaTransferAsync<'d, BUFFER, T>
|
||||||
where
|
where
|
||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
@ -2022,3 +2098,28 @@ pub mod asynch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate::any_peripheral! {
|
||||||
|
/// Any SPI peripheral.
|
||||||
|
pub peripheral AnyI2s {
|
||||||
|
#[cfg(i2s0)]
|
||||||
|
I2s0(crate::peripherals::I2S0),
|
||||||
|
#[cfg(i2s1)]
|
||||||
|
I2s1(crate::peripherals::I2S1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DmaEligible for AnyI2s {
|
||||||
|
#[cfg(gdma)]
|
||||||
|
type Dma = crate::dma::AnyGdmaChannel;
|
||||||
|
#[cfg(pdma)]
|
||||||
|
type Dma = crate::dma::AnyI2sDmaChannel;
|
||||||
|
|
||||||
|
fn dma_peripheral(&self) -> crate::dma::DmaPeripheral {
|
||||||
|
match &self.0 {
|
||||||
|
AnyI2sInner::I2s0(_) => crate::dma::DmaPeripheral::I2s0,
|
||||||
|
#[cfg(i2s1)]
|
||||||
|
AnyI2sInner::I2s1(_) => crate::dma::DmaPeripheral::I2s1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -463,14 +463,14 @@ where
|
|||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
fn new_internal(
|
fn new_internal(
|
||||||
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
spi: impl Peripheral<P = T> + 'd,
|
||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, M, T> {
|
) -> Spi<'d, M, T> {
|
||||||
crate::into_ref!(spi);
|
crate::into_ref!(spi);
|
||||||
|
|
||||||
let mut spi = Spi {
|
let mut spi = Spi {
|
||||||
spi: spi.map_into(),
|
spi,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
};
|
};
|
||||||
spi.spi.reset_peripheral();
|
spi.spi.reset_peripheral();
|
||||||
@ -571,11 +571,11 @@ impl<'d> Spi<'d, FullDuplexMode> {
|
|||||||
/// All pins are optional. Setup these pins using
|
/// All pins are optional. Setup these pins using
|
||||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
spi: impl Peripheral<P = impl Into<AnySpi> + 'd> + 'd,
|
spi: impl Peripheral<P = impl Instance> + 'd,
|
||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, FullDuplexMode> {
|
) -> Spi<'d, FullDuplexMode> {
|
||||||
Self::new_typed(spi, frequency, mode)
|
Self::new_typed(spi.map_into(), frequency, mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +588,7 @@ where
|
|||||||
/// All pins are optional. Setup these pins using
|
/// All pins are optional. Setup these pins using
|
||||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||||
pub fn new_typed(
|
pub fn new_typed(
|
||||||
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
spi: impl Peripheral<P = T> + 'd,
|
||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, FullDuplexMode, T> {
|
) -> Spi<'d, FullDuplexMode, T> {
|
||||||
@ -666,11 +666,11 @@ impl<'d> Spi<'d, HalfDuplexMode> {
|
|||||||
/// All pins are optional. Setup these pins using
|
/// All pins are optional. Setup these pins using
|
||||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||||
pub fn new_half_duplex(
|
pub fn new_half_duplex(
|
||||||
spi: impl Peripheral<P = impl Into<AnySpi> + 'd> + 'd,
|
spi: impl Peripheral<P = impl Instance> + 'd,
|
||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, HalfDuplexMode> {
|
) -> Spi<'d, HalfDuplexMode> {
|
||||||
Self::new_half_duplex_typed(spi, frequency, mode)
|
Self::new_half_duplex_typed(spi.map_into(), frequency, mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,7 +683,7 @@ where
|
|||||||
/// All pins are optional. Setup these pins using
|
/// All pins are optional. Setup these pins using
|
||||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||||
pub fn new_half_duplex_typed(
|
pub fn new_half_duplex_typed(
|
||||||
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
spi: impl Peripheral<P = T> + 'd,
|
||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, HalfDuplexMode, T> {
|
) -> Spi<'d, HalfDuplexMode, T> {
|
||||||
@ -2372,7 +2372,7 @@ pub trait ExtendedInstance: Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait Instance: private::Sealed + PeripheralMarker {
|
pub trait Instance: private::Sealed + PeripheralMarker + Into<AnySpi> + 'static {
|
||||||
fn register_block(&self) -> &RegisterBlock;
|
fn register_block(&self) -> &RegisterBlock;
|
||||||
|
|
||||||
fn sclk_signal(&self) -> OutputSignal;
|
fn sclk_signal(&self) -> OutputSignal;
|
||||||
|
@ -57,7 +57,7 @@ impl Iterator for SampleSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn writer(tx_buffer: &'static mut [u8], i2s_tx: I2sTx<'static, I2S0, Async>) {
|
async fn writer(tx_buffer: &'static mut [u8], i2s_tx: I2sTx<'static, Async>) {
|
||||||
let mut samples = SampleSource::new();
|
let mut samples = SampleSource::new();
|
||||||
for b in tx_buffer.iter_mut() {
|
for b in tx_buffer.iter_mut() {
|
||||||
*b = samples.next().unwrap();
|
*b = samples.next().unwrap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user