1use std::mem;
2use std::slice::from_raw_parts_mut;
3
4mod bindings;
5mod channel_builder;
6mod error;
7mod strip_type;
8
9use channel_builder::ChannelBuilder;
10use error::WS2811Error;
11use strip_type::StripType;
12
13use smart_leds_trait::{SmartLedsWrite, RGB8};
14
15pub struct Ws2812Rpi {
16 c_struct: bindings::ws2811_t,
17}
18
19impl Ws2812Rpi
20{
21 pub fn new(led_count: i32, pin: i32) -> Result<Self, WS2811Error> {
23 unsafe {
24 let mut ret = Self { c_struct: mem::zeroed() };
25
26 ret.c_struct.freq = 800_000;
27 ret.c_struct.dmanum = 10;
28 ret.c_struct.channel[0] = ChannelBuilder::new()
29 .pin(pin)
30 .count(led_count)
31 .strip_type(StripType::Ws2811Rgb)
32 .brightness(255)
33 .build();
34 let res: Result<(), WS2811Error> = bindings::ws2811_init(&mut ret.c_struct).into();
35
36 match res {
37 Ok(_) => {}
38 Err(e) => return Err(e),
39 }
40 return Ok(ret);
41 }
42
43 }
44
45}
46
47impl Drop for Ws2812Rpi {
48 fn drop(&mut self) {
49 unsafe {
55 bindings::ws2811_fini(&mut self.c_struct);
56 }
57 }
58}
59
60impl SmartLedsWrite for Ws2812Rpi
61{
62 type Error = error::WS2811Error;
63 type Color = RGB8;
64 fn write<T, I>(&mut self, iterator: T) -> Result<(), Self::Error>
66 where
67 T: Iterator<Item = I>,
68 I: Into<Self::Color>,
69 {
70 let mut i = 0;
71
72 let mut colors = unsafe {
73 from_raw_parts_mut(
74 self.c_struct.channel[0].leds as *mut [u8; 4],
75 self.c_struct.channel[0].count as usize,
76 )
77 };
78
79 for c in iterator {
80 let c_rgb: Self::Color = c.into();
81 colors[i] = [c_rgb.b, c_rgb.r, c_rgb.g, 0];
82 i = i + 1;
83 }
84
85 unsafe {
86 return bindings::ws2811_render(&mut self.c_struct).into();
87 }
88
89 Ok(())
90 }
91}