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+ // 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 );
4045}
4146
4247static 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) {
5459 (uint32_t ) (b );
5560}
5661
57- void pattern_snakes (uint len , uint t ) {
62+ void pattern_snakes (PIO pio , uint sm , uint len , uint t ) {
5863 for (uint i = 0 ; i < len ; ++ i ) {
5964 uint x = (i + (t >> 1 )) % 64 ;
6065 if (x < 10 )
61- put_pixel (urgb_u32 (0xff , 0 , 0 ));
66+ put_pixel (pio , sm , urgb_u32 (0xff , 0 , 0 ));
6267 else if (x >= 15 && x < 25 )
63- put_pixel (urgb_u32 (0 , 0xff , 0 ));
68+ put_pixel (pio , sm , urgb_u32 (0 , 0xff , 0 ));
6469 else if (x >= 30 && x < 40 )
65- put_pixel (urgb_u32 (0 , 0 , 0xff ));
70+ put_pixel (pio , sm , urgb_u32 (0 , 0 , 0xff ));
6671 else
67- put_pixel (0 );
72+ put_pixel (pio , sm , 0 );
6873 }
6974}
7075
71- void pattern_random (uint len , uint t ) {
76+ void pattern_random (PIO pio , uint sm , uint len , uint t ) {
7277 if (t % 8 )
7378 return ;
7479 for (uint i = 0 ; i < len ; ++ i )
75- put_pixel (rand ());
80+ put_pixel (pio , sm , rand ());
7681}
7782
78- void pattern_sparkle (uint len , uint t ) {
83+ void pattern_sparkle (PIO pio , uint sm , uint len , uint t ) {
7984 if (t % 8 )
8085 return ;
8186 for (uint i = 0 ; i < len ; ++ i )
82- put_pixel (rand () % 16 ? 0 : 0xffffffff );
87+ put_pixel (pio , sm , rand () % 16 ? 0 : 0xffffffff );
8388}
8489
85- void pattern_greys (uint len , uint t ) {
90+ void pattern_greys (PIO pio , uint sm , uint len , uint t ) {
8691 uint max = 100 ; // let's not draw too much current!
8792 t %= max ;
8893 for (uint i = 0 ; i < len ; ++ i ) {
89- put_pixel (t * 0x10101 );
94+ put_pixel (pio , sm , t * 0x10101 );
9095 if (++ t >= max ) t = 0 ;
9196 }
9297}
9398
94- typedef void (* pattern )(uint len , uint t );
99+ typedef void (* pattern )(PIO pio , uint sm , uint len , uint t );
95100const struct {
96101 pattern pat ;
97102 const char * name ;
@@ -105,12 +110,17 @@ const struct {
105110int main () {
106111 //set_sys_clock_48();
107112 stdio_init_all ();
108- printf ("WS2812 Smoke Test, using pin %d" , WS2812_PIN );
113+ printf ("WS2812 Smoke Test, using pin %d\n " , WS2812_PIN );
109114
110115 // 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 so we can address gpios >= 32 if needed and supported by the hardware
122+ bool success = pio_claim_free_sm_and_add_program_for_gpio_range (& ws2812_program , & pio , & sm , & offset , WS2812_PIN , 1 , true);
123+ hard_assert (success );
114124
115125 ws2812_program_init (pio , sm , offset , WS2812_PIN , 800000 , IS_RGBW );
116126
@@ -121,9 +131,12 @@ int main() {
121131 puts (pattern_table [pat ].name );
122132 puts (dir == 1 ? "(forward)" : "(backward)" );
123133 for (int i = 0 ; i < 1000 ; ++ i ) {
124- pattern_table [pat ].pat (NUM_PIXELS , t );
134+ pattern_table [pat ].pat (pio , sm , NUM_PIXELS , t );
125135 sleep_ms (10 );
126136 t += dir ;
127137 }
128138 }
139+
140+ // This will free resources and unload our program
141+ pio_remove_program_and_unclaim_sm (& ws2812_program , pio , sm , offset );
129142}
0 commit comments