Add DMA request priority as transfer option.

This commit is contained in:
Caleb Garrett 2024-03-10 16:53:37 -04:00
parent a58891891b
commit e92094986d
3 changed files with 63 additions and 9 deletions

View file

@ -10,7 +10,7 @@ use super::ringbuffer::{DmaCtrl, OverrunError, ReadableDmaRingBuffer, WritableDm
use super::word::{Word, WordSize};
use super::{AnyChannel, Channel, Dir, Request, STATE};
use crate::interrupt::typelevel::Interrupt;
use crate::interrupt::Priority;
use crate::interrupt;
use crate::pac;
pub(crate) struct ChannelInfo {
@ -45,6 +45,8 @@ pub struct TransferOptions {
/// FIFO threshold for DMA FIFO mode. If none, direct mode is used.
#[cfg(dma)]
pub fifo_threshold: Option<FifoThreshold>,
/// Request priority level
pub priority: Priority,
/// Enable circular DMA
///
/// Note:
@ -68,6 +70,7 @@ impl Default for TransferOptions {
flow_ctrl: FlowControl::Dma,
#[cfg(dma)]
fifo_threshold: None,
priority: Priority::VeryHigh,
circular: false,
half_transfer_ir: false,
complete_transfer_ir: true,
@ -170,6 +173,31 @@ mod dma_only {
}
}
}
/// DMA request priority
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Priority {
/// Low Priority
Low,
/// Medium Priority
Medium,
/// High Priority
High,
/// Very High Priority
VeryHigh,
}
impl From<Priority> for vals::Pl {
fn from(value: Priority) -> Self {
match value {
Priority::Low => vals::Pl::LOW,
Priority::Medium => vals::Pl::MEDIUM,
Priority::High => vals::Pl::HIGH,
Priority::VeryHigh => vals::Pl::VERYHIGH,
}
}
}
}
#[cfg(bdma)]
@ -196,6 +224,31 @@ mod bdma_only {
}
}
}
/// DMA request priority
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Priority {
/// Low Priority
Low,
/// Medium Priority
Medium,
/// High Priority
High,
/// Very High Priority
VeryHigh,
}
impl From<Priority> for vals::Pl {
fn from(value: Priority) -> Self {
match value {
Priority::Low => vals::Pl::LOW,
Priority::Medium => vals::Pl::MEDIUM,
Priority::High => vals::Pl::HIGH,
Priority::VeryHigh => vals::Pl::VERYHIGH,
}
}
}
}
pub(crate) struct ChannelState {
@ -213,8 +266,8 @@ impl ChannelState {
/// safety: must be called only once
pub(crate) unsafe fn init(
cs: critical_section::CriticalSection,
#[cfg(dma)] dma_priority: Priority,
#[cfg(bdma)] bdma_priority: Priority,
#[cfg(dma)] dma_priority: interrupt::Priority,
#[cfg(bdma)] bdma_priority: interrupt::Priority,
) {
foreach_interrupt! {
($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => {
@ -334,7 +387,7 @@ impl AnyChannel {
w.set_dir(dir.into());
w.set_msize(data_size.into());
w.set_psize(data_size.into());
w.set_pl(pac::dma::vals::Pl::VERYHIGH);
w.set_pl(options.priority.into());
w.set_minc(incr_mem);
w.set_pinc(false);
w.set_teie(true);
@ -374,7 +427,7 @@ impl AnyChannel {
w.set_tcie(options.complete_transfer_ir);
w.set_htie(options.half_transfer_ir);
w.set_circ(options.circular);
w.set_pl(pac::bdma::vals::Pl::VERYHIGH);
w.set_pl(options.priority.into());
w.set_en(false); // don't start yet
});
}

View file

@ -23,7 +23,7 @@ use core::mem;
use embassy_hal_internal::{impl_peripheral, Peripheral};
use crate::interrupt::Priority;
use crate::interrupt;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@ -131,9 +131,9 @@ pub(crate) fn slice_ptr_parts_mut<T>(slice: *mut [T]) -> (usize, usize) {
// safety: must be called only once at startup
pub(crate) unsafe fn init(
cs: critical_section::CriticalSection,
#[cfg(bdma)] bdma_priority: Priority,
#[cfg(dma)] dma_priority: Priority,
#[cfg(gpdma)] gpdma_priority: Priority,
#[cfg(bdma)] bdma_priority: interrupt::Priority,
#[cfg(dma)] dma_priority: interrupt::Priority,
#[cfg(gpdma)] gpdma_priority: interrupt::Priority,
) {
#[cfg(any(dma, bdma))]
dma_bdma::init(

View file

@ -240,6 +240,7 @@ const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOp
mburst: crate::dma::Burst::Incr4,
flow_ctrl: crate::dma::FlowControl::Peripheral,
fifo_threshold: Some(crate::dma::FifoThreshold::Full),
priority: crate::dma::Priority::VeryHigh,
circular: false,
half_transfer_ir: false,
complete_transfer_ir: true,