1#![cfg_attr(
2 feature = "doc-images",
3 doc = ::embed_doc_image::embed_image!(
4 "led_strip_simple",
5 "docs/assets/led_strip_simple.png"
6 ),
7 doc = ::embed_doc_image::embed_image!(
8 "led_strip_animated",
9 "docs/assets/led_strip_animated.png"
10 )
11)]
12pub use device_envoy_core::led_strip::*;
121pub mod led_strip_generated;
122
123#[doc(hidden)]
127pub struct LedStripEsp<const N: usize, const MAX_FRAMES: usize> {
128 command_signal: &'static LedStripCommandSignal<N, MAX_FRAMES>,
129}
130
131impl<const N: usize, const MAX_FRAMES: usize> LedStripEsp<N, MAX_FRAMES> {
132 #[doc(hidden)]
133 pub const fn new_static() -> LedStripStatic<N, MAX_FRAMES> {
134 LedStripStatic::new_static()
135 }
136
137 #[doc(hidden)]
138 pub fn new(led_strip_static: &'static LedStripStatic<N, MAX_FRAMES>) -> Self {
139 Self {
140 command_signal: led_strip_static.command_signal(),
141 }
142 }
143
144 #[doc(hidden)]
146 pub fn __command_signal(&self) -> &'static LedStripCommandSignal<N, MAX_FRAMES> {
147 self.command_signal
148 }
149}
150
151#[derive(Clone, Copy, Debug, Eq, PartialEq)]
154pub enum Engine {
155 Rmt,
157 Spi,
159}
160
161impl Default for Engine {
162 fn default() -> Self {
163 #[cfg(esp_has_rmt)]
164 {
165 return Self::Rmt;
166 }
167 #[cfg(not(esp_has_rmt))]
168 {
169 return Self::Spi;
170 }
171 #[allow(unreachable_code)]
172 Self::Rmt
173 }
174}
175
176#[doc(hidden)]
179pub const CURRENT_DEFAULT: Current = Current::Milliamps(250);
182
183#[cfg(all(target_os = "none", esp_has_rmt))]
188use embassy_futures::select::{Either, select};
189#[cfg(all(target_os = "none", esp_has_rmt))]
190use embassy_time::Timer;
191
192#[cfg(all(target_os = "none", esp_has_rmt))]
193use esp_hal::gpio::Level;
194#[cfg(all(target_os = "none", esp_has_rmt))]
195use esp_hal::rmt::{Channel, PulseCode, Tx};
196
197#[cfg(all(target_os = "none", esp_has_rmt))]
201const BIT0: PulseCode = PulseCode::new(Level::High, 8, Level::Low, 17);
202#[cfg(all(target_os = "none", esp_has_rmt))]
203const BIT1: PulseCode = PulseCode::new(Level::High, 16, Level::Low, 9);
204
205#[cfg(all(target_os = "none", esp_has_rmt))]
214#[doc(hidden)]
217pub struct RmtWs2812<'d, const LEDS: usize, const PULSES: usize> {
218 channel: Option<Channel<'d, esp_hal::Blocking, Tx>>,
219 pulse_buf: [PulseCode; PULSES],
220}
221
222#[cfg(all(target_os = "none", esp_has_rmt))]
223impl<'d, const LEDS: usize, const PULSES: usize> RmtWs2812<'d, LEDS, PULSES> {
224 #[must_use]
229 pub fn new(channel: Channel<'d, esp_hal::Blocking, Tx>) -> Self {
230 assert_eq!(
231 PULSES,
232 LEDS * 24 + 1,
233 "PULSES must equal LEDS * 24 + 1; this is enforced by led_strip!"
234 );
235 Self {
236 channel: Some(channel),
237 pulse_buf: [PulseCode::end_marker(); PULSES],
238 }
239 }
240
241 pub fn write(&mut self, frame: &Frame1d<LEDS>) -> Result<(), Error> {
246 for (led_index, pixel) in frame.iter().enumerate() {
248 let grb: u32 = ((pixel.g as u32) << 16) | ((pixel.r as u32) << 8) | (pixel.b as u32);
249 for bit_index in 0..24 {
250 let bit = (grb >> (23 - bit_index)) & 1;
251 self.pulse_buf[led_index * 24 + bit_index] = if bit == 1 { BIT1 } else { BIT0 };
252 }
253 }
254 self.pulse_buf[LEDS * 24] = PulseCode::end_marker();
257
258 let channel = self.channel.take().ok_or(Error::ChannelMissing)?;
259 let transfer = channel
260 .transmit(&self.pulse_buf)
261 .map_err(|_| Error::TransmitStart)?;
262 match transfer.wait() {
263 Ok(channel) => {
264 self.channel = Some(channel);
265 Ok(())
266 }
267 Err((err, channel)) => {
268 self.channel = Some(channel);
269 Err(Error::Transmit(err))
270 }
271 }
272 }
273}
274
275#[cfg(all(target_os = "none", esp_has_rmt))]
276#[doc(hidden)]
277#[derive(Debug)]
279pub enum Error {
280 ChannelMissing,
282 TransmitStart,
284 Transmit(esp_hal::rmt::Error),
286}
287
288#[doc(hidden)]
300#[cfg(all(target_os = "none", esp_has_rmt))]
301pub async fn led_strip_device_loop<
302 'd,
303 const LEDS: usize,
304 const PULSES: usize,
305 const MAX_FRAMES: usize,
306>(
307 mut driver: RmtWs2812<'d, LEDS, PULSES>,
308 command_signal: &'static LedStripCommandSignal<LEDS, MAX_FRAMES>,
309 combo_table: &'static [u8; 256],
310) -> ! {
311 let _ = driver.write(&Frame1d::new());
313
314 let mut pending: Option<Command<LEDS, MAX_FRAMES>> = None;
317
318 loop {
319 let command = match pending.take() {
320 Some(cmd) => cmd,
321 None => command_signal.wait().await,
322 };
323
324 match command {
325 Command::DisplayStatic(mut frame) => {
326 apply_correction(&mut frame, combo_table);
327 let _ = driver.write(&frame);
328 }
330 Command::Animate(sequence) => {
331 'animate: loop {
333 for (mut frame, duration) in sequence.iter().cloned() {
334 apply_correction(&mut frame, combo_table);
335 let _ = driver.write(&frame);
336 match select(Timer::after(duration), command_signal.wait()).await {
337 Either::First(_) => {
338 }
340 Either::Second(new_command) => {
341 pending = Some(new_command);
344 break 'animate;
345 }
346 }
347 }
348 if let Some(new_command) = command_signal.try_take() {
351 pending = Some(new_command);
352 break 'animate;
353 }
354 }
355 }
356 }
357 }
358}
359
360#[doc = include_str!("docs/current_limiting_and_gamma.md")]
400#[doc(hidden)]
405#[macro_export]
406macro_rules! led_strip {
407 ($($tt:tt)*) => { $crate::__led_strip_entry! { $($tt)* } };
408}
409
410#[doc(hidden)]
412#[macro_export]
413macro_rules! __led_strip_entry {
414 (
415 $name:ident {
416 $($before:tt)*
417 led2d: { $($led2d_fields:tt)* }
418 $($after:tt)*
419 }
420 ) => {
421 compile_error!("led_strip! is 1D-only. Use led2d! for panel generation.");
422 };
423 (
424 $name:ident {
425 $($fields:tt)*
426 }
427 ) => {
428 $crate::__led_strip_collect_fields!{
429 name = $name,
430 pin = [],
431 len = [],
432 max_current = [],
433 engine = [],
434 gamma = [],
435 max_frames = [],
436 reset_us = [],
437 fields = [$($fields)*],
438 }
439 };
440 (
441 $vis:vis $name:ident {
442 $($fields:tt)*
443 }
444 ) => {
445 $crate::__paste! {
446 $crate::__led_strip_entry! {
447 [<__ $name _visibility_inner>] {
448 $($fields)*
449 }
450 }
451 $vis type $name = [<__ $name _visibility_inner>];
452 }
453 };
454}
455
456#[cfg(target_os = "none")]
457#[doc(inline)]
458pub use led_strip;
459
460#[doc(hidden)]
461#[macro_export]
462macro_rules! __led_strip_collect_fields {
463 (
464 name = $name:ident,
465 pin = [$pin:ident],
466 len = [$len:expr],
467 max_current = [$($max_current:expr)?],
468 engine = [$($engine:tt)?],
469 gamma = [$($gamma:expr)?],
470 max_frames = [$($max_frames:expr)?],
471 reset_us = [$($reset_us:expr)?],
472 fields = [],
473 ) => {
474 $crate::__led_strip_dispatch_engine!(
475 $name,
476 $pin,
477 $len,
478 $crate::__led_strip_max_current_or_default!([$($max_current)?]),
479 [$($engine)?],
480 [$($gamma)?],
481 [$($max_frames)?],
482 [$($reset_us)?],
483 );
484 };
485 (
486 name = $name:ident,
487 pin = [],
488 len = [$($len:expr)?],
489 max_current = [$($max_current:expr)?],
490 engine = [$($engine:tt)?],
491 gamma = [$($gamma:expr)?],
492 max_frames = [$($max_frames:expr)?],
493 reset_us = [$($reset_us:expr)?],
494 fields = [],
495 ) => {
496 compile_error!("led_strip! missing required `pin` field");
497 };
498 (
499 name = $name:ident,
500 pin = [$pin:ident],
501 len = [],
502 max_current = [$($max_current:expr)?],
503 engine = [$($engine:tt)?],
504 gamma = [$($gamma:expr)?],
505 max_frames = [$($max_frames:expr)?],
506 reset_us = [$($reset_us:expr)?],
507 fields = [],
508 ) => {
509 compile_error!("led_strip! missing required `len` field");
510 };
511 (
512 name = $name:ident,
513 pin = [],
514 len = [$($len:expr)?],
515 max_current = [$($max_current:expr)?],
516 engine = [$($engine:tt)?],
517 gamma = [$($gamma:expr)?],
518 max_frames = [$($max_frames:expr)?],
519 reset_us = [$($reset_us:expr)?],
520 fields = [pin: $pin:ident $(, $($rest:tt)*)?],
521 ) => {
522 $crate::__led_strip_collect_fields!{
523 name = $name,
524 pin = [$pin],
525 len = [$($len)?],
526 max_current = [$($max_current)?],
527 engine = [$($engine)?],
528 gamma = [$($gamma)?],
529 max_frames = [$($max_frames)?],
530 reset_us = [$($reset_us)?],
531 fields = [$($($rest)*)?],
532 }
533 };
534 (
535 name = $name:ident,
536 pin = [$already_pin:ident],
537 len = [$($len:expr)?],
538 max_current = [$($max_current:expr)?],
539 engine = [$($engine:tt)?],
540 gamma = [$($gamma:expr)?],
541 max_frames = [$($max_frames:expr)?],
542 reset_us = [$($reset_us:expr)?],
543 fields = [pin: $pin:ident $(, $($rest:tt)*)?],
544 ) => {
545 compile_error!("led_strip! duplicate `pin` field");
546 };
547 (
548 name = $name:ident,
549 pin = [$($pin:ident)?],
550 len = [],
551 max_current = [$($max_current:expr)?],
552 engine = [$($engine:tt)?],
553 gamma = [$($gamma:expr)?],
554 max_frames = [$($max_frames:expr)?],
555 reset_us = [$($reset_us:expr)?],
556 fields = [len: $len:expr $(, $($rest:tt)*)?],
557 ) => {
558 $crate::__led_strip_collect_fields!{
559 name = $name,
560 pin = [$($pin)?],
561 len = [$len],
562 max_current = [$($max_current)?],
563 engine = [$($engine)?],
564 gamma = [$($gamma)?],
565 max_frames = [$($max_frames)?],
566 reset_us = [$($reset_us)?],
567 fields = [$($($rest)*)?],
568 }
569 };
570 (
571 name = $name:ident,
572 pin = [$($pin:ident)?],
573 len = [$already_len:expr],
574 max_current = [$($max_current:expr)?],
575 engine = [$($engine:tt)?],
576 gamma = [$($gamma:expr)?],
577 max_frames = [$($max_frames:expr)?],
578 reset_us = [$($reset_us:expr)?],
579 fields = [len: $len:expr $(, $($rest:tt)*)?],
580 ) => {
581 compile_error!("led_strip! duplicate `len` field");
582 };
583 (
584 name = $name:ident,
585 pin = [$($pin:ident)?],
586 len = [$($len:expr)?],
587 max_current = [],
588 engine = [$($engine:tt)?],
589 gamma = [$($gamma:expr)?],
590 max_frames = [$($max_frames:expr)?],
591 reset_us = [$($reset_us:expr)?],
592 fields = [max_current: $max_current:expr $(, $($rest:tt)*)?],
593 ) => {
594 $crate::__led_strip_collect_fields!{
595 name = $name,
596 pin = [$($pin)?],
597 len = [$($len)?],
598 max_current = [$max_current],
599 engine = [$($engine)?],
600 gamma = [$($gamma)?],
601 max_frames = [$($max_frames)?],
602 reset_us = [$($reset_us)?],
603 fields = [$($($rest)*)?],
604 }
605 };
606 (
607 name = $name:ident,
608 pin = [$($pin:ident)?],
609 len = [$($len:expr)?],
610 max_current = [$already_max_current:expr],
611 engine = [$($engine:tt)?],
612 gamma = [$($gamma:expr)?],
613 max_frames = [$($max_frames:expr)?],
614 reset_us = [$($reset_us:expr)?],
615 fields = [max_current: $max_current:expr $(, $($rest:tt)*)?],
616 ) => {
617 compile_error!("led_strip! duplicate `max_current` field");
618 };
619 (
620 name = $name:ident,
621 pin = [$($pin:ident)?],
622 len = [$($len:expr)?],
623 max_current = [$($max_current:expr)?],
624 engine = [],
625 gamma = [$($gamma:expr)?],
626 max_frames = [$($max_frames:expr)?],
627 reset_us = [$($reset_us:expr)?],
628 fields = [engine: Engine::Spi $(, $($rest:tt)*)?],
629 ) => {
630 $crate::__led_strip_collect_fields!{
631 name = $name,
632 pin = [$($pin)?],
633 len = [$($len)?],
634 max_current = [$($max_current)?],
635 engine = [Spi],
636 gamma = [$($gamma)?],
637 max_frames = [$($max_frames)?],
638 reset_us = [$($reset_us)?],
639 fields = [$($($rest)*)?],
640 }
641 };
642 (
643 name = $name:ident,
644 pin = [$($pin:ident)?],
645 len = [$($len:expr)?],
646 max_current = [$($max_current:expr)?],
647 engine = [],
648 gamma = [$($gamma:expr)?],
649 max_frames = [$($max_frames:expr)?],
650 reset_us = [$($reset_us:expr)?],
651 fields = [engine: $crate::led_strip::Engine::Spi $(, $($rest:tt)*)?],
652 ) => {
653 $crate::__led_strip_collect_fields!{
654 name = $name,
655 pin = [$($pin)?],
656 len = [$($len)?],
657 max_current = [$($max_current)?],
658 engine = [Spi],
659 gamma = [$($gamma)?],
660 max_frames = [$($max_frames)?],
661 reset_us = [$($reset_us)?],
662 fields = [$($($rest)*)?],
663 }
664 };
665 (
666 name = $name:ident,
667 pin = [$($pin:ident)?],
668 len = [$($len:expr)?],
669 max_current = [$($max_current:expr)?],
670 engine = [],
671 gamma = [$($gamma:expr)?],
672 max_frames = [$($max_frames:expr)?],
673 reset_us = [$($reset_us:expr)?],
674 fields = [engine: device_envoy_esp::led_strip::Engine::Spi $(, $($rest:tt)*)?],
675 ) => {
676 $crate::__led_strip_collect_fields!{
677 name = $name,
678 pin = [$($pin)?],
679 len = [$($len)?],
680 max_current = [$($max_current)?],
681 engine = [Spi],
682 gamma = [$($gamma)?],
683 max_frames = [$($max_frames)?],
684 reset_us = [$($reset_us)?],
685 fields = [$($($rest)*)?],
686 }
687 };
688 (
689 name = $name:ident,
690 pin = [$($pin:ident)?],
691 len = [$($len:expr)?],
692 max_current = [$($max_current:expr)?],
693 engine = [],
694 gamma = [$($gamma:expr)?],
695 max_frames = [$($max_frames:expr)?],
696 reset_us = [$($reset_us:expr)?],
697 fields = [engine: Engine::Rmt $(, $($rest:tt)*)?],
698 ) => {
699 $crate::__led_strip_collect_fields!{
700 name = $name,
701 pin = [$($pin)?],
702 len = [$($len)?],
703 max_current = [$($max_current)?],
704 engine = [Rmt],
705 gamma = [$($gamma)?],
706 max_frames = [$($max_frames)?],
707 reset_us = [$($reset_us)?],
708 fields = [$($($rest)*)?],
709 }
710 };
711 (
712 name = $name:ident,
713 pin = [$($pin:ident)?],
714 len = [$($len:expr)?],
715 max_current = [$($max_current:expr)?],
716 engine = [],
717 gamma = [$($gamma:expr)?],
718 max_frames = [$($max_frames:expr)?],
719 reset_us = [$($reset_us:expr)?],
720 fields = [engine: $crate::led_strip::Engine::Rmt $(, $($rest:tt)*)?],
721 ) => {
722 $crate::__led_strip_collect_fields!{
723 name = $name,
724 pin = [$($pin)?],
725 len = [$($len)?],
726 max_current = [$($max_current)?],
727 engine = [Rmt],
728 gamma = [$($gamma)?],
729 max_frames = [$($max_frames)?],
730 reset_us = [$($reset_us)?],
731 fields = [$($($rest)*)?],
732 }
733 };
734 (
735 name = $name:ident,
736 pin = [$($pin:ident)?],
737 len = [$($len:expr)?],
738 max_current = [$($max_current:expr)?],
739 engine = [],
740 gamma = [$($gamma:expr)?],
741 max_frames = [$($max_frames:expr)?],
742 reset_us = [$($reset_us:expr)?],
743 fields = [engine: device_envoy_esp::led_strip::Engine::Rmt $(, $($rest:tt)*)?],
744 ) => {
745 $crate::__led_strip_collect_fields!{
746 name = $name,
747 pin = [$($pin)?],
748 len = [$($len)?],
749 max_current = [$($max_current)?],
750 engine = [Rmt],
751 gamma = [$($gamma)?],
752 max_frames = [$($max_frames)?],
753 reset_us = [$($reset_us)?],
754 fields = [$($($rest)*)?],
755 }
756 };
757 (
758 name = $name:ident,
759 pin = [$($pin:ident)?],
760 len = [$($len:expr)?],
761 max_current = [$($max_current:expr)?],
762 engine = [$already_engine:tt],
763 gamma = [$($gamma:expr)?],
764 max_frames = [$($max_frames:expr)?],
765 reset_us = [$($reset_us:expr)?],
766 fields = [engine: $ignored:path $(, $($rest:tt)*)?],
767 ) => {
768 compile_error!("led_strip! duplicate `engine` field");
769 };
770 (
771 name = $name:ident,
772 pin = [$($pin:ident)?],
773 len = [$($len:expr)?],
774 max_current = [$($max_current:expr)?],
775 engine = [],
776 gamma = [$($gamma:expr)?],
777 max_frames = [$($max_frames:expr)?],
778 reset_us = [$($reset_us:expr)?],
779 fields = [engine: $ignored:path $(, $($rest:tt)*)?],
780 ) => {
781 compile_error!("led_strip! engine must be Engine::Rmt or Engine::Spi");
782 };
783 (
784 name = $name:ident,
785 pin = [$($pin:ident)?],
786 len = [$($len:expr)?],
787 max_current = [$($max_current:expr)?],
788 engine = [$($engine:tt)?],
789 gamma = [],
790 max_frames = [$($max_frames:expr)?],
791 reset_us = [$($reset_us:expr)?],
792 fields = [gamma: $gamma:expr $(, $($rest:tt)*)?],
793 ) => {
794 $crate::__led_strip_collect_fields!{
795 name = $name,
796 pin = [$($pin)?],
797 len = [$($len)?],
798 max_current = [$($max_current)?],
799 engine = [$($engine)?],
800 gamma = [$gamma],
801 max_frames = [$($max_frames)?],
802 reset_us = [$($reset_us)?],
803 fields = [$($($rest)*)?],
804 }
805 };
806 (
807 name = $name:ident,
808 pin = [$($pin:ident)?],
809 len = [$($len:expr)?],
810 max_current = [$($max_current:expr)?],
811 engine = [$($engine:tt)?],
812 gamma = [$already_gamma:expr],
813 max_frames = [$($max_frames:expr)?],
814 reset_us = [$($reset_us:expr)?],
815 fields = [gamma: $gamma:expr $(, $($rest:tt)*)?],
816 ) => {
817 compile_error!("led_strip! duplicate `gamma` field");
818 };
819 (
820 name = $name:ident,
821 pin = [$($pin:ident)?],
822 len = [$($len:expr)?],
823 max_current = [$($max_current:expr)?],
824 engine = [$($engine:tt)?],
825 gamma = [$($gamma:expr)?],
826 max_frames = [],
827 reset_us = [$($reset_us:expr)?],
828 fields = [max_frames: $max_frames:expr $(, $($rest:tt)*)?],
829 ) => {
830 $crate::__led_strip_collect_fields!{
831 name = $name,
832 pin = [$($pin)?],
833 len = [$($len)?],
834 max_current = [$($max_current)?],
835 engine = [$($engine)?],
836 gamma = [$($gamma)?],
837 max_frames = [$max_frames],
838 reset_us = [$($reset_us)?],
839 fields = [$($($rest)*)?],
840 }
841 };
842 (
843 name = $name:ident,
844 pin = [$($pin:ident)?],
845 len = [$($len:expr)?],
846 max_current = [$($max_current:expr)?],
847 engine = [$($engine:tt)?],
848 gamma = [$($gamma:expr)?],
849 max_frames = [$already_max_frames:expr],
850 reset_us = [$($reset_us:expr)?],
851 fields = [max_frames: $max_frames:expr $(, $($rest:tt)*)?],
852 ) => {
853 compile_error!("led_strip! duplicate `max_frames` field");
854 };
855 (
856 name = $name:ident,
857 pin = [$($pin:ident)?],
858 len = [$($len:expr)?],
859 max_current = [$($max_current:expr)?],
860 engine = [$($engine:tt)?],
861 gamma = [$($gamma:expr)?],
862 max_frames = [$($max_frames:expr)?],
863 reset_us = [],
864 fields = [reset_us: $reset_us:expr $(, $($rest:tt)*)?],
865 ) => {
866 $crate::__led_strip_collect_fields!{
867 name = $name,
868 pin = [$($pin)?],
869 len = [$($len)?],
870 max_current = [$($max_current)?],
871 engine = [$($engine)?],
872 gamma = [$($gamma)?],
873 max_frames = [$($max_frames)?],
874 reset_us = [$reset_us],
875 fields = [$($($rest)*)?],
876 }
877 };
878 (
879 name = $name:ident,
880 pin = [$($pin:ident)?],
881 len = [$($len:expr)?],
882 max_current = [$($max_current:expr)?],
883 engine = [$($engine:tt)?],
884 gamma = [$($gamma:expr)?],
885 max_frames = [$($max_frames:expr)?],
886 reset_us = [$already_reset_us:expr],
887 fields = [reset_us: $reset_us:expr $(, $($rest:tt)*)?],
888 ) => {
889 compile_error!("led_strip! duplicate `reset_us` field");
890 };
891 (
892 name = $name:ident,
893 pin = [$($pin:ident)?],
894 len = [$($len:expr)?],
895 max_current = [$($max_current:expr)?],
896 engine = [$($engine:tt)?],
897 gamma = [$($gamma:expr)?],
898 max_frames = [$($max_frames:expr)?],
899 reset_us = [$($reset_us:expr)?],
900 fields = [$field:ident : $value:expr $(, $($rest:tt)*)?],
901 ) => {
902 compile_error!(
903 "led_strip! unknown field; expected `pin`, `len`, `max_current`, `engine`, `gamma`, `max_frames`, or `reset_us`"
904 );
905 };
906}
907
908#[doc(hidden)]
909#[macro_export]
910macro_rules! __led_strip_max_current_or_default {
911 ([$max_current:expr]) => {
912 $max_current
913 };
914 ([]) => {
915 $crate::led_strip::CURRENT_DEFAULT
916 };
917}
918
919#[doc(hidden)]
926#[macro_export]
927macro_rules! __led_strip_inner {
928 (
929 $name:ident,
930 $pin:ident,
931 $len:expr,
932 $max_current:expr,
933 [$($gamma:expr)?],
934 [$($max_frames:expr)?],
935 [$($led2d_layout:expr)?],
936 [$($led2d_font:expr)?],
937 ) => {
938 $crate::__led_strip_impl!{
939 name = $name,
940 pin = $pin,
941 len = $len,
942 max_current = $max_current,
943 gamma = $crate::__led_strip_first_or_default!(
944 [$($gamma)?],
945 $crate::led_strip::GAMMA_DEFAULT
946 ),
947 max_frames = $crate::__led_strip_first_or_default!(
948 [$($max_frames)?],
949 $crate::led_strip::MAX_FRAMES_DEFAULT
950 ),
951 led2d_layout = [$($led2d_layout)?],
952 led2d_font = [$($led2d_font)?],
953 }
954 };
955}
956
957#[doc(hidden)]
961#[macro_export]
962macro_rules! __led_strip_parse_options {
963 (
964 name = $name:ident,
965 pin = $pin:ident,
966 len = $len:expr,
967 max_current = $max_current:expr,
968 engine = [$($engine:tt)*],
969 gamma = [$($gamma:expr)?],
970 max_frames = [$($max_frames:expr)?],
971 reset_us = [$($reset_us:expr)?],
972 ) => {
973 $crate::__led_strip_dispatch_engine! {
974 $name,
975 $pin,
976 $len,
977 $max_current,
978 [$($engine)*],
979 [$($gamma)?],
980 [$($max_frames)?],
981 [$($reset_us)?],
982 }
983 };
984 (
985 name = $name:ident,
986 pin = $pin:ident,
987 len = $len:expr,
988 max_current = $max_current:expr,
989 engine = [],
990 gamma = [$($gamma:expr)?],
991 max_frames = [$($max_frames:expr)?],
992 reset_us = [$($reset_us:expr)?],
993 engine: Engine::Spi
994 $(, $($tail:tt)*)?
995 ) => {
996 $crate::__led_strip_parse_options! {
997 name = $name,
998 pin = $pin,
999 len = $len,
1000 max_current = $max_current,
1001 engine = [Spi],
1002 gamma = [$($gamma)?],
1003 max_frames = [$($max_frames)?],
1004 reset_us = [$($reset_us)?],
1005 $($($tail)*)?
1006 }
1007 };
1008 (
1009 name = $name:ident,
1010 pin = $pin:ident,
1011 len = $len:expr,
1012 max_current = $max_current:expr,
1013 engine = [],
1014 gamma = [$($gamma:expr)?],
1015 max_frames = [$($max_frames:expr)?],
1016 reset_us = [$($reset_us:expr)?],
1017 engine: $crate::led_strip::Engine::Spi
1018 $(, $($tail:tt)*)?
1019 ) => {
1020 $crate::__led_strip_parse_options! {
1021 name = $name,
1022 pin = $pin,
1023 len = $len,
1024 max_current = $max_current,
1025 engine = [Spi],
1026 gamma = [$($gamma)?],
1027 max_frames = [$($max_frames)?],
1028 reset_us = [$($reset_us)?],
1029 $($($tail)*)?
1030 }
1031 };
1032 (
1033 name = $name:ident,
1034 pin = $pin:ident,
1035 len = $len:expr,
1036 max_current = $max_current:expr,
1037 engine = [],
1038 gamma = [$($gamma:expr)?],
1039 max_frames = [$($max_frames:expr)?],
1040 reset_us = [$($reset_us:expr)?],
1041 engine: device_envoy_esp::led_strip::Engine::Spi
1042 $(, $($tail:tt)*)?
1043 ) => {
1044 $crate::__led_strip_parse_options! {
1045 name = $name,
1046 pin = $pin,
1047 len = $len,
1048 max_current = $max_current,
1049 engine = [Spi],
1050 gamma = [$($gamma)?],
1051 max_frames = [$($max_frames)?],
1052 reset_us = [$($reset_us)?],
1053 $($($tail)*)?
1054 }
1055 };
1056 (
1057 name = $name:ident,
1058 pin = $pin:ident,
1059 len = $len:expr,
1060 max_current = $max_current:expr,
1061 engine = [],
1062 gamma = [$($gamma:expr)?],
1063 max_frames = [$($max_frames:expr)?],
1064 reset_us = [$($reset_us:expr)?],
1065 engine: Engine::Rmt
1066 $(, $($tail:tt)*)?
1067 ) => {
1068 $crate::__led_strip_parse_options! {
1069 name = $name,
1070 pin = $pin,
1071 len = $len,
1072 max_current = $max_current,
1073 engine = [Rmt],
1074 gamma = [$($gamma)?],
1075 max_frames = [$($max_frames)?],
1076 reset_us = [$($reset_us)?],
1077 $($($tail)*)?
1078 }
1079 };
1080 (
1081 name = $name:ident,
1082 pin = $pin:ident,
1083 len = $len:expr,
1084 max_current = $max_current:expr,
1085 engine = [],
1086 gamma = [$($gamma:expr)?],
1087 max_frames = [$($max_frames:expr)?],
1088 reset_us = [$($reset_us:expr)?],
1089 engine: $crate::led_strip::Engine::Rmt
1090 $(, $($tail:tt)*)?
1091 ) => {
1092 $crate::__led_strip_parse_options! {
1093 name = $name,
1094 pin = $pin,
1095 len = $len,
1096 max_current = $max_current,
1097 engine = [Rmt],
1098 gamma = [$($gamma)?],
1099 max_frames = [$($max_frames)?],
1100 reset_us = [$($reset_us)?],
1101 $($($tail)*)?
1102 }
1103 };
1104 (
1105 name = $name:ident,
1106 pin = $pin:ident,
1107 len = $len:expr,
1108 max_current = $max_current:expr,
1109 engine = [],
1110 gamma = [$($gamma:expr)?],
1111 max_frames = [$($max_frames:expr)?],
1112 reset_us = [$($reset_us:expr)?],
1113 engine: device_envoy_esp::led_strip::Engine::Rmt
1114 $(, $($tail:tt)*)?
1115 ) => {
1116 $crate::__led_strip_parse_options! {
1117 name = $name,
1118 pin = $pin,
1119 len = $len,
1120 max_current = $max_current,
1121 engine = [Rmt],
1122 gamma = [$($gamma)?],
1123 max_frames = [$($max_frames)?],
1124 reset_us = [$($reset_us)?],
1125 $($($tail)*)?
1126 }
1127 };
1128 (
1129 name = $name:ident,
1130 pin = $pin:ident,
1131 len = $len:expr,
1132 max_current = $max_current:expr,
1133 engine = [$($engine:tt)+],
1134 gamma = [$($gamma:expr)?],
1135 max_frames = [$($max_frames:expr)?],
1136 reset_us = [$($reset_us:expr)?],
1137 engine: $ignored:path
1138 $(, $($tail:tt)*)?
1139 ) => {
1140 compile_error!("led_strip! duplicate `engine` field");
1141 };
1142 (
1143 name = $name:ident,
1144 pin = $pin:ident,
1145 len = $len:expr,
1146 max_current = $max_current:expr,
1147 engine = [],
1148 gamma = [$($gamma:expr)?],
1149 max_frames = [$($max_frames:expr)?],
1150 reset_us = [$($reset_us:expr)?],
1151 engine: $ignored:path
1152 $(, $($tail:tt)*)?
1153 ) => {
1154 compile_error!("led_strip! engine must be Engine::Rmt or Engine::Spi");
1155 };
1156 (
1157 name = $name:ident,
1158 pin = $pin:ident,
1159 len = $len:expr,
1160 max_current = $max_current:expr,
1161 engine = [$($engine:tt)*],
1162 gamma = [],
1163 max_frames = [$($max_frames:expr)?],
1164 reset_us = [$($reset_us:expr)?],
1165 gamma: $gamma:expr
1166 $(, $($tail:tt)*)?
1167 ) => {
1168 $crate::__led_strip_parse_options! {
1169 name = $name,
1170 pin = $pin,
1171 len = $len,
1172 max_current = $max_current,
1173 engine = [$($engine)*],
1174 gamma = [$gamma],
1175 max_frames = [$($max_frames)?],
1176 reset_us = [$($reset_us)?],
1177 $($($tail)*)?
1178 }
1179 };
1180 (
1181 name = $name:ident,
1182 pin = $pin:ident,
1183 len = $len:expr,
1184 max_current = $max_current:expr,
1185 engine = [$($engine:tt)*],
1186 gamma = [$already_gamma:expr],
1187 max_frames = [$($max_frames:expr)?],
1188 reset_us = [$($reset_us:expr)?],
1189 gamma: $gamma:expr
1190 $(, $($tail:tt)*)?
1191 ) => {
1192 compile_error!("led_strip! duplicate `gamma` field");
1193 };
1194 (
1195 name = $name:ident,
1196 pin = $pin:ident,
1197 len = $len:expr,
1198 max_current = $max_current:expr,
1199 engine = [$($engine:tt)*],
1200 gamma = [$($gamma:expr)?],
1201 max_frames = [],
1202 reset_us = [$($reset_us:expr)?],
1203 max_frames: $max_frames:expr
1204 $(, $($tail:tt)*)?
1205 ) => {
1206 $crate::__led_strip_parse_options! {
1207 name = $name,
1208 pin = $pin,
1209 len = $len,
1210 max_current = $max_current,
1211 engine = [$($engine)*],
1212 gamma = [$($gamma)?],
1213 max_frames = [$max_frames],
1214 reset_us = [$($reset_us)?],
1215 $($($tail)*)?
1216 }
1217 };
1218 (
1219 name = $name:ident,
1220 pin = $pin:ident,
1221 len = $len:expr,
1222 max_current = $max_current:expr,
1223 engine = [$($engine:tt)*],
1224 gamma = [$($gamma:expr)?],
1225 max_frames = [$already_max_frames:expr],
1226 reset_us = [$($reset_us:expr)?],
1227 max_frames: $max_frames:expr
1228 $(, $($tail:tt)*)?
1229 ) => {
1230 compile_error!("led_strip! duplicate `max_frames` field");
1231 };
1232 (
1233 name = $name:ident,
1234 pin = $pin:ident,
1235 len = $len:expr,
1236 max_current = $max_current:expr,
1237 engine = [$($engine:tt)*],
1238 gamma = [$($gamma:expr)?],
1239 max_frames = [$($max_frames:expr)?],
1240 reset_us = [],
1241 reset_us: $reset_us:expr
1242 $(, $($tail:tt)*)?
1243 ) => {
1244 $crate::__led_strip_parse_options! {
1245 name = $name,
1246 pin = $pin,
1247 len = $len,
1248 max_current = $max_current,
1249 engine = [$($engine)*],
1250 gamma = [$($gamma)?],
1251 max_frames = [$($max_frames)?],
1252 reset_us = [$reset_us],
1253 $($($tail)*)?
1254 }
1255 };
1256 (
1257 name = $name:ident,
1258 pin = $pin:ident,
1259 len = $len:expr,
1260 max_current = $max_current:expr,
1261 engine = [$($engine:tt)*],
1262 gamma = [$($gamma:expr)?],
1263 max_frames = [$($max_frames:expr)?],
1264 reset_us = [$already_reset_us:expr],
1265 reset_us: $reset_us:expr
1266 $(, $($tail:tt)*)?
1267 ) => {
1268 compile_error!("led_strip! duplicate `reset_us` field");
1269 };
1270 (
1271 name = $name:ident,
1272 pin = $pin:ident,
1273 len = $len:expr,
1274 max_current = $max_current:expr,
1275 engine = [$($engine:tt)*],
1276 gamma = [$($gamma:expr)?],
1277 max_frames = [$($max_frames:expr)?],
1278 reset_us = [$($reset_us:expr)?],
1279 $field:ident : $value:expr
1280 $(, $($tail:tt)*)?
1281 ) => {
1282 compile_error!("led_strip! unknown field; expected `engine`, `gamma`, `max_frames`, or `reset_us`");
1283 };
1284}
1285
1286#[doc(hidden)]
1290#[macro_export]
1291macro_rules! __led_strip_dispatch_engine {
1292 (
1293 $name:ident,
1294 $pin:ident,
1295 $len:expr,
1296 $max_current:expr,
1297 [Spi],
1298 [$($gamma:expr)?],
1299 [$($max_frames:expr)?],
1300 [$($reset_us:expr)?],
1301 ) => {
1302 $crate::led_strip::spi::__led_strip_spi_inner!{
1303 $name,
1304 $pin,
1305 $len,
1306 $max_current,
1307 [$($gamma)?],
1308 [$($max_frames)?],
1309 [$($reset_us)?],
1310 [],
1311 [],
1312 }
1313 };
1314 (
1315 $name:ident,
1316 $pin:ident,
1317 $len:expr,
1318 $max_current:expr,
1319 [Rmt],
1320 [$($gamma:expr)?],
1321 [$($max_frames:expr)?],
1322 [$reset_us:expr],
1323 ) => {
1324 compile_error!("led_strip! `reset_us` is only supported with `engine: Engine::Spi`");
1325 };
1326 (
1327 $name:ident,
1328 $pin:ident,
1329 $len:expr,
1330 $max_current:expr,
1331 [Rmt],
1332 [$($gamma:expr)?],
1333 [$($max_frames:expr)?],
1334 [],
1335 ) => {
1336 $crate::__led_strip_dispatch_rmt_engine!{
1337 $name,
1338 $pin,
1339 $len,
1340 $max_current,
1341 [$($gamma)?],
1342 [$($max_frames)?],
1343 }
1344 };
1345 (
1346 $name:ident,
1347 $pin:ident,
1348 $len:expr,
1349 $max_current:expr,
1350 [],
1351 [$($gamma:expr)?],
1352 [$($max_frames:expr)?],
1353 [$reset_us:expr],
1354 ) => {
1355 compile_error!("led_strip! `reset_us` is only supported with `engine: Engine::Spi`");
1356 };
1357 (
1358 $name:ident,
1359 $pin:ident,
1360 $len:expr,
1361 $max_current:expr,
1362 [],
1363 [$($gamma:expr)?],
1364 [$($max_frames:expr)?],
1365 [],
1366 ) => {
1367 $crate::__led_strip_dispatch_default_engine!{
1368 $name,
1369 $pin,
1370 $len,
1371 $max_current,
1372 [$($gamma)?],
1373 [$($max_frames)?],
1374 }
1375 };
1376}
1377
1378#[doc(hidden)]
1380#[cfg(esp_has_rmt)]
1381#[macro_export]
1382macro_rules! __led_strip_dispatch_rmt_engine {
1383 (
1384 $name:ident,
1385 $pin:ident,
1386 $len:expr,
1387 $max_current:expr,
1388 [$($gamma:expr)?],
1389 [$($max_frames:expr)?],
1390 ) => {
1391 $crate::led_strip::__led_strip_inner!{
1392 $name,
1393 $pin,
1394 $len,
1395 $max_current,
1396 [$($gamma)?],
1397 [$($max_frames)?],
1398 [],
1399 [],
1400 }
1401 };
1402}
1403
1404#[doc(hidden)]
1406#[cfg(not(esp_has_rmt))]
1407#[macro_export]
1408macro_rules! __led_strip_dispatch_rmt_engine {
1409 (
1410 $name:ident,
1411 $pin:ident,
1412 $len:expr,
1413 $max_current:expr,
1414 [$($gamma:expr)?],
1415 [$($max_frames:expr)?],
1416 ) => {
1417 compile_error!(
1418 "led_strip! `engine: Engine::Rmt` requires an RMT-capable chip; use `engine: Engine::Spi`."
1419 );
1420 };
1421}
1422
1423#[doc(hidden)]
1425#[cfg(esp_has_rmt)]
1426#[macro_export]
1427macro_rules! __led_strip_dispatch_default_engine {
1428 (
1429 $name:ident,
1430 $pin:ident,
1431 $len:expr,
1432 $max_current:expr,
1433 [$($gamma:expr)?],
1434 [$($max_frames:expr)?],
1435 ) => {
1436 $crate::__led_strip_dispatch_rmt_engine!{
1437 $name,
1438 $pin,
1439 $len,
1440 $max_current,
1441 [$($gamma)?],
1442 [$($max_frames)?],
1443 }
1444 };
1445}
1446
1447#[doc(hidden)]
1449#[cfg(not(esp_has_rmt))]
1450#[macro_export]
1451macro_rules! __led_strip_dispatch_default_engine {
1452 (
1453 $name:ident,
1454 $pin:ident,
1455 $len:expr,
1456 $max_current:expr,
1457 [$($gamma:expr)?],
1458 [$($max_frames:expr)?],
1459 ) => {
1460 $crate::led_strip::spi::__led_strip_spi_inner!{
1461 $name,
1462 $pin,
1463 $len,
1464 $max_current,
1465 [$($gamma)?],
1466 [$($max_frames)?],
1467 [],
1468 [],
1469 [],
1470 }
1471 };
1472}
1473
1474#[doc(hidden)]
1478#[macro_export]
1479macro_rules! __led_strip_first_or_default {
1480 ([$value:expr], $_default:expr) => {
1481 $value
1482 };
1483 ([], $default:expr) => {
1484 $default
1485 };
1486}
1487
1488#[doc(hidden)]
1490#[macro_export]
1491macro_rules! __led2d_strip_methods {
1492 ($_leds:expr, $max_frames:expr, [$led_layout:expr], [$font:expr]) => {
1493 pub const FONT: $crate::led2d::Led2dFont = $font;
1495 pub const WIDTH: usize = $led_layout.width();
1497 pub const HEIGHT: usize = $led_layout.height();
1499 pub const SIZE: $crate::led2d::Size =
1501 $crate::led2d::Frame2d::<{ $led_layout.width() }, { $led_layout.height() }>::SIZE;
1502 pub const TOP_LEFT: $crate::led2d::Point =
1504 $crate::led2d::Frame2d::<{ $led_layout.width() }, { $led_layout.height() }>::TOP_LEFT;
1505 pub const TOP_RIGHT: $crate::led2d::Point =
1507 $crate::led2d::Frame2d::<{ $led_layout.width() }, { $led_layout.height() }>::TOP_RIGHT;
1508 pub const BOTTOM_LEFT: $crate::led2d::Point = $crate::led2d::Frame2d::<
1510 { $led_layout.width() },
1511 { $led_layout.height() },
1512 >::BOTTOM_LEFT;
1513 pub const BOTTOM_RIGHT: $crate::led2d::Point = $crate::led2d::Frame2d::<
1515 { $led_layout.width() },
1516 { $led_layout.height() },
1517 >::BOTTOM_RIGHT;
1518 };
1519 ($_leds:expr, $_max_frames:expr, [], []) => {};
1520}
1521
1522#[doc(hidden)]
1524#[macro_export]
1525macro_rules! __led2d_strip_trait_impl {
1526 ($name:ident, [$led_layout:expr], [$font:expr], $max_frames:expr) => {
1527 impl $crate::led2d::Led2d<{ $led_layout.width() }, { $led_layout.height() }>
1528 for &'static $name
1529 {
1530 const WIDTH: usize = $name::WIDTH;
1531 const HEIGHT: usize = $name::HEIGHT;
1532 const LEN: usize = $name::LEN;
1533 const SIZE: $crate::led2d::Size = $name::SIZE;
1534 const TOP_LEFT: $crate::led2d::Point = $name::TOP_LEFT;
1535 const TOP_RIGHT: $crate::led2d::Point = $name::TOP_RIGHT;
1536 const BOTTOM_LEFT: $crate::led2d::Point = $name::BOTTOM_LEFT;
1537 const BOTTOM_RIGHT: $crate::led2d::Point = $name::BOTTOM_RIGHT;
1538 const MAX_FRAMES: usize = $max_frames;
1539 const MAX_BRIGHTNESS: u8 = $name::MAX_BRIGHTNESS;
1540 const FONT: $crate::led2d::Led2dFont = $font;
1541
1542 fn write_frame(
1543 &self,
1544 frame2d: $crate::led2d::Frame2d<{ $led_layout.width() }, { $led_layout.height() }>,
1545 ) {
1546 let led2d = $crate::led2d::Led2dEsp::new(*self, &$led_layout);
1547 $crate::led2d::Led2dStripBacked::write_frame(&led2d, frame2d);
1548 }
1549
1550 fn animate<I>(&self, frames: I)
1551 where
1552 I: IntoIterator,
1553 I::Item: ::core::borrow::Borrow<(
1554 $crate::led2d::Frame2d<{ $led_layout.width() }, { $led_layout.height() }>,
1555 embassy_time::Duration,
1556 )>,
1557 {
1558 let led2d = $crate::led2d::Led2dEsp::new(*self, &$led_layout);
1559 $crate::led2d::Led2dStripBacked::animate(&led2d, frames);
1560 }
1561 }
1562 };
1563 ($_name:ident, [], [], $_max_frames:expr) => {};
1564}
1565
1566#[doc(hidden)]
1569#[macro_export]
1570macro_rules! __led_strip_impl {
1571 (
1572 name = $name:ident,
1573 pin = $pin:ident,
1574 len = $len:expr,
1575 max_current = $max_current:expr,
1576 gamma = $gamma:expr,
1577 max_frames = $max_frames:expr,
1578 led2d_layout = [$($led2d_layout:expr)?],
1579 led2d_font = [$($led2d_font:expr)?],
1580 ) => {
1581 ::paste::paste! {
1582 mod [<$name:snake _consts>] {
1587 pub const LEDS: usize = $len;
1589 pub const PULSES: usize = LEDS * 24 + 1;
1591 pub const WORST_CASE_MA: u32 = LEDS as u32 * 60;
1593 }
1594
1595 static [<$name:snake:upper _STATIC>]:
1599 $crate::led_strip::LedStripStatic<
1600 { [<$name:snake _consts>]::LEDS },
1601 { $max_frames },
1602 > = $crate::led_strip::LedStripEsp::new_static();
1603
1604 pub struct $name {
1608 inner: $crate::led_strip::LedStripEsp<
1609 { [<$name:snake _consts>]::LEDS },
1610 { $max_frames },
1611 >,
1612 }
1613
1614 impl $name {
1615 pub const LEN: usize = [<$name:snake _consts>]::LEDS;
1617
1618 pub const MAX_FRAMES: usize = $max_frames;
1620
1621 pub const MAX_BRIGHTNESS: u8 = <$crate::led_strip::Current>::max_brightness(
1624 $max_current,
1625 [<$name:snake _consts>]::WORST_CASE_MA,
1626 );
1627
1628 pub const COMBO_TABLE: [u8; 256] =
1630 $crate::led_strip::generate_combo_table($gamma, Self::MAX_BRIGHTNESS);
1631
1632 $crate::__led2d_strip_methods!(
1633 { [<$name:snake _consts>]::LEDS },
1634 { $max_frames },
1635 [$($led2d_layout)?],
1636 [$($led2d_font)?]
1637 );
1638
1639 pub fn new(
1644 pin: $crate::esp_hal::peripherals::$pin<'static>,
1645 channel_creator: impl ::esp_hal::rmt::TxChannelCreator<
1646 'static,
1647 ::esp_hal::Blocking,
1648 >,
1649 spawner: ::embassy_executor::Spawner,
1650 ) -> $crate::Result<&'static Self> {
1651 use ::static_cell::StaticCell;
1652
1653 static INSTANCE: StaticCell<$name> = StaticCell::new();
1654 static COMBO: StaticCell<[u8; 256]> = StaticCell::new();
1655
1656 let combo_ref: &'static [u8; 256] =
1657 COMBO.init(<$name>::COMBO_TABLE);
1658
1659 let channel = channel_creator
1660 .configure_tx(&$crate::init_and_start::rmt::ws2812_tx_config())
1661 .map_err($crate::Error::RmtConfig)?
1662 .with_pin(pin);
1663
1664 let driver =
1665 $crate::led_strip::RmtWs2812::<
1666 { [<$name:snake _consts>]::LEDS },
1667 { [<$name:snake _consts>]::PULSES },
1668 >::new(channel);
1669
1670 let strip_static: &'static _ = &[<$name:snake:upper _STATIC>];
1671
1672 spawner
1673 .spawn([<$name:snake _device_task>](driver, strip_static, combo_ref).map_err($crate::Error::TaskSpawn)?);
1674
1675 let instance = INSTANCE.init($name {
1676 inner: $crate::led_strip::LedStripEsp::new(strip_static),
1677 });
1678 Ok(instance)
1679 }
1680 }
1681
1682 impl $crate::led_strip::LedStrip<{ [<$name:snake _consts>]::LEDS }> for $name {
1683 const MAX_FRAMES: usize = $max_frames;
1684 const MAX_BRIGHTNESS: u8 = Self::MAX_BRIGHTNESS;
1685
1686 fn write_frame(
1687 &self,
1688 frame: $crate::led_strip::Frame1d<{ [<$name:snake _consts>]::LEDS }>,
1689 ) {
1690 $crate::led_strip::__write_frame(self.inner.__command_signal(), frame);
1691 }
1692
1693 fn animate<I>(&self, frames: I)
1694 where
1695 I: IntoIterator,
1696 I::Item: ::core::borrow::Borrow<(
1697 $crate::led_strip::Frame1d<{ [<$name:snake _consts>]::LEDS }>,
1698 embassy_time::Duration,
1699 )>,
1700 {
1701 $crate::led_strip::__animate(self.inner.__command_signal(), frames);
1702 }
1703 }
1704
1705 $crate::__led2d_strip_trait_impl!(
1706 $name,
1707 [$($led2d_layout)?],
1708 [$($led2d_font)?],
1709 $max_frames
1710 );
1711
1712 #[::embassy_executor::task]
1716 async fn [<$name:snake _device_task>](
1717 driver: $crate::led_strip::RmtWs2812<
1718 'static,
1719 { [<$name:snake _consts>]::LEDS },
1720 { [<$name:snake _consts>]::PULSES },
1721 >,
1722 strip_static: &'static $crate::led_strip::LedStripStatic<
1723 { [<$name:snake _consts>]::LEDS },
1724 { $max_frames },
1725 >,
1726 combo_table: &'static [u8; 256],
1727 ) {
1728 $crate::led_strip::led_strip_device_loop(
1729 driver,
1730 strip_static.command_signal(),
1731 combo_table,
1732 )
1733 .await;
1734 }
1735 }
1736 };
1737}
1738
1739#[cfg(target_os = "none")]
1744#[doc(hidden)]
1745pub mod spi;
1746
1747pub use crate::{
1749 __led_strip_dispatch_default_engine, __led_strip_dispatch_engine,
1750 __led_strip_dispatch_rmt_engine, __led_strip_first_or_default, __led_strip_impl,
1751 __led_strip_inner, __led_strip_parse_options, __led2d_strip_methods, __led2d_strip_trait_impl,
1752};