ADC DMA blocked by another interrupt
vinsynth opened this issue · comments
I'm using an STM32F411 chip via WeAct's Blackpill and am trying to read an analog input through one pin while outputting an unrelated PWM signal through another.
The PWM signal is successfully outputted via interrupt TIM1_UP_TIM10()
.
The ADC can be read over DMA when DMA2_STREAM0()
is the only active interrupt. The ADC can also be read directly via the ADC()
interrupt while also outputting PWM the same way as before; however, trying to read ADC via DMA2_STREAM0()
while outputting PWM apparently blocks the DMA2_STREAM0()
interrupt after one cycle (when ADC and its DMA initialized before PWM) or several cycles (when ADC and its DMA initialized after PWM).
Here's the gist of the initialization code:
// init adc
let adc_config = adc_cfg::AdcConfig::default()
.scan(adc_cfg::Scan::Enabled)
.continuous(adc_cfg::Continuous::Continuous)
.dma(adc_cfg::Dma::Continuous);
let mut adc = hal::adc::Adc::adc1(dp.ADC1, true, adc_config);
let x_pin = gpioa.pa0.into_analog();
adc.configure_channel(
&x_pin,
adc_cfg::Sequence::One,
adc_cfg::SampleTime::Cycles_480
);
adc.enable();
let dma = hal::dma::StreamsTuple::new(dp.DMA2);
let dma_config = hal::dma::config::DmaConfig::default()
.memory_increment(true)
.fifo_enable(true)
.fifo_error_interrupt(true)
.transfer_complete_interrupt(true);
let buf = cortex_m::singleton!(: [u16; 2] = [0; 2]).unwrap();
let mut transfer = Transfer::init_peripheral_to_memory(
dma.0,
adc,
buf,
None,
dma_config
);
unsafe { cortex_m::peripheral::NVIC::unmask(Interrupt::DMA2_STREAM0) };
cs::with(|cs| {
ADC_TRANS.borrow(cs).replace(Some(transfer));
ADC_TRANS
.borrow_ref_mut(cs)
.as_mut()
.unwrap()
.start(|adc| adc.start_conversion())
});
// init pwm
let channel = hal::timer::Channel3::new(gpioa.pa10);
let mut pwm = dp.TIM1.pwm_hz(channel, 32.kHz(), &clocks);
pwm.enable(hal::timer::Channel::C3);
pwm.listen(hal::timer::Event::Update);
cs::with(|cs| PWM_TIM.borrow(cs).replace(Some(pwm)));
unsafe { cortex_m::peripheral::NVIC::unmask(Interrupt::TIM1_UP_TIM10) };
From looking at this library, I'm under the impression that PWM also leverages DMA; is this causing a conflict, or is there something else I'm missing?