stm32/sai: deduplicate code for subblocks A/B.
This commit is contained in:
parent
c952ae0f49
commit
4deae51e65
@ -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,7 +1,10 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
|
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 _};
|
||||||
@ -500,23 +503,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> {
|
||||||
@ -530,28 +520,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) {
|
||||||
(
|
(
|
||||||
@ -590,34 +558,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;
|
||||||
@ -635,19 +575,51 @@ fn update_synchronous_config(config: &mut Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SubBlockA {
|
pub struct SubBlock<'d, T, S: SubBlockInstance> {
|
||||||
pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>(
|
peri: PeripheralRef<'d, T>,
|
||||||
peri: SubBlockAPeripheral<'d, T>,
|
_phantom: PhantomData<S>,
|
||||||
sck: impl Peripheral<P = impl SckAPin<T>> + 'd,
|
}
|
||||||
sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
|
|
||||||
fs: impl Peripheral<P = impl FsAPin<T>> + 'd,
|
pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) {
|
||||||
mclk: impl Peripheral<P = impl MclkAPin<T>> + 'd,
|
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> {
|
||||||
|
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);
|
||||||
|
|
||||||
@ -663,19 +635,19 @@ 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>(
|
pub fn new_asynchronous<S: SubBlockInstance>(
|
||||||
peri: SubBlockAPeripheral<'d, T>,
|
peri: SubBlock<'d, T, S>,
|
||||||
sck: impl Peripheral<P = impl SckAPin<T>> + 'd,
|
sck: impl Peripheral<P = impl SckPin<T, S>> + 'd,
|
||||||
sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
|
sd: impl Peripheral<P = impl SdPin<T, S>> + 'd,
|
||||||
fs: impl Peripheral<P = impl FsAPin<T>> + '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);
|
||||||
@ -687,10 +659,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()),
|
||||||
@ -702,19 +674,19 @@ impl SubBlockA {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>(
|
pub fn new_synchronous<S: SubBlockInstance>(
|
||||||
peri: SubBlockAPeripheral<'d, T>,
|
peri: SubBlock<'d, T, S>,
|
||||||
sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
|
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);
|
||||||
@ -722,10 +694,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,
|
||||||
@ -736,129 +708,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,
|
||||||
@ -964,6 +813,24 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reset() {
|
pub fn reset() {
|
||||||
T::enable_and_reset();
|
T::enable_and_reset();
|
||||||
}
|
}
|
||||||
@ -1008,7 +875,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));
|
||||||
@ -1025,22 +892,40 @@ 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 {}
|
pub trait Word: word::Word {}
|
||||||
|
|
||||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
|
pub trait SubBlockInstance: sealed::SubBlock {}
|
||||||
pin_trait!(SckAPin, Instance);
|
|
||||||
pin_trait!(SckBPin, Instance);
|
|
||||||
pin_trait!(FsAPin, Instance);
|
|
||||||
pin_trait!(FsBPin, Instance);
|
|
||||||
pin_trait!(SdAPin, Instance);
|
|
||||||
pin_trait!(SdBPin, Instance);
|
|
||||||
pin_trait!(MclkAPin, Instance);
|
|
||||||
pin_trait!(MclkBPin, Instance);
|
|
||||||
|
|
||||||
dma_trait!(DmaA, Instance);
|
pub enum A {}
|
||||||
dma_trait!(DmaB, Instance);
|
impl sealed::SubBlock for A {
|
||||||
|
const WHICH: WhichSubBlock = WhichSubBlock::A;
|
||||||
|
}
|
||||||
|
impl SubBlockInstance for A {}
|
||||||
|
pub enum B {}
|
||||||
|
impl sealed::SubBlock for B {
|
||||||
|
const WHICH: WhichSubBlock = WhichSubBlock::B;
|
||||||
|
}
|
||||||
|
impl SubBlockInstance for B {}
|
||||||
|
|
||||||
|
pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
|
||||||
|
pin_trait!(SckPin, Instance, SubBlockInstance);
|
||||||
|
pin_trait!(FsPin, Instance, SubBlockInstance);
|
||||||
|
pin_trait!(SdPin, Instance, SubBlockInstance);
|
||||||
|
pin_trait!(MclkPin, Instance, SubBlockInstance);
|
||||||
|
|
||||||
|
dma_trait!(Dma, Instance, SubBlockInstance);
|
||||||
|
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(sai, $inst:ident) => {
|
(sai, $inst:ident) => {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#![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;
|
||||||
}
|
}
|
||||||
@ -11,8 +11,8 @@ macro_rules! pin_trait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user