Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code cleanup and reformatting #2

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions examples/moving-pixel.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
//! Example that definitely works on Raspberry Pi.
//! Make sure you have "SPI" on your Pi enabled and that MOSI-Pin is connected
//! with DIN-Pin. You just need DIN pin, no clock. WS2818 uses one-wire-protocol.
//! See the specification for details
//!
//! Make sure you have "SPI" on your Pi enabled and that MOSI-Pin is connected with DIN-Pin.
//! You just need DIN pin, no clock. W
//! S2818 uses one-wire-protocol.
//! See the specification for details.

#![allow(incomplete_features)]
#![feature(generic_const_exprs)]

use ws28xx_n_channel_spi::generic_adapter::*;
use ws28xx_n_channel_spi::linux_spi::LinuxSPI;
use std::time::{Duration, Instant};
use ws28xx_n_channel_spi::pi_spi::LinuxSPI;
use ws28xx_n_channel_spi::LEDs;

// 3 channels per module is a standard RGB setup
const CHANNELS_PER_MODULE : usize = 3;
const CHANNELS_PER_MODULE: usize = 3;
// Number of modules
const NUM_MODULES : usize = 64;
const NUM_MODULES: usize = 64;
// Using 64 LEDs for an 8x8 grid as a demonstration
const NUM_LEDS : usize = NUM_MODULES * CHANNELS_PER_MODULE;
const NUM_LEDS: usize = NUM_MODULES * CHANNELS_PER_MODULE;

// Example that shows a single moving pixel though an RGB 8x8 led matrix.
fn main() {
// Create the linux SPI device adapter
let hw_adapter : LinuxSPI<NUM_LEDS> = LinuxSPI::new("/dev/spidev0.0").unwrap();
// Create an LED strip with
let mut strip : LEDs<NUM_LEDS, CHANNELS_PER_MODULE, LinuxSPI<NUM_LEDS>> = LEDs::new(hw_adapter);
let hw_adapter: LinuxSPI<NUM_LEDS> = LinuxSPI::new("/dev/spidev0.0").unwrap();
// Create an LED strip with
let mut strip: LEDs<NUM_LEDS, CHANNELS_PER_MODULE, LinuxSPI<NUM_LEDS>> = LEDs::new(hw_adapter);

// Colour order is GRB for standard NeoPixels
const PURPLE: [u8;3] = [0, 50, 30];
const OFF: [u8;3] = [0, 0, 0];
const PURPLE: [u8; 3] = [0, 50, 30];
const OFF: [u8; 3] = [0, 0, 0];

let mut i: usize = 0;
loop {

strip.set_node(i, OFF);

i = (i + 1) % (NUM_MODULES);
Expand All @@ -51,4 +52,4 @@ pub fn sleep_busy_waiting_ms(ms: u64) {
break;
}
}
}
}
53 changes: 0 additions & 53 deletions src/generic_adapter.rs

This file was deleted.

56 changes: 48 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,64 @@
//! This crate is intended to fill a nice of having an arbitraty number of colour channels
//! per node in a WS28xx setup. Previous crates focus on RGB and RGBW specifically, but
//! this crate allows for an arbitrary number of channels using generics.
//!
//!
//! Through the use of a [`generic_adapter::GenericHardware`] trait, different methods
//! of driving the LEDs may be implemented. This library comes with an SPI bit-banging
//! implementation for the raspberry pi, but because the main library is `no-std` compatible,
//! alternate hardware implementations should be possible across any platform.

#![no_std]

#![allow(incomplete_features)]
#![feature(generic_const_exprs)]

#[cfg(feature = "adapter_spidev")]
extern crate std;

pub mod generic_adapter; // generic [no_std] hardware abstraction
#[cfg(feature = "adapter_spidev")]
pub mod linux_spi; // specific [std]-implementation
pub mod pi_spi; // specific [std]-implementation

/// Hardware device abstraction, which can be implemented by many different types of back-end (embedded, linux, etc.)
pub trait GenericHardware<const B: usize> {
type Error;

/// Sequentially write `byte_array` exactly as presented.
fn write_raw(&mut self, byte_array: &[u8]) -> Result<(), Self::Error>;

/// Encode `byte_array` suitable for WS81XX bitbanging, then write it.
fn encode_and_write(&mut self, byte_array: &[u8]) -> Result<(), Self::Error>;
}

/// Struct that contains a buffer of indiviual LED values (bytes)
///
/// The buffer is passed to the hardware device to be encoded
/// when a write occurs.
///
/// Generic parameters:
/// N: Number of LEDs (modules * colours)
/// M: Number of channels (colors) per module
/// H: Type of hardware driver - can usually be inferred
pub struct LEDs<const N: usize, const M: usize, H: GenericHardware<N>> {
/// This will store the state of each LED, with one u8 per LED
leds: [u8; N],
/// The hardware device being used for output
hw_dev: H,
}

impl<const N: usize, const M: usize, H: GenericHardware<N>> LEDs<N, M, H> {
/// Constructor to initialise LEDs struct
pub fn new(hw_dev: H) -> Self {
Self {
leds: [0; N],
hw_dev,
}
}

/// Sets the value of one node in the pre-encoded LED buffer
pub fn set_node(&mut self, idx: usize, node: [u8; M]) {
self.leds[(idx * M)..(idx * M + M)].copy_from_slice(&node);
}

// Raspberry Pi SPI device
// you can easily provide your own encoding functions.
pub mod linux_spi_encoding;
/// Writes the currently stored buffer
pub fn write(&mut self) -> Result<(), H::Error> {
self.hw_dev.encode_and_write(&self.leds)
}
}
55 changes: 0 additions & 55 deletions src/linux_spi.rs

This file was deleted.

104 changes: 0 additions & 104 deletions src/linux_spi_encoding.rs

This file was deleted.

Loading