ws2811_spi/
prerendered.rs1use embedded_hal as hal;
7
8use hal::spi::{FullDuplex, Mode, Phase, Polarity};
9
10use core::marker::PhantomData;
11
12use smart_leds_trait::{SmartLedsWrite, RGB8, RGBW};
13
14use nb;
15use nb::block;
16
17pub const MODE: Mode = Mode {
22 polarity: Polarity::IdleLow,
23 phase: Phase::CaptureOnFirstTransition,
24};
25
26#[derive(Debug)]
27pub enum Error<E> {
28 OutOfBounds,
29 Spi(E),
30}
31
32pub mod devices {
33 pub struct Ws2811;
34}
35
36pub struct Ws2811<'a, SPI, DEVICE = devices::Ws2811> {
37 spi: SPI,
38 data: &'a mut [u8],
39 index: usize,
40 device: PhantomData<DEVICE>,
41}
42
43impl<'a, SPI, E> Ws2811<'a, SPI>
44where
45 SPI: FullDuplex<u8, Error = E>,
46{
47 pub fn new(spi: SPI, data: &'a mut [u8]) -> Self {
59 Self {
60 spi,
61 data,
62 index: 0,
63 device: PhantomData {},
64 }
65 }
66}
67
68impl<'a, SPI, D, E> Ws2811<'a, SPI, D>
69where
70 SPI: FullDuplex<u8, Error = E>,
71{
72 fn write_byte(&mut self, mut data: u8) -> Result<(), Error<E>> {
74 let patterns = [0b1000_1000, 0b1000_1110, 0b11101000, 0b11101110];
78
79 if self.index > self.data.len() - 4 {
80 return Err(Error::OutOfBounds);
81 }
82 for _ in 0..4 {
83 let bits = (data & 0b1100_0000) >> 6;
84 self.data[self.index] = patterns[bits as usize];
85 self.index += 1;
86 data <<= 2;
87 }
88 Ok(())
89 }
90
91 fn send_data(&mut self) -> Result<(), E> {
92 block!(self.spi.send(0))?;
96 if cfg!(feature = "mosi_idle_high") {
97 for _ in 0..140 {
98 block!(self.spi.send(0))?;
99 block!(self.spi.read())?;
100 }
101 }
102 for b in self.data[..self.index].iter() {
103 block!(self.spi.send(*b))?;
104 block!(self.spi.read())?;
105 }
106 for _ in 0..140 {
107 block!(self.spi.send(0))?;
108 block!(self.spi.read())?;
109 }
110 block!(self.spi.read())?;
112 Ok(())
113 }
114}
115
116impl<'a, SPI, E> SmartLedsWrite for Ws2811<'a, SPI>
117where
118 SPI: FullDuplex<u8, Error = E>,
119{
120 type Error = Error<E>;
121 type Color = RGB8;
122 fn write<T, I>(&mut self, iterator: T) -> Result<(), Error<E>>
124 where
125 T: Iterator<Item = I>,
126 I: Into<Self::Color>,
127 {
128 self.index = 0;
129
130 for item in iterator {
131 let item = item.into();
132 self.write_byte(item.r)?;
133 self.write_byte(item.b)?;
134 self.write_byte(item.g)?;
135 }
136 self.send_data().map_err(|e| Error::Spi(e))
137 }
138}