Merge pull request #2310 from embassy-rs/stm32-docs
stm32/sai: docs, cleanup api.
This commit is contained in:
		@@ -354,7 +354,11 @@ unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteRe
 | 
				
			|||||||
    WriteResult::Written
 | 
					    WriteResult::Written
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Initialize peripherals with the provided configuration. This should only be called once at startup.
 | 
					/// Initialize the `embassy-nrf` HAL with the provided configuration.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// This returns the peripheral singletons that can be used for creating drivers.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// This should only be called once at startup, otherwise it panics.
 | 
				
			||||||
pub fn init(config: config::Config) -> Peripherals {
 | 
					pub fn init(config: config::Config) -> Peripherals {
 | 
				
			||||||
    // Do this first, so that it panics if user is calling `init` a second time
 | 
					    // Do this first, so that it panics if user is calling `init` a second time
 | 
				
			||||||
    // before doing anything important.
 | 
					    // before doing anything important.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -672,14 +672,14 @@ fn main() {
 | 
				
			|||||||
        (("lpuart", "RTS"), quote!(crate::usart::RtsPin)),
 | 
					        (("lpuart", "RTS"), quote!(crate::usart::RtsPin)),
 | 
				
			||||||
        (("lpuart", "CK"), quote!(crate::usart::CkPin)),
 | 
					        (("lpuart", "CK"), quote!(crate::usart::CkPin)),
 | 
				
			||||||
        (("lpuart", "DE"), quote!(crate::usart::DePin)),
 | 
					        (("lpuart", "DE"), quote!(crate::usart::DePin)),
 | 
				
			||||||
        (("sai", "SCK_A"), quote!(crate::sai::SckAPin)),
 | 
					        (("sai", "SCK_A"), quote!(crate::sai::SckPin<A>)),
 | 
				
			||||||
        (("sai", "SCK_B"), quote!(crate::sai::SckBPin)),
 | 
					        (("sai", "SCK_B"), quote!(crate::sai::SckPin<B>)),
 | 
				
			||||||
        (("sai", "FS_A"), quote!(crate::sai::FsAPin)),
 | 
					        (("sai", "FS_A"), quote!(crate::sai::FsPin<A>)),
 | 
				
			||||||
        (("sai", "FS_B"), quote!(crate::sai::FsBPin)),
 | 
					        (("sai", "FS_B"), quote!(crate::sai::FsPin<B>)),
 | 
				
			||||||
        (("sai", "SD_A"), quote!(crate::sai::SdAPin)),
 | 
					        (("sai", "SD_A"), quote!(crate::sai::SdPin<A>)),
 | 
				
			||||||
        (("sai", "SD_B"), quote!(crate::sai::SdBPin)),
 | 
					        (("sai", "SD_B"), quote!(crate::sai::SdPin<B>)),
 | 
				
			||||||
        (("sai", "MCLK_A"), quote!(crate::sai::MclkAPin)),
 | 
					        (("sai", "MCLK_A"), quote!(crate::sai::MclkPin<A>)),
 | 
				
			||||||
        (("sai", "MCLK_B"), quote!(crate::sai::MclkBPin)),
 | 
					        (("sai", "MCLK_B"), quote!(crate::sai::MclkPin<B>)),
 | 
				
			||||||
        (("sai", "WS"), quote!(crate::sai::WsPin)),
 | 
					        (("sai", "WS"), quote!(crate::sai::WsPin)),
 | 
				
			||||||
        (("spi", "SCK"), quote!(crate::spi::SckPin)),
 | 
					        (("spi", "SCK"), quote!(crate::spi::SckPin)),
 | 
				
			||||||
        (("spi", "MOSI"), quote!(crate::spi::MosiPin)),
 | 
					        (("spi", "MOSI"), quote!(crate::spi::MosiPin)),
 | 
				
			||||||
@@ -995,8 +995,8 @@ fn main() {
 | 
				
			|||||||
        (("usart", "TX"), quote!(crate::usart::TxDma)),
 | 
					        (("usart", "TX"), quote!(crate::usart::TxDma)),
 | 
				
			||||||
        (("lpuart", "RX"), quote!(crate::usart::RxDma)),
 | 
					        (("lpuart", "RX"), quote!(crate::usart::RxDma)),
 | 
				
			||||||
        (("lpuart", "TX"), quote!(crate::usart::TxDma)),
 | 
					        (("lpuart", "TX"), quote!(crate::usart::TxDma)),
 | 
				
			||||||
        (("sai", "A"), quote!(crate::sai::DmaA)),
 | 
					        (("sai", "A"), quote!(crate::sai::Dma<A>)),
 | 
				
			||||||
        (("sai", "B"), quote!(crate::sai::DmaB)),
 | 
					        (("sai", "B"), quote!(crate::sai::Dma<B>)),
 | 
				
			||||||
        (("spi", "RX"), quote!(crate::spi::RxDma)),
 | 
					        (("spi", "RX"), quote!(crate::spi::RxDma)),
 | 
				
			||||||
        (("spi", "TX"), quote!(crate::spi::TxDma)),
 | 
					        (("spi", "TX"), quote!(crate::spi::TxDma)),
 | 
				
			||||||
        (("i2c", "RX"), quote!(crate::i2c::RxDma)),
 | 
					        (("i2c", "RX"), quote!(crate::i2c::RxDma)),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
//! Analog to Digital (ADC) converter driver.
 | 
					//! Analog to Digital Converter (ADC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
#![allow(missing_docs)] // TODO
 | 
					#![allow(missing_docs)] // TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Controller Area Network (CAN)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg_attr(can_bxcan, path = "bxcan.rs")]
 | 
					#[cfg_attr(can_bxcan, path = "bxcan.rs")]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Cyclic Redundancy Check (CRC)
 | 
				
			||||||
#[cfg_attr(crc_v1, path = "v1.rs")]
 | 
					#[cfg_attr(crc_v1, path = "v1.rs")]
 | 
				
			||||||
#[cfg_attr(crc_v2, path = "v2v3.rs")]
 | 
					#[cfg_attr(crc_v2, path = "v2v3.rs")]
 | 
				
			||||||
#[cfg_attr(crc_v3, path = "v2v3.rs")]
 | 
					#[cfg_attr(crc_v3, path = "v2v3.rs")]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
//! Provide access to the STM32 digital-to-analog converter (DAC).
 | 
					//! Digital to Analog Converter (DAC)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Digital Camera Interface (DCMI)
 | 
				
			||||||
use core::future::poll_fn;
 | 
					use core::future::poll_fn;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::task::Poll;
 | 
					use core::task::Poll;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Ethernet (ETH)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")]
 | 
					#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! External Interrupts (EXTI)
 | 
				
			||||||
use core::convert::Infallible;
 | 
					use core::convert::Infallible;
 | 
				
			||||||
use core::future::Future;
 | 
					use core::future::Future;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Flash memory (FLASH)
 | 
				
			||||||
use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind};
 | 
					use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(flash_f4)]
 | 
					#[cfg(flash_f4)]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Flexible Memory Controller (FMC) / Flexible Static Memory Controller (FSMC)
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_hal_internal::into_ref;
 | 
					use embassy_hal_internal::into_ref;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					//! High Resolution Timer (HRTIM)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod traits;
 | 
					mod traits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Inter-Integrated-Circuit (I2C)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg_attr(i2c_v1, path = "v1.rs")]
 | 
					#[cfg_attr(i2c_v1, path = "v1.rs")]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Inter-IC Sound (I2S)
 | 
				
			||||||
use embassy_hal_internal::into_ref;
 | 
					use embassy_hal_internal::into_ref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::gpio::sealed::{AFType, Pin as _};
 | 
					use crate::gpio::sealed::{AFType, Pin as _};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -149,15 +149,33 @@ use crate::interrupt::Priority;
 | 
				
			|||||||
pub use crate::pac::NVIC_PRIO_BITS;
 | 
					pub use crate::pac::NVIC_PRIO_BITS;
 | 
				
			||||||
use crate::rcc::sealed::RccPeripheral;
 | 
					use crate::rcc::sealed::RccPeripheral;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// `embassy-stm32` global configuration.
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
pub struct Config {
 | 
					pub struct Config {
 | 
				
			||||||
 | 
					    /// RCC config.
 | 
				
			||||||
    pub rcc: rcc::Config,
 | 
					    pub rcc: rcc::Config,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Enable debug during sleep.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// May incrase power consumption. Defaults to true.
 | 
				
			||||||
    #[cfg(dbgmcu)]
 | 
					    #[cfg(dbgmcu)]
 | 
				
			||||||
    pub enable_debug_during_sleep: bool,
 | 
					    pub enable_debug_during_sleep: bool,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// BDMA interrupt priority.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// Defaults to P0 (highest).
 | 
				
