Skip to content

Commit 694abc5

Browse files
committed
Fix WS2812 example so it works on pins >=32
See raspberrypi/pico-sdk#2030
1 parent 362f676 commit 694abc5

File tree

2 files changed

+39
-24
lines changed

2 files changed

+39
-24
lines changed

pio/ws2812/ws2812.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
#define WS2812_PIN 2
3636
#endif
3737

38-
static inline void put_pixel(uint32_t pixel_grb) {
39-
pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);
38+
static inline void put_pixel(PIO pio, uint sm, uint32_t pixel_grb) {
39+
pio_sm_put_blocking(pio, sm, pixel_grb << 8u);
4040
}
4141

4242
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
@@ -54,44 +54,44 @@ static inline uint32_t urgbw_u32(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
5454
(uint32_t) (b);
5555
}
5656

57-
void pattern_snakes(uint len, uint t) {
57+
void pattern_snakes(PIO pio, uint sm, uint len, uint t) {
5858
for (uint i = 0; i < len; ++i) {
5959
uint x = (i + (t >> 1)) % 64;
6060
if (x < 10)
61-
put_pixel(urgb_u32(0xff, 0, 0));
61+
put_pixel(pio, sm, urgb_u32(0xff, 0, 0));
6262
else if (x >= 15 && x < 25)
63-
put_pixel(urgb_u32(0, 0xff, 0));
63+
put_pixel(pio, sm, urgb_u32(0, 0xff, 0));
6464
else if (x >= 30 && x < 40)
65-
put_pixel(urgb_u32(0, 0, 0xff));
65+
put_pixel(pio, sm, urgb_u32(0, 0, 0xff));
6666
else
67-
put_pixel(0);
67+
put_pixel(pio, sm, 0);
6868
}
6969
}
7070

71-
void pattern_random(uint len, uint t) {
71+
void pattern_random(PIO pio, uint sm, uint len, uint t) {
7272
if (t % 8)
7373
return;
7474
for (uint i = 0; i < len; ++i)
75-
put_pixel(rand());
75+
put_pixel(pio, sm, rand());
7676
}
7777

78-
void pattern_sparkle(uint len, uint t) {
78+
void pattern_sparkle(PIO pio, uint sm, uint len, uint t) {
7979
if (t % 8)
8080
return;
8181
for (uint i = 0; i < len; ++i)
82-
put_pixel(rand() % 16 ? 0 : 0xffffffff);
82+
put_pixel(pio, sm, rand() % 16 ? 0 : 0xffffffff);
8383
}
8484

85-
void pattern_greys(uint len, uint t) {
85+
void pattern_greys(PIO pio, uint sm, uint len, uint t) {
8686
uint max = 100; // let's not draw too much current!
8787
t %= max;
8888
for (uint i = 0; i < len; ++i) {
89-
put_pixel(t * 0x10101);
89+
put_pixel(pio, sm, t * 0x10101);
9090
if (++t >= max) t = 0;
9191
}
9292
}
9393

94-
typedef void (*pattern)(uint len, uint t);
94+
typedef void (*pattern)(PIO pio, uint sm, uint len, uint t);
9595
const struct {
9696
pattern pat;
9797
const char *name;
@@ -105,12 +105,17 @@ const struct {
105105
int main() {
106106
//set_sys_clock_48();
107107
stdio_init_all();
108-
printf("WS2812 Smoke Test, using pin %d", WS2812_PIN);
108+
printf("WS2812 Smoke Test, using pin %d\n", WS2812_PIN);
109109

110110
// todo get free sm
111-
PIO pio = pio0;
112-
int sm = 0;
113-
uint offset = pio_add_program(pio, &ws2812_program);
111+
PIO pio;
112+
uint sm;
113+
uint offset;
114+
115+
// This will find a free pio and state machine for our program and load it for us
116+
// 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
117+
bool success = pio_claim_free_sm_and_add_program_for_gpio_range(&ws2812_program, &pio, &sm, &offset, WS2812_PIN, 1, true);
118+
hard_assert(success);
114119

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

@@ -121,9 +126,12 @@ int main() {
121126
puts(pattern_table[pat].name);
122127
puts(dir == 1 ? "(forward)" : "(backward)");
123128
for (int i = 0; i < 1000; ++i) {
124-
pattern_table[pat].pat(NUM_PIXELS, t);
129+
pattern_table[pat].pat(pio, sm, NUM_PIXELS, t);
125130
sleep_ms(10);
126131
t += dir;
127132
}
128133
}
134+
135+
// This will free resources and unload our program
136+
pio_remove_program_and_unclaim_sm(&ws2812_program, pio, sm, offset);
129137
}

pio/ws2812/ws2812_parallel.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,16 @@ void output_strips_dma(value_bits_t *bits, uint value_length) {
278278
int main() {
279279
//set_sys_clock_48();
280280
stdio_init_all();
281-
puts("WS2812 parallel");
281+
printf("WS2812 parallel using pin %d\n", WS2812_PIN_BASE);
282282

283-
// todo get free sm
284-
PIO pio = pio0;
285-
int sm = 0;
286-
uint offset = pio_add_program(pio, &ws2812_parallel_program);
283+
PIO pio;
284+
uint sm;
285+
uint offset;
286+
287+
// This will find a free pio and state machine for our program and load it for us
288+
// 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
289+
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);
290+
hard_assert(success);
287291

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

@@ -318,4 +322,7 @@ int main() {
318322
}
319323
memset(&states, 0, sizeof(states)); // clear out errors
320324
}
325+
326+
// This will free resources and unload our program
327+
pio_remove_program_and_unclaim_sm(&ws2812_parallel_program, pio, sm, offset);
321328
}

0 commit comments

Comments
 (0)