35
35
#define WS2812_PIN 2
36
36
#endif
37
37
38
- static inline void put_pixel (uint32_t pixel_grb ) {
39
- pio_sm_put_blocking (pio0 , 0 , pixel_grb << 8u );
38
+ // Check the pin is compatible with the platform
39
+ #if WS2812_PIN >= NUM_BANK0_GPIOS
40
+ #error Attempting to use a pin>=32 on a platform that does not support it
41
+ #endif
42
+
43
+ static inline void put_pixel (PIO pio , uint sm , uint32_t pixel_grb ) {
44
+ pio_sm_put_blocking (pio , sm , pixel_grb << 8u );
40
45
}
41
46
42
47
static inline uint32_t urgb_u32 (uint8_t r , uint8_t g , uint8_t b ) {
@@ -54,44 +59,44 @@ static inline uint32_t urgbw_u32(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
54
59
(uint32_t ) (b );
55
60
}
56
61
57
- void pattern_snakes (uint len , uint t ) {
62
+ void pattern_snakes (PIO pio , uint sm , uint len , uint t ) {
58
63
for (uint i = 0 ; i < len ; ++ i ) {
59
64
uint x = (i + (t >> 1 )) % 64 ;
60
65
if (x < 10 )
61
- put_pixel (urgb_u32 (0xff , 0 , 0 ));
66
+ put_pixel (pio , sm , urgb_u32 (0xff , 0 , 0 ));
62
67
else if (x >= 15 && x < 25 )
63
- put_pixel (urgb_u32 (0 , 0xff , 0 ));
68
+ put_pixel (pio , sm , urgb_u32 (0 , 0xff , 0 ));
64
69
else if (x >= 30 && x < 40 )
65
- put_pixel (urgb_u32 (0 , 0 , 0xff ));
70
+ put_pixel (pio , sm , urgb_u32 (0 , 0 , 0xff ));
66
71
else
67
- put_pixel (0 );
72
+ put_pixel (pio , sm , 0 );
68
73
}
69
74
}
70
75
71
- void pattern_random (uint len , uint t ) {
76
+ void pattern_random (PIO pio , uint sm , uint len , uint t ) {
72
77
if (t % 8 )
73
78
return ;
74
79
for (uint i = 0 ; i < len ; ++ i )
75
- put_pixel (rand ());
80
+ put_pixel (pio , sm , rand ());
76
81
}
77
82
78
- void pattern_sparkle (uint len , uint t ) {
83
+ void pattern_sparkle (PIO pio , uint sm , uint len , uint t ) {
79
84
if (t % 8 )
80
85
return ;
81
86
for (uint i = 0 ; i < len ; ++ i )
82
- put_pixel (rand () % 16 ? 0 : 0xffffffff );
87
+ put_pixel (pio , sm , rand () % 16 ? 0 : 0xffffffff );
83
88
}
84
89
85
- void pattern_greys (uint len , uint t ) {
90
+ void pattern_greys (PIO pio , uint sm , uint len , uint t ) {
86
91
uint max = 100 ; // let's not draw too much current!
87
92
t %= max ;
88
93
for (uint i = 0 ; i < len ; ++ i ) {
89
- put_pixel (t * 0x10101 );
94
+ put_pixel (pio , sm , t * 0x10101 );
90
95
if (++ t >= max ) t = 0 ;
91
96
}
92
97
}
93
98
94
- typedef void (* pattern )(uint len , uint t );
99
+ typedef void (* pattern )(PIO pio , uint sm , uint len , uint t );
95
100
const struct {
96
101
pattern pat ;
97
102
const char * name ;
@@ -105,12 +110,18 @@ const struct {
105
110
int main () {
106
111
//set_sys_clock_48();
107
112
stdio_init_all ();
108
- printf ("WS2812 Smoke Test, using pin %d" , WS2812_PIN );
113
+ printf ("WS2812 Smoke Test, using pin %d\n " , WS2812_PIN );
109
114
110
115
// todo get free sm
111
- PIO pio = pio0 ;
112
- int sm = 0 ;
113
- uint offset = pio_add_program (pio , & ws2812_program );
116
+ PIO pio ;
117
+ uint sm ;
118
+ uint offset ;
119
+
120
+ // This will find a free pio and state machine for our program and load it for us
121
+ // We use pio_claim_free_sm_and_add_program_for_gpio_range (for_gpio_range variant)
122
+ // so we will get a PIO instance suitable for addressing gpios >= 32 if needed and supported by the hardware
123
+ bool success = pio_claim_free_sm_and_add_program_for_gpio_range (& ws2812_program , & pio , & sm , & offset , WS2812_PIN , 1 , true);
124
+ hard_assert (success );
114
125
115
126
ws2812_program_init (pio , sm , offset , WS2812_PIN , 800000 , IS_RGBW );
116
127
@@ -121,9 +132,12 @@ int main() {
121
132
puts (pattern_table [pat ].name );
122
133
puts (dir == 1 ? "(forward)" : "(backward)" );
123
134
for (int i = 0 ; i < 1000 ; ++ i ) {
124
- pattern_table [pat ].pat (NUM_PIXELS , t );
135
+ pattern_table [pat ].pat (pio , sm , NUM_PIXELS , t );
125
136
sleep_ms (10 );
126
137
t += dir ;
127
138
}
128
139
}
140
+
141
+ // This will free resources and unload our program
142
+ pio_remove_program_and_unclaim_sm (& ws2812_program , pio , sm , offset );
129
143
}
0 commit comments