stm32f4xx-hal icon indicating copy to clipboard operation
stm32f4xx-hal copied to clipboard

TIMx: Conflict occurs when multiple timers work at the same time

Open flyingyizi opened this issue 3 years ago • 0 comments

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);
    }

flyingyizi avatar Apr 21 '22 19:04 flyingyizi