|
13 | 13 | //! Bear in mind that you will have to take care of timing requirements
|
14 | 14 | //! yourself then.
|
15 | 15 |
|
16 |
| -//use cortex_m; |
17 | 16 | use fugit::{ExtU32, HertzU32};
|
18 | 17 | use rp2040_hal::{
|
19 |
| - gpio::{Function, Pin, PinId, PullType, *}, |
| 18 | + gpio::{Function, Pin, PinId, *}, |
20 | 19 | pio::{PIOExt, StateMachineIndex, Tx, UninitStateMachine, PIO},
|
21 |
| - //timer::CountDown, |
| 20 | + timer::CountDown, |
22 | 21 | };
|
23 |
| -//use smart_leds_trait::SmartLedsWrite; |
| 22 | +use smart_leds_trait::SmartLedsWrite; |
24 | 23 |
|
25 |
| -///// This is the WS2812 PIO Driver. |
26 |
| -///// |
27 |
| -///// For blocking applications is recommended to use |
28 |
| -///// the [Ws2812] struct instead of this raw driver. |
29 |
| -///// |
30 |
| -///// If you use this driver directly, you will need to |
31 |
| -///// take care of the timing expectations of the [Ws2812Direct::write] |
32 |
| -///// method. |
33 |
| -///// |
34 |
| -///// Typical usage example: |
35 |
| -/////```ignore |
36 |
| -///// use rp2040_hal::clocks::init_clocks_and_plls; |
37 |
| -///// let clocks = init_clocks_and_plls(...); |
38 |
| -///// let pins = rp2040_hal::gpio::pin::bank0::Pins::new(...); |
39 |
| -///// |
40 |
| -///// let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); |
41 |
| -///// let mut ws = Ws2812Direct::new( |
42 |
| -///// pins.gpio4.into_mode(), |
43 |
| -///// &mut pio, |
44 |
| -///// sm0, |
45 |
| -///// clocks.peripheral_clock.freq(), |
46 |
| -///// ); |
47 |
| -///// |
48 |
| -///// // Then you will make sure yourself to not write too frequently: |
49 |
| -///// loop { |
50 |
| -///// use smart_leds::{SmartLedsWrite, RGB8}; |
51 |
| -///// let color : RGB8 = (255, 0, 255).into(); |
52 |
| -///// |
53 |
| -///// ws.write([color].iter().copied()).unwrap(); |
54 |
| -///// delay_for_at_least_60_microseconds(); |
55 |
| -///// }; |
56 |
| -/////``` |
| 24 | +/// This is the WS2812 PIO Driver. |
| 25 | +/// |
| 26 | +/// For blocking applications is recommended to use |
| 27 | +/// the [Ws2812] struct instead of this raw driver. |
| 28 | +/// |
| 29 | +/// If you use this driver directly, you will need to |
| 30 | +/// take care of the timing expectations of the [Ws2812Direct::write] |
| 31 | +/// method. |
| 32 | +/// |
| 33 | +/// Typical usage example: |
| 34 | +///```ignore |
| 35 | +/// use rp2040_hal::clocks::init_clocks_and_plls; |
| 36 | +/// let clocks = init_clocks_and_plls(...); |
| 37 | +/// let pins = rp2040_hal::gpio::pin::bank0::Pins::new(...); |
| 38 | +/// |
| 39 | +/// let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); |
| 40 | +/// let mut ws = Ws2812Direct::new( |
| 41 | +/// pins.gpio4.into_mode(), |
| 42 | +/// &mut pio, |
| 43 | +/// sm0, |
| 44 | +/// clocks.peripheral_clock.freq(), |
| 45 | +/// ); |
| 46 | +/// |
| 47 | +/// // Then you will make sure yourself to not write too frequently: |
| 48 | +/// loop { |
| 49 | +/// use smart_leds::{SmartLedsWrite, RGB8}; |
| 50 | +/// let color : RGB8 = (255, 0, 255).into(); |
| 51 | +/// |
| 52 | +/// ws.write([color].iter().copied()).unwrap(); |
| 53 | +/// delay_for_at_least_60_microseconds(); |
| 54 | +/// }; |
| 55 | +///``` |
57 | 56 | pub struct Ws2812Direct<P, SM, I, F>
|
58 | 57 | where
|
59 | 58 | I: PinId,
|
|
62 | 61 | SM: StateMachineIndex,
|
63 | 62 | {
|
64 | 63 | tx: Tx<(P, SM)>,
|
65 |
| - _pin: Pin<I, F, DynPullType> |
| 64 | + _pin: Pin<I, F, DynPullType>, |
66 | 65 | }
|
67 | 66 |
|
68 | 67 | impl<P, SM, I, F> Ws2812Direct<P, SM, I, F>
|
@@ -148,122 +147,122 @@ where
|
148 | 147 | }
|
149 | 148 | }
|
150 | 149 |
|
151 |
| -//impl<P, SM, I> SmartLedsWrite for Ws2812Direct<P, SM, I> |
152 |
| -//where |
153 |
| -// I: PinId, |
154 |
| -// P: PIOExt + FunctionConfig, |
155 |
| -// Function<P>: ValidPinMode<I>, |
156 |
| -// SM: StateMachineIndex, |
157 |
| -//{ |
158 |
| -// type Color = smart_leds_trait::RGB8; |
159 |
| -// type Error = (); |
160 |
| -// /// If you call this function, be advised that you will have to wait |
161 |
| -// /// at least 60 microseconds between calls of this function! |
162 |
| -// /// That means, either you get hold on a timer and the timing |
163 |
| -// /// requirements right your self, or rather use [Ws2812]. |
164 |
| -// /// |
165 |
| -// /// Please bear in mind, that it still blocks when writing into the |
166 |
| -// /// PIO FIFO until all data has been transmitted to the LED chain. |
167 |
| -// fn write<T, J>(&mut self, iterator: T) -> Result<(), ()> |
168 |
| -// where |
169 |
| -// T: Iterator<Item = J>, |
170 |
| -// J: Into<Self::Color>, |
171 |
| -// { |
172 |
| -// for item in iterator { |
173 |
| -// let color: Self::Color = item.into(); |
174 |
| -// let word = |
175 |
| -// (u32::from(color.g) << 24) | (u32::from(color.r) << 16) | (u32::from(color.b) << 8); |
176 |
| -// |
177 |
| -// while !self.tx.write(word) { |
178 |
| -// cortex_m::asm::nop(); |
179 |
| -// } |
180 |
| -// } |
181 |
| -// Ok(()) |
182 |
| -// } |
183 |
| -//} |
| 150 | +impl<P, SM, I, F> SmartLedsWrite for Ws2812Direct<P, SM, I, F> |
| 151 | +where |
| 152 | + I: PinId, |
| 153 | + P: PIOExt, |
| 154 | + F: Function, |
| 155 | + SM: StateMachineIndex, |
| 156 | +{ |
| 157 | + type Color = smart_leds_trait::RGB8; |
| 158 | + type Error = (); |
| 159 | + /// If you call this function, be advised that you will have to wait |
| 160 | + /// at least 60 microseconds between calls of this function! |
| 161 | + /// That means, either you get hold on a timer and the timing |
| 162 | + /// requirements right your self, or rather use [Ws2812]. |
| 163 | + /// |
| 164 | + /// Please bear in mind, that it still blocks when writing into the |
| 165 | + /// PIO FIFO until all data has been transmitted to the LED chain. |
| 166 | + fn write<T, J>(&mut self, iterator: T) -> Result<(), ()> |
| 167 | + where |
| 168 | + T: Iterator<Item = J>, |
| 169 | + J: Into<Self::Color>, |
| 170 | + { |
| 171 | + for item in iterator { |
| 172 | + let color: Self::Color = item.into(); |
| 173 | + let word = |
| 174 | + (u32::from(color.g) << 24) | (u32::from(color.r) << 16) | (u32::from(color.b) << 8); |
| 175 | + |
| 176 | + while !self.tx.write(word) { |
| 177 | + cortex_m::asm::nop(); |
| 178 | + } |
| 179 | + } |
| 180 | + Ok(()) |
| 181 | + } |
| 182 | +} |
| 183 | + |
| 184 | +/// Instance of a WS2812 LED chain. |
| 185 | +/// |
| 186 | +/// Use the [Ws2812::write] method to update the WS2812 LED chain. |
| 187 | +/// |
| 188 | +/// Typical usage example: |
| 189 | +///```ignore |
| 190 | +/// use rp2040_hal::clocks::init_clocks_and_plls; |
| 191 | +/// let clocks = init_clocks_and_plls(...); |
| 192 | +/// let pins = rp2040_hal::gpio::pin::bank0::Pins::new(...); |
| 193 | +/// |
| 194 | +/// let timer = Timer::new(pac.TIMER, &mut pac.RESETS); |
| 195 | +/// |
| 196 | +/// let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); |
| 197 | +/// let mut ws = Ws2812::new( |
| 198 | +/// pins.gpio4.into_mode(), |
| 199 | +/// &mut pio, |
| 200 | +/// sm0, |
| 201 | +/// clocks.peripheral_clock.freq(), |
| 202 | +/// timer.count_down(), |
| 203 | +/// ); |
| 204 | +/// |
| 205 | +/// loop { |
| 206 | +/// use smart_leds::{SmartLedsWrite, RGB8}; |
| 207 | +/// let color : RGB8 = (255, 0, 255).into(); |
| 208 | +/// |
| 209 | +/// ws.write([color].iter().copied()).unwrap(); |
| 210 | +/// |
| 211 | +/// // Do other stuff here... |
| 212 | +/// }; |
| 213 | +///``` |
| 214 | +pub struct Ws2812<'timer, P, SM, I, F> |
| 215 | +where |
| 216 | + I: PinId, |
| 217 | + P: PIOExt, |
| 218 | + F: Function, |
| 219 | + SM: StateMachineIndex, |
| 220 | +{ |
| 221 | + driver: Ws2812Direct<P, SM, I, F>, |
| 222 | + cd: CountDown<'timer>, |
| 223 | +} |
| 224 | + |
| 225 | +impl<'timer, P, SM, I, F> Ws2812<'timer, P, SM, I, F> |
| 226 | +where |
| 227 | + I: PinId, |
| 228 | + P: PIOExt, |
| 229 | + F: Function, |
| 230 | + SM: StateMachineIndex, |
| 231 | +{ |
| 232 | + /// Creates a new instance of this driver. |
| 233 | + pub fn new( |
| 234 | + pin: Pin<I, F, DynPullType>, |
| 235 | + pio: &mut PIO<P>, |
| 236 | + sm: UninitStateMachine<(P, SM)>, |
| 237 | + clock_freq: fugit::HertzU32, |
| 238 | + cd: CountDown<'timer>, |
| 239 | + ) -> Ws2812<'timer, P, SM, I, F> { |
| 240 | + let driver = Ws2812Direct::new(pin, pio, sm, clock_freq); |
| 241 | + |
| 242 | + Self { driver, cd } |
| 243 | + } |
| 244 | +} |
184 | 245 |
|
185 |
| -///// Instance of a WS2812 LED chain. |
186 |
| -///// |
187 |
| -///// Use the [Ws2812::write] method to update the WS2812 LED chain. |
188 |
| -///// |
189 |
| -///// Typical usage example: |
190 |
| -/////```ignore |
191 |
| -///// use rp2040_hal::clocks::init_clocks_and_plls; |
192 |
| -///// let clocks = init_clocks_and_plls(...); |
193 |
| -///// let pins = rp2040_hal::gpio::pin::bank0::Pins::new(...); |
194 |
| -///// |
195 |
| -///// let timer = Timer::new(pac.TIMER, &mut pac.RESETS); |
196 |
| -///// |
197 |
| -///// let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); |
198 |
| -///// let mut ws = Ws2812::new( |
199 |
| -///// pins.gpio4.into_mode(), |
200 |
| -///// &mut pio, |
201 |
| -///// sm0, |
202 |
| -///// clocks.peripheral_clock.freq(), |
203 |
| -///// timer.count_down(), |
204 |
| -///// ); |
205 |
| -///// |
206 |
| -///// loop { |
207 |
| -///// use smart_leds::{SmartLedsWrite, RGB8}; |
208 |
| -///// let color : RGB8 = (255, 0, 255).into(); |
209 |
| -///// |
210 |
| -///// ws.write([color].iter().copied()).unwrap(); |
211 |
| -///// |
212 |
| -///// // Do other stuff here... |
213 |
| -///// }; |
214 |
| -/////``` |
215 |
| -//pub struct Ws2812<'timer, P, SM, I> |
216 |
| -//where |
217 |
| -// I: PinId, |
218 |
| -// P: PIOExt + FunctionConfig, |
219 |
| -// Function<P>: ValidPinMode<I>, |
220 |
| -// SM: StateMachineIndex, |
221 |
| -//{ |
222 |
| -// driver: Ws2812Direct<P, SM, I>, |
223 |
| -// cd: CountDown<'timer>, |
224 |
| -//} |
225 |
| -// |
226 |
| -//impl<'timer, P, SM, I> Ws2812<'timer, P, SM, I> |
227 |
| -//where |
228 |
| -// I: PinId, |
229 |
| -// P: PIOExt + FunctionConfig, |
230 |
| -// Function<P>: ValidPinMode<I>, |
231 |
| -// SM: StateMachineIndex, |
232 |
| -//{ |
233 |
| -// /// Creates a new instance of this driver. |
234 |
| -// pub fn new( |
235 |
| -// pin: Pin<I, Function<P>>, |
236 |
| -// pio: &mut PIO<P>, |
237 |
| -// sm: UninitStateMachine<(P, SM)>, |
238 |
| -// clock_freq: fugit::HertzU32, |
239 |
| -// cd: CountDown, |
240 |
| -// ) -> Ws2812<'timer, P, SM, I> { |
241 |
| -// let driver = Ws2812Direct::new(pin, pio, sm, clock_freq); |
242 |
| -// |
243 |
| -// Self { driver, cd } |
244 |
| -// } |
245 |
| -//} |
246 |
| -// |
247 |
| -//impl<'timer, P, SM, I> SmartLedsWrite for Ws2812<'timer, P, SM, rp2040_hal::timer::CountDown<'timer>, I> |
248 |
| -//where |
249 |
| -// I: PinId, |
250 |
| -// P: PIOExt + FunctionConfig, |
251 |
| -// Function<P>: ValidPinMode<I>, |
252 |
| -// SM: StateMachineIndex, |
253 |
| -//{ |
254 |
| -// type Color = smart_leds_trait::RGB8; |
255 |
| -// type Error = (); |
256 |
| -// fn write<T, J>(&mut self, iterator: T) -> Result<(), ()> |
257 |
| -// where |
258 |
| -// T: Iterator<Item = J>, |
259 |
| -// J: Into<Self::Color>, |
260 |
| -// { |
261 |
| -// self.driver.tx.clear_stalled_flag(); |
262 |
| -// while !self.driver.tx.is_empty() && !self.driver.tx.has_stalled() {} |
263 |
| -// |
264 |
| -// self.cd.start(60u32.micros()); |
265 |
| -// let _ = nb::block!(self.cd.wait()); |
266 |
| -// |
267 |
| -// self.driver.write(iterator) |
268 |
| -// } |
269 |
| -//} |
| 246 | +impl<'timer, P, SM, I, F> SmartLedsWrite for Ws2812<'timer, P, SM, I, F> |
| 247 | +where |
| 248 | + I: PinId, |
| 249 | + P: PIOExt, |
| 250 | + F: Function, |
| 251 | + SM: StateMachineIndex, |
| 252 | +{ |
| 253 | + type Color = smart_leds_trait::RGB8; |
| 254 | + type Error = (); |
| 255 | + fn write<T, J>(&mut self, iterator: T) -> Result<(), ()> |
| 256 | + where |
| 257 | + T: Iterator<Item = J>, |
| 258 | + J: Into<Self::Color>, |
| 259 | + { |
| 260 | + self.driver.tx.clear_stalled_flag(); |
| 261 | + while !self.driver.tx.is_empty() && !self.driver.tx.has_stalled() {} |
| 262 | + |
| 263 | + self.cd.start(60u32.micros()); |
| 264 | + let _ = nb::block!(self.cd.wait()); |
| 265 | + |
| 266 | + self.driver.write(iterator) |
| 267 | + } |
| 268 | +} |
0 commit comments