Skip to content

Commit

Permalink
Fix WS2812 example so it works on pins >=32
Browse files Browse the repository at this point in the history
  • Loading branch information
peterharperuk committed Nov 19, 2024
1 parent 362f676 commit 7befc8d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 24 deletions.
47 changes: 28 additions & 19 deletions pio/ws2812/ws2812.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@
#else
// default to pin 2 if the board doesn't have a default WS2812 pin defined
#define WS2812_PIN 2

#endif

static inline void put_pixel(uint32_t pixel_grb) {
pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);
static inline void put_pixel(PIO pio, uint sm, uint32_t pixel_grb) {
pio_sm_put_blocking(pio, sm, pixel_grb << 8u);
}

static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
Expand All @@ -54,44 +55,44 @@ static inline uint32_t urgbw_u32(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
(uint32_t) (b);
}

void pattern_snakes(uint len, uint t) {
void pattern_snakes(PIO pio, uint sm, uint len, uint t) {
for (uint i = 0; i < len; ++i) {
uint x = (i + (t >> 1)) % 64;
if (x < 10)
put_pixel(urgb_u32(0xff, 0, 0));
put_pixel(pio, sm, urgb_u32(0xff, 0, 0));
else if (x >= 15 && x < 25)
put_pixel(urgb_u32(0, 0xff, 0));
put_pixel(pio, sm, urgb_u32(0, 0xff, 0));
else if (x >= 30 && x < 40)
put_pixel(urgb_u32(0, 0, 0xff));
put_pixel(pio, sm, urgb_u32(0, 0, 0xff));
else
put_pixel(0);
put_pixel(pio, sm, 0);
}
}

void pattern_random(uint len, uint t) {
void pattern_random(PIO pio, uint sm, uint len, uint t) {
if (t % 8)
return;
for (uint i = 0; i < len; ++i)
put_pixel(rand());
put_pixel(pio, sm, rand());
}

void pattern_sparkle(uint len, uint t) {
void pattern_sparkle(PIO pio, uint sm, uint len, uint t) {
if (t % 8)
return;
for (uint i = 0; i < len; ++i)
put_pixel(rand() % 16 ? 0 : 0xffffffff);
put_pixel(pio, sm, rand() % 16 ? 0 : 0xffffffff);
}

void pattern_greys(uint len, uint t) {
void pattern_greys(PIO pio, uint sm, uint len, uint t) {
uint max = 100; // let's not draw too much current!
t %= max;
for (uint i = 0; i < len; ++i) {
put_pixel(t * 0x10101);
put_pixel(pio, sm, t * 0x10101);
if (++t >= max) t = 0;
}
}

typedef void (*pattern)(uint len, uint t);
typedef void (*pattern)(PIO pio, uint sm, uint len, uint t);
const struct {
pattern pat;
const char *name;
Expand All @@ -105,12 +106,17 @@ const struct {
int main() {
//set_sys_clock_48();
stdio_init_all();
printf("WS2812 Smoke Test, using pin %d", WS2812_PIN);
printf("WS2812 Smoke Test, using pin %d\n", WS2812_PIN);

// todo get free sm
PIO pio = pio0;
int sm = 0;
uint offset = pio_add_program(pio, &ws2812_program);
PIO pio;
uint sm;
uint offset;

// This will find a free pio and state machine for our program and load it for us
// We use pio_claim_free_sm_and_add_program_for_gpio_range so we can address gpios >= 32 if needed and supported by the hardware
bool success = pio_claim_free_sm_and_add_program_for_gpio_range(&ws2812_program, &pio, &sm, &offset, WS2812_PIN, 1, true);
hard_assert(success);

ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW);

Expand All @@ -121,9 +127,12 @@ int main() {
puts(pattern_table[pat].name);
puts(dir == 1 ? "(forward)" : "(backward)");
for (int i = 0; i < 1000; ++i) {
pattern_table[pat].pat(NUM_PIXELS, t);
pattern_table[pat].pat(pio, sm, NUM_PIXELS, t);
sleep_ms(10);
t += dir;
}
}

// This will free resources and unload our program
pio_remove_program_and_unclaim_sm(&ws2812_program, pio, sm, offset);
}
17 changes: 12 additions & 5 deletions pio/ws2812/ws2812_parallel.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,16 @@ void output_strips_dma(value_bits_t *bits, uint value_length) {
int main() {
//set_sys_clock_48();
stdio_init_all();
puts("WS2812 parallel");
printf("WS2812 parallel using pin %d\n", WS2812_PIN_BASE);

// todo get free sm
PIO pio = pio0;
int sm = 0;
uint offset = pio_add_program(pio, &ws2812_parallel_program);
PIO pio;
uint sm;
uint offset;

// This will find a free pio and state machine for our program and load it for us
// We use pio_claim_free_sm_and_add_program_for_gpio_range so we can address gpios >= 32 if needed and supported by the hardware
bool success = pio_claim_free_sm_and_add_program_for_gpio_range(&ws2812_parallel_program, &pio, &sm, &offset, WS2812_PIN_BASE, count_of(strips), true);
hard_assert(success);

ws2812_parallel_program_init(pio, sm, offset, WS2812_PIN_BASE, count_of(strips), 800000);

Expand Down Expand Up @@ -318,4 +322,7 @@ int main() {
}
memset(&states, 0, sizeof(states)); // clear out errors
}

// This will free resources and unload our program
pio_remove_program_and_unclaim_sm(&ws2812_parallel_program, pio, sm, offset);
}

0 comments on commit 7befc8d

Please sign in to comment.