Files
ObjectFLED_CLS/ObjectFLED.h
T
2025-02-11 21:10:28 +01:00

188 lines
7.2 KiB
C++

/* ObjectFLED - Teensy 4.x DMA to all pins for independent control of large and
multiple LED display objects
Copyright (c) 2024 Kurt Funderburg
2025 Clément SAILLANT
=> added setPixel method
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission shall be included in
all copies or substantial portions of the Software.
OctoWS2811 library code was well-studied and substantial portions of it used
to implement high-speed, non-blocking DMA for LED signal output in this library.
See ObjectFLED.cpp for a summary of changes made to the original OctoWS2811.
OctoWS2811 - High Performance WS2811 LED Display Library
Copyright (c) 2013 Paul Stoffregen, PJRC.COM, LLC
http://www.pjrc.com/teensy/td_libs_OctoWS2811.html
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef __IMXRT1062__
#error "Sorry, ObjectFLED only works on Teensy 4.x boards."
#endif
#if TEENSYDUINO < 121
#error "Teensyduino version 1.21 or later is required to compile this library."
#endif
#ifndef ObjectFLED_h
#define ObjectFLED_h
#include <WProgram.h>
#include "DMAChannel.h"
//Experimentally found DSE=3, SPEED=0 gave best LED overclocking
//boot defaults DSE=6, SPEED=2.
#define OUTPUT_PAD_DSE 3 //Legal values 0-7
#define OUTPUT_PAD_SPEED 0 //Legal values 0-3
// Ordinary RGB data is converted to GPIO bitmasks on-the-fly using
// a transmit buffer sized for 2 DMA transfers. The larger this setting,
// the more interrupt latency OctoWS2811 can tolerate, but the transmit
// buffer grows in size. For good performance, the buffer should be kept
// smaller than the half the Cortex-M7 data cache.
//bitdata[B_P_D * 64] buffer holds data (10KB) for 80 LED bytes: 4DW * 8b = 32DW/LEDB = 96DW/LED
//framebuffer_index = B_P_D * 2 = pointer to next block for transfer (80 LEDB / bitdata buffer)
#define BYTES_PER_DMA 20 //= number of pairs of LEDB (40=80B) bitmasks in bitdata.
#define CORDER_RGB 0 //* WS2811, YF923
#define CORDER_RBG 1
#define CORDER_GRB 2 //* WS2811B, Most LED strips are wired this way
#define CORDER_GBR 3 //*
#define CORDER_BRG 4 //* Adafruit Product ID: 5984 As of November 5, 2024 - this strand has different 'internal' color ordering. It's now BRG not RGB,
#define CORDER_BGR 5 //* Adafruit Dotstar LEDs SK9822 uses this CO but they use inverted start/stop bits
#define CORDER_RGBW 6 //* Popular
#define CORDER_RBGW 7
#define CORDER_GRBW 8
#define CORDER_GBRW 9
#define CORDER_BRGW 10
#define CORDER_BGRW 11 // Adafruit Dotstar LEDs SK9822 uses this CO but they use inverted start/stop bits
#define CORDER_WRGB 12
#define CORDER_WRBG 13
#define CORDER_WGRB 14
#define CORDER_WGBR 15
#define CORDER_WBRG 16
#define CORDER_WBGR 17
#define CORDER_RWGB 18
#define CORDER_RWBG 19
#define CORDER_GWRB 20
#define CORDER_GWBR 21
#define CORDER_BWRG 22
#define CORDER_BWGR 23
#define CORDER_RGWB 24
#define CORDER_RBWG 25
#define CORDER_GRWB 26
#define CORDER_GBWR 27
#define CORDER_BRWG 28
#define CORDER_BGWR 29
//Usage: ObjectFLED myCube ( Num_LEDs, *drawBuffer, LED_type, numPins, *pinList, serpentineNumber )
class ObjectFLED {
public:
//Usage: ObjectFLED myCube ( Num_LEDs, *drawBuffer, LED_type, numPins, *pinList, serpentineNumber )
ObjectFLED(uint16_t numLEDs, void* drawBuf, uint8_t config, uint8_t numPins, const uint8_t* pinList, \
uint8_t serpentine = 0);
~ObjectFLED() {
// Wait for prior xmission to end, don't need to wait for latch time before deleting buffer
while (micros() - update_begin_micros < numbytes * 8 * TH_TL / OC_FACTOR / 1000 + 5);
delete frameBuffer;
}
//begin() - Use defalut LED timing: 1.0 OC Factor, 1250 nS CLK (=800 KHz), 300 nS T0H, 750 nS T1H, 300 uS LED Latch Delay.
void begin(void);
//begin(LED_Latch_Delay_uS) - sets the LED Latch Delay.
void begin(uint16_t);
//begin(LED_Overclock_Factor, LED_Latch_Delay_uS) - divides default 1250 nS LED CLK (=800 KHz),
// 300 nS T0H, 750 nS T1H; and optionally sets the LED Latch Delay.
void begin(double, uint16_t = 300);
//begin(LED_CLK_nS, LED_T0H_nS, LED_T1H_nS, LED_Latch_Delay_uS) - specifies full LED waveform timing.
void begin(uint16_t, uint16_t, uint16_t, uint16_t = 300);
void show(void);
int busy(void);
//Brightness values 0-255
void setBrightness(uint8_t);
//Color Balance is 3-byte number in RGB order. Each byte is a brightness value for that color.
void setBalance(uint32_t);
uint8_t getBrightness() { return brightness; }
uint32_t getBalance() { return colorBalance; }
void setPixel(uint32_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
void getPixel(uint32_t index, uint8_t &r, uint8_t &g, uint8_t &b, uint8_t &w);
private:
static void isr(void);
void genFrameBuffer(uint32_t);
static uint8_t* frameBuffer; //isr()
static uint32_t numbytes; //isr()
static uint8_t numpins; //isr()
static uint8_t pin_bitnum[NUM_DIGITAL_PINS]; //isr()
static uint8_t pin_offset[NUM_DIGITAL_PINS]; //isr()
DMAMEM static uint32_t bitdata[BYTES_PER_DMA * 64] __attribute__((used, aligned(32))); //isr()
DMAMEM static uint32_t bitmask[4] __attribute__((used, aligned(32)));
static DMAChannel dma1, dma2, dma3;
static DMASetting dma2next;
uint32_t update_begin_micros = 0;
uint8_t brightness = 255;
uint32_t colorBalance = 0xFFFFFF;
uint32_t rLevel = 65025;
uint32_t gLevel = 65025;
uint32_t bLevel = 65025;
void* drawBuffer;
uint16_t stripLen;
uint8_t params;
uint8_t pinlist[NUM_DIGITAL_PINS];
uint16_t comp1load[3];
uint8_t serpNumber;
float OC_FACTOR = 1.0; //used to reduce period of LED output
uint16_t TH_TL = 1250; //nS- period of LED output
uint16_t T0H = 300; //nS- duration of T0H
uint16_t T1H = 750; //nS- duration of T1H
uint16_t LATCH_DELAY = 300; //uS time to hold output low for LED latch.
//for show context switch
uint32_t bitmaskLocal[4];
uint8_t numpinsLocal;
uint8_t* frameBufferLocal;
uint32_t numbytesLocal;
uint8_t pin_bitnumLocal[NUM_DIGITAL_PINS];
uint8_t pin_offsetLocal[NUM_DIGITAL_PINS];
}; // class ObjectFLED
//fadeToColorBy(RGB_array, LED_count, Color, FadeAmount)
//Fades an RGB array towards the background color by amount.
void fadeToColorBy(void*, uint16_t, uint32_t, uint8_t);
//drawSquare(RGB_Array, LED_Rows, LED_Cols, Y_Corner, X_Corner, square_Size)
//Draws square in a 2D RGB array with lower left corner at (Y_Corner, X_Corner).
//Safe to specify -Y, -X corner, safe to draw a box which partially fits on LED plane.
void drawSquare(void*, uint16_t, uint16_t, int, int, uint32_t, uint32_t);
#endif