stm32f4xx-hal
stm32f4xx-hal copied to clipboard
TIMx: Conflict occurs when multiple timers work at the same time
env:
stm32f4xx-hal: 0.13 hw: nucleo-stm32f411 TIM4 used as embedded_hal::timer::CountDown implement TIM1 used as delay problem code:
// when comment it, all works fine, but if it exist, above "at.send_timout" always timeout
//delay.delay(2.secs());
full code view:
fn main() -> ! {
let dp = Peripherals::take().unwrap();
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.sysclk(16.MHz()).freeze();
let serial: hal::serial::Serial<_, _, u8> = dp.USART6
.serial(
...
&clocks,
).unwrap();
let (mut tx, rx) = serial.split();
// in ATCmdFuture, the timer as a countDown counter to implement timeout
let mut counter = dp.TIM4.counter_ms(&clocks);
let mut at=ATCmdFuture::new(tx, counter).unwrap();
// the delay is used in main,
let mut delay = dp.TIM1.delay_ms(&clocks);
loop {
format_buf.clear();
if core::fmt::write(&mut format_buf, format_args!("send command:{}\r\n", value)).is_ok() {
match at.send_timout(format_buf.as_bytes(), 1000){
Ok(s) => {
hprintln!("-------AT-CMD send :{}",s).unwrap();
},
Err(s) =>
hprintln!("-------AT-CMD send timeout occours fail!{}",s).unwrap(),
}
value = value.wrapping_add(1);
}
// when comment it, all works fine, but if it exist, above "at.send_timout" always timeout
delay.delay(2.secs());
}
}
pub fn send_timout(
&mut self,
buf: &[u8],
timeout: u32, /*unit is ms*/
) -> Result<usize, usize> {
if timeout == 0 {
return self.block_send(buf);
}
if let Err(_) = self.counter_start(timeout) {
log::error!("failed to start counter");
return self.block_send(buf);
}
let mut sended: usize = 0;
'outer:for word in buf.iter() {
loop {
match self.tx.write(*word) {
Ok(_) => {
sended += 1;
continue 'outer;
}
Err(nb::Error::WouldBlock) => {
match self.counter.wait() {
// The timer is still running.
Err(nb::Error::WouldBlock) => continue,
Err(nb::Error::Other(_)) =>return Err(10000),
Ok(()) => return Err(30000),
}
}
Err(nb::Error::Other(_)) => {
return Err(sended);
}
}
}
}
return Ok(sended);
}