Module imxrt_hal::gpio [−][src]
Expand description
GPIOs
This GPIO driver supports the embedded_hal
’s v2
digital traits.
Fast and Normal GPIOs
High speed, or “fast,” GPIOs are GPIOs that run on the AHB clock. Normal GPIOs run on the IPG clock.
Example
use imxrt_hal::{self, gpio::GPIO};
let mut peripherals = imxrt_hal::Peripherals::take().unwrap();
let input = GPIO::new(peripherals.iomuxc.ad_b0.p11);
assert!(!input.is_set());
let mut output = input.output();
output.set();
assert!(output.is_set());
output.toggle();
assert!(!output.is_set());
assert!(output.set_fast(true));
output.toggle();
assert!(output.is_set());
Interrupts
GPIO inputs can generate interrupts on edge or level triggers. See
InterruptConfiguration
to
understand the available configurations.
Before selecting a GPIO interrupt vector, you need to know which GPIO port and pin is associated with your pad. There’s two ways to correlate a pad to a GPIO:
- Check the reference manual. Chapter 10 of the i.MX RT 1060 reference manual has a table that associates pads to peripheral functions.
- Use the
imxrt-iomuxc
crate’s documentation. Browse to thegpio::Pin
documentation, and scroll down to see the implementors. Example: expand the implementation for B0_06, and it reveals the GPIO port and pin (GPIO2_6
).
Depending on your specific i.MX RT variant, there may be various GPIO interrupt vectors. To implement the most portable code, consider using the
GPIO[X]_Combined_0_15
GPIO[X]_Combined_16_31
interrupts, replacing [X]
with your GPIO port number. These two interrupts handle
GPIO pins 0 through 15, and GPIO pins 16 through 31, respectively.
To define the interrupt, use the APIs from the cortex-m-rt
crate.
The snippet below demonstrates a function that defines an interrupt. The interrupt invokes a user’s callback when input pin detects a rising edge.
use imxrt_hal as hal;
use hal::{
gpio::{GPIO, Input, InterruptConfiguration},
iomuxc::imxrt106x::b0::B0_10,
};
use cortex_m::interrupt::Mutex;
use core::cell::RefCell;
use hal::ral::interrupt;
/// B0_10 => GPIO2_6, so we need to register
/// the GPIO2_Combined_0_15 interrupt.
type InputPin = GPIO<B0_10, Input>;
/// The response when the interrupt fires.
/// The callback runs within a critical section.
type InterruptCallback = fn(&cortex_m::interrupt::CriticalSection);
fn setup_gpio_interrupt(mut pin: InputPin, callback: InterruptCallback) {
struct SharedState { pin: InputPin, callback: InterruptCallback }
static SHARED_STATE: Mutex<RefCell<Option<SharedState>>> = Mutex::new(RefCell::new(None));
#[cortex_m_rt::interrupt]
fn GPIO2_Combined_0_15() {
cortex_m::interrupt::free(|cs| {
SHARED_STATE.borrow(cs).borrow_mut().as_mut().map(|state| {
if state.pin.is_interrupt_status() {
state.pin.clear_interrupt_status();
(state.callback)(cs);
}
});
});
}
cortex_m::interrupt::free(|cs| {
pin.set_interrupt_configuration(InterruptConfiguration::RisingEdge);
pin.set_interrupt_enable(true);
*SHARED_STATE.borrow(cs).borrow_mut() = Some(SharedState{ pin, callback });
// Safety: shared state is set within a critical section.
unsafe { cortex_m::peripheral::NVIC::unmask(interrupt::GPIO2_Combined_0_15) };
});
}
Structs
Enums
Denotes that a pin is configured as an input
GPIO input interrupt configurations.
Denotes that a pin is configured as an output