Fix Cc::wait never resolving and refactor some APIs
				
					
				
			I think the interrupt was getting immediately re-triggered as soon as the handler exited, so I disabled the interrupt in the handler.
This commit is contained in:
		
							parent
							
								
									02781ed744
								
							
						
					
					
						commit
						e7addf094b
					
				@ -82,7 +82,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
 | 
			
		||||
 | 
			
		||||
        let r = U::regs();
 | 
			
		||||
 | 
			
		||||
        let timer = Timer::new_irqless(timer);
 | 
			
		||||
        let mut timer = Timer::new_irqless(timer);
 | 
			
		||||
 | 
			
		||||
        rxd.conf().write(|w| w.input().connect().drive().h0h1());
 | 
			
		||||
        r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
 | 
			
		||||
@ -137,9 +137,9 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
 | 
			
		||||
        let timeout = 0x8000_0000 / (config.baudrate as u32 / 40);
 | 
			
		||||
 | 
			
		||||
        timer.set_frequency(Frequency::F16MHz);
 | 
			
		||||
        timer.cc0().set(timeout);
 | 
			
		||||
        timer.cc0().short_compare_clear();
 | 
			
		||||
        timer.cc0().short_compare_stop();
 | 
			
		||||
        timer.cc(0).write(timeout);
 | 
			
		||||
        timer.cc(0).short_compare_clear();
 | 
			
		||||
        timer.cc(0).short_compare_stop();
 | 
			
		||||
 | 
			
		||||
        let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable());
 | 
			
		||||
        ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy));
 | 
			
		||||
@ -148,7 +148,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
 | 
			
		||||
        ppi_ch1.enable();
 | 
			
		||||
 | 
			
		||||
        let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable());
 | 
			
		||||
        ppi_ch2.set_event(timer.cc0().event_compare());
 | 
			
		||||
        ppi_ch2.set_event(timer.cc(0).event_compare());
 | 
			
		||||
        ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx));
 | 
			
		||||
        ppi_ch2.enable();
 | 
			
		||||
 | 
			
		||||
@ -180,7 +180,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
 | 
			
		||||
            let r = U::regs();
 | 
			
		||||
 | 
			
		||||
            let timeout = 0x8000_0000 / (baudrate as u32 / 40);
 | 
			
		||||
            state.timer.cc0().set(timeout);
 | 
			
		||||
            state.timer.cc(0).write(timeout);
 | 
			
		||||
            state.timer.clear();
 | 
			
		||||
 | 
			
		||||
            r.baudrate.write(|w| w.baudrate().variant(baudrate));
 | 
			
		||||
 | 
			
		||||
