Adding compile-time management of TIM2 channels
This commit is contained in:
parent
da9ca81856
commit
3b953e36aa
18
src/adc.rs
18
src/adc.rs
|
@ -14,8 +14,8 @@
|
||||||
///! both transfers are completed before reading the data. This is usually not significant for
|
///! both transfers are completed before reading the data. This is usually not significant for
|
||||||
///! busy-waiting because the transfers should complete at approximately the same time.
|
///! busy-waiting because the transfers should complete at approximately the same time.
|
||||||
use super::{
|
use super::{
|
||||||
hal, DMAReq, DmaConfig, MemoryToPeripheral, PeripheralToMemory, Priority,
|
hal, sampling_timer, DMAReq, DmaConfig, MemoryToPeripheral,
|
||||||
TargetAddress, Transfer,
|
PeripheralToMemory, Priority, TargetAddress, Transfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The desired ADC input buffer size. This is use configurable.
|
// The desired ADC input buffer size. This is use configurable.
|
||||||
|
@ -142,11 +142,18 @@ impl Adc0Input {
|
||||||
/// * `trigger_stream` - The DMA stream used to trigger each ADC transfer by writing a word into
|
/// * `trigger_stream` - The DMA stream used to trigger each ADC transfer by writing a word into
|
||||||
/// the SPI TX FIFO.
|
/// the SPI TX FIFO.
|
||||||
/// * `data_stream` - The DMA stream used to read samples received over SPI into a data buffer.
|
/// * `data_stream` - The DMA stream used to read samples received over SPI into a data buffer.
|
||||||
|
/// * `_trigger_channel` - The ADC sampling timer output compare channel for read triggers.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
spi: hal::spi::Spi<hal::stm32::SPI2, hal::spi::Enabled, u16>,
|
spi: hal::spi::Spi<hal::stm32::SPI2, hal::spi::Enabled, u16>,
|
||||||
trigger_stream: hal::dma::dma::Stream0<hal::stm32::DMA1>,
|
trigger_stream: hal::dma::dma::Stream0<hal::stm32::DMA1>,
|
||||||
data_stream: hal::dma::dma::Stream1<hal::stm32::DMA1>,
|
data_stream: hal::dma::dma::Stream1<hal::stm32::DMA1>,
|
||||||
|
trigger_channel: sampling_timer::Timer2Channel1,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
// Generate DMA events when an output compare of the timer hitting zero (timer roll over)
|
||||||
|
// occurs.
|
||||||
|
trigger_channel.listen_dma();
|
||||||
|
trigger_channel.to_output_compare(0);
|
||||||
|
|
||||||
// The trigger stream constantly writes to the TX FIFO using a static word (dont-care
|
// The trigger stream constantly writes to the TX FIFO using a static word (dont-care
|
||||||
// contents). Thus, neither the memory or peripheral address ever change. This is run in
|
// contents). Thus, neither the memory or peripheral address ever change. This is run in
|
||||||
// circular mode to be completed at every DMA request.
|
// circular mode to be completed at every DMA request.
|
||||||
|
@ -256,11 +263,18 @@ impl Adc1Input {
|
||||||
/// * `spi` - The SPI interface connected to ADC1.
|
/// * `spi` - The SPI interface connected to ADC1.
|
||||||
/// * `trigger_stream` - The DMA stream used to trigger ADC conversions on the SPI interface.
|
/// * `trigger_stream` - The DMA stream used to trigger ADC conversions on the SPI interface.
|
||||||
/// * `data_stream` - The DMA stream used to read ADC samples from the SPI RX FIFO.
|
/// * `data_stream` - The DMA stream used to read ADC samples from the SPI RX FIFO.
|
||||||
|
/// * `trigger_channel` - The ADC sampling timer output compare channel for read triggers.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
spi: hal::spi::Spi<hal::stm32::SPI3, hal::spi::Enabled, u16>,
|
spi: hal::spi::Spi<hal::stm32::SPI3, hal::spi::Enabled, u16>,
|
||||||
trigger_stream: hal::dma::dma::Stream2<hal::stm32::DMA1>,
|
trigger_stream: hal::dma::dma::Stream2<hal::stm32::DMA1>,
|
||||||
data_stream: hal::dma::dma::Stream3<hal::stm32::DMA1>,
|
data_stream: hal::dma::dma::Stream3<hal::stm32::DMA1>,
|
||||||
|
trigger_channel: sampling_timer::Timer2Channel2,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
// Generate DMA events when an output compare of the timer hitting zero (timer roll over)
|
||||||
|
// occurs.
|
||||||
|
trigger_channel.listen_dma();
|
||||||
|
trigger_channel.to_output_compare(0);
|
||||||
|
|
||||||
// The trigger stream constantly writes to the TX FIFO using a static word (dont-care
|
// The trigger stream constantly writes to the TX FIFO using a static word (dont-care
|
||||||
// contents). Thus, neither the memory or peripheral address ever change. This is run in
|
// contents). Thus, neither the memory or peripheral address ever change. This is run in
|
||||||
// circular mode to be completed at every DMA request.
|
// circular mode to be completed at every DMA request.
|
||||||
|
|
46
src/main.rs
46
src/main.rs
|
@ -62,6 +62,7 @@ mod dac;
|
||||||
mod eeprom;
|
mod eeprom;
|
||||||
mod iir;
|
mod iir;
|
||||||
mod pounder;
|
mod pounder;
|
||||||
|
mod sampling_timer;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
use adc::{Adc0Input, Adc1Input, AdcInputs};
|
use adc::{Adc0Input, Adc1Input, AdcInputs};
|
||||||
|
@ -187,8 +188,6 @@ const APP: () = {
|
||||||
|
|
||||||
eeprom_i2c: hal::i2c::I2c<hal::stm32::I2C2>,
|
eeprom_i2c: hal::i2c::I2c<hal::stm32::I2C2>,
|
||||||
|
|
||||||
timer: hal::timer::Timer<hal::stm32::TIM2>,
|
|
||||||
|
|
||||||
// Note: It appears that rustfmt generates a format that GDB cannot recognize, which
|
// Note: It appears that rustfmt generates a format that GDB cannot recognize, which
|
||||||
// results in GDB breakpoints being set improperly.
|
// results in GDB breakpoints being set improperly.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
@ -264,6 +263,16 @@ const APP: () = {
|
||||||
let dma_streams =
|
let dma_streams =
|
||||||
hal::dma::dma::StreamsTuple::new(dp.DMA1, ccdr.peripheral.DMA1);
|
hal::dma::dma::StreamsTuple::new(dp.DMA1, ccdr.peripheral.DMA1);
|
||||||
|
|
||||||
|
// Configure timer 2 to trigger conversions for the ADC
|
||||||
|
let timer2 = dp.TIM2.timer(
|
||||||
|
SAMPLE_FREQUENCY_KHZ.khz(),
|
||||||
|
ccdr.peripheral.TIM2,
|
||||||
|
&ccdr.clocks,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut sampling_timer = sampling_timer::SamplingTimer::new(timer2);
|
||||||
|
let sampling_timer_channels = sampling_timer.channels();
|
||||||
|
|
||||||
// Configure the SPI interfaces to the ADCs and DACs.
|
// Configure the SPI interfaces to the ADCs and DACs.
|
||||||
let adcs = {
|
let adcs = {
|
||||||
let adc0 = {
|
let adc0 = {
|
||||||
|
@ -296,7 +305,12 @@ const APP: () = {
|
||||||
&ccdr.clocks,
|
&ccdr.clocks,
|
||||||
);
|
);
|
||||||
|
|
||||||
Adc0Input::new(spi, dma_streams.0, dma_streams.1)
|
Adc0Input::new(
|
||||||
|
spi,
|
||||||
|
dma_streams.0,
|
||||||
|
dma_streams.1,
|
||||||
|
sampling_timer_channels.ch1,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let adc1 = {
|
let adc1 = {
|
||||||
|
@ -329,7 +343,12 @@ const APP: () = {
|
||||||
&ccdr.clocks,
|
&ccdr.clocks,
|
||||||
);
|
);
|
||||||
|
|
||||||
Adc1Input::new(spi, dma_streams.2, dma_streams.3)
|
Adc1Input::new(
|
||||||
|
spi,
|
||||||
|
dma_streams.2,
|
||||||
|
dma_streams.3,
|
||||||
|
sampling_timer_channels.ch2,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
AdcInputs::new(adc0, adc1)
|
AdcInputs::new(adc0, adc1)
|
||||||
|
@ -697,22 +716,8 @@ const APP: () = {
|
||||||
// Utilize the cycle counter for RTIC scheduling.
|
// Utilize the cycle counter for RTIC scheduling.
|
||||||
cp.DWT.enable_cycle_counter();
|
cp.DWT.enable_cycle_counter();
|
||||||
|
|
||||||
// Configure timer 2 to trigger conversions for the ADC
|
// Start sampling ADCs.
|
||||||
let timer2 = dp.TIM2.timer(
|
sampling_timer.start();
|
||||||
SAMPLE_FREQUENCY_KHZ.khz(),
|
|
||||||
ccdr.peripheral.TIM2,
|
|
||||||
&ccdr.clocks,
|
|
||||||
);
|
|
||||||
{
|
|
||||||
// Listen to the CH1 and CH2 comparison events. These channels should have a value of
|
|
||||||
// zero loaded into them, so the event should occur whenever the timer overflows. Note
|
|
||||||
// that we use channels instead of timer updates because each SPI DMA transfer needs a
|
|
||||||
// unique request line.
|
|
||||||
let t2_regs = unsafe { &*hal::stm32::TIM2::ptr() };
|
|
||||||
t2_regs
|
|
||||||
.dier
|
|
||||||
.modify(|_, w| w.cc1de().set_bit().cc2de().set_bit());
|
|
||||||
}
|
|
||||||
|
|
||||||
init::LateResources {
|
init::LateResources {
|
||||||
afe0: afe0,
|
afe0: afe0,
|
||||||
|
@ -721,7 +726,6 @@ const APP: () = {
|
||||||
adcs,
|
adcs,
|
||||||
dacs,
|
dacs,
|
||||||
|
|
||||||
timer: timer2,
|
|
||||||
pounder: pounder_devices,
|
pounder: pounder_devices,
|
||||||
|
|
||||||
eeprom_i2c,
|
eeprom_i2c,
|
||||||
|
|
Loading…
Reference in New Issue