Skip to content

Commit 7befc8d

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

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

pio/ws2812/ws2812.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@
3333
#else
3434
// default to pin 2 if the board doesn't have a default WS2812 pin defined
3535
#define WS2812_PIN 2
36+
3637
#endif
3738

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

4243
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
@@ -54,44 +55,44 @@ static inline uint32_t urgbw_u32(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
5455
(uint32_t) (b);
5556
}
5657

57-
void pattern_snakes(uint len, uint t) {
58+
void pattern_snakes(PIO pio, uint sm, uint len, uint t) {
5859
for (uint i = 0; i < len; ++i) {
5960
uint x = (i + (t >> 1)) % 64;
6061
if (x < 10)
61-
put_pixel(urgb_u32(0xff, 0, 0));
62+
put_pixel(pio, sm, urgb_u32(0xff, 0, 0));
6263
else if (x >= 15 && x < 25)
63-
put_pixel(urgb_u32(0, 0xff, 0));
64+
put_pixel(pio, sm, urgb_u32(0, 0xff, 0));
6465
else if (x >= 30 && x < 40)
65-
put_pixel(urgb_u32(0, 0, 0xff));
66+
put_pixel(pio, sm, urgb_u32(0, 0, 0xff));
6667
else
67-
put_pixel(0);
68+
put_pixel(pio, sm, 0);
6869
}
6970
}
7071

71-
void pattern_random(uint len, uint t) {
72+
void pattern_random(PIO pio, uint sm, uint len, uint t) {
7273
if (t % 8)
7374
return;
7475
for (uint i = 0; i < len; ++i)
75-
put_pixel(rand());
76+
put_pixel(pio, sm, rand());
7677
}
7778

78-
void pattern_sparkle(uint len, uint t) {
79+
void pattern_sparkle(PIO pio, uint sm, uint len, uint t) {
7980
if (t % 8)
8081
return;
8182
for (uint i = 0; i < len; ++i)
82-
put_pixel(rand() % 16 ? 0 : 0xffffffff);
83+
put_pixel(pio, sm, rand() % 16 ? 0 : 0xffffffff);
8384
}
8485

85-
void pattern_greys(uint len, uint t) {
86+
void pattern_greys(PIO pio, uint sm, uint len, uint t) {
8687
uint max = 100; // let's not draw too much current!
8788
t %= max;
8889
for (uint i = 0; i < len; ++i) {
89-
put_pixel(t * 0x10101);
90+
put_pixel(pio, sm, t * 0x10101);
9091
if (++t >= max) t = 0;
9192
}
9293
}
9394

94-
typedef void (*pattern)(uint len, uint t);
95+
typedef void (*pattern)(PIO pio, uint sm, uint len, uint t);
9596
const struct {
9697
pattern pat;
9798
const char *name;
@@ -105,12 +106,17 @@ const struct {
105106
int main() {
106107
//set_sys_clock_48();
107108
stdio_init_all();
108-
printf("WS2812 Smoke Test, using pin %d", WS2812_PIN);
109+
printf("WS2812 Smoke Test, using pin %d\n", WS2812_PIN);
109110

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

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

@@ -121,9 +127,12 @@ int main() {
121127
puts(pattern_table[pat].name);
122128
puts(dir == 1 ? "(forward)" : "(backward)");
123129
for (int i = 0; i < 1000; ++i) {
124-
pattern_table[pat].pat(NUM_PIXELS, t);
130+
pattern_table[pat].pat(pio, sm, NUM_PIXELS, t);
125131
sleep_ms(10);
126132
t += dir;
127133
}
128134
}
135+
136+
// This will free resources and unload our program
137+
pio_remove_program_and_unclaim_sm(&ws2812_program, pio, sm, offset);
129138
}

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)