From ac3a03df45df542129e965da4b75237760e49808 Mon Sep 17 00:00:00 2001 From: Christian Bach Date: Mon, 11 Nov 2024 15:19:57 +0100 Subject: [PATCH 1/3] bump smart-leds-trait to v0.3.0 and crate version to v0.9.0 since there are breaking changes --- Cargo.toml | 4 ++-- src/lib.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dab7e96..11b6ba8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ws2812-pio" -version = "0.8.0" +version = "0.9.0" edition = "2021" license = "Apache-2.0" description = "Driver implementation for the WS2812 smart LED using the RP2040's PIO peripheral." @@ -12,6 +12,6 @@ embedded-hal = "0.2.5" fugit = "0.3.5" rp2040-hal = "0.10" pio = "0.2.0" -smart-leds-trait = "0.2.1" +smart-leds-trait = "0.3.0" nb = "1.0.0" cortex-m = "0.7.3" diff --git a/src/lib.rs b/src/lib.rs index acc6481..04eace6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,7 @@ use smart_leds_trait::SmartLedsWrite; /// use smart_leds::{SmartLedsWrite, RGB8}; /// let color : RGB8 = (255, 0, 255).into(); /// -/// ws.write([color].iter().copied()).unwrap(); +/// ws.write([color]).unwrap(); /// delay_for_at_least_60_microseconds(); /// }; ///``` @@ -166,7 +166,7 @@ where /// PIO FIFO until all data has been transmitted to the LED chain. fn write(&mut self, iterator: T) -> Result<(), ()> where - T: Iterator, + T: IntoIterator, J: Into, { for item in iterator { @@ -256,7 +256,7 @@ where type Error = (); fn write(&mut self, iterator: T) -> Result<(), ()> where - T: Iterator, + T: IntoIterator, J: Into, { self.driver.tx.clear_stalled_flag(); From 8279fef5c6b7800fecd0abdb81d7e11fa2c40105 Mon Sep 17 00:00:00 2001 From: Christian Bach Date: Mon, 11 Nov 2024 15:46:45 +0100 Subject: [PATCH 2/3] Add color reorder functionality --- Cargo.toml | 2 +- src/lib.rs | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 11b6ba8..dab870c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ws2812-pio" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "Apache-2.0" description = "Driver implementation for the WS2812 smart LED using the RP2040's PIO peripheral." diff --git a/src/lib.rs b/src/lib.rs index 04eace6..347db1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,67 @@ use smart_leds_trait::SmartLedsWrite; /// delay_for_at_least_60_microseconds(); /// }; ///``` +/// +/// // It is possible to change the color ordering by using +/// // the constructor ```new_with_chip_config``` along with the +/// // ordering enum ```Ws2812ColorOrder```: +///```ignore +/// let mut ws = Ws2812Direct::new_with_chip_config( +/// pins.gpio4.into_mode(), +/// &mut pio, +/// sm0, +/// clocks.peripheral_clock.freq(), +/// Ws2812ColorOrder::RGB, +/// ); +/// ``` + +#[derive(Copy, Clone)] +pub enum Ws2812ColorOrder { + RGB, + GRB, + RBG, + BGR, + GBR, + BRG, +} + +impl Ws2812ColorOrder { + fn get_color_value(&self, color: &smart_leds_trait::RGB8) -> u32 { + match self { + Ws2812ColorOrder::RGB => { + return (u32::from(color.r) << 24) + | (u32::from(color.g) << 16) + | (u32::from(color.b) << 8) + } + Ws2812ColorOrder::GRB => { + return (u32::from(color.g) << 24) + | (u32::from(color.r) << 16) + | (u32::from(color.b) << 8) + } + Ws2812ColorOrder::RBG => { + return (u32::from(color.r) << 24) + | (u32::from(color.b) << 16) + | (u32::from(color.g) << 8) + } + Ws2812ColorOrder::BGR => { + return (u32::from(color.b) << 24) + | (u32::from(color.g) << 16) + | (u32::from(color.r) << 8) + } + Ws2812ColorOrder::GBR => { + return (u32::from(color.g) << 24) + | (u32::from(color.b) << 16) + | (u32::from(color.r) << 8) + } + Ws2812ColorOrder::BRG => { + return (u32::from(color.b) << 24) + | (u32::from(color.r) << 16) + | (u32::from(color.g) << 8) + } + }; + } +} + pub struct Ws2812Direct where I: AnyPin, @@ -61,6 +122,7 @@ where { tx: Tx<(P, SM)>, _pin: I, + _converter: Ws2812ColorOrder, } impl Ws2812Direct @@ -75,6 +137,16 @@ where pio: &mut PIO

, sm: UninitStateMachine<(P, SM)>, clock_freq: fugit::HertzU32, + ) -> Self { + Ws2812Direct::new_with_chip_config(pin, pio, sm, clock_freq, Ws2812ColorOrder::GRB) + } + /// Creates a new instance of this driver. + pub fn new_with_chip_config( + pin: I, + pio: &mut PIO

, + sm: UninitStateMachine<(P, SM)>, + clock_freq: fugit::HertzU32, + chip_config: Ws2812ColorOrder, ) -> Self { // prepare the PIO program let side_set = pio::SideSet::new(false, 1, false); @@ -145,6 +217,7 @@ where Self { tx, _pin: I::from(pin), + _converter: chip_config, } } } @@ -171,10 +244,8 @@ where { for item in iterator { let color: Self::Color = item.into(); - let word = - (u32::from(color.g) << 24) | (u32::from(color.r) << 16) | (u32::from(color.b) << 8); - while !self.tx.write(word) { + while !self.tx.write(self._converter.get_color_value(&color)) { cortex_m::asm::nop(); } } @@ -212,6 +283,20 @@ where /// // Do other stuff here... /// }; ///``` +/// +/// // It is possible to change the color ordering by using +/// // the constructor ```new_with_chip_config``` along with the +/// // ordering enum ```Ws2812ColorOrder```: +///```ignore +/// let mut ws = Ws2812::new_with_chip_config( +/// pins.gpio4.into_mode(), +/// &mut pio, +/// sm0, +/// clocks.peripheral_clock.freq(), +/// timer.count_down(), +/// Ws2812ColorOrder::RGB, +/// ); +/// ``` pub struct Ws2812 where C: CountDown, @@ -242,6 +327,20 @@ where Self { driver, cd } } + + /// Creates a new instance of this driver. + pub fn new_with_chip_config( + pin: I, + pio: &mut PIO

, + sm: UninitStateMachine<(P, SM)>, + clock_freq: fugit::HertzU32, + cd: C, + chip_config: Ws2812ColorOrder, + ) -> Ws2812 { + let driver = Ws2812Direct::new_with_chip_config(pin, pio, sm, clock_freq, chip_config); + + Self { driver, cd } + } } impl SmartLedsWrite for Ws2812 From 86a82da5fd86bfcc38d59a176d384b5090d21144 Mon Sep 17 00:00:00 2001 From: Christian Bach Date: Tue, 12 Nov 2024 16:26:25 +0100 Subject: [PATCH 3/3] extract the struct Ws2812ColorOrder into its own file --- src/lib.rs | 51 +++------------------------------------ src/ws2812_color_order.rs | 46 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 48 deletions(-) create mode 100644 src/ws2812_color_order.rs diff --git a/src/lib.rs b/src/lib.rs index 347db1d..d739f0c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,53 +66,8 @@ use smart_leds_trait::SmartLedsWrite; /// Ws2812ColorOrder::RGB, /// ); /// ``` - -#[derive(Copy, Clone)] -pub enum Ws2812ColorOrder { - RGB, - GRB, - RBG, - BGR, - GBR, - BRG, -} - -impl Ws2812ColorOrder { - fn get_color_value(&self, color: &smart_leds_trait::RGB8) -> u32 { - match self { - Ws2812ColorOrder::RGB => { - return (u32::from(color.r) << 24) - | (u32::from(color.g) << 16) - | (u32::from(color.b) << 8) - } - Ws2812ColorOrder::GRB => { - return (u32::from(color.g) << 24) - | (u32::from(color.r) << 16) - | (u32::from(color.b) << 8) - } - Ws2812ColorOrder::RBG => { - return (u32::from(color.r) << 24) - | (u32::from(color.b) << 16) - | (u32::from(color.g) << 8) - } - Ws2812ColorOrder::BGR => { - return (u32::from(color.b) << 24) - | (u32::from(color.g) << 16) - | (u32::from(color.r) << 8) - } - Ws2812ColorOrder::GBR => { - return (u32::from(color.g) << 24) - | (u32::from(color.b) << 16) - | (u32::from(color.r) << 8) - } - Ws2812ColorOrder::BRG => { - return (u32::from(color.b) << 24) - | (u32::from(color.r) << 16) - | (u32::from(color.g) << 8) - } - }; - } -} +mod ws2812_color_order; +pub use ws2812_color_order::Ws2812ColorOrder; pub struct Ws2812Direct where @@ -245,7 +200,7 @@ where for item in iterator { let color: Self::Color = item.into(); - while !self.tx.write(self._converter.get_color_value(&color)) { + while !self.tx.write(self._converter._get_color_value(&color)) { cortex_m::asm::nop(); } } diff --git a/src/ws2812_color_order.rs b/src/ws2812_color_order.rs new file mode 100644 index 0000000..5518087 --- /dev/null +++ b/src/ws2812_color_order.rs @@ -0,0 +1,46 @@ +#[derive(Copy, Clone)] +pub enum Ws2812ColorOrder { + RGB, + GRB, + RBG, + BGR, + GBR, + BRG, +} + +impl Ws2812ColorOrder { + pub fn _get_color_value(&self, color: &smart_leds_trait::RGB8) -> u32 { + match self { + Ws2812ColorOrder::RGB => { + return (u32::from(color.r) << 24) + | (u32::from(color.g) << 16) + | (u32::from(color.b) << 8) + } + Ws2812ColorOrder::GRB => { + return (u32::from(color.g) << 24) + | (u32::from(color.r) << 16) + | (u32::from(color.b) << 8) + } + Ws2812ColorOrder::RBG => { + return (u32::from(color.r) << 24) + | (u32::from(color.b) << 16) + | (u32::from(color.g) << 8) + } + Ws2812ColorOrder::BGR => { + return (u32::from(color.b) << 24) + | (u32::from(color.g) << 16) + | (u32::from(color.r) << 8) + } + Ws2812ColorOrder::GBR => { + return (u32::from(color.g) << 24) + | (u32::from(color.b) << 16) + | (u32::from(color.r) << 8) + } + Ws2812ColorOrder::BRG => { + return (u32::from(color.b) << 24) + | (u32::from(color.r) << 16) + | (u32::from(color.g) << 8) + } + }; + } +}