Adafruit NeoPXL8 Arduino Library
Adafruit_NeoPXL8.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017 P Burgess for Adafruit Industries
2 //
3 // SPDX-License-Identifier: MIT
4 
21 #ifndef _ADAFRUIT_NEOPXL8_H_
22 #define _ADAFRUIT_NEOPXL8_H_
23 
24 #include <Adafruit_NeoPixel.h>
25 #if defined(ARDUINO_ARCH_RP2040)
26 #include "../../hardware_dma/include/hardware/dma.h"
27 #include "hardware/irq.h"
28 #include "hardware/pio.h"
29 #include "pico/mutex.h"
30 #elif defined(CONFIG_IDF_TARGET_ESP32S3)
31 #include <driver/periph_ctrl.h>
32 #include <esp_private/gdma.h>
33 #include <esp_rom_gpio.h>
34 #include <hal/dma_types.h>
35 #include <hal/gpio_hal.h>
36 #include <soc/lcd_cam_struct.h>
37 #else // SAMD
38 #include <Adafruit_ZeroDMA.h>
39 #endif
40 
41 // NEOPXL8 CLASS -----------------------------------------------------------
42 
49 class Adafruit_NeoPXL8 : public Adafruit_NeoPixel {
50 
51 public:
72  Adafruit_NeoPXL8(uint16_t n, int8_t *p = NULL, neoPixelType t = NEO_GRB);
73  ~Adafruit_NeoPXL8(void);
74 
84 #if defined(ARDUINO_ARCH_RP2040)
85  bool begin(bool dbuf = false, PIO pio_instance = pio0);
86 #else
87  bool begin(bool dbuf = false);
88 #endif
89 
93  void show(void);
94 
102  void stage(void);
103 
110  bool canShow(void) const;
111 
118  bool canStage(void) const;
119 
120  // Brightness is stored differently here than in normal NeoPixel library.
121  // In either case it's *specified* the same: 0 (off) to 255 (brightest).
122  // Classic NeoPixel rearranges this internally so 0 is max, 1 is off and
123  // 255 is just below max...it's a decision based on how fixed-point math
124  // is handled in that code. Here it's stored internally as 1 (off) to
125  // 256 (brightest), requiring a 16-bit value.
126 
136  void setBrightness(uint8_t b) { brightness = (uint16_t)b + 1; }
137 
142  uint8_t getBrightness(void) const { return brightness - 1; }
143 
163  void setLatchTime(uint16_t us = 300) { latchtime = us; };
164 
165 #if defined(ARDUINO_ARCH_RP2040)
166 
173  void dma_callback(void);
174 #endif
175 
176 protected:
177 #if defined(ARDUINO_ARCH_RP2040)
178  PIO pio;
179  uint8_t sm;
180  int dma_channel;
181  dma_channel_config dma_config;
182 #elif defined(CONFIG_IDF_TARGET_ESP32S3)
183  gdma_channel_handle_t dma_chan;
184  dma_descriptor_t *desc;
185  uint8_t *allocAddr;
186  uint32_t *alignedAddr[2];
187 #else // SAMD
188  Adafruit_ZeroDMA dma;
189  DmacDescriptor *desc;
190  uint8_t *allocAddr;
191  uint32_t *alignedAddr[2];
192 #endif
193  int8_t pins[8];
194  uint8_t bitmask[8];
195  uint8_t *dmaBuf[2] = {NULL, NULL};
196  uint16_t brightness = 255;
197  bool staged;
198  uint16_t latchtime = 300;
199  uint8_t dbuf_index = 0;
200 };
201 
202 // NEOPXL8HDR CLASS --------------------------------------------------------
203 
212 
213 public:
235  Adafruit_NeoPXL8HDR(uint16_t n, int8_t *p = NULL, neoPixelType t = NEO_GRB);
237 
255 #if defined(ARDUINO_ARCH_RP2040)
256  bool begin(bool blend = false, uint8_t bits = 4, bool dbuf = false,
257  PIO pio_instance = pio0);
258 #else
259  bool begin(bool blend = false, uint8_t bits = 4, bool dbuf = false);
260 #endif
261 
279  void setBrightness(uint8_t b);
280 
300  void setBrightness(uint16_t b, float y);
301 
318  void setBrightness(uint16_t r, uint16_t g, uint16_t b);
319 
337  void setBrightness(uint16_t r, uint16_t g, uint16_t b, uint16_t w);
338 
356  void setBrightness(uint16_t r, uint16_t g, uint16_t b, float y);
357 
377  void setBrightness(uint16_t r, uint16_t g, uint16_t b, uint16_t w, float y);
378 
383  void show(void);
384 
389  void refresh(void);
390 
395  void stage(void) const {};
396 
402  bool canStage(void) const { return true; }
403 
409  bool canShow(void) const { return true; }
410 
419  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
420 
431  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
432 
440  void setPixelColor(uint16_t n, uint32_t c);
441 
452  void set16(uint16_t n, uint16_t r, uint16_t g, uint16_t b, uint16_t w = 0);
453 
469  uint32_t getPixelColor(uint16_t n) const;
470 
487  void get16(uint16_t n, uint16_t *r, uint16_t *g, uint16_t *b,
488  uint16_t *w = NULL) const;
489 
503  uint16_t *getPixels(void) const { return pixel_buf[2]; }
504 
513  uint32_t getFPS(void) const { return fps; }
514 
519  void clear(void) { memset(pixel_buf[2], 0, numBytes * sizeof(uint16_t)); }
520 
521 protected:
527  void calc_gamma_table(void);
528  float gfactor;
529  uint16_t *pixel_buf[3] = {NULL, NULL, NULL};
530  uint16_t *dither_table = NULL;
531  uint32_t last_show_time = 0;
532  uint32_t avg_show_interval = 0;
533  uint32_t fps = 0;
534  uint32_t last_fps_time = 0;
535  uint16_t g16[4][256];
536  uint16_t brightness_rgbw[4];
537  uint8_t dither_bits;
538  uint8_t dither_index = 0;
539  uint8_t stage_index = 0;
540  volatile bool new_pixels = true;
541 #if defined(ARDUINO_ARCH_RP2040)
542  mutex_t mutex;
543 #elif defined(CONFIG_IDF_TARGET_ESP32S3)
544  SemaphoreHandle_t mutex;
545 #endif
546 };
547 
548 // The DEFAULT_PINS macros provide shortcuts for the most commonly-used pin
549 // lists on certain boards. For example, with a Feather M0, the default list
550 // will match an unaltered, factory-fresh NeoPXL8 FeatherWing M0. If ANY pins
551 // are changed on the FeatherWing, or if using a different pin sequence than
552 // these defaults, a user sketch must provide its own correct pin list.
553 // These may work for sloppy quick code but are NOT true in all situations!
554 #if defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_SCORPIO)
555 #define NEOPXL8_DEFAULT_PINS \
556  { 16, 17, 18, 19, 20, 21, 22, 23 }
557 #elif defined(ADAFRUIT_FEATHER_M0) || defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS)
558 #define NEOPXL8_DEFAULT_PINS \
559  { PIN_SERIAL1_RX, PIN_SERIAL1_TX, MISO, 13, 5, SDA, A4, A3 }
560 #elif defined(ADAFRUIT_FEATHER_M4_EXPRESS) || \
561  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3) || \
562  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM)
563 #define NEOPXL8_DEFAULT_PINS \
564  { SCK, 5, 9, 6, 13, 12, 11, 10 }
565 #elif defined(ADAFRUIT_METRO_M4_EXPRESS)
566 #define NEOPXL8_DEFAULT_PINS \
567  { 7, 4, 5, 6, 3, 2, 10, 11 }
568 #elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
569 #define NEOPXL8_DEFAULT_PINS \
570  { 30, 31, 32, 33, 36, 37, 34, 35 }
571 #elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
572 #define NEOPXL8_DEFAULT_PINS \
573  { 6, 7, 9, 8, 13, 12, 11, 10 }
574 #else
575 #define NEOPXL8_DEFAULT_PINS \
576  { 0, 1, 2, 3, 4, 5, 6, 7 }
577 #endif
578 
579 #endif // _ADAFRUIT_NEOPXL8_H_
uint16_t * getPixels(void) const
Get a pointer directly to the NeoPXL8HDR data buffer in RAM. Pixel data is unsigned 16-bit...
Definition: Adafruit_NeoPXL8.h:503
uint8_t dbuf_index
0/1 DMA buffer index
Definition: Adafruit_NeoPXL8.h:199
int8_t pins[8]
Pin list for 8 NeoPixel strips.
Definition: Adafruit_NeoPXL8.h:193
Adafruit_NeoPXL8HDR is a subclass of Adafruit_NeoPXL8 with additions for 16-bits-per-channel color...
Definition: Adafruit_NeoPXL8.h:211
void setBrightness(uint8_t b)
Set strip brightness for subsequent show() calls. Unlike the Adafruit_NeoPixel library, this function is non-destructive – original color values passed to setPixelColor() will always be accurately returned by getPixelColor(), even if brightness is adjusted.
Definition: Adafruit_NeoPXL8.h:136
uint16_t brightness
Brightness (stored 1-256, not 0-255)
Definition: Adafruit_NeoPXL8.h:196
bool canStage(void) const
Overload the canStage() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compatibility.
Definition: Adafruit_NeoPXL8.h:402
uint32_t getFPS(void) const
Query overall display refresh rate in frames-per-second. This is only an estimate and requires a mome...
Definition: Adafruit_NeoPXL8.h:513
void stage(void) const
Overload the stage() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compati...
Definition: Adafruit_NeoPXL8.h:395
void show(void)
Process and issue new data to the NeoPixel strands.
Definition: Adafruit_NeoPXL8.cpp:719
float gfactor
Gamma: 1.0=linear, 2.6=typ.
Definition: Adafruit_NeoPXL8.h:528
bool canShow(void) const
Overload the canShow() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compatibility.
Definition: Adafruit_NeoPXL8.h:409
void clear(void)
Fill the whole NeoPixel strip with 0 / black / off.
Definition: Adafruit_NeoPXL8.h:519
DmacDescriptor * desc
DMA descriptor pointer.
Definition: Adafruit_NeoPXL8.h:189
uint8_t getBrightness(void) const
Query brightness value last assigned with setBrightness().
Definition: Adafruit_NeoPXL8.h:142
void setLatchTime(uint16_t us=300)
Change the NeoPixel end-of-data latch period. Here be dragons.
Definition: Adafruit_NeoPXL8.h:163
bool canShow(void) const
Poll whether last show() transfer has completed and library is idle. Of questionable utility...
Definition: Adafruit_NeoPXL8.cpp:833
Adafruit_NeoPXL8(uint16_t n, int8_t *p=NULL, neoPixelType t=NEO_GRB)
NeoPXL8 constructor. Instantiates a new NeoPXL8 object (must follow with a begin() call to alloc buff...
Definition: Adafruit_NeoPXL8.cpp:100
uint8_t bitmask[8]
Pattern generator bitmask for each pin.
Definition: Adafruit_NeoPXL8.h:194
bool canStage(void) const
Poll whether last show() data transfer has completed, but not necessarily the end-of-data latch...
Definition: Adafruit_NeoPXL8.cpp:826
uint8_t * allocAddr
Allocated buffer into which dmaBuf points.
Definition: Adafruit_NeoPXL8.h:190
uint32_t * alignedAddr[2]
long-aligned ptrs into dmaBuf
Definition: Adafruit_NeoPXL8.h:191
uint8_t * dmaBuf[2]
Buffer for pixel data + any extra.
Definition: Adafruit_NeoPXL8.h:195
Adafruit_ZeroDMA dma
DMA object.
Definition: Adafruit_NeoPXL8.h:163
uint16_t latchtime
Pixel data latch time, microseconds.
Definition: Adafruit_NeoPXL8.h:198
bool staged
If set, data is ready for DMA trigger.
Definition: Adafruit_NeoPXL8.h:197
bool begin(bool dbuf=false)
Allocate buffers and initialize hardware for NeoPXL8 output.
Definition: Adafruit_NeoPXL8.cpp:294
void stage(void)
Preprocess NeoPixel data into DMA-ready format, but do not issue to strands yet. Esoteric but potenti...
Definition: Adafruit_NeoPXL8.cpp:627
uint8_t dither_bits
bits for temporal dither
Definition: Adafruit_NeoPXL8.h:537
Adafruit_NeoPXL8 is a subclass of Adafruit_NeoPixel containing buffers for DMA-formatted 8-way concur...
Definition: Adafruit_NeoPXL8.h:49