Merge pull request from caleb-garrett/dma-priority

Configurable DMA Request Priority
This commit is contained in:
Dario Nieuwenhuis 2024-03-10 22:42:03 +00:00 committed by GitHub
commit ac06ca2fa0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 52 additions and 10 deletions
embassy-stm32/src

View file

@ -10,8 +10,7 @@ use super::ringbuffer::{DmaCtrl, OverrunError, ReadableDmaRingBuffer, WritableDm
use super::word::{Word, WordSize}; use super::word::{Word, WordSize};
use super::{AnyChannel, Channel, Dir, Request, STATE}; use super::{AnyChannel, Channel, Dir, Request, STATE};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::interrupt::Priority; use crate::{interrupt, pac};
use crate::pac;
pub(crate) struct ChannelInfo { pub(crate) struct ChannelInfo {
pub(crate) dma: DmaInfo, pub(crate) dma: DmaInfo,
@ -45,6 +44,8 @@ pub struct TransferOptions {
/// FIFO threshold for DMA FIFO mode. If none, direct mode is used. /// FIFO threshold for DMA FIFO mode. If none, direct mode is used.
#[cfg(dma)] #[cfg(dma)]
pub fifo_threshold: Option<FifoThreshold>, pub fifo_threshold: Option<FifoThreshold>,
/// Request priority level
pub priority: Priority,
/// Enable circular DMA /// Enable circular DMA
/// ///
/// Note: /// Note:
@ -68,6 +69,7 @@ impl Default for TransferOptions {
flow_ctrl: FlowControl::Dma, flow_ctrl: FlowControl::Dma,
#[cfg(dma)] #[cfg(dma)]
fifo_threshold: None, fifo_threshold: None,
priority: Priority::VeryHigh,
circular: false, circular: false,
half_transfer_ir: false, half_transfer_ir: false,
complete_transfer_ir: true, complete_transfer_ir: true,
@ -75,6 +77,44 @@ impl Default for TransferOptions {
} }
} }
/// 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,
}
#[cfg(dma)]
impl From<Priority> for pac::dma::vals::Pl {
fn from(value: Priority) -> Self {
match value {
Priority::Low => pac::dma::vals::Pl::LOW,
Priority::Medium => pac::dma::vals::Pl::MEDIUM,
Priority::High => pac::dma::vals::Pl::HIGH,
Priority::VeryHigh => pac::dma::vals::Pl::VERYHIGH,
}
}
}
#[cfg(bdma)]
impl From<Priority> for pac::bdma::vals::Pl {
fn from(value: Priority) -> Self {
match value {
Priority::Low => pac::bdma::vals::Pl::LOW,
Priority::Medium => pac::bdma::vals::Pl::MEDIUM,
Priority::High => pac::bdma::vals::Pl::HIGH,
Priority::VeryHigh => pac::bdma::vals::Pl::VERYHIGH,
}
}
}
#[cfg(dma)] #[cfg(dma)]
pub use dma_only::*; pub use dma_only::*;
#[cfg(dma)] #[cfg(dma)]
@ -213,8 +253,8 @@ impl ChannelState {
/// safety: must be called only once /// safety: must be called only once
pub(crate) unsafe fn init( pub(crate) unsafe fn init(
cs: critical_section::CriticalSection, cs: critical_section::CriticalSection,
#[cfg(dma)] dma_priority: Priority, #[cfg(dma)] dma_priority: interrupt::Priority,
#[cfg(bdma)] bdma_priority: Priority, #[cfg(bdma)] bdma_priority: interrupt::Priority,
) { ) {
foreach_interrupt! { foreach_interrupt! {
($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => { ($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => {
@ -334,7 +374,7 @@ impl AnyChannel {
w.set_dir(dir.into()); w.set_dir(dir.into());
w.set_msize(data_size.into()); w.set_msize(data_size.into());
w.set_psize(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_minc(incr_mem);
w.set_pinc(false); w.set_pinc(false);
w.set_teie(true); w.set_teie(true);
@ -374,7 +414,7 @@ impl AnyChannel {
w.set_tcie(options.complete_transfer_ir); w.set_tcie(options.complete_transfer_ir);
w.set_htie(options.half_transfer_ir); w.set_htie(options.half_transfer_ir);
w.set_circ(options.circular); 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 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 embassy_hal_internal::{impl_peripheral, Peripheral};
use crate::interrupt::Priority; use crate::interrupt;
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[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 // safety: must be called only once at startup
pub(crate) unsafe fn init( pub(crate) unsafe fn init(
cs: critical_section::CriticalSection, cs: critical_section::CriticalSection,
#[cfg(bdma)] bdma_priority: Priority, #[cfg(bdma)] bdma_priority: interrupt::Priority,
#[cfg(dma)] dma_priority: Priority, #[cfg(dma)] dma_priority: interrupt::Priority,
#[cfg(gpdma)] gpdma_priority: Priority, #[cfg(gpdma)] gpdma_priority: interrupt::Priority,
) { ) {
#[cfg(any(dma, bdma))] #[cfg(any(dma, bdma))]
dma_bdma::init( dma_bdma::init(

View file

@ -240,12 +240,14 @@ const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOp
mburst: crate::dma::Burst::Incr4, mburst: crate::dma::Burst::Incr4,
flow_ctrl: crate::dma::FlowControl::Peripheral, flow_ctrl: crate::dma::FlowControl::Peripheral,
fifo_threshold: Some(crate::dma::FifoThreshold::Full), fifo_threshold: Some(crate::dma::FifoThreshold::Full),
priority: crate::dma::Priority::VeryHigh,
circular: false, circular: false,
half_transfer_ir: false, half_transfer_ir: false,
complete_transfer_ir: true, complete_transfer_ir: true,
}; };
#[cfg(all(sdmmc_v1, not(dma)))] #[cfg(all(sdmmc_v1, not(dma)))]
const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions { const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions {
priority: crate::dma::Priority::VeryHigh,
circular: false, circular: false,
half_transfer_ir: false, half_transfer_ir: false,
complete_transfer_ir: true, complete_transfer_ir: true,