Updating DACs to utilize DBM
This commit is contained in:
parent
ec2aaecb48
commit
fb1ea765ce
|
@ -874,7 +874,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stm32h7xx-hal"
|
name = "stm32h7xx-hal"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+https://github.com/stm32-rs/stm32h7xx-hal?branch=dma#0bfeeca4ce120c1b7c6d140a7da73a4372b874d8"
|
source = "git+https://github.com/quartiq/stm32h7xx-hal?branch=feature/dma-buffer-swap-logic#5f97920b639f8cb29c9f30c89a33960d5b2082f8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bare-metal 1.0.0",
|
"bare-metal 1.0.0",
|
||||||
"cast",
|
"cast",
|
||||||
|
|
|
@ -56,8 +56,8 @@ default-features = false
|
||||||
|
|
||||||
[dependencies.stm32h7xx-hal]
|
[dependencies.stm32h7xx-hal]
|
||||||
features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"]
|
features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"]
|
||||||
git = "https://github.com/stm32-rs/stm32h7xx-hal"
|
git = "https://github.com/quartiq/stm32h7xx-hal"
|
||||||
branch = "dma"
|
branch = "feature/dma-buffer-swap-logic"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]
|
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]
|
||||||
|
|
|
@ -117,11 +117,11 @@ macro_rules! adc_input {
|
||||||
|
|
||||||
/// Whenever the DMA request occurs, it should write into SPI's TX FIFO to start a DMA
|
/// Whenever the DMA request occurs, it should write into SPI's TX FIFO to start a DMA
|
||||||
/// transfer.
|
/// transfer.
|
||||||
fn address(&self) -> u32 {
|
fn address(&self) -> usize {
|
||||||
// Note(unsafe): It is assumed that SPI is owned by another DMA transfer and this DMA is
|
// Note(unsafe): It is assumed that SPI is owned by another DMA transfer and this DMA is
|
||||||
// only used for the transmit-half of DMA.
|
// only used for the transmit-half of DMA.
|
||||||
let regs = unsafe { &*hal::stm32::$spi::ptr() };
|
let regs = unsafe { &*hal::stm32::$spi::ptr() };
|
||||||
®s.txdr as *const _ as u32
|
®s.txdr as *const _ as usize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/dac.rs
23
src/dac.rs
|
@ -34,12 +34,11 @@
|
||||||
///! DMA channels to arbitrate which transfer occurs first.
|
///! DMA channels to arbitrate which transfer occurs first.
|
||||||
///!
|
///!
|
||||||
///!
|
///!
|
||||||
///! # Future Improvements
|
///! # Limitations
|
||||||
///!
|
///!
|
||||||
///! In this implementation, single buffer mode DMA transfers are used. As a result of this, it's
|
///! While double-buffered mode is used for DMA to avoid lost DAC-update events, there is no check
|
||||||
///! possible that a timer comparison could be missed during the swap-over, which will result in a
|
///! for re-use of a previously provided DAC output buffer. It is assumed that the DMA request is
|
||||||
///! delay of a single output code. In the future, this can be remedied by utilize double-buffer
|
///! served promptly after the transfer completes.
|
||||||
///! mode for the DMA transfers.
|
|
||||||
use super::{
|
use super::{
|
||||||
hal, sampling_timer, DMAReq, DmaConfig, MemoryToPeripheral, TargetAddress,
|
hal, sampling_timer, DMAReq, DmaConfig, MemoryToPeripheral, TargetAddress,
|
||||||
Transfer, SAMPLE_BUFFER_SIZE,
|
Transfer, SAMPLE_BUFFER_SIZE,
|
||||||
|
@ -50,8 +49,8 @@ use super::{
|
||||||
// processed). Note that the contents of AXI SRAM is uninitialized, so the buffer contents on
|
// processed). Note that the contents of AXI SRAM is uninitialized, so the buffer contents on
|
||||||
// startup are undefined. The dimensions are `ADC_BUF[adc_index][ping_pong_index][sample_index]`.
|
// startup are undefined. The dimensions are `ADC_BUF[adc_index][ping_pong_index][sample_index]`.
|
||||||
#[link_section = ".axisram.buffers"]
|
#[link_section = ".axisram.buffers"]
|
||||||
static mut DAC_BUF: [[[u16; SAMPLE_BUFFER_SIZE]; 2]; 2] =
|
static mut DAC_BUF: [[[u16; SAMPLE_BUFFER_SIZE]; 3]; 2] =
|
||||||
[[[0; SAMPLE_BUFFER_SIZE]; 2]; 2];
|
[[[0; SAMPLE_BUFFER_SIZE]; 3]; 2];
|
||||||
|
|
||||||
macro_rules! dac_output {
|
macro_rules! dac_output {
|
||||||
($name:ident, $index:literal, $data_stream:ident,
|
($name:ident, $index:literal, $data_stream:ident,
|
||||||
|
@ -92,8 +91,8 @@ macro_rules! dac_output {
|
||||||
const REQUEST_LINE: Option<u8> = Some(DMAReq::$dma_req as u8);
|
const REQUEST_LINE: Option<u8> = Some(DMAReq::$dma_req as u8);
|
||||||
|
|
||||||
/// Whenever the DMA request occurs, it should write into SPI's TX FIFO.
|
/// Whenever the DMA request occurs, it should write into SPI's TX FIFO.
|
||||||
fn address(&self) -> u32 {
|
fn address(&self) -> usize {
|
||||||
&self.spi.inner().txdr as *const _ as u32
|
&self.spi.inner().txdr as *const _ as usize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +128,7 @@ macro_rules! dac_output {
|
||||||
// The stream constantly writes to the TX FIFO to write new update codes.
|
// The stream constantly writes to the TX FIFO to write new update codes.
|
||||||
let trigger_config = DmaConfig::default()
|
let trigger_config = DmaConfig::default()
|
||||||
.memory_increment(true)
|
.memory_increment(true)
|
||||||
|
.double_buffer(true)
|
||||||
.peripheral_increment(false);
|
.peripheral_increment(false);
|
||||||
|
|
||||||
// Listen for any potential SPI error signals, which may indicate that we are not generating
|
// Listen for any potential SPI error signals, which may indicate that we are not generating
|
||||||
|
@ -153,7 +153,8 @@ macro_rules! dac_output {
|
||||||
$spi::new(trigger_channel, spi),
|
$spi::new(trigger_channel, spi),
|
||||||
// Note(unsafe): This buffer is only used once and provided for the DMA transfer.
|
// Note(unsafe): This buffer is only used once and provided for the DMA transfer.
|
||||||
unsafe { &mut DAC_BUF[$index][0] },
|
unsafe { &mut DAC_BUF[$index][0] },
|
||||||
None,
|
// Note(unsafe): This buffer is only used once and provided for the DMA transfer.
|
||||||
|
unsafe { Some(&mut DAC_BUF[$index][1]) },
|
||||||
trigger_config,
|
trigger_config,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -162,7 +163,7 @@ macro_rules! dac_output {
|
||||||
Self {
|
Self {
|
||||||
transfer,
|
transfer,
|
||||||
// Note(unsafe): This buffer is only used once and provided for the next DMA transfer.
|
// Note(unsafe): This buffer is only used once and provided for the next DMA transfer.
|
||||||
next_buffer: unsafe { Some(&mut DAC_BUF[$index][1]) },
|
next_buffer: unsafe { Some(&mut DAC_BUF[$index][2]) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue