@@ -39,14 +39,51 @@ pub mod devices {
39
39
pub struct Sk6812w ;
40
40
}
41
41
42
- pub struct Ws2812 < SPI , DEVICE = devices:: Ws2812 > {
42
+ /// The color order the WS2812-like device expects. In most cases, this is GRB
43
+ /// and doesn't need to be specified separately.
44
+ ///
45
+ /// For SK6812W devices (with a separate white channel) this is unused
46
+ pub mod pixel_order {
47
+ pub struct RGB ;
48
+ pub struct RBG ;
49
+ pub struct GRB ;
50
+ pub struct GBR ;
51
+ pub struct BRG ;
52
+ pub struct BGR ;
53
+ }
54
+
55
+ /// Used to define the pixel order, refer to the pixel_order module
56
+ pub trait OrderedColors {
57
+ fn order ( color : RGB8 ) -> [ u8 ; 3 ] ;
58
+ }
59
+
60
+ macro_rules! impl_ordered_colors {
61
+ ( $struct_name: ident, $r_field: ident, $g_field: ident, $b_field: ident) => {
62
+ impl OrderedColors for pixel_order:: $struct_name {
63
+ fn order( color: RGB8 ) -> [ u8 ; 3 ] {
64
+ [ color. $r_field, color. $g_field, color. $b_field]
65
+ }
66
+ }
67
+ } ;
68
+ }
69
+
70
+ impl_ordered_colors ! ( RGB , r, g, b) ;
71
+ impl_ordered_colors ! ( RBG , r, b, g) ;
72
+ impl_ordered_colors ! ( GRB , g, r, b) ;
73
+ impl_ordered_colors ! ( GBR , g, b, r) ;
74
+ impl_ordered_colors ! ( BRG , b, r, g) ;
75
+ impl_ordered_colors ! ( BGR , b, g, r) ;
76
+
77
+ pub struct Ws2812 < SPI , DEVICE = devices:: Ws2812 , PIXELORDER = pixel_order:: GRB > {
43
78
spi : SPI ,
44
- device : PhantomData < DEVICE > ,
79
+ _device : PhantomData < DEVICE > ,
80
+ _pixel_order : PhantomData < PIXELORDER > ,
45
81
}
46
82
47
- impl < SPI , E > Ws2812 < SPI >
83
+ impl < SPI , E , PO > Ws2812 < SPI , devices :: Ws2812 , PO >
48
84
where
49
85
SPI : SpiBus < u8 , Error = E > ,
86
+ PO : OrderedColors ,
50
87
{
51
88
/// Use ws2812 devices via spi
52
89
///
@@ -59,12 +96,13 @@ where
59
96
pub fn new ( spi : SPI ) -> Self {
60
97
Self {
61
98
spi,
62
- device : PhantomData { } ,
99
+ _device : PhantomData { } ,
100
+ _pixel_order : PhantomData { } ,
63
101
}
64
102
}
65
103
}
66
104
67
- impl < SPI , E > Ws2812 < SPI , devices:: Sk6812w >
105
+ impl < SPI , E , PO > Ws2812 < SPI , devices:: Sk6812w , PO >
68
106
where
69
107
SPI : SpiBus < u8 , Error = E > ,
70
108
{
@@ -81,12 +119,13 @@ where
81
119
pub fn new_sk6812w ( spi : SPI ) -> Self {
82
120
Self {
83
121
spi,
84
- device : PhantomData { } ,
122
+ _device : PhantomData { } ,
123
+ _pixel_order : PhantomData { } ,
85
124
}
86
125
}
87
126
}
88
127
89
- impl < SPI , D , E > Ws2812 < SPI , D >
128
+ impl < SPI , D , E , PO > Ws2812 < SPI , D , PO >
90
129
where
91
130
SPI : SpiBus < u8 , Error = E > ,
92
131
{
@@ -113,7 +152,7 @@ where
113
152
}
114
153
}
115
154
116
- impl < SPI , E > SmartLedsWrite for Ws2812 < SPI >
155
+ impl < SPI , E , PO : OrderedColors > SmartLedsWrite for Ws2812 < SPI , devices :: Ws2812 , PO >
117
156
where
118
157
SPI : SpiBus < u8 , Error = E > ,
119
158
{
@@ -130,17 +169,18 @@ where
130
169
}
131
170
132
171
for item in iterator {
133
- let item = item. into ( ) ;
134
- self . write_byte ( item. g ) ?;
135
- self . write_byte ( item. r ) ?;
136
- self . write_byte ( item. b ) ?;
172
+ let color: RGB8 = item. into ( ) ;
173
+ let ordered_color = PO :: order ( color) ;
174
+ self . write_byte ( ordered_color[ 0 ] ) ?;
175
+ self . write_byte ( ordered_color[ 1 ] ) ?;
176
+ self . write_byte ( ordered_color[ 2 ] ) ?;
137
177
}
138
178
self . reset ( ) ?;
139
179
Ok ( ( ) )
140
180
}
141
181
}
142
182
143
- impl < SPI , E > SmartLedsWrite for Ws2812 < SPI , devices:: Sk6812w >
183
+ impl < SPI , E , PO > SmartLedsWrite for Ws2812 < SPI , devices:: Sk6812w , PO >
144
184
where
145
185
SPI : SpiBus < u8 , Error = E > ,
146
186
{
@@ -158,6 +198,7 @@ where
158
198
159
199
for item in iterator {
160
200
let item = item. into ( ) ;
201
+ // SK6812W always expects GRBW order
161
202
self . write_byte ( item. g ) ?;
162
203
self . write_byte ( item. r ) ?;
163
204
self . write_byte ( item. b ) ?;
0 commit comments