Skip to content

Commit

Permalink
Add flushing PIO data
Browse files Browse the repository at this point in the history
[Problem]
When providing data fast enough, multiple frames could be concatenated
since we only waited 60 microseconds after the last bytes were pushed
to the PIO, not since the last bytes were actually pushed to the
neopixels.

[Solution]
"Flush" the PIO after pushing the last bytes, by waiting until it's
empty.
  • Loading branch information
krzmaz committed Nov 26, 2024
1 parent a067644 commit 88f80a0
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ where
for (r, g, b) in cons.pop_iter().skip(2).take(len).tuples() {
ws2812.write(r, g, b);
}

// wait for the state machine to write all bytes
ws2812.flush();
// let the neopixels latch on
Timer::after_micros(60).await;
}
9 changes: 9 additions & 0 deletions src/ws2812.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> {
self.sm.tx().dma_push(self.dma.reborrow(), data).await;
}

// see https://github.com/rp-rs/ws2812-pio-rs/blob/944494ca9dad73933f700408c3054c8f14c78998/src/lib.rs#L262-L263
pub fn flush(&mut self) {
// clear stalled flag first
self.sm.tx().stalled();
while !self.sm.tx().empty() && !self.sm.tx().stalled() {
cortex_m::asm::nop();
}
}

pub fn write(&mut self, r: u8, g: u8, b: u8) {
let word = convert_colors_to_word(r, g, b);
// we need to watch out not to overflow the FIFO, see:
Expand Down

0 comments on commit 88f80a0

Please sign in to comment.