1082: stm32: Add basic support for DMA priority settings r=lulf a=matoushybl This adds very basic support for specifying priority for DMA interrupts. Unfortunately, the patch now doesn't allow for specifying different priorities for DMA1/DMA2, or BDMA1/BDMA2, which I didn't know how to support. 1083: stm32: Fix H7 unaligned erase r=lulf a=matoushybl This PR simplifies erasing sectors on the H7, which was buggy. Co-authored-by: Matous Hybl <hyblmatous@gmail.com>
This commit is contained in:
commit
9f854110f2
@ -3,6 +3,7 @@
|
|||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
||||||
|
use embassy_cortex_m::interrupt::Priority;
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use super::{TransferOptions, Word, WordSize};
|
use super::{TransferOptions, Word, WordSize};
|
||||||
@ -38,10 +39,12 @@ impl State {
|
|||||||
static STATE: State = State::new();
|
static STATE: State = State::new();
|
||||||
|
|
||||||
/// safety: must be called only once
|
/// safety: must be called only once
|
||||||
pub(crate) unsafe fn init() {
|
pub(crate) unsafe fn init(irq_priority: Priority) {
|
||||||
foreach_interrupt! {
|
foreach_interrupt! {
|
||||||
($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => {
|
($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => {
|
||||||
crate::interrupt::$irq::steal().enable();
|
let irq = crate::interrupt::$irq::steal();
|
||||||
|
irq.set_priority(irq_priority);
|
||||||
|
irq.enable();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
crate::_generated::init_bdma();
|
crate::_generated::init_bdma();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
||||||
|
use embassy_cortex_m::interrupt::Priority;
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use super::{Burst, FlowControl, Request, TransferOptions, Word, WordSize};
|
use super::{Burst, FlowControl, Request, TransferOptions, Word, WordSize};
|
||||||
@ -67,10 +68,12 @@ impl State {
|
|||||||
static STATE: State = State::new();
|
static STATE: State = State::new();
|
||||||
|
|
||||||
/// safety: must be called only once
|
/// safety: must be called only once
|
||||||
pub(crate) unsafe fn init() {
|
pub(crate) unsafe fn init(irq_priority: 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) => {
|
||||||
interrupt::$irq::steal().enable();
|
let irq = interrupt::$irq::steal();
|
||||||
|
irq.set_priority(irq_priority);
|
||||||
|
irq.enable();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
crate::_generated::init_dma();
|
crate::_generated::init_dma();
|
||||||
|
@ -12,6 +12,8 @@ use core::mem;
|
|||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll, Waker};
|
use core::task::{Context, Poll, Waker};
|
||||||
|
|
||||||
|
#[cfg(any(dma, bdma))]
|
||||||
|
use embassy_cortex_m::interrupt::Priority;
|
||||||
use embassy_hal_common::{impl_peripheral, into_ref};
|
use embassy_hal_common::{impl_peripheral, into_ref};
|
||||||
|
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
@ -294,11 +296,11 @@ pub struct NoDma;
|
|||||||
impl_peripheral!(NoDma);
|
impl_peripheral!(NoDma);
|
||||||
|
|
||||||
// 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(#[cfg(bdma)] bdma_priority: Priority, #[cfg(dma)] dma_priority: Priority) {
|
||||||
#[cfg(bdma)]
|
#[cfg(bdma)]
|
||||||
bdma::init();
|
bdma::init(bdma_priority);
|
||||||
#[cfg(dma)]
|
#[cfg(dma)]
|
||||||
dma::init();
|
dma::init(dma_priority);
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
dmamux::init();
|
dmamux::init();
|
||||||
#[cfg(gpdma)]
|
#[cfg(gpdma)]
|
||||||
|
@ -79,24 +79,19 @@ pub(crate) unsafe fn blocking_erase(from: u32, to: u32) -> Result<(), Error> {
|
|||||||
let from = from - super::FLASH_BASE as u32;
|
let from = from - super::FLASH_BASE as u32;
|
||||||
let to = to - super::FLASH_BASE as u32;
|
let to = to - super::FLASH_BASE as u32;
|
||||||
|
|
||||||
let bank_size = (super::FLASH_SIZE / 2) as u32;
|
let (start, end) = if to <= super::FLASH_SIZE as u32 {
|
||||||
|
|
||||||
let (bank, start, end) = if to <= bank_size {
|
|
||||||
let start_sector = from / super::ERASE_SIZE as u32;
|
let start_sector = from / super::ERASE_SIZE as u32;
|
||||||
let end_sector = to / super::ERASE_SIZE as u32;
|
let end_sector = to / super::ERASE_SIZE as u32;
|
||||||
(0, start_sector, end_sector)
|
(start_sector, end_sector)
|
||||||
} else if from >= SECOND_BANK_OFFSET as u32 && to <= (SECOND_BANK_OFFSET as u32 + bank_size) {
|
|
||||||
let start_sector = (from - SECOND_BANK_OFFSET as u32) / super::ERASE_SIZE as u32;
|
|
||||||
let end_sector = (to - SECOND_BANK_OFFSET as u32) / super::ERASE_SIZE as u32;
|
|
||||||
(1, start_sector, end_sector)
|
|
||||||
} else {
|
} else {
|
||||||
error!("Attempting to write outside of defined sectors");
|
error!("Attempting to write outside of defined sectors {:x} {:x}", from, to);
|
||||||
return Err(Error::Unaligned);
|
return Err(Error::Unaligned);
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("Erasing bank {}, sectors from {} to {}", bank, start, end);
|
trace!("Erasing sectors from {} to {}", start, end);
|
||||||
for sector in start..end {
|
for sector in start..end {
|
||||||
let ret = erase_sector(pac::FLASH.bank(bank), sector as u8);
|
let bank = if sector >= 8 { 1 } else { 0 };
|
||||||
|
let ret = erase_sector(pac::FLASH.bank(bank), (sector % 8) as u8);
|
||||||
if ret.is_err() {
|
if ret.is_err() {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,8 @@ pub(crate) mod _generated {
|
|||||||
// Reexports
|
// Reexports
|
||||||
pub use _generated::{peripherals, Peripherals};
|
pub use _generated::{peripherals, Peripherals};
|
||||||
pub use embassy_cortex_m::executor;
|
pub use embassy_cortex_m::executor;
|
||||||
|
#[cfg(any(dma, bdma))]
|
||||||
|
use embassy_cortex_m::interrupt::Priority;
|
||||||
pub use embassy_cortex_m::interrupt::_export::interrupt;
|
pub use embassy_cortex_m::interrupt::_export::interrupt;
|
||||||
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||||
#[cfg(feature = "unstable-pac")]
|
#[cfg(feature = "unstable-pac")]
|
||||||
@ -91,6 +93,10 @@ pub struct Config {
|
|||||||
pub rcc: rcc::Config,
|
pub rcc: rcc::Config,
|
||||||
#[cfg(dbgmcu)]
|
#[cfg(dbgmcu)]
|
||||||
pub enable_debug_during_sleep: bool,
|
pub enable_debug_during_sleep: bool,
|
||||||
|
#[cfg(bdma)]
|
||||||
|
pub bdma_interrupt_priority: Priority,
|
||||||
|
#[cfg(dma)]
|
||||||
|
pub dma_interrupt_priority: Priority,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@ -99,6 +105,10 @@ impl Default for Config {
|
|||||||
rcc: Default::default(),
|
rcc: Default::default(),
|
||||||
#[cfg(dbgmcu)]
|
#[cfg(dbgmcu)]
|
||||||
enable_debug_during_sleep: true,
|
enable_debug_during_sleep: true,
|
||||||
|
#[cfg(bdma)]
|
||||||
|
bdma_interrupt_priority: Priority::P0,
|
||||||
|
#[cfg(dma)]
|
||||||
|
dma_interrupt_priority: Priority::P0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +147,12 @@ pub fn init(config: Config) -> Peripherals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gpio::init();
|
gpio::init();
|
||||||
dma::init();
|
dma::init(
|
||||||
|
#[cfg(bdma)]
|
||||||
|
config.bdma_interrupt_priority,
|
||||||
|
#[cfg(dma)]
|
||||||
|
config.dma_interrupt_priority,
|
||||||
|
);
|
||||||
#[cfg(feature = "exti")]
|
#[cfg(feature = "exti")]
|
||||||
exti::init();
|
exti::init();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user