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  uint offset;
183 #elif defined(CONFIG_IDF_TARGET_ESP32S3)
184  gdma_channel_handle_t dma_chan;
185  dma_descriptor_t *desc;
186  uint8_t *allocAddr;
187  uint32_t *alignedAddr[2];
188 #else // SAMD
189  Adafruit_ZeroDMA dma;
190  DmacDescriptor *desc;
191  uint8_t *allocAddr;
192  uint32_t *alignedAddr[2];
193 #endif
194  int8_t pins[8];
195  uint8_t bitmask[8];
196  uint8_t *dmaBuf[2] = {NULL, NULL};
197  uint16_t brightness = 255;
198  bool staged;
199  uint16_t latchtime = 300;
200  uint8_t dbuf_index = 0;
201 };
202 
203 // NEOPXL8HDR CLASS --------------------------------------------------------
204 
213 
214 public:
236  Adafruit_NeoPXL8HDR(uint16_t n, int8_t *p = NULL, neoPixelType t = NEO_GRB);
238 
256 #if defined(ARDUINO_ARCH_RP2040)
257  bool begin(bool blend = false, uint8_t bits = 4, bool dbuf = false,
258  PIO pio_instance = pio0);
259 #else
260  bool begin(bool blend = false, uint8_t bits = 4, bool dbuf = false);
261 #endif
262 
280  void setBrightness(uint8_t b);
281 
301  void setBrightness(uint16_t b, float y);
302 
319  void setBrightness(uint16_t r, uint16_t g, uint16_t b);
320 
338  void setBrightness(uint16_t r, uint16_t g, uint16_t b, uint16_t w);
339 
357  void setBrightness(uint16_t r, uint16_t g, uint16_t b, float y);
358 
378  void setBrightness(uint16_t r, uint16_t g, uint16_t b, uint16_t w, float y);
379 
384  void show(void);
385 
390  void refresh(void);
391 
396  void stage(void) const {};
397 
403  bool canStage(void) const { return true; }
404 
410  bool canShow(void) const { return true; }
411 
420  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
421 
432  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
433 
441  void setPixelColor(uint16_t n, uint32_t c);
442 
453  void set16(uint16_t n, uint16_t r, uint16_t g, uint16_t b, uint16_t w = 0);
454 
470  uint32_t getPixelColor(uint16_t n) const;
471 
488  void get16(uint16_t n, uint16_t *r, uint16_t *g, uint16_t *b,
489  uint16_t *w = NULL) const;
490 
504  uint16_t *getPixels(void) const { return pixel_buf[2]; }
505 
514  uint32_t getFPS(void) const { return fps; }
515 
520  void clear(void) { memset(pixel_buf[2], 0, numBytes * sizeof(uint16_t)); }
521 
522 protected:
528  void calc_gamma_table(void);
529  float gfactor;
530  uint16_t *pixel_buf[3] = {NULL, NULL, NULL};
531  uint16_t *dither_table = NULL;
532  uint32_t last_show_time = 0;
533  uint32_t avg_show_interval = 0;
534  uint32_t fps = 0;
535  uint32_t last_fps_time = 0;
536  uint16_t g16[4][256];
537  uint16_t brightness_rgbw[4];
538  uint8_t dither_bits;
539  uint8_t dither_index = 0;
540  uint8_t stage_index = 0;
541  volatile bool new_pixels = true;
542 #if defined(ARDUINO_ARCH_RP2040)
543  mutex_t mutex;
544 #elif defined(CONFIG_IDF_TARGET_ESP32S3)
545  SemaphoreHandle_t mutex;
546 #endif
547 };
548 
549 // The DEFAULT_PINS macros provide shortcuts for the most commonly-used pin
550 // lists on certain boards. For example, with a Feather M0, the default list
551 // will match an unaltered, factory-fresh NeoPXL8 FeatherWing M0. If ANY pins
552 // are changed on the FeatherWing, or if using a different pin sequence than
553 // these defaults, a user sketch must provide its own correct pin list.
554 // These may work for sloppy quick code but are NOT true in all situations!
555 #if defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_SCORPIO)
556 #define NEOPXL8_DEFAULT_PINS \
557  { 16, 17, 18, 19, 20, 21, 22, 23 }
558 #elif defined(ADAFRUIT_FEATHER_M0) || defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS)
559 #define NEOPXL8_DEFAULT_PINS \
560  { PIN_SERIAL1_RX, PIN_SERIAL1_TX, MISO, 13, 5, SDA, A4, A3 }
561 #elif defined(ADAFRUIT_FEATHER_M4_EXPRESS) || \
562  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3) || \
563  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM)
564 #define NEOPXL8_DEFAULT_PINS \
565  { SCK, 5, 9, 6, 13, 12, 11, 10 }
566 #elif defined(ADAFRUIT_METRO_M4_EXPRESS)
567 #define NEOPXL8_DEFAULT_PINS \
568  { 7, 4, 5, 6, 3, 2, 10, 11 }
569 #elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
570 #define NEOPXL8_DEFAULT_PINS \
571  { 30, 31, 32, 33, 36, 37, 34, 35 }
572 #elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
573 #define NEOPXL8_DEFAULT_PINS \
574  { 6, 7, 9, 8, 13, 12, 11, 10 }
575 #else
576 #define NEOPXL8_DEFAULT_PINS \
577  { 0, 1, 2, 3, 4, 5, 6, 7 }
578 #endif
579 
580 #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:504
uint8_t dbuf_index
0/1 DMA buffer index
Definition: Adafruit_NeoPXL8.h:200
int8_t pins[8]
Pin list for 8 NeoPixel strips.
Definition: Adafruit_NeoPXL8.h:194
Adafruit_NeoPXL8HDR is a subclass of Adafruit_NeoPXL8 with additions for 16-bits-per-channel color...
Definition: Adafruit_NeoPXL8.h:212
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:197
bool canStage(void) const
Overload the canStage() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compatibility.
Definition: Adafruit_NeoPXL8.h:403
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:514
void stage(void) const
Overload the stage() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compati...
Definition: Adafruit_NeoPXL8.h:396
void show(void)
Process and issue new data to the NeoPixel strands.
Definition: Adafruit_NeoPXL8.cpp:725
float gfactor
Gamma: 1.0=linear, 2.6=typ.
Definition: Adafruit_NeoPXL8.h:529
bool canShow(void) const
Overload the canShow() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compatibility.
Definition: Adafruit_NeoPXL8.h:410
void clear(void)
Fill the whole NeoPixel strip with 0 / black / off.
Definition: Adafruit_NeoPXL8.h:520
DmacDescriptor * desc
DMA descriptor pointer.
Definition: Adafruit_NeoPXL8.h:190
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:839
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:195
bool canStage(void) const
Poll whether last show() data transfer has completed, but not necessarily the end-of-data latch...
Definition: Adafruit_NeoPXL8.cpp:832
uint8_t * allocAddr
Allocated buffer into which dmaBuf points.
Definition: Adafruit_NeoPXL8.h:191
uint32_t * alignedAddr[2]
long-aligned ptrs into dmaBuf
Definition: Adafruit_NeoPXL8.h:192
uint8_t * dmaBuf[2]
Buffer for pixel data + any extra.
Definition: Adafruit_NeoPXL8.h:196
Adafruit_ZeroDMA dma
DMA object.
Definition: Adafruit_NeoPXL8.h:163
uint16_t latchtime
Pixel data latch time, microseconds.
Definition: Adafruit_NeoPXL8.h:199
bool staged
If set, data is ready for DMA trigger.
Definition: Adafruit_NeoPXL8.h:198
bool begin(bool dbuf=false)
Allocate buffers and initialize hardware for NeoPXL8 output.
Definition: Adafruit_NeoPXL8.cpp:300
void stage(void)
Preprocess NeoPixel data into DMA-ready format, but do not issue to strands yet. Esoteric but potenti...
Definition: Adafruit_NeoPXL8.cpp:633
uint8_t dither_bits
bits for temporal dither
Definition: Adafruit_NeoPXL8.h:538
Adafruit_NeoPXL8 is a subclass of Adafruit_NeoPixel containing buffers for DMA-formatted 8-way concur...
Definition: Adafruit_NeoPXL8.h:49