@@ -360,6 +360,187 @@ void notFound(Request &req, Response &res) {
360360}
361361#endif /* USE_BRIDGE */
362362
363+ #if defined(USE_NEOPIXEL)
364+ #include " clk.h"
365+ #include " gpio.h"
366+ #include " dma.h"
367+ #include " pwm.h"
368+
369+ #include " ws2811.h"
370+
371+ #define ARRAY_SIZE (stuff ) (sizeof (stuff) / sizeof (stuff[0 ]))
372+
373+ #define TARGET_FREQ WS2811_TARGET_FREQ
374+ #define GPIO_PIN 18
375+ #define DMA 10
376+ // #define STRIP_TYPE WS2811_STRIP_RGB // WS2812/SK6812RGB integrated chip+leds
377+ #define STRIP_TYPE WS2811_STRIP_GBR // WS2812/SK6812RGB integrated chip+leds
378+ // #define STRIP_TYPE SK6812_STRIP_RGBW // SK6812RGBW (NOT SK6812RGB)
379+
380+ #define WIDTH 8
381+ #define HEIGHT 8
382+ #define LED_COUNT (WIDTH * HEIGHT )
383+
384+ static int width = WIDTH ;
385+ static int height = HEIGHT ;
386+ static int led_count = LED_COUNT ;
387+
388+ ws2811_t ledstring =
389+ {
390+ .freq = TARGET_FREQ ,
391+ .dmanum = DMA ,
392+ .channel =
393+ {
394+ [0 ] =
395+ {
396+ .gpionum = GPIO_PIN ,
397+ .invert = 0 ,
398+ .count = LED_COUNT ,
399+ .strip_type = STRIP_TYPE ,
400+ .brightness = 255 ,
401+ },
402+ [1 ] =
403+ {
404+ .gpionum = 0 ,
405+ .invert = 0 ,
406+ .count = 0 ,
407+ .brightness = 0 ,
408+ },
409+ },
410+ };
411+
412+ ws2811_led_t *matrix;
413+
414+ void matrix_render (void )
415+ {
416+ int x, y;
417+
418+ for (x = 0 ; x < width; x++)
419+ {
420+ for (y = 0 ; y < height; y++)
421+ {
422+ ledstring.channel [0 ].leds [(y * width) + x] = matrix[y * width + x];
423+ }
424+ }
425+ }
426+
427+ void matrix_raise (void )
428+ {
429+ int x, y;
430+
431+ for (y = 0 ; y < (height - 1 ); y++)
432+ {
433+ for (x = 0 ; x < width; x++)
434+ {
435+ // This is for the 8x8 Pimoroni Unicorn-HAT where the LEDS in subsequent
436+ // rows are arranged in opposite directions
437+ matrix[y * width + x] = matrix[(y + 1 )*width + width - x - 1 ];
438+ }
439+ }
440+ }
441+
442+ void matrix_clear (void )
443+ {
444+ int x, y;
445+
446+ for (y = 0 ; y < (height ); y++)
447+ {
448+ for (x = 0 ; x < width; x++)
449+ {
450+ matrix[y * width + x] = 0 ;
451+ }
452+ }
453+ }
454+
455+ int dotspos[] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 };
456+
457+ ws2811_led_t dotcolors[] =
458+ {
459+ 0x00200000 , // red
460+ 0x00201000 , // orange
461+ 0x00202000 , // yellow
462+ 0x00002000 , // green
463+ 0x00002020 , // lightblue
464+ 0x00000020 , // blue
465+ 0x00100010 , // purple
466+ 0x00200010 , // pink
467+ };
468+
469+ ws2811_led_t dotcolors_rgbw[] =
470+ {
471+ 0x00200000 , // red
472+ 0x10200000 , // red + W
473+ 0x00002000 , // green
474+ 0x10002000 , // green + W
475+ 0x00000020 , // blue
476+ 0x10000020 , // blue + W
477+ 0x00101010 , // white
478+ 0x10101010 , // white + W
479+
480+ };
481+
482+ void matrix_bottom (void )
483+ {
484+ int i;
485+
486+ for (i = 0 ; i < (int )(ARRAY_SIZE (dotspos)); i++)
487+ {
488+ dotspos[i]++;
489+ if (dotspos[i] > (width - 1 ))
490+ {
491+ dotspos[i] = 0 ;
492+ }
493+
494+ if (ledstring.channel [0 ].strip_type == SK6812_STRIP_RGBW ) {
495+ matrix[dotspos[i] + (height - 1 ) * width] = dotcolors_rgbw[i];
496+ } else {
497+ matrix[dotspos[i] + (height - 1 ) * width] = dotcolors[i];
498+ }
499+ }
500+ }
501+
502+ int ws2811_init (void )
503+ {
504+ ws2811_return_t ret;
505+
506+ matrix = (ws2811_led_t *) malloc (sizeof (ws2811_led_t ) * width * height);
507+
508+ if ((ret = ws2811_init (&ledstring)) != WS2811_SUCCESS )
509+ {
510+ fprintf (stderr, " ws2811_init failed: %s\n " , ws2811_get_return_t_str (ret));
511+ return ret;
512+ }
513+
514+ return ret;
515+ }
516+
517+ void ws2811_test (void )
518+ {
519+ ws2811_return_t ret;
520+
521+ for (int i=0 ; i < 75 ; i++)
522+ {
523+ matrix_raise ();
524+ matrix_bottom ();
525+ matrix_render ();
526+
527+ if ((ret = ws2811_render (&ledstring)) != WS2811_SUCCESS )
528+ {
529+ fprintf (stderr, " ws2811_render failed: %s\n " , ws2811_get_return_t_str (ret));
530+ break ;
531+ }
532+
533+ // 15 frames /sec
534+ usleep (1000000 / 15 );
535+ }
536+
537+ matrix_clear ();
538+ matrix_render ();
539+ ws2811_render (&ledstring);
540+ }
541+
542+ #endif /* USE_NEOPIXEL */
543+
363544// -------------------------------------------------------------------------
364545//
365546// The MIT License (MIT)
@@ -1446,6 +1627,13 @@ int main()
14461627// hw_info.gnss = GNSS_setup();
14471628
14481629 Traffic_setup ();
1630+
1631+ #if defined(USE_NEOPIXEL)
1632+ // LED_setup();
1633+
1634+ ws2811_init ();
1635+ #endif /* USE_NEOPIXEL */
1636+
14491637 NMEA_setup ();
14501638
14511639 Traffic_TCP_Server.setup (JSON_SRV_TCP_PORT );
@@ -1486,6 +1674,13 @@ int main()
14861674 Serial.println ((unsigned long ) RELAY_SRC_PORT );
14871675#endif /* USE_BRIDGE */
14881676
1677+ #if defined(USE_NEOPIXEL)
1678+ // LED_test();
1679+
1680+ ws2811_test ();
1681+ ws2811_fini (&ledstring);
1682+ #endif /* USE_NEOPIXEL */
1683+
14891684 Sound_setup ();
14901685 SoC->Sound_test (reset_info.reason );
14911686
0 commit comments