stm32/sdmmc: Fix SDIOv1 writes
This commit is contained in:
@ -192,6 +192,7 @@ mod low_level_api {
|
||||
options.flow_ctrl == crate::dma::FlowControl::Dma,
|
||||
"Peripheral flow control not supported"
|
||||
);
|
||||
assert!(options.fifo_threshold.is_none(), "FIFO mode not supported");
|
||||
|
||||
let ch = dma.ch(channel_number as _);
|
||||
|
||||
|
@ -4,7 +4,7 @@ use core::task::Waker;
|
||||
use embassy_cortex_m::interrupt::Priority;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use super::{Burst, FlowControl, Request, TransferOptions, Word, WordSize};
|
||||
use super::{Burst, FifoThreshold, FlowControl, Request, TransferOptions, Word, WordSize};
|
||||
use crate::_generated::DMA_CHANNEL_COUNT;
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::pac::dma::{regs, vals};
|
||||
@ -40,6 +40,17 @@ impl From<FlowControl> for vals::Pfctrl {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FifoThreshold> for vals::Fth {
|
||||
fn from(value: FifoThreshold) -> Self {
|
||||
match value {
|
||||
FifoThreshold::Quarter => vals::Fth::QUARTER,
|
||||
FifoThreshold::Half => vals::Fth::HALF,
|
||||
FifoThreshold::ThreeQuarters => vals::Fth::THREEQUARTERS,
|
||||
FifoThreshold::Full => vals::Fth::FULL,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ChannelState {
|
||||
waker: AtomicWaker,
|
||||
}
|
||||
@ -236,6 +247,16 @@ mod low_level_api {
|
||||
ch.par().write_value(peri_addr as u32);
|
||||
ch.m0ar().write_value(mem_addr as u32);
|
||||
ch.ndtr().write_value(regs::Ndtr(mem_len as _));
|
||||
ch.fcr().write(|w| {
|
||||
if let Some(fth) = options.fifo_threshold {
|
||||
// FIFO mode
|
||||
w.set_dmdis(vals::Dmdis::DISABLED);
|
||||
w.set_fth(fth.into());
|
||||
} else {
|
||||
// Direct mode
|
||||
w.set_dmdis(vals::Dmdis::ENABLED);
|
||||
}
|
||||
});
|
||||
ch.cr().write(|w| {
|
||||
w.set_dir(dir);
|
||||
w.set_msize(data_size);
|
||||
|
@ -176,8 +176,16 @@ mod low_level_api {
|
||||
mem_len: usize,
|
||||
incr_mem: bool,
|
||||
data_size: WordSize,
|
||||
_options: TransferOptions,
|
||||
options: TransferOptions,
|
||||
) {
|
||||
assert!(options.mburst == crate::dma::Burst::Single, "Burst mode not supported");
|
||||
assert!(options.pburst == crate::dma::Burst::Single, "Burst mode not supported");
|
||||
assert!(
|
||||
options.flow_ctrl == crate::dma::FlowControl::Dma,
|
||||
"Peripheral flow control not supported"
|
||||
);
|
||||
assert!(options.fifo_threshold.is_none(), "FIFO mode not supported");
|
||||
|
||||
// "Preceding reads and writes cannot be moved past subsequent writes."
|
||||
fence(Ordering::SeqCst);
|
||||
|
||||
|
@ -186,6 +186,19 @@ pub enum FlowControl {
|
||||
Peripheral,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum FifoThreshold {
|
||||
/// 1/4 full FIFO
|
||||
Quarter,
|
||||
/// 1/2 full FIFO
|
||||
Half,
|
||||
/// 3/4 full FIFO
|
||||
ThreeQuarters,
|
||||
/// Full FIFO
|
||||
Full,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct TransferOptions {
|
||||
@ -195,6 +208,8 @@ pub struct TransferOptions {
|
||||
pub mburst: Burst,
|
||||
/// Flow control configuration
|
||||
pub flow_ctrl: FlowControl,
|
||||
/// FIFO threshold for DMA FIFO mode. If none, direct mode is used.
|
||||
pub fifo_threshold: Option<FifoThreshold>,
|
||||
}
|
||||
|
||||
impl Default for TransferOptions {
|
||||
@ -203,6 +218,7 @@ impl Default for TransferOptions {
|
||||
pburst: Burst::Single,
|
||||
mburst: Burst::Single,
|
||||
flow_ctrl: FlowControl::Dma,
|
||||
fifo_threshold: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user