Skip to content

Commit 4c21961

Browse files
committed
WIP4
BUILDING! Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent 8f88250 commit 4c21961

File tree

1 file changed

+154
-155
lines changed

1 file changed

+154
-155
lines changed

src/lib.rs

+154-155
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,46 @@
1313
//! Bear in mind that you will have to take care of timing requirements
1414
//! yourself then.
1515
16-
//use cortex_m;
1716
use fugit::{ExtU32, HertzU32};
1817
use rp2040_hal::{
19-
gpio::{Function, Pin, PinId, PullType, *},
18+
gpio::{Function, Pin, PinId, *},
2019
pio::{PIOExt, StateMachineIndex, Tx, UninitStateMachine, PIO},
21-
//timer::CountDown,
20+
timer::CountDown,
2221
};
23-
//use smart_leds_trait::SmartLedsWrite;
22+
use smart_leds_trait::SmartLedsWrite;
2423

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+
///```
5756
pub struct Ws2812Direct<P, SM, I, F>
5857
where
5958
I: PinId,
@@ -62,7 +61,7 @@ where
6261
SM: StateMachineIndex,
6362
{
6463
tx: Tx<(P, SM)>,
65-
_pin: Pin<I, F, DynPullType>
64+
_pin: Pin<I, F, DynPullType>,
6665
}
6766

6867
impl<P, SM, I, F> Ws2812Direct<P, SM, I, F>
@@ -148,122 +147,122 @@ where
148147
}
149148
}
150149

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+
}
184245

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

Comments
 (0)