			||||||
    #[cfg(bdma)]
 | 
					    #[cfg(bdma)]
 | 
				
			||||||
    pub bdma_interrupt_priority: Priority,
 | 
					    pub bdma_interrupt_priority: Priority,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// DMA interrupt priority.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// Defaults to P0 (highest).
 | 
				
			||||||
    #[cfg(dma)]
 | 
					    #[cfg(dma)]
 | 
				
			||||||
    pub dma_interrupt_priority: Priority,
 | 
					    pub dma_interrupt_priority: Priority,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// GPDMA interrupt priority.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// Defaults to P0 (highest).
 | 
				
			||||||
    #[cfg(gpdma)]
 | 
					    #[cfg(gpdma)]
 | 
				
			||||||
    pub gpdma_interrupt_priority: Priority,
 | 
					    pub gpdma_interrupt_priority: Priority,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -178,7 +196,11 @@ impl Default for Config {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Initialize embassy.
 | 
					/// Initialize the `embassy-stm32` HAL with the provided configuration.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// This returns the peripheral singletons that can be used for creating drivers.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// This should only be called once at startup, otherwise it panics.
 | 
				
			||||||
pub fn init(config: Config) -> Peripherals {
 | 
					pub fn init(config: Config) -> Peripherals {
 | 
				
			||||||
    critical_section::with(|cs| {
 | 
					    critical_section::with(|cs| {
 | 
				
			||||||
        let p = Peripherals::take_with_cs(cs);
 | 
					        let p = Peripherals::take_with_cs(cs);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					//! Quad Serial Peripheral Interface (QSPI)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod enums;
 | 
					pub mod enums;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Random Number Generator (RNG)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::future::poll_fn;
 | 
					use core::future::poll_fn;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
//! RTC peripheral abstraction
 | 
					//! Real Time Clock (RTC)
 | 
				
			||||||
mod datetime;
 | 
					mod datetime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "low-power")]
 | 
					#[cfg(feature = "low-power")]
 | 
				
			||||||
@@ -163,7 +163,7 @@ impl RtcTimeProvider {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// RTC Abstraction
 | 
					/// RTC driver.
 | 
				
			||||||
pub struct Rtc {
 | 
					pub struct Rtc {
 | 
				
			||||||
    #[cfg(feature = "low-power")]
 | 
					    #[cfg(feature = "low-power")]
 | 
				
			||||||
    stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>,
 | 
					    stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,11 @@
 | 
				
			|||||||
 | 
					//! Serial Audio Interface (SAI)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_embedded_hal::SetConfig;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
 | 
					use embassy_hal_internal::{into_ref, PeripheralRef};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use self::sealed::WhichSubBlock;
 | 
				
			||||||
pub use crate::dma::word;
 | 
					pub use crate::dma::word;
 | 
				
			||||||
use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer};
 | 
					use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer};
 | 
				
			||||||
use crate::gpio::sealed::{AFType, Pin as _};
 | 
					use crate::gpio::sealed::{AFType, Pin as _};
 | 
				
			||||||
@@ -11,48 +14,32 @@ use crate::pac::sai::{vals, Sai as Regs};
 | 
				
			|||||||
use crate::rcc::RccPeripheral;
 | 
					use crate::rcc::RccPeripheral;
 | 
				
			||||||
use crate::{peripherals, Peripheral};
 | 
					use crate::{peripherals, Peripheral};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SAI error
 | 
				
			||||||
#[derive(Debug, PartialEq, Eq)]
 | 
					#[derive(Debug, PartialEq, Eq)]
 | 
				
			||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
					#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
				
			||||||
pub enum Error {
 | 
					pub enum Error {
 | 
				
			||||||
 | 
					    /// `write` called on a SAI in receive mode.
 | 
				
			||||||
    NotATransmitter,
 | 
					    NotATransmitter,
 | 
				
			||||||
 | 
					    /// `read` called on a SAI in transmit mode.
 | 
				
			||||||
    NotAReceiver,
 | 
					    NotAReceiver,
 | 
				
			||||||
    OverrunError,
 | 
					    /// Overrun
 | 
				
			||||||
 | 
					    Overrun,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<ringbuffer::OverrunError> for Error {
 | 
					impl From<ringbuffer::OverrunError> for Error {
 | 
				
			||||||
    fn from(_: ringbuffer::OverrunError) -> Self {
 | 
					    fn from(_: ringbuffer::OverrunError) -> Self {
 | 
				
			||||||
        Self::OverrunError
 | 
					        Self::Overrun
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Master/slave mode.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
pub enum SyncBlock {
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
    None,
 | 
					 | 
				
			||||||
    Sai1BlockA,
 | 
					 | 
				
			||||||
    Sai1BlockB,
 | 
					 | 
				
			||||||
    Sai2BlockA,
 | 
					 | 
				
			||||||
    Sai2BlockB,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					 | 
				
			||||||
pub enum SyncIn {
 | 
					 | 
				
			||||||
    None,
 | 
					 | 
				
			||||||
    ChannelZero,
 | 
					 | 
				
			||||||
    ChannelOne,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					 | 
				
			||||||
pub enum Mode {
 | 
					pub enum Mode {
 | 
				
			||||||
    Master,
 | 
					    Master,
 | 
				
			||||||
    Slave,
 | 
					    Slave,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					 | 
				
			||||||
pub enum TxRx {
 | 
					 | 
				
			||||||
    Transmitter,
 | 
					 | 
				
			||||||
    Receiver,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Mode {
 | 
					impl Mode {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    const fn mode(&self, tx_rx: TxRx) -> vals::Mode {
 | 
					    const fn mode(&self, tx_rx: TxRx) -> vals::Mode {
 | 
				
			||||||
@@ -69,7 +56,17 @@ impl Mode {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Direction: transmit or receive
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
 | 
					pub enum TxRx {
 | 
				
			||||||
 | 
					    Transmitter,
 | 
				
			||||||
 | 
					    Receiver,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Data slot size.
 | 
				
			||||||
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum SlotSize {
 | 
					pub enum SlotSize {
 | 
				
			||||||
    DataSize,
 | 
					    DataSize,
 | 
				
			||||||
    /// 16 bit data length on 16 bit wide channel
 | 
					    /// 16 bit data length on 16 bit wide channel
 | 
				
			||||||
@@ -80,7 +77,7 @@ pub enum SlotSize {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl SlotSize {
 | 
					impl SlotSize {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn slotsz(&self) -> vals::Slotsz {
 | 
					    const fn slotsz(&self) -> vals::Slotsz {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            SlotSize::DataSize => vals::Slotsz::DATASIZE,
 | 
					            SlotSize::DataSize => vals::Slotsz::DATASIZE,
 | 
				
			||||||
            SlotSize::Channel16 => vals::Slotsz::BIT16,
 | 
					            SlotSize::Channel16 => vals::Slotsz::BIT16,
 | 
				
			||||||
@@ -89,7 +86,9 @@ impl SlotSize {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Data size.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum DataSize {
 | 
					pub enum DataSize {
 | 
				
			||||||
    Data8,
 | 
					    Data8,
 | 
				
			||||||
    Data10,
 | 
					    Data10,
 | 
				
			||||||
@@ -101,7 +100,7 @@ pub enum DataSize {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl DataSize {
 | 
					impl DataSize {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn ds(&self) -> vals::Ds {
 | 
					    const fn ds(&self) -> vals::Ds {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            DataSize::Data8 => vals::Ds::BIT8,
 | 
					            DataSize::Data8 => vals::Ds::BIT8,
 | 
				
			||||||
            DataSize::Data10 => vals::Ds::BIT10,
 | 
					            DataSize::Data10 => vals::Ds::BIT10,
 | 
				
			||||||
@@ -113,7 +112,9 @@ impl DataSize {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// FIFO threshold level.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum FifoThreshold {
 | 
					pub enum FifoThreshold {
 | 
				
			||||||
    Empty,
 | 
					    Empty,
 | 
				
			||||||
    Quarter,
 | 
					    Quarter,
 | 
				
			||||||
@@ -124,7 +125,7 @@ pub enum FifoThreshold {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl FifoThreshold {
 | 
					impl FifoThreshold {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn fth(&self) -> vals::Fth {
 | 
					    const fn fth(&self) -> vals::Fth {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            FifoThreshold::Empty => vals::Fth::EMPTY,
 | 
					            FifoThreshold::Empty => vals::Fth::EMPTY,
 | 
				
			||||||
            FifoThreshold::Quarter => vals::Fth::QUARTER1,
 | 
					            FifoThreshold::Quarter => vals::Fth::QUARTER1,
 | 
				
			||||||
@@ -135,38 +136,9 @@ impl FifoThreshold {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Output value on mute.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
pub enum FifoLevel {
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
    Empty,
 | 
					 | 
				
			||||||
    FirstQuarter,
 | 
					 | 
				
			||||||
    SecondQuarter,
 | 
					 | 
				
			||||||
    ThirdQuarter,
 | 
					 | 
				
			||||||
    FourthQuarter,
 | 
					 | 
				
			||||||
    Full,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					 | 
				
			||||||
impl From<vals::Flvl> for FifoLevel {
 | 
					 | 
				
			||||||
    fn from(flvl: vals::Flvl) -> Self {
 | 
					 | 
				
			||||||
        match flvl {
 | 
					 | 
				
			||||||
            vals::Flvl::EMPTY => FifoLevel::Empty,
 | 
					 | 
				
			||||||
            vals::Flvl::QUARTER1 => FifoLevel::FirstQuarter,
 | 
					 | 
				
			||||||
            vals::Flvl::QUARTER2 => FifoLevel::SecondQuarter,
 | 
					 | 
				
			||||||
            vals::Flvl::QUARTER3 => FifoLevel::ThirdQuarter,
 | 
					 | 
				
			||||||
            vals::Flvl::QUARTER4 => FifoLevel::FourthQuarter,
 | 
					 | 
				
			||||||
            vals::Flvl::FULL => FifoLevel::Full,
 | 
					 | 
				
			||||||
            _ => FifoLevel::Empty,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					 | 
				
			||||||
pub enum MuteDetection {
 | 
					 | 
				
			||||||
    NoMute,
 | 
					 | 
				
			||||||
    Mute,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					 | 
				
			||||||
pub enum MuteValue {
 | 
					pub enum MuteValue {
 | 
				
			||||||
    Zero,
 | 
					    Zero,
 | 
				
			||||||
    LastValue,
 | 
					    LastValue,
 | 
				
			||||||
@@ -174,7 +146,7 @@ pub enum MuteValue {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl MuteValue {
 | 
					impl MuteValue {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn muteval(&self) -> vals::Muteval {
 | 
					    const fn muteval(&self) -> vals::Muteval {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            MuteValue::Zero => vals::Muteval::SENDZERO,
 | 
					            MuteValue::Zero => vals::Muteval::SENDZERO,
 | 
				
			||||||
            MuteValue::LastValue => vals::Muteval::SENDLAST,
 | 
					            MuteValue::LastValue => vals::Muteval::SENDLAST,
 | 
				
			||||||
@@ -182,13 +154,9 @@ impl MuteValue {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Protocol variant to use.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
pub enum OverUnderStatus {
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
    NoError,
 | 
					 | 
				
			||||||
    OverUnderRunDetected,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					 | 
				
			||||||
pub enum Protocol {
 | 
					pub enum Protocol {
 | 
				
			||||||
    Free,
 | 
					    Free,
 | 
				
			||||||
    Spdif,
 | 
					    Spdif,
 | 
				
			||||||
@@ -197,7 +165,7 @@ pub enum Protocol {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl Protocol {
 | 
					impl Protocol {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn prtcfg(&self) -> vals::Prtcfg {
 | 
					    const fn prtcfg(&self) -> vals::Prtcfg {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            Protocol::Free => vals::Prtcfg::FREE,
 | 
					            Protocol::Free => vals::Prtcfg::FREE,
 | 
				
			||||||
            Protocol::Spdif => vals::Prtcfg::SPDIF,
 | 
					            Protocol::Spdif => vals::Prtcfg::SPDIF,
 | 
				
			||||||
@@ -206,7 +174,9 @@ impl Protocol {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Sync input between SAI units/blocks.
 | 
				
			||||||
#[derive(Copy, Clone, PartialEq)]
 | 
					#[derive(Copy, Clone, PartialEq)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum SyncInput {
 | 
					pub enum SyncInput {
 | 
				
			||||||
    /// Not synced to any other SAI unit.
 | 
					    /// Not synced to any other SAI unit.
 | 
				
			||||||
    None,
 | 
					    None,
 | 
				
			||||||
@@ -218,7 +188,7 @@ pub enum SyncInput {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl SyncInput {
 | 
					impl SyncInput {
 | 
				
			||||||
    pub const fn syncen(&self) -> vals::Syncen {
 | 
					    const fn syncen(&self) -> vals::Syncen {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            SyncInput::None => vals::Syncen::ASYNCHRONOUS,
 | 
					            SyncInput::None => vals::Syncen::ASYNCHRONOUS,
 | 
				
			||||||
            SyncInput::Internal => vals::Syncen::INTERNAL,
 | 
					            SyncInput::Internal => vals::Syncen::INTERNAL,
 | 
				
			||||||
@@ -228,8 +198,10 @@ impl SyncInput {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SAI instance to sync from.
 | 
				
			||||||
#[cfg(sai_v4)]
 | 
					#[cfg(sai_v4)]
 | 
				
			||||||
#[derive(Copy, Clone, PartialEq)]
 | 
					#[derive(Copy, Clone, PartialEq)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum SyncInputInstance {
 | 
					pub enum SyncInputInstance {
 | 
				
			||||||
    #[cfg(peri_sai1)]
 | 
					    #[cfg(peri_sai1)]
 | 
				
			||||||
    Sai1 = 0,
 | 
					    Sai1 = 0,
 | 
				
			||||||
@@ -241,7 +213,9 @@ pub enum SyncInputInstance {
 | 
				
			|||||||
    Sai4 = 3,
 | 
					    Sai4 = 3,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Channels (stereo or mono).
 | 
				
			||||||
#[derive(Copy, Clone, PartialEq)]
 | 
					#[derive(Copy, Clone, PartialEq)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum StereoMono {
 | 
					pub enum StereoMono {
 | 
				
			||||||
    Stereo,
 | 
					    Stereo,
 | 
				
			||||||
    Mono,
 | 
					    Mono,
 | 
				
			||||||
@@ -249,7 +223,7 @@ pub enum StereoMono {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl StereoMono {
 | 
					impl StereoMono {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn mono(&self) -> vals::Mono {
 | 
					    const fn mono(&self) -> vals::Mono {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            StereoMono::Stereo => vals::Mono::STEREO,
 | 
					            StereoMono::Stereo => vals::Mono::STEREO,
 | 
				
			||||||
            StereoMono::Mono => vals::Mono::MONO,
 | 
					            StereoMono::Mono => vals::Mono::MONO,
 | 
				
			||||||
@@ -257,15 +231,18 @@ impl StereoMono {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Bit order
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
pub enum BitOrder {
 | 
					pub enum BitOrder {
 | 
				
			||||||
 | 
					    /// Least significant bit first.
 | 
				
			||||||
    LsbFirst,
 | 
					    LsbFirst,
 | 
				
			||||||
 | 
					    /// Most significant bit first.
 | 
				
			||||||
    MsbFirst,
 | 
					    MsbFirst,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl BitOrder {
 | 
					impl BitOrder {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn lsbfirst(&self) -> vals::Lsbfirst {
 | 
					    const fn lsbfirst(&self) -> vals::Lsbfirst {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            BitOrder::LsbFirst => vals::Lsbfirst::LSBFIRST,
 | 
					            BitOrder::LsbFirst => vals::Lsbfirst::LSBFIRST,
 | 
				
			||||||
            BitOrder::MsbFirst => vals::Lsbfirst::MSBFIRST,
 | 
					            BitOrder::MsbFirst => vals::Lsbfirst::MSBFIRST,
 | 
				
			||||||
@@ -273,6 +250,7 @@ impl BitOrder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Frame sync offset.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
pub enum FrameSyncOffset {
 | 
					pub enum FrameSyncOffset {
 | 
				
			||||||
    /// This is used in modes other than standard I2S phillips mode
 | 
					    /// This is used in modes other than standard I2S phillips mode
 | 
				
			||||||
@@ -283,7 +261,7 @@ pub enum FrameSyncOffset {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl FrameSyncOffset {
 | 
					impl FrameSyncOffset {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn fsoff(&self) -> vals::Fsoff {
 | 
					    const fn fsoff(&self) -> vals::Fsoff {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            FrameSyncOffset::OnFirstBit => vals::Fsoff::ONFIRST,
 | 
					            FrameSyncOffset::OnFirstBit => vals::Fsoff::ONFIRST,
 | 
				
			||||||
            FrameSyncOffset::BeforeFirstBit => vals::Fsoff::BEFOREFIRST,
 | 
					            FrameSyncOffset::BeforeFirstBit => vals::Fsoff::BEFOREFIRST,
 | 
				
			||||||
@@ -291,15 +269,18 @@ impl FrameSyncOffset {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Frame sync polarity
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
pub enum FrameSyncPolarity {
 | 
					pub enum FrameSyncPolarity {
 | 
				
			||||||
 | 
					    /// Sync signal is active low.
 | 
				
			||||||
    ActiveLow,
 | 
					    ActiveLow,
 | 
				
			||||||
 | 
					    /// Sync signal is active high
 | 
				
			||||||
    ActiveHigh,
 | 
					    ActiveHigh,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl FrameSyncPolarity {
 | 
					impl FrameSyncPolarity {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn fspol(&self) -> vals::Fspol {
 | 
					    const fn fspol(&self) -> vals::Fspol {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            FrameSyncPolarity::ActiveLow => vals::Fspol::FALLINGEDGE,
 | 
					            FrameSyncPolarity::ActiveLow => vals::Fspol::FALLINGEDGE,
 | 
				
			||||||
            FrameSyncPolarity::ActiveHigh => vals::Fspol::RISINGEDGE,
 | 
					            FrameSyncPolarity::ActiveHigh => vals::Fspol::RISINGEDGE,
 | 
				
			||||||
@@ -307,7 +288,9 @@ impl FrameSyncPolarity {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Sync definition.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum FrameSyncDefinition {
 | 
					pub enum FrameSyncDefinition {
 | 
				
			||||||
    StartOfFrame,
 | 
					    StartOfFrame,
 | 
				
			||||||
    ChannelIdentification,
 | 
					    ChannelIdentification,
 | 
				
			||||||
@@ -315,7 +298,7 @@ pub enum FrameSyncDefinition {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl FrameSyncDefinition {
 | 
					impl FrameSyncDefinition {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn fsdef(&self) -> bool {
 | 
					    const fn fsdef(&self) -> bool {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            FrameSyncDefinition::StartOfFrame => false,
 | 
					            FrameSyncDefinition::StartOfFrame => false,
 | 
				
			||||||
            FrameSyncDefinition::ChannelIdentification => true,
 | 
					            FrameSyncDefinition::ChannelIdentification => true,
 | 
				
			||||||
@@ -323,7 +306,9 @@ impl FrameSyncDefinition {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Clock strobe.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum ClockStrobe {
 | 
					pub enum ClockStrobe {
 | 
				
			||||||
    Falling,
 | 
					    Falling,
 | 
				
			||||||
    Rising,
 | 
					    Rising,
 | 
				
			||||||
@@ -331,7 +316,7 @@ pub enum ClockStrobe {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl ClockStrobe {
 | 
					impl ClockStrobe {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn ckstr(&self) -> vals::Ckstr {
 | 
					    const fn ckstr(&self) -> vals::Ckstr {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            ClockStrobe::Falling => vals::Ckstr::FALLINGEDGE,
 | 
					            ClockStrobe::Falling => vals::Ckstr::FALLINGEDGE,
 | 
				
			||||||
            ClockStrobe::Rising => vals::Ckstr::RISINGEDGE,
 | 
					            ClockStrobe::Rising => vals::Ckstr::RISINGEDGE,
 | 
				
			||||||
@@ -339,7 +324,9 @@ impl ClockStrobe {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Complements format for negative samples.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum ComplementFormat {
 | 
					pub enum ComplementFormat {
 | 
				
			||||||
    OnesComplement,
 | 
					    OnesComplement,
 | 
				
			||||||
    TwosComplement,
 | 
					    TwosComplement,
 | 
				
			||||||
@@ -347,7 +334,7 @@ pub enum ComplementFormat {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl ComplementFormat {
 | 
					impl ComplementFormat {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn cpl(&self) -> vals::Cpl {
 | 
					    const fn cpl(&self) -> vals::Cpl {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            ComplementFormat::OnesComplement => vals::Cpl::ONESCOMPLEMENT,
 | 
					            ComplementFormat::OnesComplement => vals::Cpl::ONESCOMPLEMENT,
 | 
				
			||||||
            ComplementFormat::TwosComplement => vals::Cpl::TWOSCOMPLEMENT,
 | 
					            ComplementFormat::TwosComplement => vals::Cpl::TWOSCOMPLEMENT,
 | 
				
			||||||
@@ -355,7 +342,9 @@ impl ComplementFormat {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Companding setting.
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum Companding {
 | 
					pub enum Companding {
 | 
				
			||||||
    None,
 | 
					    None,
 | 
				
			||||||
    MuLaw,
 | 
					    MuLaw,
 | 
				
			||||||
@@ -364,7 +353,7 @@ pub enum Companding {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl Companding {
 | 
					impl Companding {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn comp(&self) -> vals::Comp {
 | 
					    const fn comp(&self) -> vals::Comp {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            Companding::None => vals::Comp::NOCOMPANDING,
 | 
					            Companding::None => vals::Comp::NOCOMPANDING,
 | 
				
			||||||
            Companding::MuLaw => vals::Comp::MULAW,
 | 
					            Companding::MuLaw => vals::Comp::MULAW,
 | 
				
			||||||
@@ -373,7 +362,9 @@ impl Companding {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Output drive
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum OutputDrive {
 | 
					pub enum OutputDrive {
 | 
				
			||||||
    OnStart,
 | 
					    OnStart,
 | 
				
			||||||
    Immediately,
 | 
					    Immediately,
 | 
				
			||||||
@@ -381,7 +372,7 @@ pub enum OutputDrive {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl OutputDrive {
 | 
					impl OutputDrive {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn outdriv(&self) -> vals::Outdriv {
 | 
					    const fn outdriv(&self) -> vals::Outdriv {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            OutputDrive::OnStart => vals::Outdriv::ONSTART,
 | 
					            OutputDrive::OnStart => vals::Outdriv::ONSTART,
 | 
				
			||||||
            OutputDrive::Immediately => vals::Outdriv::IMMEDIATELY,
 | 
					            OutputDrive::Immediately => vals::Outdriv::IMMEDIATELY,
 | 
				
			||||||
@@ -389,7 +380,9 @@ impl OutputDrive {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Master clock divider.
 | 
				
			||||||
#[derive(Copy, Clone, PartialEq)]
 | 
					#[derive(Copy, Clone, PartialEq)]
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
pub enum MasterClockDivider {
 | 
					pub enum MasterClockDivider {
 | 
				
			||||||
    MasterClockDisabled,
 | 
					    MasterClockDisabled,
 | 
				
			||||||
    Div1,
 | 
					    Div1,
 | 
				
			||||||
@@ -412,7 +405,7 @@ pub enum MasterClockDivider {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl MasterClockDivider {
 | 
					impl MasterClockDivider {
 | 
				
			||||||
    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
					    #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
 | 
				
			||||||
    pub const fn mckdiv(&self) -> u8 {
 | 
					    const fn mckdiv(&self) -> u8 {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            MasterClockDivider::MasterClockDisabled => 0,
 | 
					            MasterClockDivider::MasterClockDisabled => 0,
 | 
				
			||||||
            MasterClockDivider::Div1 => 0,
 | 
					            MasterClockDivider::Div1 => 0,
 | 
				
			||||||
@@ -436,6 +429,7 @@ impl MasterClockDivider {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// [`SAI`] configuration.
 | 
					/// [`SAI`] configuration.
 | 
				
			||||||
 | 
					#[allow(missing_docs)]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
pub struct Config {
 | 
					pub struct Config {
 | 
				
			||||||
@@ -459,7 +453,7 @@ pub struct Config {
 | 
				
			|||||||
    pub clock_strobe: ClockStrobe,
 | 
					    pub clock_strobe: ClockStrobe,
 | 
				
			||||||
    pub output_drive: OutputDrive,
 | 
					    pub output_drive: OutputDrive,
 | 
				
			||||||
    pub master_clock_divider: MasterClockDivider,
 | 
					    pub master_clock_divider: MasterClockDivider,
 | 
				
			||||||
    pub is_high_impedenane_on_inactive_slot: bool,
 | 
					    pub is_high_impedance_on_inactive_slot: bool,
 | 
				
			||||||
    pub fifo_threshold: FifoThreshold,
 | 
					    pub fifo_threshold: FifoThreshold,
 | 
				
			||||||
    pub companding: Companding,
 | 
					    pub companding: Companding,
 | 
				
			||||||
    pub complement_format: ComplementFormat,
 | 
					    pub complement_format: ComplementFormat,
 | 
				
			||||||
@@ -490,7 +484,7 @@ impl Default for Config {
 | 
				
			|||||||
            master_clock_divider: MasterClockDivider::MasterClockDisabled,
 | 
					            master_clock_divider: MasterClockDivider::MasterClockDisabled,
 | 
				
			||||||
            clock_strobe: ClockStrobe::Rising,
 | 
					            clock_strobe: ClockStrobe::Rising,
 | 
				
			||||||
            output_drive: OutputDrive::Immediately,
 | 
					            output_drive: OutputDrive::Immediately,
 | 
				
			||||||
            is_high_impedenane_on_inactive_slot: false,
 | 
					            is_high_impedance_on_inactive_slot: false,
 | 
				
			||||||
            fifo_threshold: FifoThreshold::ThreeQuarters,
 | 
					            fifo_threshold: FifoThreshold::ThreeQuarters,
 | 
				
			||||||
            companding: Companding::None,
 | 
					            companding: Companding::None,
 | 
				
			||||||
            complement_format: ComplementFormat::TwosComplement,
 | 
					            complement_format: ComplementFormat::TwosComplement,
 | 
				
			||||||
@@ -501,23 +495,10 @@ impl Default for Config {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Config {
 | 
					impl Config {
 | 
				
			||||||
    pub fn new_i2s() -> Self {
 | 
					    /// Create a new config with all default values.
 | 
				
			||||||
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
        return Default::default();
 | 
					        return Default::default();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn new_msb_first() -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            bit_order: BitOrder::MsbFirst,
 | 
					 | 
				
			||||||
            frame_sync_offset: FrameSyncOffset::OnFirstBit,
 | 
					 | 
				
			||||||
            ..Default::default()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					 | 
				
			||||||
enum WhichSubBlock {
 | 
					 | 
				
			||||||
    A = 0,
 | 
					 | 
				
			||||||
    B = 1,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum RingBuffer<'d, C: Channel, W: word::Word> {
 | 
					enum RingBuffer<'d, C: Channel, W: word::Word> {
 | 
				
			||||||
@@ -531,28 +512,6 @@ fn dr<W: word::Word>(w: crate::pac::sai::Sai, sub_block: WhichSubBlock) -> *mut
 | 
				
			|||||||
    ch.dr().as_ptr() as _
 | 
					    ch.dr().as_ptr() as _
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct SubBlock<'d, T: Instance, C: Channel, W: word::Word> {
 | 
					 | 
				
			||||||
    _peri: PeripheralRef<'d, T>,
 | 
					 | 
				
			||||||
    sd: Option<PeripheralRef<'d, AnyPin>>,
 | 
					 | 
				
			||||||
    fs: Option<PeripheralRef<'d, AnyPin>>,
 | 
					 | 
				
			||||||
    sck: Option<PeripheralRef<'d, AnyPin>>,
 | 
					 | 
				
			||||||
    mclk: Option<PeripheralRef<'d, AnyPin>>,
 | 
					 | 
				
			||||||
    ring_buffer: RingBuffer<'d, C, W>,
 | 
					 | 
				
			||||||
    sub_block: WhichSubBlock,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct SubBlockA {}
 | 
					 | 
				
			||||||
pub struct SubBlockB {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct SubBlockAPeripheral<'d, T>(PeripheralRef<'d, T>);
 | 
					 | 
				
			||||||
pub struct SubBlockBPeripheral<'d, T>(PeripheralRef<'d, T>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct Sai<'d, T: Instance> {
 | 
					 | 
				
			||||||
    _peri: PeripheralRef<'d, T>,
 | 
					 | 
				
			||||||
    sub_block_a_peri: Option<SubBlockAPeripheral<'d, T>>,
 | 
					 | 
				
			||||||
    sub_block_b_peri: Option<SubBlockBPeripheral<'d, T>>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// return the type for (sd, sck)
 | 
					// return the type for (sd, sck)
 | 
				
			||||||
fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) {
 | 
					fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) {
 | 
				
			||||||
    (
 | 
					    (
 | 
				
			||||||
@@ -591,34 +550,6 @@ fn get_ring_buffer<'d, T: Instance, C: Channel, W: word::Word>(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> Sai<'d, T> {
 | 
					 | 
				
			||||||
    pub fn new(peri: impl Peripheral<P = T> + 'd) -> Self {
 | 
					 | 
				
			||||||
        T::enable_and_reset();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            _peri: unsafe { peri.clone_unchecked().into_ref() },
 | 
					 | 
				
			||||||
            sub_block_a_peri: Some(SubBlockAPeripheral(unsafe { peri.clone_unchecked().into_ref() })),
 | 
					 | 
				
			||||||
            sub_block_b_peri: Some(SubBlockBPeripheral(peri.into_ref())),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn take_sub_block_a(self: &mut Self) -> Option<SubBlockAPeripheral<'d, T>> {
 | 
					 | 
				
			||||||
        if self.sub_block_a_peri.is_some() {
 | 
					 | 
				
			||||||
            self.sub_block_a_peri.take()
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            None
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn take_sub_block_b(self: &mut Self) -> Option<SubBlockBPeripheral<'d, T>> {
 | 
					 | 
				
			||||||
        if self.sub_block_b_peri.is_some() {
 | 
					 | 
				
			||||||
            self.sub_block_b_peri.take()
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            None
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn update_synchronous_config(config: &mut Config) {
 | 
					fn update_synchronous_config(config: &mut Config) {
 | 
				
			||||||
    config.mode = Mode::Slave;
 | 
					    config.mode = Mode::Slave;
 | 
				
			||||||
    config.sync_output = false;
 | 
					    config.sync_output = false;
 | 
				
			||||||
@@ -636,19 +567,58 @@ fn update_synchronous_config(config: &mut Config) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl SubBlockA {
 | 
					/// SAI subblock instance.
 | 
				
			||||||
    pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>(
 | 
					pub struct SubBlock<'d, T, S: SubBlockInstance> {
 | 
				
			||||||
        peri: SubBlockAPeripheral<'d, T>,
 | 
					    peri: PeripheralRef<'d, T>,
 | 
				
			||||||
        sck: impl Peripheral<P = impl SckAPin<T>> + 'd,
 | 
					    _phantom: PhantomData<S>,
 | 
				
			||||||
        sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
 | 
					}
 | 
				
			||||||
        fs: impl Peripheral<P = impl FsAPin<T>> + 'd,
 | 
					
 | 
				
			||||||
        mclk: impl Peripheral<P = impl MclkAPin<T>> + 'd,
 | 
					/// Split the main SAIx peripheral into the two subblocks.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// You can then create a [`Sai`] driver for each each half.
 | 
				
			||||||
 | 
					pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) {
 | 
				
			||||||
 | 
					    into_ref!(peri);
 | 
				
			||||||
 | 
					    T::enable_and_reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					        SubBlock {
 | 
				
			||||||
 | 
					            peri: unsafe { peri.clone_unchecked() },
 | 
				
			||||||
 | 
					            _phantom: PhantomData,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        SubBlock {
 | 
				
			||||||
 | 
					            peri,
 | 
				
			||||||
 | 
					            _phantom: PhantomData,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SAI sub-block driver.
 | 
				
			||||||
 | 
					pub struct Sai<'d, T: Instance, C: Channel, W: word::Word> {
 | 
				
			||||||
 | 
					    _peri: PeripheralRef<'d, T>,
 | 
				
			||||||
 | 
					    sd: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
 | 
					    fs: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
 | 
					    sck: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
 | 
					    mclk: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
 | 
					    ring_buffer: RingBuffer<'d, C, W>,
 | 
				
			||||||
 | 
					    sub_block: WhichSubBlock,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
 | 
				
			||||||
 | 
					    /// Create a new SAI driver in asynchronous mode with MCLK.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// You can obtain the [`SubBlock`] with [`split_subblocks`].
 | 
				
			||||||
 | 
					    pub fn new_asynchronous_with_mclk<S: SubBlockInstance>(
 | 
				
			||||||
 | 
					        peri: SubBlock<'d, T, S>,
 | 
				
			||||||
 | 
					        sck: impl Peripheral<P = impl SckPin<T, S>> + 'd,
 | 
				
			||||||
 | 
					        sd: impl Peripheral<P = impl SdPin<T, S>> + 'd,
 | 
				
			||||||
 | 
					        fs: impl Peripheral<P = impl FsPin<T, S>> + 'd,
 | 
				
			||||||
 | 
					        mclk: impl Peripheral<P = impl MclkPin<T, S>> + 'd,
 | 
				
			||||||
        dma: impl Peripheral<P = C> + 'd,
 | 
					        dma: impl Peripheral<P = C> + 'd,
 | 
				
			||||||
        dma_buf: &'d mut [W],
 | 
					        dma_buf: &'d mut [W],
 | 
				
			||||||
        mut config: Config,
 | 
					        mut config: Config,
 | 
				
			||||||
    ) -> SubBlock<'d, T, C, W>
 | 
					    ) -> Self
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        C: Channel + DmaA<T>,
 | 
					        C: Channel + Dma<T, S>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        into_ref!(mclk);
 | 
					        into_ref!(mclk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -664,19 +634,22 @@ impl SubBlockA {
 | 
				
			|||||||
        Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config)
 | 
					        Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>(
 | 
					    /// Create a new SAI driver in asynchronous mode without MCLK.
 | 
				
			||||||
        peri: SubBlockAPeripheral<'d, T>,
 | 
					    ///
 | 
				
			||||||
        sck: impl Peripheral<P = impl SckAPin<T>> + 'd,
 | 
					    /// You can obtain the [`SubBlock`] with [`split_subblocks`].
 | 
				
			||||||
        sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
 | 
					    pub fn new_asynchronous<S: SubBlockInstance>(
 | 
				
			||||||
        fs: impl Peripheral<P = impl FsAPin<T>> + 'd,
 | 
					        peri: SubBlock<'d, T, S>,
 | 
				
			||||||
 | 
					        sck: impl Peripheral<P = impl SckPin<T, S>> + 'd,
 | 
				
			||||||
 | 
					        sd: impl Peripheral<P = impl SdPin<T, S>> + 'd,
 | 
				
			||||||
 | 
					        fs: impl Peripheral<P = impl FsPin<T, S>> + 'd,
 | 
				
			||||||
        dma: impl Peripheral<P = C> + 'd,
 | 
					        dma: impl Peripheral<P = C> + 'd,
 | 
				
			||||||
        dma_buf: &'d mut [W],
 | 
					        dma_buf: &'d mut [W],
 | 
				
			||||||
        config: Config,
 | 
					        config: Config,
 | 
				
			||||||
    ) -> SubBlock<'d, T, C, W>
 | 
					    ) -> Self
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        C: Channel + DmaA<T>,
 | 
					        C: Channel + Dma<T, S>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        let peri = peri.0;
 | 
					        let peri = peri.peri;
 | 
				
			||||||
        into_ref!(peri, dma, sck, sd, fs);
 | 
					        into_ref!(peri, dma, sck, sd, fs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
 | 
					        let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
 | 
				
			||||||
@@ -688,10 +661,10 @@ impl SubBlockA {
 | 
				
			|||||||
        fs.set_as_af(fs.af_num(), ck_af_type);
 | 
					        fs.set_as_af(fs.af_num(), ck_af_type);
 | 
				
			||||||
        fs.set_speed(crate::gpio::Speed::VeryHigh);
 | 
					        fs.set_speed(crate::gpio::Speed::VeryHigh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let sub_block = WhichSubBlock::A;
 | 
					        let sub_block = S::WHICH;
 | 
				
			||||||
        let request = dma.request();
 | 
					        let request = dma.request();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SubBlock::new_inner(
 | 
					        Self::new_inner(
 | 
				
			||||||
            peri,
 | 
					            peri,
 | 
				
			||||||
            sub_block,
 | 
					            sub_block,
 | 
				
			||||||
            Some(sck.map_into()),
 | 
					            Some(sck.map_into()),
 | 
				
			||||||
@@ -703,19 +676,22 @@ impl SubBlockA {
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>(
 | 
					    /// Create a new SAI driver in synchronous mode.
 | 
				
			||||||
        peri: SubBlockAPeripheral<'d, T>,
 | 
					    ///
 | 
				
			||||||
        sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
 | 
					    /// You can obtain the [`SubBlock`] with [`split_subblocks`].
 | 
				
			||||||
 | 
					    pub fn new_synchronous<S: SubBlockInstance>(
 | 
				
			||||||
 | 
					        peri: SubBlock<'d, T, S>,
 | 
				
			||||||
 | 
					        sd: impl Peripheral<P = impl SdPin<T, S>> + 'd,
 | 
				
			||||||
        dma: impl Peripheral<P = C> + 'd,
 | 
					        dma: impl Peripheral<P = C> + 'd,
 | 
				
			||||||
        dma_buf: &'d mut [W],
 | 
					        dma_buf: &'d mut [W],
 | 
				
			||||||
        mut config: Config,
 | 
					        mut config: Config,
 | 
				
			||||||
    ) -> SubBlock<'d, T, C, W>
 | 
					    ) -> Self
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        C: Channel + DmaA<T>,
 | 
					        C: Channel + Dma<T, S>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        update_synchronous_config(&mut config);
 | 
					        update_synchronous_config(&mut config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let peri = peri.0;
 | 
					        let peri = peri.peri;
 | 
				
			||||||
        into_ref!(dma, peri, sd);
 | 
					        into_ref!(dma, peri, sd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
 | 
					        let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
 | 
				
			||||||
@@ -723,10 +699,10 @@ impl SubBlockA {
 | 
				
			|||||||
        sd.set_as_af(sd.af_num(), sd_af_type);
 | 
					        sd.set_as_af(sd.af_num(), sd_af_type);
 | 
				
			||||||
        sd.set_speed(crate::gpio::Speed::VeryHigh);
 | 
					        sd.set_speed(crate::gpio::Speed::VeryHigh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let sub_block = WhichSubBlock::A;
 | 
					        let sub_block = S::WHICH;
 | 
				
			||||||
        let request = dma.request();
 | 
					        let request = dma.request();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SubBlock::new_inner(
 | 
					        Self::new_inner(
 | 
				
			||||||
            peri,
 | 
					            peri,
 | 
				
			||||||
            sub_block,
 | 
					            sub_block,
 | 
				
			||||||
            None,
 | 
					            None,
 | 
				
			||||||
@@ -737,129 +713,6 @@ impl SubBlockA {
 | 
				
			|||||||
            config,
 | 
					            config,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl SubBlockB {
 | 
					 | 
				
			||||||
    pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>(
 | 
					 | 
				
			||||||
        peri: SubBlockBPeripheral<'d, T>,
 | 
					 | 
				
			||||||
        sck: impl Peripheral<P = impl SckBPin<T>> + 'd,
 | 
					 | 
				
			||||||
        sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
 | 
					 | 
				
			||||||
        fs: impl Peripheral<P = impl FsBPin<T>> + 'd,
 | 
					 | 
				
			||||||
        mclk: impl Peripheral<P = impl MclkBPin<T>> + 'd,
 | 
					 | 
				
			||||||
        dma: impl Peripheral<P = C> + 'd,
 | 
					 | 
				
			||||||
        dma_buf: &'d mut [W],
 | 
					 | 
				
			||||||
        mut config: Config,
 | 
					 | 
				
			||||||
    ) -> SubBlock<'d, T, C, W>
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        C: Channel + DmaB<T>,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        into_ref!(mclk);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        mclk.set_as_af(mclk.af_num(), ck_af_type);
 | 
					 | 
				
			||||||
        mclk.set_speed(crate::gpio::Speed::VeryHigh);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if config.master_clock_divider == MasterClockDivider::MasterClockDisabled {
 | 
					 | 
				
			||||||
            config.master_clock_divider = MasterClockDivider::Div1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>(
 | 
					 | 
				
			||||||
        peri: SubBlockBPeripheral<'d, T>,
 | 
					 | 
				
			||||||
        sck: impl Peripheral<P = impl SckBPin<T>> + 'd,
 | 
					 | 
				
			||||||
        sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
 | 
					 | 
				
			||||||
        fs: impl Peripheral<P = impl FsBPin<T>> + 'd,
 | 
					 | 
				
			||||||
        dma: impl Peripheral<P = C> + 'd,
 | 
					 | 
				
			||||||
        dma_buf: &'d mut [W],
 | 
					 | 
				
			||||||
        config: Config,
 | 
					 | 
				
			||||||
    ) -> SubBlock<'d, T, C, W>
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        C: Channel + DmaB<T>,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        let peri = peri.0;
 | 
					 | 
				
			||||||
        into_ref!(dma, peri, sck, sd, fs);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        sd.set_as_af(sd.af_num(), sd_af_type);
 | 
					 | 
				
			||||||
        sd.set_speed(crate::gpio::Speed::VeryHigh);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        sck.set_as_af(sck.af_num(), ck_af_type);
 | 
					 | 
				
			||||||
        sck.set_speed(crate::gpio::Speed::VeryHigh);
 | 
					 | 
				
			||||||
        fs.set_as_af(fs.af_num(), ck_af_type);
 | 
					 | 
				
			||||||
        fs.set_speed(crate::gpio::Speed::VeryHigh);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let sub_block = WhichSubBlock::B;
 | 
					 | 
				
			||||||
        let request = dma.request();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SubBlock::new_inner(
 | 
					 | 
				
			||||||
            peri,
 | 
					 | 
				
			||||||
            sub_block,
 | 
					 | 
				
			||||||
            Some(sck.map_into()),
 | 
					 | 
				
			||||||
            None,
 | 
					 | 
				
			||||||
            Some(sd.map_into()),
 | 
					 | 
				
			||||||
            Some(fs.map_into()),
 | 
					 | 
				
			||||||
            get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx),
 | 
					 | 
				
			||||||
            config,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>(
 | 
					 | 
				
			||||||
        peri: SubBlockBPeripheral<'d, T>,
 | 
					 | 
				
			||||||
        sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
 | 
					 | 
				
			||||||
        dma: impl Peripheral<P = C> + 'd,
 | 
					 | 
				
			||||||
        dma_buf: &'d mut [W],
 | 
					 | 
				
			||||||
        mut config: Config,
 | 
					 | 
				
			||||||
    ) -> SubBlock<'d, T, C, W>
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        C: Channel + DmaB<T>,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        update_synchronous_config(&mut config);
 | 
					 | 
				
			||||||
        let peri = peri.0;
 | 
					 | 
				
			||||||
        into_ref!(dma, peri, sd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        sd.set_as_af(sd.af_num(), sd_af_type);
 | 
					 | 
				
			||||||
        sd.set_speed(crate::gpio::Speed::VeryHigh);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let sub_block = WhichSubBlock::B;
 | 
					 | 
				
			||||||
        let request = dma.request();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SubBlock::new_inner(
 | 
					 | 
				
			||||||
            peri,
 | 
					 | 
				
			||||||
            sub_block,
 | 
					 | 
				
			||||||
            None,
 | 
					 | 
				
			||||||
            None,
 | 
					 | 
				
			||||||
            Some(sd.map_into()),
 | 
					 | 
				
			||||||
            None,
 | 
					 | 
				
			||||||
            get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx),
 | 
					 | 
				
			||||||
            config,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
 | 
					 | 
				
			||||||
    pub fn start(self: &mut Self) {
 | 
					 | 
				
			||||||
        match self.ring_buffer {
 | 
					 | 
				
			||||||
            RingBuffer::Writable(ref mut rb) => {
 | 
					 | 
				
			||||||
                rb.start();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            RingBuffer::Readable(ref mut rb) => {
 | 
					 | 
				
			||||||
                rb.start();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn is_transmitter(ring_buffer: &RingBuffer<C, W>) -> bool {
 | 
					 | 
				
			||||||
        match ring_buffer {
 | 
					 | 
				
			||||||
            RingBuffer::Writable(_) => true,
 | 
					 | 
				
			||||||
            _ => false,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn new_inner(
 | 
					    fn new_inner(
 | 
				
			||||||
        peri: impl Peripheral<P = T> + 'd,
 | 
					        peri: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
@@ -929,7 +782,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
 | 
				
			|||||||
                w.set_cpl(config.complement_format.cpl());
 | 
					                w.set_cpl(config.complement_format.cpl());
 | 
				
			||||||
                w.set_muteval(config.mute_value.muteval());
 | 
					                w.set_muteval(config.mute_value.muteval());
 | 
				
			||||||
                w.set_mutecnt(config.mute_detection_counter.0 as u8);
 | 
					                w.set_mutecnt(config.mute_detection_counter.0 as u8);
 | 
				
			||||||
                w.set_tris(config.is_high_impedenane_on_inactive_slot);
 | 
					                w.set_tris(config.is_high_impedance_on_inactive_slot);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ch.frcr().modify(|w| {
 | 
					            ch.frcr().modify(|w| {
 | 
				
			||||||
@@ -965,10 +818,31 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Start the SAI driver.
 | 
				
			||||||
 | 
					    pub fn start(&mut self) {
 | 
				
			||||||
 | 
					        match self.ring_buffer {
 | 
				
			||||||
 | 
					            RingBuffer::Writable(ref mut rb) => {
 | 
				
			||||||
 | 
					                rb.start();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            RingBuffer::Readable(ref mut rb) => {
 | 
				
			||||||
 | 
					                rb.start();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn is_transmitter(ring_buffer: &RingBuffer<C, W>) -> bool {
 | 
				
			||||||
 | 
					        match ring_buffer {
 | 
				
			||||||
 | 
					            RingBuffer::Writable(_) => true,
 | 
				
			||||||
 | 
					            _ => false,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Reset SAI operation.
 | 
				
			||||||
    pub fn reset() {
 | 
					    pub fn reset() {
 | 
				
			||||||
        T::enable_and_reset();
 | 
					        T::enable_and_reset();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Flush.
 | 
				
			||||||
    pub fn flush(&mut self) {
 | 
					    pub fn flush(&mut self) {
 | 
				
			||||||
        let ch = T::REGS.ch(self.sub_block as usize);
 | 
					        let ch = T::REGS.ch(self.sub_block as usize);
 | 
				
			||||||
        ch.cr1().modify(|w| w.set_saien(false));
 | 
					        ch.cr1().modify(|w| w.set_saien(false));
 | 
				
			||||||
@@ -983,19 +857,18 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
 | 
				
			|||||||
        ch.cr1().modify(|w| w.set_saien(true));
 | 
					        ch.cr1().modify(|w| w.set_saien(true));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Enable or disable mute.
 | 
				
			||||||
    pub fn set_mute(&mut self, value: bool) {
 | 
					    pub fn set_mute(&mut self, value: bool) {
 | 
				
			||||||
        let ch = T::REGS.ch(self.sub_block as usize);
 | 
					        let ch = T::REGS.ch(self.sub_block as usize);
 | 
				
			||||||
        ch.cr2().modify(|w| w.set_mute(value));
 | 
					        ch.cr2().modify(|w| w.set_mute(value));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[allow(dead_code)]
 | 
					    /// Write data to the SAI ringbuffer.
 | 
				
			||||||
    /// Reconfigures it with the supplied config.
 | 
					    ///
 | 
				
			||||||
    fn reconfigure(&mut self, _config: Config) {}
 | 
					    /// This appends the data to the buffer and returns immediately. The
 | 
				
			||||||
 | 
					    /// data will be transmitted in the background.
 | 
				
			||||||
    pub fn get_current_config(&self) -> Config {
 | 
					    ///
 | 
				
			||||||
        Config::default()
 | 
					    /// If there's no space in the buffer, this waits until there is.
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub async fn write(&mut self, data: &[W]) -> Result<(), Error> {
 | 
					    pub async fn write(&mut self, data: &[W]) -> Result<(), Error> {
 | 
				
			||||||
        match &mut self.ring_buffer {
 | 
					        match &mut self.ring_buffer {
 | 
				
			||||||
            RingBuffer::Writable(buffer) => {
 | 
					            RingBuffer::Writable(buffer) => {
 | 
				
			||||||
@@ -1006,6 +879,12 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Read data from the SAI ringbuffer.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// SAI is always receiving data in the background. This function pops already-received
 | 
				
			||||||
 | 
					    /// data from the buffer.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// If there's less than `data.len()` data in the buffer, this waits until there is.
 | 
				
			||||||
    pub async fn read(&mut self, data: &mut [W]) -> Result<(), Error> {
 | 
					    pub async fn read(&mut self, data: &mut [W]) -> Result<(), Error> {
 | 
				
			||||||
        match &mut self.ring_buffer {
 | 
					        match &mut self.ring_buffer {
 | 
				
			||||||
            RingBuffer::Readable(buffer) => {
 | 
					            RingBuffer::Readable(buffer) => {
 | 
				
			||||||
@@ -1017,7 +896,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance, C: Channel, W: word::Word> Drop for SubBlock<'d, T, C, W> {
 | 
					impl<'d, T: Instance, C: Channel, W: word::Word> Drop for Sai<'d, T, C, W> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        let ch = T::REGS.ch(self.sub_block as usize);
 | 
					        let ch = T::REGS.ch(self.sub_block as usize);
 | 
				
			||||||
        ch.cr1().modify(|w| w.set_saien(false));
 | 
					        ch.cr1().modify(|w| w.set_saien(false));
 | 
				
			||||||
@@ -1034,22 +913,43 @@ pub(crate) mod sealed {
 | 
				
			|||||||
    pub trait Instance {
 | 
					    pub trait Instance {
 | 
				
			||||||
        const REGS: Regs;
 | 
					        const REGS: Regs;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[derive(Copy, Clone)]
 | 
				
			||||||
 | 
					    pub enum WhichSubBlock {
 | 
				
			||||||
 | 
					        A = 0,
 | 
				
			||||||
 | 
					        B = 1,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub trait SubBlock {
 | 
				
			||||||
 | 
					        const WHICH: WhichSubBlock;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait Word: word::Word {}
 | 
					/// Sub-block instance trait.
 | 
				
			||||||
 | 
					pub trait SubBlockInstance: sealed::SubBlock {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Sub-block A.
 | 
				
			||||||
 | 
					pub enum A {}
 | 
				
			||||||
 | 
					impl sealed::SubBlock for A {
 | 
				
			||||||
 | 
					    const WHICH: WhichSubBlock = WhichSubBlock::A;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl SubBlockInstance for A {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Sub-block B.
 | 
				
			||||||
 | 
					pub enum B {}
 | 
				
			||||||
 | 
					impl sealed::SubBlock for B {
 | 
				
			||||||
 | 
					    const WHICH: WhichSubBlock = WhichSubBlock::B;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl SubBlockInstance for B {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SAI instance trait.
 | 
				
			||||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
 | 
					pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
 | 
				
			||||||
pin_trait!(SckAPin, Instance);
 | 
					pin_trait!(SckPin, Instance, SubBlockInstance);
 | 
				
			||||||
pin_trait!(SckBPin, Instance);
 | 
					pin_trait!(FsPin, Instance, SubBlockInstance);
 | 
				
			||||||
pin_trait!(FsAPin, Instance);
 | 
					pin_trait!(SdPin, Instance, SubBlockInstance);
 | 
				
			||||||
pin_trait!(FsBPin, Instance);
 | 
					pin_trait!(MclkPin, Instance, SubBlockInstance);
 | 
				
			||||||
pin_trait!(SdAPin, Instance);
 | 
					 | 
				
			||||||
pin_trait!(SdBPin, Instance);
 | 
					 | 
				
			||||||
pin_trait!(MclkAPin, Instance);
 | 
					 | 
				
			||||||
pin_trait!(MclkBPin, Instance);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
dma_trait!(DmaA, Instance);
 | 
					dma_trait!(Dma, Instance, SubBlockInstance);
 | 
				
			||||||
dma_trait!(DmaB, Instance);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
foreach_peripheral!(
 | 
					foreach_peripheral!(
 | 
				
			||||||
    (sai, $inst:ident) => {
 | 
					    (sai, $inst:ident) => {
 | 
				
			||||||
@@ -1060,13 +960,3 @@ foreach_peripheral!(
 | 
				
			|||||||
        impl Instance for peripherals::$inst {}
 | 
					        impl Instance for peripherals::$inst {}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'d, T: Instance> SetConfig for Sai<'d, T> {
 | 
					 | 
				
			||||||
    type Config = Config;
 | 
					 | 
				
			||||||
    type ConfigError = ();
 | 
					 | 
				
			||||||
    fn set_config(&mut self, _config: &Self::Config) -> Result<(), ()> {
 | 
					 | 
				
			||||||
        // self.reconfigure(*config);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Secure Digital / MultiMedia Card (SDMMC)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::default::Default;
 | 
					use core::default::Default;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Serial Peripheral Interface (SPI)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::ptr;
 | 
					use core::ptr;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,18 +1,18 @@
 | 
				
			|||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! pin_trait {
 | 
					macro_rules! pin_trait {
 | 
				
			||||||
    ($signal:ident, $instance:path) => {
 | 
					    ($signal:ident, $instance:path $(, $mode:path)?) => {
 | 
				
			||||||
        #[doc = concat!(stringify!($signal), " pin trait")]
 | 
					        #[doc = concat!(stringify!($signal), " pin trait")]
 | 
				
			||||||
        pub trait $signal<T: $instance>: crate::gpio::Pin {
 | 
					        pub trait $signal<T: $instance $(, M: $mode)?>: crate::gpio::Pin {
 | 
				
			||||||
            #[doc = concat!("Get the AF number needed to use this pin as", stringify!($signal))]
 | 
					            #[doc = concat!("Get the AF number needed to use this pin as ", stringify!($signal))]
 | 
				
			||||||
            fn af_num(&self) -> u8;
 | 
					            fn af_num(&self) -> u8;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! pin_trait_impl {
 | 
					macro_rules! pin_trait_impl {
 | 
				
			||||||
    (crate::$mod:ident::$trait:ident, $instance:ident, $pin:ident, $af:expr) => {
 | 
					    (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $af:expr) => {
 | 
				
			||||||
        impl crate::$mod::$trait<crate::peripherals::$instance> for crate::peripherals::$pin {
 | 
					        impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$pin {
 | 
				
			||||||
            fn af_num(&self) -> u8 {
 | 
					            fn af_num(&self) -> u8 {
 | 
				
			||||||
                $af
 | 
					                $af
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -23,9 +23,9 @@ macro_rules! pin_trait_impl {
 | 
				
			|||||||
// ====================
 | 
					// ====================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! dma_trait {
 | 
					macro_rules! dma_trait {
 | 
				
			||||||
    ($signal:ident, $instance:path) => {
 | 
					    ($signal:ident, $instance:path$(, $mode:path)?) => {
 | 
				
			||||||
        #[doc = concat!(stringify!($signal), " DMA request trait")]
 | 
					        #[doc = concat!(stringify!($signal), " DMA request trait")]
 | 
				
			||||||
        pub trait $signal<T: $instance>: crate::dma::Channel {
 | 
					        pub trait $signal<T: $instance $(, M: $mode)?>: crate::dma::Channel {
 | 
				
			||||||
            #[doc = concat!("Get the DMA request number needed to use this channel as", stringify!($signal))]
 | 
					            #[doc = concat!("Get the DMA request number needed to use this channel as", stringify!($signal))]
 | 
				
			||||||
            /// Note: in some chips, ST calls this the "channel", and calls channels "streams".
 | 
					            /// Note: in some chips, ST calls this the "channel", and calls channels "streams".
 | 
				
			||||||
            /// `embassy-stm32` always uses the "channel" and "request number" names.
 | 
					            /// `embassy-stm32` always uses the "channel" and "request number" names.
 | 
				
			||||||
@@ -37,8 +37,8 @@ macro_rules! dma_trait {
 | 
				
			|||||||
#[allow(unused)]
 | 
					#[allow(unused)]
 | 
				
			||||||
macro_rules! dma_trait_impl {
 | 
					macro_rules! dma_trait_impl {
 | 
				
			||||||
    // DMAMUX
 | 
					    // DMAMUX
 | 
				
			||||||
    (crate::$mod:ident::$trait:ident, $instance:ident, {dmamux: $dmamux:ident}, $request:expr) => {
 | 
					    (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dmamux: $dmamux:ident}, $request:expr) => {
 | 
				
			||||||
        impl<T> crate::$mod::$trait<crate::peripherals::$instance> for T
 | 
					        impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T
 | 
				
			||||||
        where
 | 
					        where
 | 
				
			||||||
            T: crate::dma::Channel + crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
 | 
					            T: crate::dma::Channel + crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -49,8 +49,8 @@ macro_rules! dma_trait_impl {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // DMAMUX
 | 
					    // DMAMUX
 | 
				
			||||||
    (crate::$mod:ident::$trait:ident, $instance:ident, {dma: $dma:ident}, $request:expr) => {
 | 
					    (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dma: $dma:ident}, $request:expr) => {
 | 
				
			||||||
        impl<T> crate::$mod::$trait<crate::peripherals::$instance> for T
 | 
					        impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T
 | 
				
			||||||
        where
 | 
					        where
 | 
				
			||||||
            T: crate::dma::Channel,
 | 
					            T: crate::dma::Channel,
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -61,8 +61,8 @@ macro_rules! dma_trait_impl {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // DMA/GPDMA, without DMAMUX
 | 
					    // DMA/GPDMA, without DMAMUX
 | 
				
			||||||
    (crate::$mod:ident::$trait:ident, $instance:ident, {channel: $channel:ident}, $request:expr) => {
 | 
					    (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {channel: $channel:ident}, $request:expr) => {
 | 
				
			||||||
        impl crate::$mod::$trait<crate::peripherals::$instance> for crate::peripherals::$channel {
 | 
					        impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel {
 | 
				
			||||||
            fn request(&self) -> crate::dma::Request {
 | 
					            fn request(&self) -> crate::dma::Request {
 | 
				
			||||||
                $request
 | 
					                $request
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					//! Unique ID (UID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Get this device's unique 96-bit ID.
 | 
					/// Get this device's unique 96-bit ID.
 | 
				
			||||||
pub fn uid() -> &'static [u8; 12] {
 | 
					pub fn uid() -> &'static [u8; 12] {
 | 
				
			||||||
    unsafe { &*crate::pac::UID.uid(0).as_ptr().cast::<[u8; 12]>() }
 | 
					    unsafe { &*crate::pac::UID.uid(0).as_ptr().cast::<[u8; 12]>() }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Universal Synchronous/Asynchronous Receiver Transmitter (USART, UART, LPUART)
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::future::poll_fn;
 | 
					use core::future::poll_fn;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					//! USB On The Go (OTG)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::rcc::RccPeripheral;
 | 
					use crate::rcc::RccPeripheral;
 | 
				
			||||||
use crate::{interrupt, peripherals};
 | 
					use crate::{interrupt, peripherals};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Watchdog Timer (IWDG, WWDG)
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_hal_internal::{into_ref, Peripheral};
 | 
					use embassy_hal_internal::{into_ref, Peripheral};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user