Use enumset for DMA interrupts instead of countless functions (#2196)

* [1/x] Use enumset for DMA interrupts instead of countless functions

* [2/x] Remove the countless functions from RegisterAccess

* Use Into

* [3/3] Use enums everywhere in the DMA module

* Remove redundant enum_set!

* Remove `available_` prefix

* Use `pending_` prefix

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
This commit is contained in:
Dominic Fischer 2024-09-23 09:43:56 +01:00 committed by GitHub
parent 89d9de67eb
commit 794cdb0af4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 731 additions and 803 deletions

View File

@ -58,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed an issue with DMA transfers potentially not waking up the correct async task (#2065) - Fixed an issue with DMA transfers potentially not waking up the correct async task (#2065)
- Fixed an issue with LCD_CAM i8080 where it would send double the clocks in 16bit mode (#2085) - Fixed an issue with LCD_CAM i8080 where it would send double the clocks in 16bit mode (#2085)
- Fix i2c embedded-hal transaction (#2028) - Fix i2c embedded-hal transaction (#2028)
- Fix some inconsistencies in DMA interrupt bits (#2169)
- Fix SPI DMA alternating `write` and `read` for ESP32 and ESP32-S2 (#2131) - Fix SPI DMA alternating `write` and `read` for ESP32 and ESP32-S2 (#2131)
- Fix I2C ending up in a state when only re-creating the peripheral makes it useable again (#2141) - Fix I2C ending up in a state when only re-creating the peripheral makes it useable again (#2141)
- Fix `SpiBus::transfer` transferring data twice in some cases (#2159) - Fix `SpiBus::transfer` transferring data twice in some cases (#2159)

View File

@ -139,10 +139,6 @@ impl<const N: u8> RegisterAccess for Channel<N> {
.modify(|_, w| unsafe { w.outlink_addr().bits(address) }); .modify(|_, w| unsafe { w.outlink_addr().bits(address) });
} }
fn has_out_descriptor_error() -> bool {
Self::out_int().raw().read().out_dscr_err().bit()
}
fn set_out_peripheral(peripheral: u8) { fn set_out_peripheral(peripheral: u8) {
Self::ch() Self::ch()
.out_peri_sel() .out_peri_sel()
@ -155,34 +151,6 @@ impl<const N: u8> RegisterAccess for Channel<N> {
.modify(|_, w| w.outlink_start().set_bit()); .modify(|_, w| w.outlink_start().set_bit());
} }
fn clear_ch_out_done() {
Self::out_int()
.clr()
.write(|w| w.out_done().clear_bit_by_one());
}
fn is_ch_out_done_set() -> bool {
Self::out_int().raw().read().out_done().bit()
}
fn listen_ch_out_done() {
Self::out_int().ena().modify(|_, w| w.out_done().set_bit())
}
fn unlisten_ch_out_done() {
Self::out_int()
.ena()
.modify(|_, w| w.out_done().clear_bit())
}
fn is_listening_ch_out_done() -> bool {
Self::out_int().ena().read().out_done().bit()
}
fn is_out_done() -> bool {
Self::out_int().raw().read().out_total_eof().bit()
}
fn last_out_dscr_address() -> usize { fn last_out_dscr_address() -> usize {
Self::ch() Self::ch()
.out_eof_des_addr() .out_eof_des_addr()
@ -191,16 +159,6 @@ impl<const N: u8> RegisterAccess for Channel<N> {
.bits() as _ .bits() as _
} }
fn is_out_eof_interrupt_set() -> bool {
Self::out_int().raw().read().out_eof().bit()
}
fn reset_out_eof_interrupt() {
Self::out_int()
.clr()
.write(|w| w.out_eof().clear_bit_by_one());
}
#[cfg(esp32s3)] #[cfg(esp32s3)]
fn set_in_ext_mem_block_size(size: DmaExtMemBKSize) { fn set_in_ext_mem_block_size(size: DmaExtMemBKSize) {
Self::ch() Self::ch()
@ -259,18 +217,6 @@ impl<const N: u8> RegisterAccess for Channel<N> {
.modify(|_, w| unsafe { w.inlink_addr().bits(address) }); .modify(|_, w| unsafe { w.inlink_addr().bits(address) });
} }
fn has_in_descriptor_error() -> bool {
Self::in_int().raw().read().in_dscr_err().bit()
}
fn has_in_descriptor_error_dscr_empty() -> bool {
Self::in_int().raw().read().in_dscr_empty().bit()
}
fn has_in_descriptor_error_err_eof() -> bool {
Self::in_int().raw().read().in_err_eof().bit()
}
fn set_in_peripheral(peripheral: u8) { fn set_in_peripheral(peripheral: u8) {
Self::ch() Self::ch()
.in_peri_sel() .in_peri_sel()
@ -283,122 +229,177 @@ impl<const N: u8> RegisterAccess for Channel<N> {
.modify(|_, w| w.inlink_start().set_bit()); .modify(|_, w| w.inlink_start().set_bit());
} }
fn is_in_done() -> bool { fn listen_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
Self::in_int().raw().read().in_suc_eof().bit() Self::out_int().ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().set_bit(),
DmaTxInterrupt::DescriptorError => w.out_dscr_err().set_bit(),
DmaTxInterrupt::Eof => w.out_eof().set_bit(),
DmaTxInterrupt::Done => w.out_done().set_bit(),
};
}
w
})
} }
fn is_listening_in_eof() -> bool { fn unlisten_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
Self::in_int().ena().read().in_suc_eof().bit_is_set() Self::out_int().ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().clear_bit(),
DmaTxInterrupt::DescriptorError => w.out_dscr_err().clear_bit(),
DmaTxInterrupt::Eof => w.out_eof().clear_bit(),
DmaTxInterrupt::Done => w.out_done().clear_bit(),
};
}
w
})
} }
fn is_listening_out_eof() -> bool { fn is_listening_out() -> EnumSet<DmaTxInterrupt> {
Self::out_int().ena().read().out_total_eof().bit_is_set() let mut result = EnumSet::new();
let int_ena = Self::out_int().ena().read();
if int_ena.out_total_eof().bit_is_set() {
result |= DmaTxInterrupt::TotalEof;
}
if int_ena.out_dscr_err().bit_is_set() {
result |= DmaTxInterrupt::DescriptorError;
}
if int_ena.out_eof().bit_is_set() {
result |= DmaTxInterrupt::Eof;
}
if int_ena.out_done().bit_is_set() {
result |= DmaTxInterrupt::Done;
}
result
} }
fn listen_in_eof() { fn pending_out_interrupts() -> EnumSet<DmaTxInterrupt> {
Self::in_int().ena().modify(|_, w| w.in_suc_eof().set_bit()); let mut result = EnumSet::new();
let int_raw = Self::out_int().raw().read();
if int_raw.out_total_eof().bit_is_set() {
result |= DmaTxInterrupt::TotalEof;
}
if int_raw.out_dscr_err().bit_is_set() {
result |= DmaTxInterrupt::DescriptorError;
}
if int_raw.out_eof().bit_is_set() {
result |= DmaTxInterrupt::Eof;
}
if int_raw.out_done().bit_is_set() {
result |= DmaTxInterrupt::Done;
}
result
} }
fn listen_out_eof() { fn clear_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
Self::out_int() Self::out_int().clr().write(|w| {
.ena() for interrupt in interrupts.into() {
.modify(|_, w| w.out_total_eof().set_bit()); match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().clear_bit_by_one(),
DmaTxInterrupt::DescriptorError => w.out_dscr_err().clear_bit_by_one(),
DmaTxInterrupt::Eof => w.out_eof().clear_bit_by_one(),
DmaTxInterrupt::Done => w.out_done().clear_bit_by_one(),
};
}
w
})
} }
fn unlisten_in_eof() { fn listen_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
Self::in_int() Self::in_int().ena().modify(|_, w| {
.ena() for interrupt in interrupts.into() {
.modify(|_, w| w.in_suc_eof().clear_bit()); match interrupt {
DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().set_bit(),
DmaRxInterrupt::ErrorEof => w.in_err_eof().set_bit(),
DmaRxInterrupt::DescriptorError => w.in_dscr_err().set_bit(),
DmaRxInterrupt::DescriptorEmpty => w.in_dscr_empty().set_bit(),
DmaRxInterrupt::Done => w.in_done().set_bit(),
};
}
w
})
} }
fn unlisten_out_eof() { fn unlisten_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
Self::out_int() Self::in_int().ena().modify(|_, w| {
.ena() for interrupt in interrupts.into() {
.modify(|_, w| w.out_total_eof().clear_bit()); match interrupt {
DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().clear_bit(),
DmaRxInterrupt::ErrorEof => w.in_err_eof().clear_bit(),
DmaRxInterrupt::DescriptorError => w.in_dscr_err().clear_bit(),
DmaRxInterrupt::DescriptorEmpty => w.in_dscr_empty().clear_bit(),
DmaRxInterrupt::Done => w.in_done().clear_bit(),
};
}
w
})
} }
fn listen_ch_in_done() { fn is_listening_in() -> EnumSet<DmaRxInterrupt> {
Self::in_int().ena().modify(|_, w| w.in_done().set_bit()) let mut result = EnumSet::new();
let int_ena = Self::in_int().ena().read();
if int_ena.in_dscr_err().bit_is_set() {
result |= DmaRxInterrupt::DescriptorError;
}
if int_ena.in_dscr_empty().bit_is_set() {
result |= DmaRxInterrupt::DescriptorEmpty;
}
if int_ena.in_suc_eof().bit_is_set() {
result |= DmaRxInterrupt::SuccessfulEof;
}
if int_ena.in_err_eof().bit_is_set() {
result |= DmaRxInterrupt::ErrorEof;
}
if int_ena.in_done().bit_is_set() {
result |= DmaRxInterrupt::Done;
}
result
} }
fn clear_ch_in_done() { fn pending_in_interrupts() -> EnumSet<DmaRxInterrupt> {
Self::in_int() let mut result = EnumSet::new();
.clr()
.write(|w| w.in_done().clear_bit_by_one()); let int_raw = Self::in_int().raw().read();
if int_raw.in_dscr_err().bit_is_set() {
result |= DmaRxInterrupt::DescriptorError;
}
if int_raw.in_dscr_empty().bit_is_set() {
result |= DmaRxInterrupt::DescriptorEmpty;
}
if int_raw.in_suc_eof().bit_is_set() {
result |= DmaRxInterrupt::SuccessfulEof;
}
if int_raw.in_err_eof().bit_is_set() {
result |= DmaRxInterrupt::ErrorEof;
}
if int_raw.in_done().bit_is_set() {
result |= DmaRxInterrupt::Done;
}
result
} }
fn is_ch_in_done_set() -> bool { fn clear_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
Self::in_int().raw().read().in_done().bit() Self::in_int().clr().write(|w| {
} for interrupt in interrupts.into() {
match interrupt {
fn unlisten_ch_in_done() { DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().clear_bit_by_one(),
Self::in_int().ena().modify(|_, w| w.in_done().clear_bit()); DmaRxInterrupt::ErrorEof => w.in_err_eof().clear_bit_by_one(),
} DmaRxInterrupt::DescriptorError => w.in_dscr_err().clear_bit_by_one(),
DmaRxInterrupt::DescriptorEmpty => w.in_dscr_empty().clear_bit_by_one(),
fn is_listening_ch_in_done() -> bool { DmaRxInterrupt::Done => w.in_done().clear_bit_by_one(),
Self::in_int().ena().read().in_done().bit() };
} }
w
fn listen_in_descriptor_error() { })
Self::in_int()
.ena()
.modify(|_, w| w.in_dscr_err().set_bit())
}
fn unlisten_in_descriptor_error() {
Self::in_int()
.ena()
.modify(|_, w| w.in_dscr_err().clear_bit())
}
fn is_listening_in_descriptor_error() -> bool {
Self::in_int().ena().read().in_dscr_err().bit()
}
fn listen_in_descriptor_error_dscr_empty() {
Self::in_int()
.ena()
.modify(|_, w| w.in_dscr_empty().set_bit())
}
fn unlisten_in_descriptor_error_dscr_empty() {
Self::in_int()
.ena()
.modify(|_, w| w.in_dscr_empty().clear_bit())
}
fn is_listening_in_descriptor_error_dscr_empty() -> bool {
Self::in_int().ena().read().in_dscr_empty().bit()
}
fn listen_in_descriptor_error_err_eof() {
Self::in_int().ena().modify(|_, w| w.in_err_eof().set_bit())
}
fn unlisten_in_descriptor_error_err_eof() {
Self::in_int()
.ena()
.modify(|_, w| w.in_err_eof().clear_bit())
}
fn is_listening_in_descriptor_error_err_eof() -> bool {
Self::in_int().ena().read().in_err_eof().bit()
}
fn listen_out_descriptor_error() {
Self::out_int()
.ena()
.modify(|_, w| w.out_dscr_err().set_bit())
}
fn unlisten_out_descriptor_error() {
Self::out_int()
.ena()
.modify(|_, w| w.out_dscr_err().clear_bit())
}
fn is_listening_out_descriptor_error() -> bool {
Self::out_int().ena().read().out_dscr_err().bit()
} }
} }

