ws2812_flexio/flexio/
mod.rs

1use imxrt_ral as ral;
2
3use ral::{flexio, Valid};
4
5mod dma;
6mod driver;
7mod flexio_configurator;
8mod idle_timer_finished_watcher;
9mod interleaved_pixels;
10mod interrupt_handler;
11mod maybe_own;
12mod preprocessed_pixels;
13
14use crate::Pins;
15
16pub use preprocessed_pixels::PreprocessedPixels;
17
18use self::{idle_timer_finished_watcher::IdleTimerFinishedWatcher, maybe_own::MaybeOwn};
19
20/// A WS2812 Neopixel LED Strip driver based on the i.MX RT FlexIO module
21pub struct WS2812Driver<const N: u8, const L: usize, PINS: Pins<N, L>>
22where
23    flexio::Instance<N>: Valid,
24{
25    _pins: PINS,
26    inner: MaybeOwn<InterruptHandlerData<N>>,
27}
28
29/// The result of [WS2812Driver::write_dma()][WS2812Driver::write_dma].
30pub struct WriteDmaResult<R> {
31    /// The result of the concurrent function
32    pub result: R,
33    /// True if the concurrent function took longer than writing the
34    /// data to the LED strips. This might indicate a render lag.
35    pub lagged: bool,
36}
37
38/// Static memory required by the [`WS2812Driver::take_interrupt_handler`] function.
39///
40/// For RTIC 2, it is recommended to have this allocated by the `#[init]` macro, like so:
41///
42/// ```rust
43/// #[init(local = [
44///     ws2812_data: Option<ws2812_flexio::InterruptHandlerData<2>> = None
45/// ])]
46/// fn init(cx: init::Context) -> (Shared, Local) {
47///     // ...
48/// }
49/// ```
50pub struct InterruptHandlerData<const N: u8> {
51    finished_watcher: IdleTimerFinishedWatcher<N>,
52}
53
54/// An interrupt handler that signals to the driver
55/// that an interrupt happened.
56///
57/// For correct functionality of [`WS2812Driver::write_dma`] in
58/// waker-based async runtimes (like RTIC 2), it is required to invoke the
59/// [`InterruptHandler::on_interrupt`] function every time an interrupt
60/// of the associated FlexIO peripheral happens.
61pub struct InterruptHandler<const N: u8> {
62    data: &'static InterruptHandlerData<N>,
63}