@ -115,7 +115,7 @@ impl<'d, T: Instance> Timer<'d, T> {
 | 
			
		||||
        // TODO: is there a reason someone would want to set this lower?
 | 
			
		||||
        regs.bitmode.write(|w| w.bitmode()._32bit());
 | 
			
		||||
 | 
			
		||||
        let this = Self {
 | 
			
		||||
        let mut this = Self {
 | 
			
		||||
            phantom: PhantomData,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@ -125,14 +125,13 @@ impl<'d, T: Instance> Timer<'d, T> {
 | 
			
		||||
        // Initialize the counter at 0.
 | 
			
		||||
        this.clear();
 | 
			
		||||
 | 
			
		||||
        // Initialize all the shorts as disabled.
 | 
			
		||||
        for n in 0..T::CCS {
 | 
			
		||||
            let cc = Cc::<T> {
 | 
			
		||||
                n,
 | 
			
		||||
                phantom: PhantomData,
 | 
			
		||||
            };
 | 
			
		||||
            let cc = this.cc(n);
 | 
			
		||||
            // Initialize all the shorts as disabled.
 | 
			
		||||
            cc.unshort_compare_clear();
 | 
			
		||||
            cc.unshort_compare_stop();
 | 
			
		||||
            // Initialize the CC registers as 0.
 | 
			
		||||
            cc.write(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this
 | 
			
		||||
@ -196,57 +195,36 @@ impl<'d, T: Instance> Timer<'d, T> {
 | 
			
		||||
                .events_compare()
 | 
			
		||||
                .is_generated()
 | 
			
		||||
            {
 | 
			
		||||
                // Clear the interrupt, otherwise the interrupt will be repeatedly raised as soon as the interrupt handler exits.
 | 
			
		||||
                // We can't clear the event, because it's used to poll whether the future is done or still pending.
 | 
			
		||||
                regs.intenclr.write(|w| match n {
 | 
			
		||||
                    0 => w.compare0().clear(),
 | 
			
		||||
                    1 => w.compare1().clear(),
 | 
			
		||||
                    2 => w.compare2().clear(),
 | 
			
		||||
                    3 => w.compare3().clear(),
 | 
			
		||||
                    4 => w.compare4().clear(),
 | 
			
		||||
                    5 => w.compare5().clear(),
 | 
			
		||||
                    _ => unreachable!("No timers have more than 6 CC registers"),
 | 
			
		||||
                });
 | 
			
		||||
                T::waker(n).wake();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the 0th CC register.
 | 
			
		||||
    pub fn cc0<'a>(&'a self) -> Cc<'a, T> {
 | 
			
		||||
        Cc {
 | 
			
		||||
            n: 0,
 | 
			
		||||
            phantom: PhantomData,
 | 
			
		||||
    /// Returns this timer's `n`th CC register.
 | 
			
		||||
    ///
 | 
			
		||||
    /// # Panics
 | 
			
		||||
    /// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer).
 | 
			
		||||
    pub fn cc(&mut self, n: usize) -> Cc<T> {
 | 
			
		||||
        if n >= T::CCS {
 | 
			
		||||
            panic!(
 | 
			
		||||
                "Cannot get CC register {} of timer with {} CC registers.",
 | 
			
		||||
                n,
 | 
			
		||||
                T::CCS
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the 1st CC register.
 | 
			
		||||
    pub fn cc1<'a>(&'a self) -> Cc<'a, T> {
 | 
			
		||||
        Cc {
 | 
			
		||||
            n: 1,
 | 
			
		||||
            phantom: PhantomData,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the 2nd CC register.
 | 
			
		||||
    pub fn cc2<'a>(&'a self) -> Cc<'a, T> {
 | 
			
		||||
        Cc {
 | 
			
		||||
            n: 2,
 | 
			
		||||
            phantom: PhantomData,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the 3rd CC register.
 | 
			
		||||
    pub fn cc3<'a>(&'a self) -> Cc<'a, T> {
 | 
			
		||||
        Cc {
 | 
			
		||||
            n: 3,
 | 
			
		||||
            phantom: PhantomData,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: ExtendedInstance> Timer<'d, T> {
 | 
			
		||||
    /// Returns the 4th CC register.
 | 
			
		||||
    pub fn cc4<'a>(&'a self) -> Cc<'a, T> {
 | 
			
		||||
        Cc {
 | 
			
		||||
            n: 4,
 | 
			
		||||
            phantom: PhantomData,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the 5th CC register.
 | 
			
		||||
    pub fn cc5<'a>(&'a self) -> Cc<'a, T> {
 | 
			
		||||
        Cc {
 | 
			
		||||
            n: 5,
 | 
			
		||||
            n,
 | 
			
		||||
            phantom: PhantomData,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -266,14 +244,14 @@ pub struct Cc<'a, T: Instance> {
 | 
			
		||||
 | 
			
		||||
impl<'a, T: Instance> Cc<'a, T> {
 | 
			
		||||
    /// Get the current value stored in the register.
 | 
			
		||||
    pub fn value(&self) -> u32 {
 | 
			
		||||
    pub fn read(&self) -> u32 {
 | 
			
		||||
        T::regs().cc[self.n].read().cc().bits()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the value stored in the register.
 | 
			
		||||
    ///
 | 
			
		||||
    /// `event_compare` will fire when the timer's counter reaches this value.
 | 
			
		||||
    pub fn set(&self, value: u32) {
 | 
			
		||||
    pub fn write(&self, value: u32) {
 | 
			
		||||
        // SAFETY: there are no invalid values for the CC register.
 | 
			
		||||
        T::regs().cc[self.n].write(|w| unsafe { w.cc().bits(value) })
 | 
			
		||||
    }
 | 
			
		||||
@ -281,7 +259,7 @@ impl<'a, T: Instance> Cc<'a, T> {
 | 
			
		||||
    /// Capture the current value of the timer's counter in this register, and return it.
 | 
			
		||||
    pub fn capture(&self) -> u32 {
 | 
			
		||||
        T::regs().tasks_capture[self.n].write(|w| w.tasks_capture().trigger());
 | 
			
		||||
        self.value()
 | 
			
		||||
        self.read()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns this CC register's CAPTURE task, for use with PPI.
 | 
			
		||||
@ -359,7 +337,9 @@ impl<'a, T: Instance> Cc<'a, T> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Wait until the timer's counter reaches the value stored in this register.
 | 
			
		||||
    pub async fn wait(&self) {
 | 
			
		||||
    ///
 | 
			
		||||
    /// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`.
 | 
			
		||||
    pub async fn wait(&mut self) {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
        // Enable the interrupt for this CC's COMPARE event.
 | 
			
		||||
@ -394,6 +374,8 @@ impl<'a, T: Instance> Cc<'a, T> {
 | 
			
		||||
                .events_compare()
 | 
			
		||||
                .is_generated()
 | 
			
		||||
            {
 | 
			
		||||
                // Reset the register for next time
 | 
			
		||||
                regs.events_compare[self.n].write(|w| w.events_compare().not_generated());
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
@ -401,7 +383,7 @@ impl<'a, T: Instance> Cc<'a, T> {
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
        // Trigger the interrupt to be disabled.
 | 
			
		||||
        drop(on_drop);
 | 
			
		||||
        // The interrupt was already disabled in the interrupt handler, so there's no need to disable it again.
 | 
			
		||||
        on_drop.defuse();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -318,7 +318,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
 | 
			
		||||
    ) -> Self {
 | 
			
		||||
        let baudrate = config.baudrate;
 | 
			
		||||
        let uarte = Uarte::new(uarte, irq, rxd, txd, cts, rts, config);
 | 
			
		||||
        let timer = Timer::new_irqless(timer);
 | 
			
		||||
        let mut timer = Timer::new_irqless(timer);
 | 
			
		||||
 | 
			
		||||
        unborrow!(ppi_ch1, ppi_ch2);
 | 
			
		||||
 | 
			
		||||
@ -333,9 +333,9 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
 | 
			
		||||
        let timeout = 0x8000_0000 / (baudrate as u32 / 40);
 | 
			
		||||
 | 
			
		||||
        timer.set_frequency(Frequency::F16MHz);
 | 
			
		||||
        timer.cc0().set(timeout);
 | 
			
		||||
        timer.cc0().short_compare_clear();
 | 
			
		||||
        timer.cc0().short_compare_stop();
 | 
			
		||||
        timer.cc(0).write(timeout);
 | 
			
		||||
        timer.cc(0).short_compare_clear();
 | 
			
		||||
        timer.cc(0).short_compare_stop();
 | 
			
		||||
 | 
			
		||||
        let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable());
 | 
			
		||||
        ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy));
 | 
			
		||||
@ -344,7 +344,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
 | 
			
		||||
        ppi_ch1.enable();
 | 
			
		||||
 | 
			
		||||
        let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable());
 | 
			
		||||
        ppi_ch2.set_event(timer.cc0().event_compare());
 | 
			
		||||
        ppi_ch2.set_event(timer.cc(0).event_compare());
 | 
			
		||||
        ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx));
 | 
			
		||||
        ppi_ch2.enable();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user