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
|
||||
///! busy-waiting because the transfers should complete at approximately the same time.
|
||||
use super::{
|
||||
hal, DMAReq, DmaConfig, MemoryToPeripheral, PeripheralToMemory, Priority,
|
||||
TargetAddress, Transfer,
|
||||
hal, sampling_timer, DMAReq, DmaConfig, MemoryToPeripheral,
|
||||
PeripheralToMemory, Priority, TargetAddress, Transfer,
|
||||
};
|
||||
|
||||
// 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
|
||||
/// the SPI TX FIFO.
|
||||
/// * `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(
|
||||
spi: hal::spi::Spi<hal::stm32::SPI2, hal::spi::Enabled, u16>,
|
||||
trigger_stream: hal::dma::dma::Stream0<hal::stm32::DMA1>,
|
||||
data_stream: hal::dma::dma::Stream1<hal::stm32::DMA1>,
|
||||
trigger_channel: sampling_timer::Timer2Channel1,
|
||||
) -> 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
|
||||
// contents). Thus, neither the memory or peripheral address ever change. This is run in
|
||||
// circular mode to be completed at every DMA request.
|
||||
|
@ -256,11 +263,18 @@ impl Adc1Input {
|
|||
/// * `spi` - The SPI interface connected to ADC1.
|
||||
/// * `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.
|
||||
/// * `trigger_channel` - The ADC sampling timer output compare channel for read triggers.
|
||||
pub fn new(
|
||||
spi: hal::spi::Spi<hal::stm32::SPI3, hal::spi::Enabled, u16>,
|
||||
trigger_stream: hal::dma::dma::Stream2<hal::stm32::DMA1>,
|
||||
data_stream: hal::dma::dma::Stream3<hal::stm32::DMA1>,
|
||||
trigger_channel: sampling_timer::Timer2Channel2,
|
||||
) -> 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
|
||||
// contents). Thus, neither the memory or peripheral address ever change. This is run in
|
||||
// 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 iir;
|
||||
mod pounder;
|
||||
mod sampling_timer;
|
||||
mod server;
|
||||
|
||||
use adc::{Adc0Input, Adc1Input, AdcInputs};
|
||||
|
@ -187,8 +188,6 @@ const APP: () = {
|
|||
|
||||
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
|
||||
// results in GDB breakpoints being set improperly.
|
||||
#[rustfmt::skip]
|
||||
|
@ -264,6 +263,16 @@ const APP: () = {
|
|||
let dma_streams =
|
||||
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.
|
||||
let adcs = {
|
||||
let adc0 = {
|
||||
|
@ -296,7 +305,12 @@ const APP: () = {
|
|||
&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 = {
|
||||
|
@ -329,7 +343,12 @@ const APP: () = {
|
|||
&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)
|
||||
|
@ -697,22 +716,8 @@ const APP: () = {
|
|||
// Utilize the cycle counter for RTIC scheduling.
|
||||
cp.DWT.enable_cycle_counter();
|
||||
|
||||
// Configure timer 2 to trigger conversions for the ADC
|
||||
let timer2 = dp.TIM2.timer(
|
||||
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());
|
||||
}
|
||||
// Start sampling ADCs.
|
||||
sampling_timer.start();
|
||||
|
||||
init::LateResources {
|
||||
afe0: afe0,
|
||||
|
@ -721,7 +726,6 @@ const APP: () = {
|
|||
adcs,
|
||||
dacs,
|
||||
|
||||
timer: timer2,
|
||||
pounder: pounder_devices,
|
||||
|
||||
eeprom_i2c,
|
||||
|
|
Loading…
Reference in New Issue