possible bugfix for asynch GPIO
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
shared-hal-ci / Check build (pull_request) Has been cancelled
shared-hal-ci / Check formatting (pull_request) Has been cancelled
shared-hal-ci / Check Documentation Build (pull_request) Has been cancelled
shared-hal-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (pull_request) Has been cancelled
va108xx-ci / Run Tests (pull_request) Has been cancelled
va108xx-ci / Check formatting (pull_request) Has been cancelled
va108xx-ci / Check Documentation Build (pull_request) Has been cancelled
va108xx-ci / Clippy (pull_request) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Check build (pull_request) Has been cancelled
va416xx-ci / Run Tests (pull_request) Has been cancelled
va416xx-ci / Check formatting (pull_request) Has been cancelled
va416xx-ci / Check Documentation Build (pull_request) Has been cancelled
va416xx-ci / Clippy (pull_request) Has been cancelled
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
shared-hal-ci / Check build (pull_request) Has been cancelled
shared-hal-ci / Check formatting (pull_request) Has been cancelled
shared-hal-ci / Check Documentation Build (pull_request) Has been cancelled
shared-hal-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (pull_request) Has been cancelled
va108xx-ci / Run Tests (pull_request) Has been cancelled
va108xx-ci / Check formatting (pull_request) Has been cancelled
va108xx-ci / Check Documentation Build (pull_request) Has been cancelled
va108xx-ci / Clippy (pull_request) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Check build (pull_request) Has been cancelled
va416xx-ci / Run Tests (pull_request) Has been cancelled
va416xx-ci / Check formatting (pull_request) Has been cancelled
va416xx-ci / Check Documentation Build (pull_request) Has been cancelled
va416xx-ci / Clippy (pull_request) Has been cancelled
This commit is contained in:
@@ -71,8 +71,14 @@ async fn main(spawner: Spawner) {
|
||||
let out_pb22 = Output::new(portb.pb22, PinState::Low);
|
||||
let in_pb23 = Input::new_floating(portb.pb23);
|
||||
|
||||
let mut in_pa1_async = InputPinAsync::new(in_pa1, pac::Interrupt::OC10);
|
||||
let mut in_pb23_async = InputPinAsync::new(in_pb23, PB22_TO_PB23_IRQ);
|
||||
let mut in_pa1_async = InputPinAsync::new(
|
||||
in_pa1,
|
||||
va108xx_hal::InterruptConfig::new(pac::Interrupt::OC10, true, true),
|
||||
);
|
||||
let mut in_pb23_async = InputPinAsync::new(
|
||||
in_pb23,
|
||||
va108xx_hal::InterruptConfig::new(PB22_TO_PB23_IRQ, true, true),
|
||||
);
|
||||
|
||||
spawner
|
||||
.spawn(output_task(
|
||||
|
||||
@@ -21,9 +21,6 @@ use crate::{InterruptConfig, NUM_PORT_A, NUM_PORT_B};
|
||||
#[cfg(feature = "vor4x")]
|
||||
use super::ll::PortDoesNotSupportInterrupts;
|
||||
|
||||
#[cfg(feature = "vor1x")]
|
||||
use va108xx as pac;
|
||||
|
||||
pub use super::ll::InterruptEdge;
|
||||
use super::{
|
||||
Input, Port,
|
||||
@@ -118,10 +115,13 @@ pub fn on_interrupt_for_async_gpio_for_port(
|
||||
}
|
||||
|
||||
fn on_interrupt_for_async_gpio_for_port_generic(port: Port) {
|
||||
let gpio = unsafe { port.steal_gpio() };
|
||||
let mut gpio = unsafe { port.steal_regs() };
|
||||
|
||||
let irq_enb = gpio.read_irq_enable();
|
||||
let edge_status = gpio.read_edge_status();
|
||||
// Clear the edge status event. We have the relevant copy now.
|
||||
gpio.write_edge_status(edge_status);
|
||||
|
||||
let (wakers, edge_detection) = pin_group_to_waker_and_edge_detection_group(port);
|
||||
|
||||
on_interrupt_for_port(irq_enb, edge_status, wakers, edge_detection);
|
||||
@@ -134,14 +134,16 @@ fn on_interrupt_for_port(
|
||||
wakers: &'static [AtomicWaker],
|
||||
edge_detection: &'static [AtomicBool],
|
||||
) {
|
||||
// Check all enabled interrupts.
|
||||
while irq_enb != 0 {
|
||||
// For all enabled interrupts, check whether the corresponding edge detection has
|
||||
// triggered.
|
||||
let bit_pos = irq_enb.trailing_zeros() as usize;
|
||||
let bit_mask = 1 << bit_pos;
|
||||
|
||||
wakers[bit_pos].wake();
|
||||
|
||||
if edge_status & bit_mask != 0 {
|
||||
edge_detection[bit_pos].store(true, core::sync::atomic::Ordering::Relaxed);
|
||||
wakers[bit_pos].wake();
|
||||
|
||||
// Clear the processed bit
|
||||
irq_enb &= !bit_mask;
|
||||
@@ -163,13 +165,11 @@ pub struct InputPinFuture {
|
||||
impl InputPinFuture {
|
||||
/// Create a new input pin future from mutable reference to an [Input] pin.
|
||||
#[cfg(feature = "vor1x")]
|
||||
pub fn new_with_input_pin(pin: &mut Input, irq: pac::Interrupt, edge: InterruptEdge) -> Self {
|
||||
pub fn new_with_input_pin(pin: &mut Input, edge: InterruptEdge) -> Self {
|
||||
let (waker_group, edge_detection_group) =
|
||||
pin_group_to_waker_and_edge_detection_group(pin.id().port());
|
||||
edge_detection_group[pin.id().offset()].store(false, core::sync::atomic::Ordering::Relaxed);
|
||||
pin.configure_edge_interrupt(edge);
|
||||
#[cfg(feature = "vor1x")]
|
||||
pin.enable_interrupt(InterruptConfig::new(irq, true, true));
|
||||
Self {
|
||||
id: pin.id(),
|
||||
waker_group,
|
||||
@@ -223,8 +223,6 @@ impl Future for InputPinFuture {
|
||||
/// Input pin which has additional asynchronous support.
|
||||
pub struct InputPinAsync {
|
||||
pin: Input,
|
||||
#[cfg(feature = "vor1x")]
|
||||
irq: va108xx::Interrupt,
|
||||
}
|
||||
|
||||
impl InputPinAsync {
|
||||
@@ -235,8 +233,10 @@ impl InputPinAsync {
|
||||
/// generic [on_interrupt_for_async_gpio_for_port] function must be called inside that function
|
||||
/// for the asynchronous functionality to work.
|
||||
#[cfg(feature = "vor1x")]
|
||||
pub fn new(pin: Input, irq: va108xx::Interrupt) -> Self {
|
||||
Self { pin, irq }
|
||||
pub fn new(mut pin: Input, irq_config: InterruptConfig) -> Self {
|
||||
pin.enable_interrupt(irq_config);
|
||||
pin.clear_edge_event();
|
||||
Self { pin }
|
||||
}
|
||||
|
||||
/// Create a new asynchronous input pin from an [Input] pin. The interrupt ID to be used must be
|
||||
@@ -246,10 +246,11 @@ impl InputPinAsync {
|
||||
/// generic [on_interrupt_for_async_gpio_for_port] function must be called inside that function
|
||||
/// for the asynchronous functionality to work.
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub fn new(pin: Input) -> Result<Self, PortDoesNotSupportInterrupts> {
|
||||
pub fn new(mut pin: Input) -> Result<Self, PortDoesNotSupportInterrupts> {
|
||||
if pin.id().port() == Port::G {
|
||||
return Err(PortDoesNotSupportInterrupts);
|
||||
}
|
||||
pin.clear_edge_event();
|
||||
Ok(Self { pin })
|
||||
}
|
||||
|
||||
@@ -259,8 +260,7 @@ impl InputPinAsync {
|
||||
pub async fn wait_for_high(&mut self) {
|
||||
// Unwrap okay, checked pin in constructor.
|
||||
#[cfg(feature = "vor1x")]
|
||||
let fut =
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::LowToHigh);
|
||||
let fut = InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::LowToHigh);
|
||||
#[cfg(feature = "vor4x")]
|
||||
let fut =
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::LowToHigh).unwrap();
|
||||
@@ -300,8 +300,7 @@ impl InputPinAsync {
|
||||
pub async fn wait_for_low(&mut self) {
|
||||
// Unwrap okay, checked pin in constructor.
|
||||
#[cfg(feature = "vor1x")]
|
||||
let fut =
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::HighToLow);
|
||||
let fut = InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::HighToLow);
|
||||
#[cfg(feature = "vor4x")]
|
||||
let fut =
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::HighToLow).unwrap();
|
||||
@@ -315,7 +314,7 @@ impl InputPinAsync {
|
||||
pub async fn wait_for_falling_edge(&mut self) {
|
||||
// Unwrap okay, checked pin in constructor.
|
||||
#[cfg(feature = "vor1x")]
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::HighToLow).await;
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::HighToLow).await;
|
||||
#[cfg(feature = "vor4x")]
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::HighToLow)
|
||||
.unwrap()
|
||||
@@ -326,14 +325,14 @@ impl InputPinAsync {
|
||||
pub async fn wait_for_rising_edge(&mut self) {
|
||||
// Unwrap okay, checked pin in constructor.
|
||||
#[cfg(feature = "vor1x")]
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::LowToHigh).await;
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::LowToHigh).await;
|
||||
}
|
||||
|
||||
/// Asynchronously wait until the pin sees any edge (either rising or falling).
|
||||
pub async fn wait_for_any_edge(&mut self) {
|
||||
// Unwrap okay, checked pin in constructor.
|
||||
#[cfg(feature = "vor1x")]
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::BothEdges).await;
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::BothEdges).await;
|
||||
#[cfg(feature = "vor4x")]
|
||||
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::BothEdges)
|
||||
.unwrap()
|
||||
|
||||
@@ -384,6 +384,16 @@ impl LowLevelGpio {
|
||||
self.gpio.write_tog_out(self.mask_32());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear_edge_event(&mut self) {
|
||||
// Clear any pending edge events.
|
||||
let mask = self.mask_32();
|
||||
self.gpio.modify_edge_status(|mut val| {
|
||||
val &= !mask;
|
||||
val
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "vor1x")]
|
||||
pub fn enable_interrupt(&mut self, irq_cfg: crate::InterruptConfig) {
|
||||
if irq_cfg.route {
|
||||
|
||||
@@ -162,6 +162,11 @@ impl Input {
|
||||
self.0.configure_delay(delay_1, delay_2);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear_edge_event(&mut self) {
|
||||
self.0.clear_edge_event();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn configure_filter_type(&mut self, filter: FilterType, clksel: FilterClockSelect) {
|
||||
self.0.configure_filter_type(filter, clksel);
|
||||
|
||||
@@ -58,7 +58,6 @@ pub struct Gpio {
|
||||
/// Read-only register which shows enabled and active interrupts. Called IRQ_end by Vorago.
|
||||
#[mmio(PureRead)]
|
||||
irq_status: u32,
|
||||
#[mmio(PureRead)]
|
||||
edge_status: u32,
|
||||
|
||||
#[cfg(feature = "vor1x")]
|
||||
|
||||
@@ -137,7 +137,7 @@ impl Port {
|
||||
/// # Safety
|
||||
///
|
||||
/// Circumvents ownership and safety guarantees by the HAL.
|
||||
pub unsafe fn steal_gpio(&self) -> gpio::regs::MmioGpio<'static> {
|
||||
pub unsafe fn steal_regs(&self) -> gpio::regs::MmioGpio<'static> {
|
||||
gpio::regs::Gpio::new_mmio(*self)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user