Add two-wire addressable DotStar RGB LEDs to Pixel.h

Pixel.h now contains Pixel() and Dot() classes.
Dot() class uses more streamlined methods; must next update Pixel() to use similar methods, which will allow Pixel and Dot to be more "interchangeable".
This commit is contained in:
Gregg 2022-02-05 09:17:56 -06:00
parent 852a916d61
commit a21cc0679d
2 changed files with 144 additions and 4 deletions

View File

@ -1,7 +1,13 @@
////////////////////////////////////////////
// Addressable LEDs //
////////////////////////////////////////////
#include "Pixel.h"
///////////////////
////////////////////////////////////////////
// Single-Wire RGB/RGBW NeoPixels //
////////////////////////////////////////////
Pixel::Pixel(int pin, pixel_type_t pType){
@ -125,3 +131,95 @@ void IRAM_ATTR Pixel::loadData(void *arg){
///////////////////
volatile Pixel::pixel_status_t Pixel::status;
////////////////////////////////////////////
// Two-Wire RGB DotStars //
////////////////////////////////////////////
Dot::Dot(uint8_t dataPin, uint8_t clockPin){
pinMode(dataPin,OUTPUT);
pinMode(clockPin,OUTPUT);
digitalWrite(dataPin,LOW);
digitalWrite(clockPin,LOW);
dataMask=1<<(dataPin%32);
clockMask=1<<(clockPin%32);
#ifdef CONFIG_IDF_TARGET_ESP32C3
dataSetReg=&GPIO.out_w1ts.val;
dataClearReg=&GPIO.out_w1tc.val;
clockSetReg=&GPIO.out_w1ts.val;
clockClearReg=&GPIO.out_w1tc.val;
#else
if(dataPin<32){
dataSetReg=&GPIO.out_w1ts;
dataClearReg=&GPIO.out_w1tc;
} else {
dataSetReg=&GPIO.out1_w1ts.val;
dataClearReg=&GPIO.out1_w1tc.val;
}
if(clockPin<32){
clockSetReg=&GPIO.out_w1ts;
clockClearReg=&GPIO.out_w1tc;
} else {
clockSetReg=&GPIO.out1_w1ts.val;
clockClearReg=&GPIO.out1_w1tc.val;
}
#endif
}
///////////////////
void Dot::set(Color *c, int nPixels, boolean multiColor){
*dataClearReg=dataMask; // send all zeros
for(int j=0;j<31;j++){
*clockSetReg=clockMask;
*clockClearReg=clockMask;
}
for(int i=0;i<nPixels;i++){
for(int b=31;b>=0;b--){
if((c->val>>b)&1)
*dataSetReg=dataMask;
else
*dataClearReg=dataMask;
*clockSetReg=clockMask;
*clockClearReg=clockMask;
}
if(multiColor)
c++;
}
*dataClearReg=dataMask; // send all zeros
for(int j=0;j<31;j++){
*clockSetReg=clockMask;
*clockClearReg=clockMask;
}
}
///////////////////
Dot::Color Dot::RGB(uint8_t red, uint8_t green, uint8_t blue, uint8_t drive){
Color x;
x.red=red;
x.green=green;
x.blue=blue;
x.drive=drive;
x.flags=7;
return(x);
}
///////////////////
Dot::Color Dot::HSV(float h, float s, float v, float level){
float r,g,b;
LedPin::HSVtoRGB(h,s/100.0,v/100.0,&r,&g,&b);
return(RGB(r*255,g*255,b*255,level/100*31.5));
}
////////////////////////////////////////////

View File

@ -1,13 +1,17 @@
////////////////////////////////////
// Addressable LED Pixel //
////////////////////////////////////
////////////////////////////////////////////
// Addressable LEDs //
////////////////////////////////////////////
#pragma once
#include "RFControl.h"
#include "PwmPin.h"
////////////////////////////////////////////
// Single-Wire RGB/RGBW NeoPixels //
////////////////////////////////////////////
class Pixel {
public:
@ -57,3 +61,41 @@ class Pixel {
return(*rf);
}
};
////////////////////////////////////////////
// Two-Wire RGB DotStars //
////////////////////////////////////////////
class Dot {
public:
struct Color {
union{
struct {
uint8_t red:8;
uint8_t green:8;
uint8_t blue:8;
uint8_t drive:5;
uint8_t flags:3;
};
uint32_t val;
};
};
private:
uint32_t dataMask;
uint32_t clockMask;
volatile uint32_t *dataSetReg;
volatile uint32_t *dataClearReg;
volatile uint32_t *clockSetReg;
volatile uint32_t *clockClearReg;
public:
Dot(uint8_t dataPin, uint8_t clockPin);
void set(Color c, int nPixels=1){set(&c,nPixels,false);}
void set (Color *c, int nPixels, boolean multiColor=true);
static Color RGB(uint8_t red, uint8_t green, uint8_t blue, uint8_t drive=31);
static Color HSV(float h, float s, float v, float level=100);
};
////////////////////////////////////////////