View File

@ -302,6 +302,53 @@ pub enum DmaInterrupt {
TxDone, TxDone,
} }
/// Types of interrupts emitted by the TX channel.
#[derive(EnumSetType)]
pub enum DmaTxInterrupt {
/// Triggered when all data corresponding to a linked list (including
/// multiple descriptors) have been sent via transmit channel.
TotalEof,
/// Triggered when an error is detected in a transmit descriptor on transmit
/// channel.
DescriptorError,
/// Triggered when EOF in a transmit descriptor is true and data
/// corresponding to this descriptor have been sent via transmit
/// channel.
Eof,
/// Triggered when all data corresponding to a transmit descriptor have been
/// sent via transmit channel.
Done,
}
/// Types of interrupts emitted by the RX channel.
#[derive(EnumSetType)]
pub enum DmaRxInterrupt {
/// Triggered when the size of the buffer pointed by receive descriptors
/// is smaller than the length of data to be received via receive channel.
DescriptorEmpty,
/// Triggered when an error is detected in a receive descriptor on receive
/// channel.
DescriptorError,
/// Triggered when an error is detected in the data segment corresponding to
/// a descriptor received via receive channel n.
/// This interrupt is used only for UHCI0 peripheral (UART0 or UART1).
ErrorEof,
/// Triggered when the suc_eof bit in a receive descriptor is 1 and the data
/// corresponding to this receive descriptor has been received via receive
/// channel.
SuccessfulEof,
/// Triggered when all data corresponding to a receive descriptor have been
/// received via receive channel.
Done,
}
/// The default chunk size used for DMA transfers. /// The default chunk size used for DMA transfers.
pub const CHUNK_SIZE: usize = 4092; pub const CHUNK_SIZE: usize = 4092;
@ -983,8 +1030,12 @@ impl TxCircularState {
where where
T: TxPrivate, T: TxPrivate,
{ {
if channel.descriptors_handled() { if channel
channel.reset_descriptors_handled(); .pending_out_interrupts()
.contains(DmaTxInterrupt::Eof)
{
channel.clear_out(DmaTxInterrupt::Eof);
let descr_address = channel.last_out_dscr_address() as *mut DmaDescriptor; let descr_address = channel.last_out_dscr_address() as *mut DmaDescriptor;
let mut ptr = self.last_seen_handled_descriptor_ptr; let mut ptr = self.last_seen_handled_descriptor_ptr;
@ -1226,50 +1277,32 @@ pub trait RxPrivate: crate::private::Sealed {
#[cfg(gdma)] #[cfg(gdma)]
fn set_mem2mem_mode(&mut self, value: bool); fn set_mem2mem_mode(&mut self, value: bool);
fn listen_ch_in_done(&self); fn listen_in(&self, interrupts: impl Into<EnumSet<DmaRxInterrupt>>);
fn clear_ch_in_done(&self); fn unlisten_in(&self, interrupts: impl Into<EnumSet<DmaRxInterrupt>>);
fn is_ch_in_done_set(&self) -> bool; fn is_listening_in(&self) -> EnumSet<DmaRxInterrupt>;
fn unlisten_ch_in_done(&self); fn clear_in(&self, interrupts: impl Into<EnumSet<DmaRxInterrupt>>);
fn is_listening_ch_in_done(&self) -> bool; fn pending_in_interrupts(&self) -> EnumSet<DmaRxInterrupt>;
fn is_done(&self) -> bool; fn is_done(&self) -> bool;
fn is_listening_eof(&self) -> bool; fn has_error(&self) -> bool {
self.pending_in_interrupts()
.contains(DmaRxInterrupt::DescriptorError)
}
fn listen_eof(&self); fn has_dscr_empty_error(&self) -> bool {
self.pending_in_interrupts()
.contains(DmaRxInterrupt::DescriptorEmpty)
}
fn unlisten_eof(&self); fn has_eof_error(&self) -> bool {
self.pending_in_interrupts()
/// Descriptor error detected .contains(DmaRxInterrupt::ErrorEof)
fn has_error(&self) -> bool; }
/// ERR_DSCR_EMPTY error detected
fn has_dscr_empty_error(&self) -> bool;
/// ERR_EOF error detected
fn has_eof_error(&self) -> bool;
fn is_listening_in_descriptor_error(&self) -> bool;
fn listen_in_descriptor_error(&self);
fn unlisten_in_descriptor_error(&self);
fn is_listening_in_descriptor_error_dscr_empty(&self) -> bool;
fn listen_in_descriptor_error_dscr_empty(&self);
fn unlisten_in_descriptor_error_dscr_empty(&self);
fn is_listening_in_descriptor_error_err_eof(&self) -> bool;
fn listen_in_descriptor_error_err_eof(&self);
fn unlisten_in_descriptor_error_err_eof(&self);
fn clear_interrupts(&self); fn clear_interrupts(&self);
@ -1308,17 +1341,13 @@ where
fn start_transfer(&mut self) -> Result<(), DmaError> { fn start_transfer(&mut self) -> Result<(), DmaError> {
R::start_in(); R::start_in();
if R::has_in_descriptor_error() { if R::pending_in_interrupts().contains(DmaRxInterrupt::DescriptorError) {
Err(DmaError::DescriptorError) Err(DmaError::DescriptorError)
} else { } else {
Ok(()) Ok(())
} }
} }
fn is_done(&self) -> bool {
R::is_in_done()
}
fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker; fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker;
} }
@ -1426,94 +1455,35 @@ where
CH::Channel::set_mem2mem_mode(value); CH::Channel::set_mem2mem_mode(value);
} }
fn listen_ch_in_done(&self) { fn listen_in(&self, interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
CH::Channel::listen_ch_in_done(); CH::Channel::listen_in(interrupts);
} }
fn clear_ch_in_done(&self) { fn unlisten_in(&self, interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
CH::Channel::clear_ch_in_done(); CH::Channel::unlisten_in(interrupts);
} }
fn is_ch_in_done_set(&self) -> bool { fn is_listening_in(&self) -> EnumSet<DmaRxInterrupt> {
CH::Channel::is_ch_in_done_set() CH::Channel::is_listening_in()
} }
fn unlisten_ch_in_done(&self) { fn clear_in(&self, interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
CH::Channel::unlisten_ch_in_done(); CH::Channel::clear_in(interrupts);
} }
fn is_listening_ch_in_done(&self) -> bool { fn pending_in_interrupts(&self) -> EnumSet<DmaRxInterrupt> {
CH::Channel::is_listening_ch_in_done() CH::Channel::pending_in_interrupts()
} }
fn is_done(&self) -> bool { fn is_done(&self) -> bool {
self.rx_impl.is_done() self.pending_in_interrupts()
.contains(DmaRxInterrupt::SuccessfulEof)
} }
fn init_channel(&mut self) { fn init_channel(&mut self) {
CH::Channel::init_channel(); CH::Channel::init_channel();
} }
fn is_listening_eof(&self) -> bool {
CH::Channel::is_listening_in_eof()
}
fn listen_eof(&self) {
CH::Channel::listen_in_eof()
}
fn unlisten_eof(&self) {
CH::Channel::unlisten_in_eof()
}
fn has_error(&self) -> bool {
CH::Channel::has_in_descriptor_error()
}
fn has_dscr_empty_error(&self) -> bool {
CH::Channel::has_in_descriptor_error_dscr_empty()
}
fn has_eof_error(&self) -> bool {
CH::Channel::has_in_descriptor_error_err_eof()
}
fn is_listening_in_descriptor_error(&self) -> bool {
CH::Channel::is_listening_in_descriptor_error()
}
fn listen_in_descriptor_error(&self) {
CH::Channel::listen_in_descriptor_error();
}
fn unlisten_in_descriptor_error(&self) {
CH::Channel::unlisten_in_descriptor_error();
}
fn is_listening_in_descriptor_error_dscr_empty(&self) -> bool {
CH::Channel::is_listening_in_descriptor_error_dscr_empty()
}
fn listen_in_descriptor_error_dscr_empty(&self) {
CH::Channel::listen_in_descriptor_error_dscr_empty();
}
fn unlisten_in_descriptor_error_dscr_empty(&self) {
CH::Channel::unlisten_in_descriptor_error_dscr_empty();
}
fn is_listening_in_descriptor_error_err_eof(&self) -> bool {
CH::Channel::is_listening_in_descriptor_error_err_eof()
}
fn listen_in_descriptor_error_err_eof(&self) {
CH::Channel::listen_in_descriptor_error_err_eof();
}
fn unlisten_in_descriptor_error_err_eof(&self) {
CH::Channel::unlisten_in_descriptor_error_err_eof();
}
fn clear_interrupts(&self) { fn clear_interrupts(&self) {
CH::Channel::clear_in_interrupts(); CH::Channel::clear_in_interrupts();
} }
@ -1542,45 +1512,35 @@ pub trait TxPrivate: crate::private::Sealed {
buffer: &mut BUF, buffer: &mut BUF,
) -> Result<(), DmaError>; ) -> Result<(), DmaError>;
fn listen_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>);
fn unlisten_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>);
fn is_listening_out(&self) -> EnumSet<DmaTxInterrupt>;
fn clear_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>);
fn pending_out_interrupts(&self) -> EnumSet<DmaTxInterrupt>;
fn start_transfer(&mut self) -> Result<(), DmaError>; fn start_transfer(&mut self) -> Result<(), DmaError>;
#[cfg(esp32s3)] #[cfg(esp32s3)]
fn set_ext_mem_block_size(&self, size: DmaExtMemBKSize); fn set_ext_mem_block_size(&self, size: DmaExtMemBKSize);
fn clear_ch_out_done(&self); fn is_done(&self) -> bool {
self.pending_out_interrupts()
.contains(DmaTxInterrupt::TotalEof)
}
fn is_ch_out_done_set(&self) -> bool; fn has_error(&self) -> bool {
self.pending_out_interrupts()
fn listen_ch_out_done(&self); .contains(DmaTxInterrupt::DescriptorError)
}
fn unlisten_ch_out_done(&self);
fn is_listening_ch_out_done(&self) -> bool;
fn is_done(&self) -> bool;
fn is_listening_eof(&self) -> bool;
fn listen_eof(&self);
fn unlisten_eof(&self);
fn is_listening_out_descriptor_error(&self) -> bool;
fn listen_out_descriptor_error(&self);
fn unlisten_out_descriptor_error(&self);
fn has_error(&self) -> bool;
fn clear_interrupts(&self); fn clear_interrupts(&self);
fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker; fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker;
fn descriptors_handled(&self) -> bool;
fn reset_descriptors_handled(&self);
fn last_out_dscr_address(&self) -> usize; fn last_out_dscr_address(&self) -> usize;
} }
@ -1612,47 +1572,27 @@ where
fn start_transfer(&mut self) -> Result<(), DmaError> { fn start_transfer(&mut self) -> Result<(), DmaError> {
R::start_out(); R::start_out();
if R::has_out_descriptor_error() { if R::pending_out_interrupts().contains(DmaTxInterrupt::DescriptorError) {
Err(DmaError::DescriptorError) Err(DmaError::DescriptorError)
} else { } else {
Ok(()) Ok(())
} }
} }
fn clear_ch_out_done(&self) { fn listen_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
R::clear_ch_out_done(); R::listen_out(interrupts)
} }
fn unlisten_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
fn is_ch_out_done_set(&self) -> bool { R::unlisten_out(interrupts)
R::is_ch_out_done_set()
} }
fn is_listening_out(&self) -> EnumSet<DmaTxInterrupt> {
fn listen_ch_out_done(&self) { R::is_listening_out()
R::listen_ch_out_done();
} }
fn clear_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
fn unlisten_ch_out_done(&self) { R::clear_out(interrupts)
R::unlisten_ch_out_done();
} }
fn pending_out_interrupts(&self) -> EnumSet<DmaTxInterrupt> {
fn is_listening_ch_out_done(&self) -> bool { R::pending_out_interrupts()
R::is_listening_ch_out_done()
}
fn is_done(&self) -> bool {
R::is_out_done()
}
fn descriptors_handled(&self) -> bool {
R::is_out_eof_interrupt_set()
}
fn reset_descriptors_handled(&self) {
R::reset_out_eof_interrupt();
}
fn last_out_dscr_address(&self) -> usize {
R::last_out_dscr_address()
} }
fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker; fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker;
@ -1743,76 +1683,36 @@ where
CH::Channel::set_out_ext_mem_block_size(size); CH::Channel::set_out_ext_mem_block_size(size);
} }
fn clear_ch_out_done(&self) { fn listen_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
self.tx_impl.clear_ch_out_done(); CH::Channel::listen_out(interrupts);
} }
fn is_ch_out_done_set(&self) -> bool { fn unlisten_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
self.tx_impl.is_ch_out_done_set() CH::Channel::unlisten_out(interrupts);
} }
fn listen_ch_out_done(&self) { fn is_listening_out(&self) -> EnumSet<DmaTxInterrupt> {
self.tx_impl.listen_ch_out_done(); CH::Channel::is_listening_out()
} }
fn unlisten_ch_out_done(&self) { fn clear_out(&self, interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
self.tx_impl.unlisten_ch_out_done(); CH::Channel::clear_out(interrupts);
} }
fn is_listening_ch_out_done(&self) -> bool { fn pending_out_interrupts(&self) -> EnumSet<DmaTxInterrupt> {
self.tx_impl.is_listening_ch_out_done() CH::Channel::pending_out_interrupts()
}
fn is_done(&self) -> bool {
self.tx_impl.is_done()
}
fn is_listening_eof(&self) -> bool {
CH::Channel::is_listening_out_eof()
}
fn listen_eof(&self) {
CH::Channel::listen_out_eof()
}
fn unlisten_eof(&self) {
CH::Channel::unlisten_out_eof()
}
fn has_error(&self) -> bool {
CH::Channel::has_out_descriptor_error()
} }
fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker { fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker {
CH::Tx::waker() CH::Tx::waker()
} }
fn is_listening_out_descriptor_error(&self) -> bool {
CH::Channel::is_listening_out_descriptor_error()
}
fn listen_out_descriptor_error(&self) {
CH::Channel::listen_out_descriptor_error();
}
fn unlisten_out_descriptor_error(&self) {
CH::Channel::unlisten_out_descriptor_error();
}
fn clear_interrupts(&self) { fn clear_interrupts(&self) {
CH::Channel::clear_out_interrupts(); CH::Channel::clear_out_interrupts();
} }
fn descriptors_handled(&self) -> bool {
self.tx_impl.descriptors_handled()
}
fn reset_descriptors_handled(&self) {
self.tx_impl.reset_descriptors_handled()
}
fn last_out_dscr_address(&self) -> usize { fn last_out_dscr_address(&self) -> usize {
self.tx_impl.last_out_dscr_address() CH::Channel::last_out_dscr_address()
} }
} }
@ -1828,17 +1728,21 @@ pub trait RegisterAccess: crate::private::Sealed {
fn clear_out_interrupts(); fn clear_out_interrupts();
fn reset_out(); fn reset_out();
fn set_out_descriptors(address: u32); fn set_out_descriptors(address: u32);
fn has_out_descriptor_error() -> bool;
fn set_out_peripheral(peripheral: u8); fn set_out_peripheral(peripheral: u8);
fn start_out(); fn start_out();
fn clear_ch_out_done();
fn is_ch_out_done_set() -> bool; fn listen_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>);
fn listen_ch_out_done(); fn unlisten_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>);
fn unlisten_ch_out_done(); fn is_listening_out() -> EnumSet<DmaTxInterrupt>;
fn is_listening_ch_out_done() -> bool; fn clear_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>);
fn is_out_done() -> bool; fn pending_out_interrupts() -> EnumSet<DmaTxInterrupt>;
fn is_out_eof_interrupt_set() -> bool;
fn reset_out_eof_interrupt(); fn listen_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>);
fn unlisten_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>);
fn is_listening_in() -> EnumSet<DmaRxInterrupt>;
fn clear_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>);
fn pending_in_interrupts() -> EnumSet<DmaRxInterrupt>;
fn last_out_dscr_address() -> usize; fn last_out_dscr_address() -> usize;
#[cfg(esp32s3)] #[cfg(esp32s3)]
@ -1848,42 +1752,8 @@ pub trait RegisterAccess: crate::private::Sealed {
fn clear_in_interrupts(); fn clear_in_interrupts();
fn reset_in(); fn reset_in();
fn set_in_descriptors(address: u32); fn set_in_descriptors(address: u32);
fn has_in_descriptor_error() -> bool;
fn has_in_descriptor_error_dscr_empty() -> bool;
fn has_in_descriptor_error_err_eof() -> bool;
fn set_in_peripheral(peripheral: u8); fn set_in_peripheral(peripheral: u8);
fn start_in(); fn start_in();
fn is_in_done() -> bool;
fn is_listening_in_eof() -> bool;
fn is_listening_out_eof() -> bool;
fn listen_in_eof();
fn listen_out_eof();
fn unlisten_in_eof();
fn unlisten_out_eof();
fn listen_in_descriptor_error();
fn unlisten_in_descriptor_error();
fn is_listening_in_descriptor_error() -> bool;
fn listen_in_descriptor_error_dscr_empty();
fn unlisten_in_descriptor_error_dscr_empty();
fn is_listening_in_descriptor_error_dscr_empty() -> bool;
fn listen_in_descriptor_error_err_eof();
fn unlisten_in_descriptor_error_err_eof();
fn is_listening_in_descriptor_error_err_eof() -> bool;
fn listen_out_descriptor_error();
fn unlisten_out_descriptor_error();
fn is_listening_out_descriptor_error() -> bool;
fn listen_ch_in_done();
fn clear_ch_in_done();
fn is_ch_in_done_set() -> bool;
fn unlisten_ch_in_done();
fn is_listening_ch_in_done() -> bool;
} }
#[doc(hidden)] #[doc(hidden)]
@ -1920,8 +1790,8 @@ where
pub fn listen(&mut self, interrupts: EnumSet<DmaInterrupt>) { pub fn listen(&mut self, interrupts: EnumSet<DmaInterrupt>) {
for interrupt in interrupts { for interrupt in interrupts {
match interrupt { match interrupt {
DmaInterrupt::RxDone => self.rx.listen_ch_in_done(), DmaInterrupt::RxDone => self.rx.listen_in(DmaRxInterrupt::Done),
DmaInterrupt::TxDone => self.tx.listen_ch_out_done(), DmaInterrupt::TxDone => self.tx.listen_out(DmaTxInterrupt::Done),
} }
} }
} }
@ -1930,8 +1800,8 @@ where
pub fn unlisten(&mut self, interrupts: EnumSet<DmaInterrupt>) { pub fn unlisten(&mut self, interrupts: EnumSet<DmaInterrupt>) {
for interrupt in interrupts { for interrupt in interrupts {
match interrupt { match interrupt {
DmaInterrupt::RxDone => self.rx.unlisten_ch_in_done(), DmaInterrupt::RxDone => self.rx.unlisten_in(DmaRxInterrupt::Done),
DmaInterrupt::TxDone => self.tx.unlisten_ch_out_done(), DmaInterrupt::TxDone => self.tx.unlisten_out(DmaTxInterrupt::Done),
} }
} }
} }
@ -1952,8 +1822,8 @@ where
pub fn clear_interrupts(&mut self, interrupts: EnumSet<DmaInterrupt>) { pub fn clear_interrupts(&mut self, interrupts: EnumSet<DmaInterrupt>) {
for interrupt in interrupts { for interrupt in interrupts {
match interrupt { match interrupt {
DmaInterrupt::RxDone => self.rx.clear_ch_in_done(), DmaInterrupt::RxDone => self.rx.clear_in(DmaRxInterrupt::Done),
DmaInterrupt::TxDone => self.tx.clear_ch_out_done(), DmaInterrupt::TxDone => self.tx.clear_out(DmaTxInterrupt::Done),
} }
} }
} }
@ -2684,7 +2554,12 @@ where
pub fn wait(self) -> Result<(), DmaError> { pub fn wait(self) -> Result<(), DmaError> {
self.instance.peripheral_wait_dma(false, true); self.instance.peripheral_wait_dma(false, true);
if self.instance.tx().has_error() { if self
.instance
.tx()
.pending_out_interrupts()
.contains(DmaTxInterrupt::DescriptorError)
{
Err(DmaError::DescriptorError) Err(DmaError::DescriptorError)
} else { } else {
Ok(()) Ok(())
@ -2732,7 +2607,12 @@ where
pub fn wait(self) -> Result<(), DmaError> { pub fn wait(self) -> Result<(), DmaError> {
self.instance.peripheral_wait_dma(true, false); self.instance.peripheral_wait_dma(true, false);
if self.instance.rx().has_error() { if self
.instance
.rx()
.pending_in_interrupts()
.contains(DmaRxInterrupt::DescriptorError)
{
Err(DmaError::DescriptorError) Err(DmaError::DescriptorError)
} else { } else {
Ok(()) Ok(())
@ -2781,7 +2661,17 @@ where
pub fn wait(self) -> Result<(), DmaError> { pub fn wait(self) -> Result<(), DmaError> {
self.instance.peripheral_wait_dma(true, true); self.instance.peripheral_wait_dma(true, true);
if self.instance.tx().has_error() || self.instance.rx().has_error() { if self
.instance
.tx()
.pending_out_interrupts()
.contains(DmaTxInterrupt::DescriptorError)
|| self
.instance
.rx()
.pending_in_interrupts()
.contains(DmaRxInterrupt::DescriptorError)
{
Err(DmaError::DescriptorError) Err(DmaError::DescriptorError)
} else { } else {
Ok(()) Ok(())
@ -2854,7 +2744,12 @@ where
pub fn stop(self) -> Result<(), DmaError> { pub fn stop(self) -> Result<(), DmaError> {
self.instance.peripheral_dma_stop(); self.instance.peripheral_dma_stop();
if self.instance.tx().has_error() { if self
.instance
.tx()
.pending_out_interrupts()
.contains(DmaTxInterrupt::DescriptorError)
{
Err(DmaError::DescriptorError) Err(DmaError::DescriptorError)
} else { } else {
Ok(()) Ok(())
@ -2964,12 +2859,16 @@ pub(crate) mod asynch {
if self.tx.is_done() { if self.tx.is_done() {
self.tx.clear_interrupts(); self.tx.clear_interrupts();
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} else if self.tx.has_error() { } else if self
.tx
.pending_out_interrupts()
.contains(DmaTxInterrupt::DescriptorError)
{
self.tx.clear_interrupts(); self.tx.clear_interrupts();
Poll::Ready(Err(DmaError::DescriptorError)) Poll::Ready(Err(DmaError::DescriptorError))
} else { } else {
self.tx.listen_eof(); self.tx
self.tx.listen_out_descriptor_error(); .listen_out(DmaTxInterrupt::TotalEof | DmaTxInterrupt::DescriptorError);
Poll::Pending Poll::Pending
} }
} }
@ -2980,8 +2879,8 @@ pub(crate) mod asynch {
TX: Tx, TX: Tx,
{ {
fn drop(&mut self) { fn drop(&mut self) {
self.tx.unlisten_eof(); self.tx
self.tx.unlisten_out_descriptor_error(); .unlisten_out(DmaTxInterrupt::TotalEof | DmaTxInterrupt::DescriptorError);
} }
} }
@ -3016,17 +2915,20 @@ pub(crate) mod asynch {
if self.rx.is_done() { if self.rx.is_done() {
self.rx.clear_interrupts(); self.rx.clear_interrupts();
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} else if self.rx.has_error() } else if !self.rx.pending_in_interrupts().is_disjoint(
|| self.rx.has_dscr_empty_error() DmaRxInterrupt::DescriptorError
|| self.rx.has_eof_error() | DmaRxInterrupt::DescriptorEmpty
{ | DmaRxInterrupt::ErrorEof,
) {
self.rx.clear_interrupts(); self.rx.clear_interrupts();
Poll::Ready(Err(DmaError::DescriptorError)) Poll::Ready(Err(DmaError::DescriptorError))
} else { } else {
self.rx.listen_eof(); self.rx.listen_in(
self.rx.listen_in_descriptor_error(); DmaRxInterrupt::SuccessfulEof
self.rx.listen_in_descriptor_error_dscr_empty(); | DmaRxInterrupt::DescriptorError
self.rx.listen_in_descriptor_error_err_eof(); | DmaRxInterrupt::DescriptorEmpty
| DmaRxInterrupt::ErrorEof,
);
Poll::Pending Poll::Pending
} }
} }
@ -3037,10 +2939,11 @@ pub(crate) mod asynch {
RX: Rx, RX: Rx,
{ {
fn drop(&mut self) { fn drop(&mut self) {
self.rx.unlisten_eof(); self.rx.unlisten_in(
self.rx.unlisten_in_descriptor_error(); DmaRxInterrupt::DescriptorError
self.rx.unlisten_in_descriptor_error_dscr_empty(); | DmaRxInterrupt::DescriptorEmpty
self.rx.unlisten_in_descriptor_error_err_eof(); | DmaRxInterrupt::ErrorEof,
);
} }
} }
@ -3075,15 +2978,23 @@ pub(crate) mod asynch {
cx: &mut core::task::Context<'_>, cx: &mut core::task::Context<'_>,
) -> Poll<Self::Output> { ) -> Poll<Self::Output> {
TX::waker().register(cx.waker()); TX::waker().register(cx.waker());
if self.tx.is_ch_out_done_set() { if self
self.tx.clear_ch_out_done(); .tx
.pending_out_interrupts()
.contains(DmaTxInterrupt::Done)
{
self.tx.clear_out(DmaTxInterrupt::Done);
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} else if self.tx.has_error() { } else if self
.tx
.pending_out_interrupts()
.contains(DmaTxInterrupt::DescriptorError)
{
self.tx.clear_interrupts(); self.tx.clear_interrupts();
Poll::Ready(Err(DmaError::DescriptorError)) Poll::Ready(Err(DmaError::DescriptorError))
} else { } else {
self.tx.listen_ch_out_done(); self.tx
self.tx.listen_out_descriptor_error(); .listen_out(DmaTxInterrupt::Done | DmaTxInterrupt::DescriptorError);
Poll::Pending Poll::Pending
} }
} }
@ -3095,8 +3006,8 @@ pub(crate) mod asynch {
TX: Tx, TX: Tx,
{ {
fn drop(&mut self) { fn drop(&mut self) {
self.tx.unlisten_ch_out_done(); self.tx
self.tx.unlisten_out_descriptor_error(); .unlisten_out(DmaTxInterrupt::Done | DmaTxInterrupt::DescriptorError);
} }
} }
@ -3131,20 +3042,27 @@ pub(crate) mod asynch {
cx: &mut core::task::Context<'_>, cx: &mut core::task::Context<'_>,
) -> Poll<Self::Output> { ) -> Poll<Self::Output> {
RX::waker().register(cx.waker()); RX::waker().register(cx.waker());
if self.rx.is_ch_in_done_set() { if self
self.rx.clear_ch_in_done(); .rx
Poll::Ready(Ok(())) .pending_in_interrupts()
} else if self.rx.has_error() .contains(DmaRxInterrupt::Done)
|| self.rx.has_dscr_empty_error()
|| self.rx.has_eof_error()
{ {
self.rx.clear_in(DmaRxInterrupt::Done);
Poll::Ready(Ok(()))
} else if !self.rx.pending_in_interrupts().is_disjoint(
DmaRxInterrupt::DescriptorError
| DmaRxInterrupt::DescriptorEmpty
| DmaRxInterrupt::ErrorEof,
) {
self.rx.clear_interrupts(); self.rx.clear_interrupts();
Poll::Ready(Err(DmaError::DescriptorError)) Poll::Ready(Err(DmaError::DescriptorError))
} else { } else {
self.rx.listen_ch_in_done(); self.rx.listen_in(
self.rx.listen_in_descriptor_error(); DmaRxInterrupt::Done
self.rx.listen_in_descriptor_error_dscr_empty(); | DmaRxInterrupt::DescriptorError
self.rx.listen_in_descriptor_error_err_eof(); | DmaRxInterrupt::DescriptorEmpty
| DmaRxInterrupt::ErrorEof,
);
Poll::Pending Poll::Pending
} }
} }
@ -3156,50 +3074,57 @@ pub(crate) mod asynch {
RX: Rx, RX: Rx,
{ {
fn drop(&mut self) { fn drop(&mut self) {
self.rx.unlisten_ch_in_done(); self.rx.unlisten_in(
self.rx.unlisten_in_descriptor_error(); DmaRxInterrupt::Done
self.rx.unlisten_in_descriptor_error_dscr_empty(); | DmaRxInterrupt::DescriptorError
self.rx.unlisten_in_descriptor_error_err_eof(); | DmaRxInterrupt::DescriptorEmpty
| DmaRxInterrupt::ErrorEof,
);
} }
} }
fn handle_interrupt<Channel: RegisterAccess, Rx: RxChannel<Channel>, Tx: TxChannel<Channel>>() { fn handle_interrupt<Channel: RegisterAccess, Rx: RxChannel<Channel>, Tx: TxChannel<Channel>>() {
if Channel::has_in_descriptor_error() if Channel::pending_in_interrupts().is_disjoint(
|| Channel::has_in_descriptor_error_dscr_empty() DmaRxInterrupt::DescriptorError
|| Channel::has_in_descriptor_error_err_eof() | DmaRxInterrupt::DescriptorEmpty
| DmaRxInterrupt::ErrorEof,
) {
Channel::unlisten_in(
DmaRxInterrupt::DescriptorError
| DmaRxInterrupt::DescriptorEmpty
| DmaRxInterrupt::ErrorEof
| DmaRxInterrupt::SuccessfulEof
| DmaRxInterrupt::Done,
);
Rx::waker().wake()
}
if Channel::pending_out_interrupts().contains(DmaTxInterrupt::DescriptorError) {
Channel::unlisten_out(
DmaTxInterrupt::DescriptorError | DmaTxInterrupt::TotalEof | DmaTxInterrupt::Done,
);
Tx::waker().wake()
}
if Channel::pending_in_interrupts().contains(DmaRxInterrupt::SuccessfulEof) {
Channel::unlisten_in(DmaRxInterrupt::SuccessfulEof);
Rx::waker().wake()
}
if Channel::pending_in_interrupts().contains(DmaRxInterrupt::Done) {
Channel::unlisten_in(DmaRxInterrupt::Done);
Rx::waker().wake()
}
if Channel::pending_out_interrupts().contains(DmaTxInterrupt::TotalEof)
&& Channel::is_listening_out().contains(DmaTxInterrupt::TotalEof)
{ {
Channel::unlisten_in_descriptor_error(); Channel::unlisten_out(DmaTxInterrupt::TotalEof);
Channel::unlisten_in_descriptor_error_dscr_empty();
Channel::unlisten_in_descriptor_error_err_eof();
Channel::unlisten_in_eof();
Channel::unlisten_ch_in_done();
Rx::waker().wake()
}
if Channel::has_out_descriptor_error() {
Channel::unlisten_out_descriptor_error();
Channel::unlisten_out_eof();
Channel::unlisten_ch_out_done();
Tx::waker().wake() Tx::waker().wake()
} }
if Channel::is_in_done() && Channel::is_listening_in_eof() { if Channel::pending_out_interrupts().contains(DmaTxInterrupt::Done) {
Channel::unlisten_in_eof(); Channel::unlisten_out(DmaTxInterrupt::Done);
Rx::waker().wake()
}
if Channel::is_ch_in_done_set() {
Channel::unlisten_ch_in_done();
Rx::waker().wake()
}
if Channel::is_out_done() && Channel::is_listening_out_eof() {
Channel::unlisten_out_eof();
Tx::waker().wake()
}
if Channel::is_ch_out_done_set() {
Channel::unlisten_ch_out_done();
Tx::waker().wake() Tx::waker().wake()
} }
} }

View File

@ -83,11 +83,6 @@ macro_rules! ImplSpiChannel {
.modify(|_, w| unsafe { w.outlink_addr().bits(address) }); .modify(|_, w| unsafe { w.outlink_addr().bits(address) });
} }
fn has_out_descriptor_error() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().outlink_dscr_error().bit()
}
fn set_out_peripheral(_peripheral: u8) { fn set_out_peripheral(_peripheral: u8) {
// no-op // no-op
} }
@ -97,53 +92,11 @@ macro_rules! ImplSpiChannel {
spi.dma_out_link().modify(|_, w| w.outlink_start().set_bit()); spi.dma_out_link().modify(|_, w| w.outlink_start().set_bit());
} }
fn clear_ch_out_done() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_clr().write(|w| w.out_done().clear_bit_by_one());
}
fn is_ch_out_done_set() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().out_done().bit()
}
fn listen_ch_out_done() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_, w| w.out_done().set_bit());
}
fn unlisten_ch_out_done() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_, w| w.out_done().clear_bit());
}
fn is_listening_ch_out_done() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().read().out_done().bit()
}
fn is_out_done() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().out_total_eof().bit()
}
fn last_out_dscr_address() -> usize { fn last_out_dscr_address() -> usize {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.out_eof_des_addr().read().dma_out_eof_des_addr().bits() as usize spi.out_eof_des_addr().read().dma_out_eof_des_addr().bits() as usize
} }
fn is_out_eof_interrupt_set() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().out_eof().bit()
}
fn reset_out_eof_interrupt() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_clr().write(|w| {
w.out_eof().clear_bit_by_one()
});
}
fn set_in_burstmode(burst_mode: bool) { fn set_in_burstmode(burst_mode: bool) {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_conf() spi.dma_conf()
@ -174,21 +127,6 @@ macro_rules! ImplSpiChannel {
.modify(|_, w| unsafe { w.inlink_addr().bits(address) }); .modify(|_, w| unsafe { w.inlink_addr().bits(address) });
} }
fn has_in_descriptor_error() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().inlink_dscr_error().bit()
}
fn has_in_descriptor_error_dscr_empty() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().inlink_dscr_empty().bit()
}
fn has_in_descriptor_error_err_eof() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().in_err_eof().bit()
}
fn set_in_peripheral(_peripheral: u8) { fn set_in_peripheral(_peripheral: u8) {
// no-op // no-op
} }
@ -198,124 +136,187 @@ macro_rules! ImplSpiChannel {
spi.dma_in_link().modify(|_, w| w.inlink_start().set_bit()); spi.dma_in_link().modify(|_, w| w.inlink_start().set_bit());
} }
fn is_in_done() -> bool { fn listen_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().in_done().bit() spi.dma_int_ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().set_bit(),
DmaTxInterrupt::DescriptorError => w.outlink_dscr_error().set_bit(),
DmaTxInterrupt::Eof => w.out_eof().set_bit(),
DmaTxInterrupt::Done => w.out_done().set_bit(),
};
}
w
})
} }
fn is_listening_in_eof() -> bool { fn unlisten_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().read().in_suc_eof().bit_is_set() spi.dma_int_ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().clear_bit(),
DmaTxInterrupt::DescriptorError => w.outlink_dscr_error().clear_bit(),
DmaTxInterrupt::Eof => w.out_eof().clear_bit(),
DmaTxInterrupt::Done => w.out_done().clear_bit(),
};
}
w
})
} }
fn is_listening_out_eof() -> bool { fn is_listening_out() -> EnumSet<DmaTxInterrupt> {
let mut result = EnumSet::new();
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().read().out_total_eof().bit_is_set() let int_ena = spi.dma_int_ena().read();
if int_ena.out_total_eof().bit_is_set() {
result |= DmaTxInterrupt::TotalEof;
}
if int_ena.outlink_dscr_error().bit_is_set() {
result |= DmaTxInterrupt::DescriptorError;
}
if int_ena.out_eof().bit_is_set() {
result |= DmaTxInterrupt::Eof;
}
if int_ena.out_done().bit_is_set() {
result |= DmaTxInterrupt::Done;
}
result
} }
fn listen_in_eof() { fn pending_out_interrupts() -> EnumSet<DmaTxInterrupt> {
let mut result = EnumSet::new();
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_, w| w.in_suc_eof().set_bit()); let int_raw = spi.dma_int_raw().read();
if int_raw.out_total_eof().bit_is_set() {
result |= DmaTxInterrupt::TotalEof;
}
if int_raw.outlink_dscr_error().bit_is_set() {
result |= DmaTxInterrupt::DescriptorError;
}
if int_raw.out_eof().bit_is_set() {
result |= DmaTxInterrupt::Eof;
}
if int_raw.out_done().bit_is_set() {
result |= DmaTxInterrupt::Done;
}
result
} }
fn listen_out_eof() { fn clear_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_, w| w.out_total_eof().set_bit()); spi.dma_int_clr().write(|w| {
for interrupt in interrupts.into() {
match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().clear_bit_by_one(),
DmaTxInterrupt::DescriptorError => w.outlink_dscr_error().clear_bit_by_one(),
DmaTxInterrupt::Eof => w.out_eof().clear_bit_by_one(),
DmaTxInterrupt::Done => w.out_done().clear_bit_by_one(),
};
}
w
})
} }
fn unlisten_in_eof() { fn listen_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_, w| w.in_suc_eof().clear_bit()); spi.dma_int_ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().set_bit(),
DmaRxInterrupt::ErrorEof => w.in_err_eof().set_bit(),
DmaRxInterrupt::DescriptorError => w.inlink_dscr_error().set_bit(),
DmaRxInterrupt::DescriptorEmpty => w.inlink_dscr_empty().set_bit(),
DmaRxInterrupt::Done => w.in_done().set_bit(),
};
}
w
})
} }
fn unlisten_out_eof() { fn unlisten_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_, w| w.out_total_eof().clear_bit()); spi.dma_int_ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().clear_bit(),
DmaRxInterrupt::ErrorEof => w.in_err_eof().clear_bit(),
DmaRxInterrupt::DescriptorError => w.inlink_dscr_error().clear_bit(),
DmaRxInterrupt::DescriptorEmpty => w.inlink_dscr_empty().clear_bit(),
DmaRxInterrupt::Done => w.in_done().clear_bit(),
};
}
w
})
} }
fn listen_ch_in_done(){ fn is_listening_in() -> EnumSet<DmaRxInterrupt> {
let mut result = EnumSet::new();
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_, w| w.in_done().set_bit()); let int_ena = spi.dma_int_ena().read();
if int_ena.inlink_dscr_error().bit_is_set() {
result |= DmaRxInterrupt::DescriptorError;
}
if int_ena.inlink_dscr_empty().bit_is_set() {
result |= DmaRxInterrupt::DescriptorEmpty;
}
if int_ena.in_suc_eof().bit_is_set() {
result |= DmaRxInterrupt::SuccessfulEof;
}
if int_ena.in_err_eof().bit_is_set() {
result |= DmaRxInterrupt::ErrorEof;
}
if int_ena.in_done().bit_is_set() {
result |= DmaRxInterrupt::Done;
}
result
} }
fn clear_ch_in_done(){ fn pending_in_interrupts() -> EnumSet<DmaRxInterrupt> {
let mut result = EnumSet::new();
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_clr().write(|w| w.in_done().clear_bit_by_one()); let int_raw = spi.dma_int_raw().read();
if int_raw.inlink_dscr_error().bit_is_set() {
result |= DmaRxInterrupt::DescriptorError;
}
if int_raw.inlink_dscr_empty().bit_is_set() {
result |= DmaRxInterrupt::DescriptorEmpty;
}
if int_raw.in_suc_eof().bit_is_set() {
result |= DmaRxInterrupt::SuccessfulEof;
}
if int_raw.in_err_eof().bit_is_set() {
result |= DmaRxInterrupt::ErrorEof;
}
if int_raw.in_done().bit_is_set() {
result |= DmaRxInterrupt::Done;
}
result
} }
fn is_ch_in_done_set() -> bool { fn clear_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_raw().read().in_done().bit() spi.dma_int_clr().modify(|_, w| {
} for interrupt in interrupts.into() {
match interrupt {
fn unlisten_ch_in_done() { DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().clear_bit_by_one(),
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; DmaRxInterrupt::ErrorEof => w.in_err_eof().clear_bit_by_one(),
spi.dma_int_ena().modify(|_, w| w.in_done().clear_bit()); DmaRxInterrupt::DescriptorError => w.inlink_dscr_error().clear_bit_by_one(),
} DmaRxInterrupt::DescriptorEmpty => w.inlink_dscr_empty().clear_bit_by_one(),
DmaRxInterrupt::Done => w.in_done().clear_bit_by_one(),
fn is_listening_ch_in_done() -> bool { };
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR }; }
spi.dma_int_ena().read().in_done().bit() w
} })
fn listen_in_descriptor_error() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_,w| w.inlink_dscr_error().set_bit())
}
fn unlisten_in_descriptor_error() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_,w| w.inlink_dscr_error().clear_bit())
}
fn is_listening_in_descriptor_error() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().read().inlink_dscr_error().bit()
}
fn listen_in_descriptor_error_dscr_empty() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_,w| w.inlink_dscr_empty().set_bit())
}
fn unlisten_in_descriptor_error_dscr_empty() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_,w| w.inlink_dscr_empty().clear_bit())
}
fn is_listening_in_descriptor_error_dscr_empty() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().read().inlink_dscr_empty().bit()
}
fn listen_in_descriptor_error_err_eof() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_,w| w.in_err_eof().set_bit())
}
fn unlisten_in_descriptor_error_err_eof() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_,w| w.in_err_eof().clear_bit())
}
fn is_listening_in_descriptor_error_err_eof() -> bool{
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().read().in_err_eof().bit()
}
fn listen_out_descriptor_error() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_,w| w.outlink_dscr_error().set_bit())
}
fn unlisten_out_descriptor_error() {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().modify(|_,w| w.outlink_dscr_error().clear_bit())
}
fn is_listening_out_descriptor_error() -> bool {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_int_ena().read().outlink_dscr_error().bit()
} }
} }
@ -462,11 +463,6 @@ macro_rules! ImplI2sChannel {
.modify(|_, w| unsafe { w.outlink_addr().bits(address) }); .modify(|_, w| unsafe { w.outlink_addr().bits(address) });
} }
fn has_out_descriptor_error() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().out_dscr_err().bit()
}
fn set_out_peripheral(_peripheral: u8) { fn set_out_peripheral(_peripheral: u8) {
// no-op // no-op
} }
@ -476,54 +472,11 @@ macro_rules! ImplI2sChannel {
reg_block.out_link().modify(|_, w| w.outlink_start().set_bit()); reg_block.out_link().modify(|_, w| w.outlink_start().set_bit());
} }
fn clear_ch_out_done() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_clr().write(|w| w.out_done().clear_bit_by_one());
}
fn is_ch_out_done_set() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().out_done().bit()
}
fn listen_ch_out_done() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.out_done().set_bit());
}
fn unlisten_ch_out_done() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.out_done().clear_bit());
}
fn is_listening_ch_out_done() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().read().out_done().bit()
}
fn is_out_done() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().out_eof().bit()
}
fn last_out_dscr_address() -> usize { fn last_out_dscr_address() -> usize {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.out_eof_des_addr().read().out_eof_des_addr().bits() as usize reg_block.out_eof_des_addr().read().out_eof_des_addr().bits() as usize
} }
fn is_out_eof_interrupt_set() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().out_eof().bit()
}
fn reset_out_eof_interrupt() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_clr().write(|w| {
w.out_eof()
.clear_bit_by_one()
});
}
fn set_in_burstmode(burst_mode: bool) { fn set_in_burstmode(burst_mode: bool) {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.lc_conf() reg_block.lc_conf()
@ -558,21 +511,6 @@ macro_rules! ImplI2sChannel {
.modify(|_, w| unsafe { w.inlink_addr().bits(address) }); .modify(|_, w| unsafe { w.inlink_addr().bits(address) });
} }
fn has_in_descriptor_error() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().in_dscr_err().bit()
}
fn has_in_descriptor_error_dscr_empty() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().in_dscr_empty().bit()
}
fn has_in_descriptor_error_err_eof() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().in_err_eof().bit()
}
fn set_in_peripheral(_peripheral: u8) { fn set_in_peripheral(_peripheral: u8) {
// no-op // no-op
} }
@ -582,124 +520,187 @@ macro_rules! ImplI2sChannel {
reg_block.in_link().modify(|_, w| w.inlink_start().set_bit()); reg_block.in_link().modify(|_, w| w.inlink_start().set_bit());
} }
fn is_in_done() -> bool { fn listen_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().in_done().bit() reg_block.int_ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().set_bit(),
DmaTxInterrupt::DescriptorError => w.out_dscr_err().set_bit(),
DmaTxInterrupt::Eof => w.out_eof().set_bit(),
DmaTxInterrupt::Done => w.out_done().set_bit(),
};
}
w
})
} }
fn is_listening_in_eof() -> bool { fn unlisten_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().read().in_suc_eof().bit() reg_block.int_ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().clear_bit(),
DmaTxInterrupt::DescriptorError => w.out_dscr_err().clear_bit(),
DmaTxInterrupt::Eof => w.out_eof().clear_bit(),
DmaTxInterrupt::Done => w.out_done().clear_bit(),
};
}
w
})
} }
fn is_listening_out_eof() -> bool { fn is_listening_out() -> EnumSet<DmaTxInterrupt> {
let mut result = EnumSet::new();
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().read().out_eof().bit() let int_ena = reg_block.int_ena().read();
if int_ena.out_total_eof().bit_is_set() {
result |= DmaTxInterrupt::TotalEof;
}
if int_ena.out_dscr_err().bit_is_set() {
result |= DmaTxInterrupt::DescriptorError;
}
if int_ena.out_eof().bit_is_set() {
result |= DmaTxInterrupt::Eof;
}
if int_ena.out_done().bit_is_set() {
result |= DmaTxInterrupt::Done;
}
result
} }
fn listen_in_eof() { fn pending_out_interrupts() -> EnumSet<DmaTxInterrupt> {
let mut result = EnumSet::new();
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_,w| w.in_suc_eof().set_bit() ); let int_raw = reg_block.int_raw().read();
if int_raw.out_total_eof().bit_is_set() {
result |= DmaTxInterrupt::TotalEof;
}
if int_raw.out_dscr_err().bit_is_set() {
result |= DmaTxInterrupt::DescriptorError;
}
if int_raw.out_eof().bit_is_set() {
result |= DmaTxInterrupt::Eof;
}
if int_raw.out_done().bit_is_set() {
result |= DmaTxInterrupt::Done;
}
result
} }
fn listen_out_eof() { fn clear_out(interrupts: impl Into<EnumSet<DmaTxInterrupt>>) {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_,w| w.out_eof().set_bit() ); reg_block.int_clr().write(|w| {
for interrupt in interrupts.into() {
match interrupt {
DmaTxInterrupt::TotalEof => w.out_total_eof().clear_bit_by_one(),
DmaTxInterrupt::DescriptorError => w.out_dscr_err().clear_bit_by_one(),
DmaTxInterrupt::Eof => w.out_eof().clear_bit_by_one(),
DmaTxInterrupt::Done => w.out_done().clear_bit_by_one(),
};
}
w
})
} }
fn unlisten_in_eof() { fn listen_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_,w| w.in_suc_eof().clear_bit() ); reg_block.int_ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().set_bit(),
DmaRxInterrupt::ErrorEof => w.in_err_eof().set_bit(),
DmaRxInterrupt::DescriptorError => w.in_dscr_err().set_bit(),
DmaRxInterrupt::DescriptorEmpty => w.in_dscr_empty().set_bit(),
DmaRxInterrupt::Done => w.in_done().set_bit(),
};
}
w
})
} }
fn unlisten_out_eof() { fn unlisten_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_,w| w.out_eof().clear_bit() ); reg_block.int_ena().modify(|_, w| {
for interrupt in interrupts.into() {
match interrupt {
DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().clear_bit(),
DmaRxInterrupt::ErrorEof => w.in_err_eof().clear_bit(),
DmaRxInterrupt::DescriptorError => w.in_dscr_err().clear_bit(),
DmaRxInterrupt::DescriptorEmpty => w.in_dscr_empty().clear_bit(),
DmaRxInterrupt::Done => w.in_done().clear_bit(),
};
}
w
})
} }
fn listen_ch_in_done(){ fn is_listening_in() -> EnumSet<DmaRxInterrupt> {
let mut result = EnumSet::new();
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.in_done().set_bit()); let int_ena = reg_block.int_ena().read();
if int_ena.in_dscr_err().bit_is_set() {
result |= DmaRxInterrupt::DescriptorError;
}
if int_ena.in_dscr_empty().bit_is_set() {
result |= DmaRxInterrupt::DescriptorEmpty;
}
if int_ena.in_suc_eof().bit_is_set() {
result |= DmaRxInterrupt::SuccessfulEof;
}
if int_ena.in_err_eof().bit_is_set() {
result |= DmaRxInterrupt::ErrorEof;
}
if int_ena.in_done().bit_is_set() {
result |= DmaRxInterrupt::Done;
}
result
} }
fn clear_ch_in_done(){ fn pending_in_interrupts() -> EnumSet<DmaRxInterrupt> {
let mut result = EnumSet::new();
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_clr().write(|w| w.in_done().clear_bit_by_one()); let int_raw = reg_block.int_raw().read();
if int_raw.in_dscr_err().bit_is_set() {
result |= DmaRxInterrupt::DescriptorError;
}
if int_raw.in_dscr_empty().bit_is_set() {
result |= DmaRxInterrupt::DescriptorEmpty;
}
if int_raw.in_suc_eof().bit_is_set() {
result |= DmaRxInterrupt::SuccessfulEof;
}
if int_raw.in_err_eof().bit_is_set() {
result |= DmaRxInterrupt::ErrorEof;
}
if int_raw.in_done().bit_is_set() {
result |= DmaRxInterrupt::Done;
}
result
} }
fn is_ch_in_done_set() -> bool { fn clear_in(interrupts: impl Into<EnumSet<DmaRxInterrupt>>) {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_raw().read().in_done().bit() reg_block.int_clr().write(|w| {
} for interrupt in interrupts.into() {
match interrupt {
fn unlisten_ch_in_done() { DmaRxInterrupt::SuccessfulEof => w.in_suc_eof().clear_bit_by_one(),
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; DmaRxInterrupt::ErrorEof => w.in_err_eof().clear_bit_by_one(),
reg_block.int_ena().modify(|_, w| w.in_done().clear_bit()); DmaRxInterrupt::DescriptorError => w.in_dscr_err().clear_bit_by_one(),
} DmaRxInterrupt::DescriptorEmpty => w.in_dscr_empty().clear_bit_by_one(),
DmaRxInterrupt::Done => w.in_done().clear_bit_by_one(),
fn is_listening_ch_in_done() -> bool { };
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR }; }
reg_block.int_ena().read().in_done().bit() w
} })
fn listen_in_descriptor_error(){
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.in_dscr_err().set_bit());
}
fn unlisten_in_descriptor_error() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.in_dscr_err().clear_bit());
}
fn is_listening_in_descriptor_error() -> bool {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().read().in_dscr_err().bit()
}
fn listen_in_descriptor_error_dscr_empty() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.in_dscr_empty().set_bit());
}
fn unlisten_in_descriptor_error_dscr_empty() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.in_dscr_empty().clear_bit());
}
fn is_listening_in_descriptor_error_dscr_empty() -> bool{
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().read().in_dscr_empty().bit()
}
fn listen_in_descriptor_error_err_eof() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.in_err_eof().set_bit());
}
fn unlisten_in_descriptor_error_err_eof() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.in_err_eof().clear_bit());
}
fn is_listening_in_descriptor_error_err_eof() -> bool{
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().read().in_err_eof().bit()
}
fn listen_out_descriptor_error() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.out_dscr_err().set_bit());
}
fn unlisten_out_descriptor_error() {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().modify(|_, w| w.out_dscr_err().clear_bit());
}
fn is_listening_out_descriptor_error() -> bool{
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.int_ena().read().out_dscr_err().bit()
} }
} }