stm32/dma: simplify impls a bit.
This commit is contained in:
parent
b316d2620c
commit
022c4cb739
@ -59,7 +59,7 @@ unsafe fn on_irq() {
|
|||||||
let isr = pac::$dma.isr().read();
|
let isr = pac::$dma.isr().read();
|
||||||
let dman = dma_num!($dma);
|
let dman = dma_num!($dma);
|
||||||
|
|
||||||
for chn in 0..crate::pac::dma_channels_count!($dma) {
|
for chn in 0..pac::dma_channels_count!($dma) {
|
||||||
let cr = pac::$dma.ch(chn).cr();
|
let cr = pac::$dma.ch(chn).cr();
|
||||||
if isr.tcif(chn) && cr.read().tcie() {
|
if isr.tcif(chn) && cr.read().tcie() {
|
||||||
cr.write(|_| ()); // Disable channel interrupts with the default value.
|
cr.write(|_| ()); // Disable channel interrupts with the default value.
|
||||||
@ -90,9 +90,8 @@ pac::dma_channels! {
|
|||||||
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
||||||
|
|
||||||
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
|
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
|
||||||
low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
|
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
crate::pac::$dma_peri,
|
pac::$dma_peri,
|
||||||
$channel_num,
|
$channel_num,
|
||||||
#[cfg(any(bdma_v2, dmamux))]
|
#[cfg(any(bdma_v2, dmamux))]
|
||||||
request,
|
request,
|
||||||
@ -112,9 +111,8 @@ pac::dma_channels! {
|
|||||||
|
|
||||||
unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) {
|
unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) {
|
||||||
let buf = [repeated];
|
let buf = [repeated];
|
||||||
low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
|
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
crate::pac::$dma_peri,
|
pac::$dma_peri,
|
||||||
$channel_num,
|
$channel_num,
|
||||||
#[cfg(any(bdma_v2, dmamux))]
|
#[cfg(any(bdma_v2, dmamux))]
|
||||||
request,
|
request,
|
||||||
@ -132,9 +130,8 @@ pac::dma_channels! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
|
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
|
||||||
low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
|
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
crate::pac::$dma_peri,
|
pac::$dma_peri,
|
||||||
$channel_num,
|
$channel_num,
|
||||||
#[cfg(any(bdma_v2, dmamux))]
|
#[cfg(any(bdma_v2, dmamux))]
|
||||||
request,
|
request,
|
||||||
@ -152,14 +149,14 @@ pac::dma_channels! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn request_stop(&mut self){
|
fn request_stop(&mut self){
|
||||||
unsafe {low_level_api::request_stop(crate::pac::$dma_peri, $channel_num);}
|
unsafe {low_level_api::request_stop(pac::$dma_peri, $channel_num);}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_running(&self) -> bool {
|
fn is_running(&self) -> bool {
|
||||||
unsafe {low_level_api::is_running(crate::pac::$dma_peri, $channel_num)}
|
unsafe {low_level_api::is_running(pac::$dma_peri, $channel_num)}
|
||||||
}
|
}
|
||||||
fn remaining_transfers(&mut self) -> u16 {
|
fn remaining_transfers(&mut self) -> u16 {
|
||||||
unsafe {low_level_api::get_remaining_transfers(crate::pac::$dma_peri, $channel_num)}
|
unsafe {low_level_api::get_remaining_transfers(pac::$dma_peri, $channel_num)}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_waker(&mut self, waker: &Waker) {
|
fn set_waker(&mut self, waker: &Waker) {
|
||||||
@ -198,6 +195,8 @@ mod low_level_api {
|
|||||||
) {
|
) {
|
||||||
let ch = dma.ch(channel_number as _);
|
let ch = dma.ch(channel_number as _);
|
||||||
|
|
||||||
|
reset_status(dma, channel_number);
|
||||||
|
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
super::super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request);
|
super::super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request);
|
||||||
|
|
||||||
|
@ -85,17 +85,15 @@ pac::dma_channels! {
|
|||||||
($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => {
|
($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => {
|
||||||
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
||||||
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
|
unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
|
||||||
let isrn = $channel_num as usize / 4;
|
|
||||||
let isrbit = $channel_num as usize % 4;
|
|
||||||
low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
|
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
|
pac::$dma_peri,
|
||||||
|
$channel_num,
|
||||||
request,
|
request,
|
||||||
vals::Dir::MEMORYTOPERIPHERAL,
|
vals::Dir::MEMORYTOPERIPHERAL,
|
||||||
reg_addr as *const u32,
|
reg_addr as *const u32,
|
||||||
buf.as_ptr() as *mut u32,
|
buf.as_ptr() as *mut u32,
|
||||||
buf.len(),
|
buf.len(),
|
||||||
true,
|
true,
|
||||||
crate::pac::$dma_peri.st($channel_num as _),
|
|
||||||
vals::Size::from(W::bits()),
|
vals::Size::from(W::bits()),
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
<Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
|
<Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
|
||||||
@ -106,17 +104,15 @@ pac::dma_channels! {
|
|||||||
|
|
||||||
unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) {
|
unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) {
|
||||||
let buf = [repeated];
|
let buf = [repeated];
|
||||||
let isrn = $channel_num as usize / 4;
|
|
||||||
let isrbit = $channel_num as usize % 4;
|
|
||||||
low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
|
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
|
pac::$dma_peri,
|
||||||
|
$channel_num,
|
||||||
request,
|
request,
|
||||||
vals::Dir::MEMORYTOPERIPHERAL,
|
vals::Dir::MEMORYTOPERIPHERAL,
|
||||||
reg_addr as *const u32,
|
reg_addr as *const u32,
|
||||||
buf.as_ptr() as *mut u32,
|
buf.as_ptr() as *mut u32,
|
||||||
count,
|
count,
|
||||||
false,
|
false,
|
||||||
crate::pac::$dma_peri.st($channel_num as _),
|
|
||||||
vals::Size::from(W::bits()),
|
vals::Size::from(W::bits()),
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
<Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
|
<Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
|
||||||
@ -126,17 +122,15 @@ pac::dma_channels! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
|
unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
|
||||||
let isrn = $channel_num as usize / 4;
|
|
||||||
let isrbit = $channel_num as usize % 4;
|
|
||||||
low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
|
|
||||||
low_level_api::start_transfer(
|
low_level_api::start_transfer(
|
||||||
|
pac::$dma_peri,
|
||||||
|
$channel_num,
|
||||||
request,
|
request,
|
||||||
vals::Dir::PERIPHERALTOMEMORY,
|
vals::Dir::PERIPHERALTOMEMORY,
|
||||||
reg_addr as *const u32,
|
reg_addr as *const u32,
|
||||||
buf.as_ptr() as *mut u32,
|
buf.as_ptr() as *mut u32,
|
||||||
buf.len(),
|
buf.len(),
|
||||||
true,
|
true,
|
||||||
crate::pac::$dma_peri.st($channel_num as _),
|
|
||||||
vals::Size::from(W::bits()),
|
vals::Size::from(W::bits()),
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
<Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
|
<Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
|
||||||
@ -146,15 +140,15 @@ pac::dma_channels! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn request_stop(&mut self) {
|
fn request_stop(&mut self) {
|
||||||
unsafe {low_level_api::request_stop(&crate::pac::$dma_peri, $channel_num);}
|
unsafe {low_level_api::request_stop(pac::$dma_peri, $channel_num);}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_running(&self) -> bool {
|
fn is_running(&self) -> bool {
|
||||||
unsafe {low_level_api::is_running(&crate::pac::$dma_peri, $channel_num)}
|
unsafe {low_level_api::is_running(pac::$dma_peri, $channel_num)}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remaining_transfers(&mut self) -> u16 {
|
fn remaining_transfers(&mut self) -> u16 {
|
||||||
unsafe {low_level_api::get_remaining_transfers(&crate::pac::$dma_peri, $channel_num)}
|
unsafe {low_level_api::get_remaining_transfers(pac::$dma_peri, $channel_num)}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_waker(&mut self, waker: &Waker) {
|
fn set_waker(&mut self, waker: &Waker) {
|
||||||
@ -179,13 +173,14 @@ mod low_level_api {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub unsafe fn start_transfer(
|
pub unsafe fn start_transfer(
|
||||||
|
dma: pac::dma::Dma,
|
||||||
|
channel_number: u8,
|
||||||
request: Request,
|
request: Request,
|
||||||
dir: vals::Dir,
|
dir: vals::Dir,
|
||||||
peri_addr: *const u32,
|
peri_addr: *const u32,
|
||||||
mem_addr: *mut u32,
|
mem_addr: *mut u32,
|
||||||
mem_len: usize,
|
mem_len: usize,
|
||||||
incr_mem: bool,
|
incr_mem: bool,
|
||||||
ch: crate::pac::dma::St,
|
|
||||||
data_size: vals::Size,
|
data_size: vals::Size,
|
||||||
#[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
|
#[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
|
||||||
#[cfg(dmamux)] dmamux_ch_num: u8,
|
#[cfg(dmamux)] dmamux_ch_num: u8,
|
||||||
@ -196,6 +191,9 @@ mod low_level_api {
|
|||||||
// "Preceding reads and writes cannot be moved past subsequent writes."
|
// "Preceding reads and writes cannot be moved past subsequent writes."
|
||||||
fence(Ordering::SeqCst);
|
fence(Ordering::SeqCst);
|
||||||
|
|
||||||
|
reset_status(dma, channel_number);
|
||||||
|
|
||||||
|
let ch = dma.st(channel_number as _);
|
||||||
ch.par().write_value(peri_addr as u32);
|
ch.par().write_value(peri_addr as u32);
|
||||||
ch.m0ar().write_value(mem_addr as u32);
|
ch.m0ar().write_value(mem_addr as u32);
|
||||||
ch.ndtr().write_value(regs::Ndtr(mem_len as _));
|
ch.ndtr().write_value(regs::Ndtr(mem_len as _));
|
||||||
@ -223,34 +221,31 @@ mod low_level_api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Stops the DMA channel.
|
/// Stops the DMA channel.
|
||||||
pub unsafe fn request_stop(dma: &pac::dma::Dma, channel_number: u8) {
|
pub unsafe fn request_stop(dma: pac::dma::Dma, channel_number: u8) {
|
||||||
// Reset status
|
|
||||||
let isrn = channel_number as usize / 4;
|
|
||||||
let isrbit = channel_number as usize % 4;
|
|
||||||
reset_status(dma, isrn, isrbit);
|
|
||||||
|
|
||||||
// get a handle on the channel itself
|
// get a handle on the channel itself
|
||||||
let ch = dma.st(channel_number as _);
|
let ch = dma.st(channel_number as _);
|
||||||
|
|
||||||
// Disable the channel and interrupts with the default value.
|
// Disable the channel. Keep the IEs enabled so the irqs still fire.
|
||||||
ch.cr().write(|_| ());
|
ch.cr().write(|w| {
|
||||||
|
w.set_teie(true);
|
||||||
|
w.set_tcie(true);
|
||||||
|
});
|
||||||
|
|
||||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||||
fence(Ordering::SeqCst);
|
fence(Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the running status of the channel
|
/// Gets the running status of the channel
|
||||||
pub unsafe fn is_running(dma: &pac::dma::Dma, ch: u8) -> bool {
|
pub unsafe fn is_running(dma: pac::dma::Dma, ch: u8) -> bool {
|
||||||
// get a handle on the channel itself
|
// get a handle on the channel itself
|
||||||
let ch = dma.st(ch as _);
|
let ch = dma.st(ch as _);
|
||||||
|
// Get whether it's enabled (running)
|
||||||
// Wait for the transfer to complete when it was ongoing.
|
|
||||||
ch.cr().read().en()
|
ch.cr().read().en()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the total remaining transfers for the channel
|
/// Gets the total remaining transfers for the channel
|
||||||
/// Note: this will be zero for transfers that completed without cancellation.
|
/// Note: this will be zero for transfers that completed without cancellation.
|
||||||
pub unsafe fn get_remaining_transfers(dma: &pac::dma::Dma, ch: u8) -> u16 {
|
pub unsafe fn get_remaining_transfers(dma: pac::dma::Dma, ch: u8) -> u16 {
|
||||||
// get a handle on the channel itself
|
// get a handle on the channel itself
|
||||||
let ch = dma.st(ch as _);
|
let ch = dma.st(ch as _);
|
||||||
// read the remaining transfer count. If this is zero, the transfer completed fully.
|
// read the remaining transfer count. If this is zero, the transfer completed fully.
|
||||||
@ -262,7 +257,10 @@ mod low_level_api {
|
|||||||
STATE.ch_wakers[state_number].register(waker);
|
STATE.ch_wakers[state_number].register(waker);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn reset_status(dma: &crate::pac::dma::Dma, isrn: usize, isrbit: usize) {
|
pub unsafe fn reset_status(dma: pac::dma::Dma, channel_number: u8) {
|
||||||
|
let isrn = channel_number as usize / 4;
|
||||||
|
let isrbit = channel_number as usize % 4;
|
||||||
|
|
||||||
dma.ifcr(isrn).write(|w| {
|
dma.ifcr(isrn).write(|w| {
|
||||||
w.set_tcif(isrbit, true);
|
w.set_tcif(isrbit, true);
|
||||||
w.set_teif(isrbit, true);
|
w.set_teif(isrbit, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user