Skip to content

Commit

Permalink
This should make using the WS2812 examples a bit easier. (raspberrypi#84
Browse files Browse the repository at this point in the history
)

* This should make using the WS2812 examples a bit easier.
Moved parameters to the top as defines:
- Number of LEDs in your NeoPixel/WS2812 strip/ring
- Flag if the LEDs are WRGB or not
Changed PIN to 2 as pin 0 is used for serial UART.
  • Loading branch information
josefwegner authored Oct 22, 2021
1 parent ad51837 commit 74aff26
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 23 deletions.
15 changes: 10 additions & 5 deletions pio/ws2812/ws2812.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
#include "hardware/clocks.h"
#include "ws2812.pio.h"

#define IS_RGBW true
#define NUM_PIXELS 150
#ifndef PICO_DEFAULT_WS2812_PIN
#warning "no WS2812 default PIN defined for board, please check if pin 2 is okay"
#define PICO_DEFAULT_WS2812_PIN 2
#endif

static inline void put_pixel(uint32_t pixel_grb) {
pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);
}
Expand Down Expand Up @@ -71,8 +78,6 @@ const struct {
{pattern_greys, "Greys"},
};

const int PIN_TX = 0;

int main() {
//set_sys_clock_48();
stdio_init_all();
Expand All @@ -83,7 +88,7 @@ int main() {
int sm = 0;
uint offset = pio_add_program(pio, &ws2812_program);

ws2812_program_init(pio, sm, offset, PIN_TX, 800000, true);
ws2812_program_init(pio, sm, offset, PICO_DEFAULT_WS2812_PIN, 800000, IS_RGBW);

int t = 0;
while (1) {
Expand All @@ -92,9 +97,9 @@ int main() {
puts(pattern_table[pat].name);
puts(dir == 1 ? "(forward)" : "(backward)");
for (int i = 0; i < 1000; ++i) {
pattern_table[pat].pat(150, t);
pattern_table[pat].pat(NUM_PIXELS, t);
sleep_ms(10);
t += dir;
}
}
}
}
33 changes: 15 additions & 18 deletions pio/ws2812/ws2812_parallel.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
#include "ws2812.pio.h"

#define FRAC_BITS 4
#define PIN_TX 0
#define NUM_PIXELS 64
#define WS2812_PIN_BASE 2

// horrible temporary hack to avoid changing pattern code
static uint8_t *current_string_out;
Expand Down Expand Up @@ -174,17 +175,15 @@ void dither_values(const value_bits_t *colors, value_bits_t *state, const value_
}
}

#define MAX_LENGTH 100

// requested colors * 4 to allow for WRGB
static value_bits_t colors[MAX_LENGTH * 4];
// requested colors * 4 to allow for RGBW
static value_bits_t colors[NUM_PIXELS * 4];
// double buffer the state of the string, since we update next version in parallel with DMAing out old version
static value_bits_t states[2][MAX_LENGTH * 4];
static value_bits_t states[2][NUM_PIXELS * 4];

// example - string 0 is RGB only
static uint8_t string0_data[MAX_LENGTH * 3];
// example - string 1 is WRGB
static uint8_t string1_data[MAX_LENGTH * 4];
static uint8_t string0_data[NUM_PIXELS * 3];
// example - string 1 is RGBW
static uint8_t string1_data[NUM_PIXELS * 4];

string_t string0 = {
.data = string0_data,
Expand Down Expand Up @@ -213,7 +212,7 @@ string_t *strings[] = {
#define DMA_CHANNELS_MASK (DMA_CHANNEL_MASK | DMA_CB_CHANNEL_MASK)

// start of each value fragment (+1 for NULL terminator)
static uintptr_t fragment_start[MAX_LENGTH * 4 + 1];
static uintptr_t fragment_start[NUM_PIXELS * 4 + 1];

// posted when it is safe to output a new set of values
static struct semaphore reset_delay_complete_sem;
Expand Down Expand Up @@ -286,7 +285,7 @@ int main() {
int sm = 0;
uint offset = pio_add_program(pio, &ws2812_parallel_program);

ws2812_parallel_program_init(pio, sm, offset, PIN_TX, count_of(strings), 800000);
ws2812_parallel_program_init(pio, sm, offset, WS2812_PIN_BASE, count_of(strings), 800000);

sem_init(&reset_delay_complete_sem, 1, 1); // initially posted so we don't block first time
dma_init(pio, sm);
Expand All @@ -300,19 +299,17 @@ int main() {
int brightness = 0;
uint current = 0;
for (int i = 0; i < 1000; ++i) {
int n = 64;

current_string_out = string0.data;
current_string_4color = false;
pattern_table[pat].pat(n, t);
pattern_table[pat].pat(NUM_PIXELS, t);
current_string_out = string1.data;
current_string_4color = true;
pattern_table[pat].pat(n, t);
pattern_table[pat].pat(NUM_PIXELS, t);

transform_strings(strings, count_of(strings), colors, n * 4, brightness);
dither_values(colors, states[current], states[current ^ 1], n * 4);
transform_strings(strings, count_of(strings), colors, NUM_PIXELS * 4, brightness);
dither_values(colors, states[current], states[current ^ 1], NUM_PIXELS * 4);
sem_acquire_blocking(&reset_delay_complete_sem);
output_strings_dma(states[current], n * 4);
output_strings_dma(states[current], NUM_PIXELS * 4);

current ^= 1;
t += dir;
Expand Down

0 comments on commit 74aff26

Please sign in to comment.