Skip to content

Commit 99f7ee8

Browse files
Rework reset_single_transaction feature to handle the reset correctly
If the feature is used, the reset needs to be added to the data before sending it out. Otherwise, the reset is sent after the data is sent. Also - Always add mosi_idle_high reset to buffer - Update comments - Avoid constructing an additional array just to add the zeroes (will probably result in the same binary)
1 parent 9cd3e1a commit 99f7ee8

File tree

1 file changed

+49
-28
lines changed

1 file changed

+49
-28
lines changed

src/prerendered.rs

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,19 @@ impl<'a, SPI, E> Ws2812<'a, SPI>
4444
where
4545
SPI: SpiBus<u8, Error = E>,
4646
{
47-
/// Use ws2812 devices via spi
47+
/// Use WS2812 devices via SPI
4848
///
4949
/// The SPI bus should run within 2 MHz to 3.8 MHz
5050
///
51-
/// You may need to look at the datasheet and your own hal to verify this.
51+
/// You may need to look at the datasheet and your own HAL to verify this.
5252
///
53-
/// You need to provide a buffer `data`, whoose length is at least 12 * the
54-
/// length of the led strip + 140 bytes (or 280, if using the `mosi_idle_high` feature)
53+
/// You need to provide a buffer `data`, whose length is at least 12 * the
54+
/// length of the led strip
55+
/// - + 140 bytes if using the `reset_single_transaction` feature
56+
/// - + 140 bytes if using the `mosi_idle_high` feature
57+
/// - + 280 bytes if using the `mosi_idle_high` and `reset_single_transaction` features
5558
///
56-
/// Please ensure that the mcu is pretty fast, otherwise weird timing
59+
/// Please ensure that the MCU is pretty fast, otherwise weird timing
5760
/// issues will occur
5861
pub fn new(spi: SPI, data: &'a mut [u8]) -> Self {
5962
Self {
@@ -69,18 +72,21 @@ impl<'a, SPI, E> Ws2812<'a, SPI, devices::Sk6812w>
6972
where
7073
SPI: SpiBus<u8, Error = E>,
7174
{
72-
/// Use sk6812w devices via spi
75+
/// Use SK6812W devices via SPI
7376
///
7477
/// The SPI bus should run within 2.3 MHz to 3.8 MHz at least.
7578
///
76-
/// You may need to look at the datasheet and your own hal to verify this.
79+
/// You may need to look at the datasheet and your own HAL to verify this.
7780
///
78-
/// You need to provide a buffer `data`, whoose length is at least 16 * the
79-
/// length of the led strip + 140 bytes (or 280, if using the `mosi_idle_high` feature)
81+
/// You need to provide a buffer `data`, whose length is at least 16 * the
82+
/// length of the led strip
83+
/// - + 140 bytes if using the `reset_single_transaction` feature
84+
/// - + 140 bytes if using the `mosi_idle_high` feature
85+
/// - + 280 bytes if using the `mosi_idle_high` and `reset_single_transaction` features
8086
///
81-
/// Please ensure that the mcu is pretty fast, otherwise weird timing
87+
/// Please ensure that the MCU is pretty fast, otherwise weird timing
8288
/// issues will occur
83-
// The spi frequencies are just the limits, the available timing data isn't
89+
// The SPI frequencies are just the limits, the available timing data isn't
8490
// complete
8591
pub fn new_sk6812w(spi: SPI, data: &'a mut [u8]) -> Self {
8692
Self {
@@ -96,7 +102,7 @@ impl<'a, SPI, D, E> Ws2812<'a, SPI, D>
96102
where
97103
SPI: SpiBus<u8, Error = E>,
98104
{
99-
/// Write a single byte for ws2812 devices
105+
/// Write a single byte for WS2812-like devices
100106
fn write_byte(&mut self, mut data: u8) -> Result<(), Error<E>> {
101107
// Send two bits in one spi byte. High time first, then the low time
102108
// The maximum for T0H is 500ns, the minimum for one bit 1063 ns.
@@ -116,21 +122,20 @@ where
116122
}
117123

118124
/// Add a reset sequence (140 zeroes) to the data buffer
119-
#[cfg(feature = "reset_single_transaction")]
120-
fn flush(&mut self) -> Result<(), Error<E>> {
121-
let flush_data = [(); FLUSH_DATA_LEN].map(|_| 0);
122-
125+
// Is always used for `mosi_idle_high`, as otherwise the time required to fill the buffer can lead to idle cycles on the SPI bus
126+
fn write_reset(&mut self) -> Result<(), Error<E>> {
123127
if self.index + FLUSH_DATA_LEN > self.data.len() {
124128
return Err(Error::OutOfBounds);
125129
}
126-
self.data[self.index..(self.index + FLUSH_DATA_LEN)].copy_from_slice(&flush_data);
127-
self.index += FLUSH_DATA_LEN;
130+
for _ in 0..FLUSH_DATA_LEN {
131+
self.data[self.index] = 0;
132+
self.index += 1;
133+
}
128134
Ok(())
129135
}
130136

131137
/// Send a reset sequence (140 zeroes) on the bus
132-
#[cfg(not(feature = "reset_single_transaction"))]
133-
fn flush(&mut self) -> Result<(), Error<E>> {
138+
fn send_reset(&mut self) -> Result<(), Error<E>> {
134139
for _ in 0..FLUSH_DATA_LEN {
135140
self.spi.write(&[0]).map_err(Error::Spi)?;
136141
}
@@ -149,7 +154,7 @@ where
149154
{
150155
type Error = Error<E>;
151156
type Color = RGB8;
152-
/// Write all the items of an iterator to a ws2812 strip
157+
/// Write all the items of an iterator to a WS2812 strip
153158
fn write<T, I>(&mut self, iterator: T) -> Result<(), Error<E>>
154159
where
155160
T: IntoIterator<Item = I>,
@@ -158,7 +163,7 @@ where
158163
self.index = 0;
159164

160165
if cfg!(feature = "mosi_idle_high") {
161-
self.flush()?;
166+
self.write_reset()?;
162167
}
163168

164169
for item in iterator {
@@ -168,8 +173,16 @@ where
168173
self.write_byte(item.b)?;
169174
}
170175

171-
self.flush()?;
172-
self.send_data().map_err(Error::Spi)
176+
if cfg!(feature = "reset_single_transaction") {
177+
self.write_reset()?;
178+
}
179+
180+
self.send_data().map_err(Error::Spi)?;
181+
182+
if !cfg!(feature = "reset_single_transaction") {
183+
self.send_reset()?;
184+
}
185+
Ok(())
173186
}
174187
}
175188

@@ -179,7 +192,7 @@ where
179192
{
180193
type Error = Error<E>;
181194
type Color = RGBW<u8, u8>;
182-
/// Write all the items of an iterator to a ws2812 strip
195+
/// Write all the items of an iterator to a SK6812W strip
183196
fn write<T, I>(&mut self, iterator: T) -> Result<(), Error<E>>
184197
where
185198
T: IntoIterator<Item = I>,
@@ -188,7 +201,7 @@ where
188201
self.index = 0;
189202

190203
if cfg!(feature = "mosi_idle_high") {
191-
self.flush()?;
204+
self.write_reset()?;
192205
}
193206

194207
for item in iterator {
@@ -199,7 +212,15 @@ where
199212
self.write_byte(item.a.0)?;
200213
}
201214

202-
self.flush()?;
203-
self.send_data().map_err(Error::Spi)
215+
if cfg!(feature = "reset_single_transaction") {
216+
self.write_reset()?;
217+
}
218+
219+
self.send_data().map_err(Error::Spi)?;
220+
221+
if !cfg!(feature = "reset_single_transaction") {
222+
self.send_reset()?;
223+
}
224+
Ok(())
204225
}
205226
}

0 commit comments

Comments
 (0)