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