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  bool begin(bool dbuf = false);
85 
89  void show(void);
90 
98  void stage(void);
99 
106  bool canShow(void) const;
107 
114  bool canStage(void) const;
115 
116  // Brightness is stored differently here than in normal NeoPixel library.
117  // In either case it's *specified* the same: 0 (off) to 255 (brightest).
118  // Classic NeoPixel rearranges this internally so 0 is max, 1 is off and
119  // 255 is just below max...it's a decision based on how fixed-point math
120  // is handled in that code. Here it's stored internally as 1 (off) to
121  // 256 (brightest), requiring a 16-bit value.
122 
132  void setBrightness(uint8_t b) { brightness = (uint16_t)b + 1; }
133 
138  uint8_t getBrightness(void) const { return brightness - 1; }
139 
159  void setLatchTime(uint16_t us = 300) { latchtime = us; };
160 
161 #if defined(ARDUINO_ARCH_RP2040)
162 
169  void dma_callback(void);
170 #endif
171 
172 protected:
173 #if defined(ARDUINO_ARCH_RP2040)
174  PIO pio = NULL;
175  uint sm = -1;
176  uint offset = 0;
177  int dma_channel;
178  dma_channel_config dma_config;
179 #elif defined(CONFIG_IDF_TARGET_ESP32S3)
180  gdma_channel_handle_t dma_chan;
181  dma_descriptor_t *desc;
182  uint8_t *allocAddr;
183  uint32_t *alignedAddr[2];
184 #else // SAMD
185  Adafruit_ZeroDMA dma;
186  DmacDescriptor *desc;
187  uint8_t *allocAddr;
188  uint32_t *alignedAddr[2];
189 #endif
190  int8_t pins[8];
191  uint8_t bitmask[8];
192  uint8_t *dmaBuf[2] = {NULL, NULL};
193  uint16_t brightness = 255;
194  bool staged;
195  uint16_t latchtime = 300;
196  uint8_t dbuf_index = 0;
197 };
198 
199 // NEOPXL8HDR CLASS --------------------------------------------------------
200 
209 
210 public:
232  Adafruit_NeoPXL8HDR(uint16_t n, int8_t *p = NULL, neoPixelType t = NEO_GRB);
234 
252  bool begin(bool blend = false, uint8_t bits = 4, bool dbuf = false);
253 
271  void setBrightness(uint8_t b);
272 
292  void setBrightness(uint16_t b, float y);
293 
310  void setBrightness(uint16_t r, uint16_t g, uint16_t b);
311 
329  void setBrightness(uint16_t r, uint16_t g, uint16_t b, uint16_t w);
330 
348  void setBrightness(uint16_t r, uint16_t g, uint16_t b, float y);
349 
369  void setBrightness(uint16_t r, uint16_t g, uint16_t b, uint16_t w, float y);
370 
375  void show(void);
376 
381  void refresh(void);
382 
387  void stage(void) const {};
388 
394  bool canStage(void) const { return true; }
395 
401  bool canShow(void) const { return true; }
402 
411  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
412 
423  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
424 
432  void setPixelColor(uint16_t n, uint32_t c);
433 
444  void set16(uint16_t n, uint16_t r, uint16_t g, uint16_t b, uint16_t w = 0);
445 
461  uint32_t getPixelColor(uint16_t n) const;
462 
479  void get16(uint16_t n, uint16_t *r, uint16_t *g, uint16_t *b,
480  uint16_t *w = NULL) const;
481 
495  uint16_t *getPixels(void) const { return pixel_buf[2]; }
496 
505  uint32_t getFPS(void) const { return fps; }
506 
511  void clear(void) { memset(pixel_buf[2], 0, numBytes * sizeof(uint16_t)); }
512 
513 protected:
519  void calc_gamma_table(void);
520  float gfactor;
521  uint16_t *pixel_buf[3] = {NULL, NULL, NULL};
522  uint16_t *dither_table = NULL;
523  uint32_t last_show_time = 0;
524  uint32_t avg_show_interval = 0;
525  uint32_t fps = 0;
526  uint32_t last_fps_time = 0;
527  uint16_t g16[4][256];
528  uint16_t brightness_rgbw[4];
529  uint8_t dither_bits;
530  uint8_t dither_index = 0;
531  uint8_t stage_index = 0;
532  volatile bool new_pixels = true;
533 #if defined(ARDUINO_ARCH_RP2040)
534  mutex_t mutex;
535 #elif defined(CONFIG_IDF_TARGET_ESP32S3)
536  SemaphoreHandle_t mutex;
537 #endif
538 };
539 
540 // The DEFAULT_PINS macros provide shortcuts for the most commonly-used pin
541 // lists on certain boards. For example, with a Feather M0, the default list
542 // will match an unaltered, factory-fresh NeoPXL8 FeatherWing M0. If ANY pins
543 // are changed on the FeatherWing, or if using a different pin sequence than
544 // these defaults, a user sketch must provide its own correct pin list.
545 // These may work for sloppy quick code but are NOT true in all situations!
546 #if defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_SCORPIO)
547 #define NEOPXL8_DEFAULT_PINS \
548  { 16, 17, 18, 19, 20, 21, 22, 23 }
549 #elif defined(ADAFRUIT_FEATHER_M0) || defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS)
550 #define NEOPXL8_DEFAULT_PINS \
551  { PIN_SERIAL1_RX, PIN_SERIAL1_TX, MISO, 13, 5, SDA, A4, A3 }
552 #elif defined(ADAFRUIT_FEATHER_M4_EXPRESS) || \
553  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3) || \
554  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM)
555 #define NEOPXL8_DEFAULT_PINS \
556  { SCK, 5, 9, 6, 13, 12, 11, 10 }
557 #elif defined(ADAFRUIT_METRO_M4_EXPRESS)
558 #define NEOPXL8_DEFAULT_PINS \
559  { 7, 4, 5, 6, 3, 2, 10, 11 }
560 #elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
561 #define NEOPXL8_DEFAULT_PINS \
562  { 30, 31, 32, 33, 36, 37, 34, 35 }
563 #elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
564 #define NEOPXL8_DEFAULT_PINS \
565  { 6, 7, 9, 8, 13, 12, 11, 10 }
566 #else
567 #define NEOPXL8_DEFAULT_PINS \
568  { 0, 1, 2, 3, 4, 5, 6, 7 }
569 #endif
570 
571 #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:495
uint8_t dbuf_index
0/1 DMA buffer index
Definition: Adafruit_NeoPXL8.h:196
int8_t pins[8]
Pin list for 8 NeoPixel strips.
Definition: Adafruit_NeoPXL8.h:190
Adafruit_NeoPXL8HDR is a subclass of Adafruit_NeoPXL8 with additions for 16-bits-per-channel color...
Definition: Adafruit_NeoPXL8.h:208
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:132
uint16_t brightness
Brightness (stored 1-256, not 0-255)
Definition: Adafruit_NeoPXL8.h:193
bool canStage(void) const
Overload the canStage() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compatibility.
Definition: Adafruit_NeoPXL8.h:394
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:505
void stage(void) const
Overload the stage() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compati...
Definition: Adafruit_NeoPXL8.h:387
void show(void)
Process and issue new data to the NeoPixel strands.
Definition: Adafruit_NeoPXL8.cpp:731
float gfactor
Gamma: 1.0=linear, 2.6=typ.
Definition: Adafruit_NeoPXL8.h:520
bool canShow(void) const
Overload the canShow() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compatibility.
Definition: Adafruit_NeoPXL8.h:401
void clear(void)
Fill the whole NeoPixel strip with 0 / black / off.
Definition: Adafruit_NeoPXL8.h:511
DmacDescriptor * desc
DMA descriptor pointer.
Definition: Adafruit_NeoPXL8.h:186
uint8_t getBrightness(void) const
Query brightness value last assigned with setBrightness().
Definition: Adafruit_NeoPXL8.h:138
void setLatchTime(uint16_t us=300)
Change the NeoPixel end-of-data latch period. Here be dragons.
Definition: Adafruit_NeoPXL8.h:159
bool canShow(void) const
Poll whether last show() transfer has completed and library is idle. Of questionable utility...
Definition: Adafruit_NeoPXL8.cpp:845
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:191
bool canStage(void) const
Poll whether last show() data transfer has completed, but not necessarily the end-of-data latch...
Definition: Adafruit_NeoPXL8.cpp:838
uint8_t * allocAddr
Allocated buffer into which dmaBuf points.
Definition: Adafruit_NeoPXL8.h:187
uint32_t * alignedAddr[2]
long-aligned ptrs into dmaBuf
Definition: Adafruit_NeoPXL8.h:188
uint8_t * dmaBuf[2]
Buffer for pixel data + any extra.
Definition: Adafruit_NeoPXL8.h:192
Adafruit_ZeroDMA dma
DMA object.
Definition: Adafruit_NeoPXL8.h:159
uint16_t latchtime
Pixel data latch time, microseconds.
Definition: Adafruit_NeoPXL8.h:195
bool staged
If set, data is ready for DMA trigger.
Definition: Adafruit_NeoPXL8.h:194
bool begin(bool dbuf=false)
Allocate buffers and initialize hardware for NeoPXL8 output.
Definition: Adafruit_NeoPXL8.cpp:297
void stage(void)
Preprocess NeoPixel data into DMA-ready format, but do not issue to strands yet. Esoteric but potenti...
Definition: Adafruit_NeoPXL8.cpp:639
uint8_t dither_bits
bits for temporal dither
Definition: Adafruit_NeoPXL8.h:529
Adafruit_NeoPXL8 is a subclass of Adafruit_NeoPixel containing buffers for DMA-formatted 8-way concur...
Definition: Adafruit_NeoPXL8.h:49