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 #if defined(ESP_IDF_VERSION_MAJOR) && (ESP_IDF_VERSION_MAJOR >= 5)
37 #include <hal/gpio_ll.h>
38 #endif
39 #include <soc/lcd_cam_struct.h>
40 #else // SAMD
41 #include <Adafruit_ZeroDMA.h>
42 #endif
43 
44 // NEOPXL8 CLASS -----------------------------------------------------------
45 
52 class Adafruit_NeoPXL8 : public Adafruit_NeoPixel {
53 
54 public:
75  Adafruit_NeoPXL8(uint16_t n, int8_t *p = NULL, neoPixelType t = NEO_GRB);
76  ~Adafruit_NeoPXL8(void);
77 
87  bool begin(bool dbuf = false);
88 
92  void show(void);
93 
101  void stage(void);
102 
109  bool canShow(void) const;
110 
117  bool canStage(void) const;
118 
119  // Brightness is stored differently here than in normal NeoPixel library.
120  // In either case it's *specified* the same: 0 (off) to 255 (brightest).
121  // Classic NeoPixel rearranges this internally so 0 is max, 1 is off and
122  // 255 is just below max...it's a decision based on how fixed-point math
123  // is handled in that code. Here it's stored internally as 1 (off) to
124  // 256 (brightest), requiring a 16-bit value.
125 
135  void setBrightness(uint8_t b) { brightness = (uint16_t)b + 1; }
136 
141  uint8_t getBrightness(void) const { return brightness - 1; }
142 
162  void setLatchTime(uint16_t us = 300) { latchtime = us; };
163 
164 #if defined(ARDUINO_ARCH_RP2040)
165 
172  void dma_callback(void);
173 #endif
174 
175 protected:
176 #if defined(ARDUINO_ARCH_RP2040)
177  PIO pio = NULL;
178  uint sm = -1;
179  uint offset = 0;
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  bool begin(bool blend = false, uint8_t bits = 4, bool dbuf = false);
256 
274  void setBrightness(uint8_t b);
275 
295  void setBrightness(uint16_t b, float y);
296 
313  void setBrightness(uint16_t r, uint16_t g, uint16_t b);
314 
332  void setBrightness(uint16_t r, uint16_t g, uint16_t b, uint16_t w);
333 
351  void setBrightness(uint16_t r, uint16_t g, uint16_t b, float y);
352 
372  void setBrightness(uint16_t r, uint16_t g, uint16_t b, uint16_t w, float y);
373 
378  void show(void);
379 
384  void refresh(void);
385 
390  void stage(void) const {};
391 
397  bool canStage(void) const { return true; }
398 
404  bool canShow(void) const { return true; }
405 
414  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
415 
426  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
427 
435  void setPixelColor(uint16_t n, uint32_t c);
436 
447  void set16(uint16_t n, uint16_t r, uint16_t g, uint16_t b, uint16_t w = 0);
448 
464  uint32_t getPixelColor(uint16_t n) const;
465 
482  void get16(uint16_t n, uint16_t *r, uint16_t *g, uint16_t *b,
483  uint16_t *w = NULL) const;
484 
498  uint16_t *getPixels(void) const { return pixel_buf[2]; }
499 
508  uint32_t getFPS(void) const { return fps; }
509 
514  void clear(void) { memset(pixel_buf[2], 0, numBytes * sizeof(uint16_t)); }
515 
516 protected:
522  void calc_gamma_table(void);
523  float gfactor;
524  uint16_t *pixel_buf[3] = {NULL, NULL, NULL};
525  uint16_t *dither_table = NULL;
526  uint32_t last_show_time = 0;
527  uint32_t avg_show_interval = 0;
528  uint32_t fps = 0;
529  uint32_t last_fps_time = 0;
530  uint16_t g16[4][256];
531  uint16_t brightness_rgbw[4];
532  uint8_t dither_bits;
533  uint8_t dither_index = 0;
534  uint8_t stage_index = 0;
535  volatile bool new_pixels = true;
536 #if defined(ARDUINO_ARCH_RP2040)
537  mutex_t mutex;
538 #elif defined(CONFIG_IDF_TARGET_ESP32S3)
539  SemaphoreHandle_t mutex;
540 #endif
541 };
542 
543 // The DEFAULT_PINS macros provide shortcuts for the most commonly-used pin
544 // lists on certain boards. For example, with a Feather M0, the default list
545 // will match an unaltered, factory-fresh NeoPXL8 FeatherWing M0. If ANY pins
546 // are changed on the FeatherWing, or if using a different pin sequence than
547 // these defaults, a user sketch must provide its own correct pin list.
548 // These may work for sloppy quick code but are NOT true in all situations!
549 #if defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_SCORPIO)
550 #define NEOPXL8_DEFAULT_PINS \
551  { 16, 17, 18, 19, 20, 21, 22, 23 }
552 #elif defined(ADAFRUIT_FEATHER_M0) || defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS)
553 #define NEOPXL8_DEFAULT_PINS \
554  { PIN_SERIAL1_RX, PIN_SERIAL1_TX, MISO, 13, 5, SDA, A4, A3 }
555 #elif defined(ADAFRUIT_FEATHER_M4_EXPRESS) || \
556  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3) || \
557  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM)
558 #define NEOPXL8_DEFAULT_PINS \
559  { SCK, 5, 9, 6, 13, 12, 11, 10 }
560 #elif defined(ADAFRUIT_METRO_M4_EXPRESS)
561 #define NEOPXL8_DEFAULT_PINS \
562  { 7, 4, 5, 6, 3, 2, 10, 11 }
563 #elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
564 #define NEOPXL8_DEFAULT_PINS \
565  { 30, 31, 32, 33, 36, 37, 34, 35 }
566 #elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
567 #define NEOPXL8_DEFAULT_PINS \
568  { 6, 7, 9, 8, 13, 12, 11, 10 }
569 #else
570 #define NEOPXL8_DEFAULT_PINS \
571  { 0, 1, 2, 3, 4, 5, 6, 7 }
572 #endif
573 
574 #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:498
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:135
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:397
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:508
void stage(void) const
Overload the stage() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compati...
Definition: Adafruit_NeoPXL8.h:390
void show(void)
Process and issue new data to the NeoPixel strands.
Definition: Adafruit_NeoPXL8.cpp:745
float gfactor
Gamma: 1.0=linear, 2.6=typ.
Definition: Adafruit_NeoPXL8.h:523
bool canShow(void) const
Overload the canShow() function from Adafruit_NeoPXL8. Does nothing in NeoPXL8HDR, provided for compatibility.
Definition: Adafruit_NeoPXL8.h:404
void clear(void)
Fill the whole NeoPixel strip with 0 / black / off.
Definition: Adafruit_NeoPXL8.h:514
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:141
void setLatchTime(uint16_t us=300)
Change the NeoPixel end-of-data latch period. Here be dragons.
Definition: Adafruit_NeoPXL8.h:162
bool canShow(void) const
Poll whether last show() transfer has completed and library is idle. Of questionable utility...
Definition: Adafruit_NeoPXL8.cpp:859
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:852
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:162
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:311
void stage(void)
Preprocess NeoPixel data into DMA-ready format, but do not issue to strands yet. Esoteric but potenti...
Definition: Adafruit_NeoPXL8.cpp:653
uint8_t dither_bits
bits for temporal dither
Definition: Adafruit_NeoPXL8.h:532
Adafruit_NeoPXL8 is a subclass of Adafruit_NeoPixel containing buffers for DMA-formatted 8-way concur...
Definition: Adafruit_NeoPXL8.h:52