From 4af3a22764f6cbbfeeccd1dec43b504040315c7d Mon Sep 17 00:00:00 2001 From: Gregg Date: Fri, 21 Jan 2022 21:56:51 -0600 Subject: [PATCH] Update logic so Pixel uses only ONE channel and shares across all instances --- src/extras/Pixel.cpp | 11 +++++++++-- src/extras/Pixel.h | 5 +++-- src/extras/RFControl.cpp | 23 ++++++++++------------- src/extras/extras.ino | 12 +++++++++--- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/extras/Pixel.cpp b/src/extras/Pixel.cpp index 7ece3ab..e26e4d0 100644 --- a/src/extras/Pixel.cpp +++ b/src/extras/Pixel.cpp @@ -4,10 +4,14 @@ /////////////////// Pixel::Pixel(int pin){ + + if(!rf) // RMT Channel not yet assigned + rf=new RFControl(pin,false,false); // set clock to 1/80 usec, no default driver - rf=new RFControl(pin,false,false); // set clock to 1/80 usec, no default driver - if(!rf) + if(!*rf) // if RMT Channel could NOT be assigned (no more channels) return; + + this->pin=pin; setTiming(0.32, 0.88, 0.64, 0.56, 80.0); // set default timing parameters (suitable for most SK68 and WS28 RGB pixels) @@ -67,6 +71,8 @@ void Pixel::setColors(const uint32_t *data, uint32_t nPixels, boolean multiColor status.px=this; status.multiColor=multiColor; + rmt_set_gpio(rf->getChannel(),RMT_MODE_TX,(gpio_num_t)(pin),false); + loadData(this); // load first two bytes of data to get started loadData(this); @@ -122,3 +128,4 @@ void IRAM_ATTR Pixel::loadData(void *arg){ /////////////////// volatile Pixel::pixel_status_t Pixel::status; +RFControl *Pixel::rf=NULL; diff --git a/src/extras/Pixel.h b/src/extras/Pixel.h index b2a05b4..419f5ed 100644 --- a/src/extras/Pixel.h +++ b/src/extras/Pixel.h @@ -21,11 +21,12 @@ class Pixel { }; private: - RFControl *rf; // Pixel utilizes RFControl + static RFControl *rf; // Pixel utilizes RFControl (shared across all Pixel instances) uint32_t pattern[2]; // storage for zero-bit and one-bit pulses uint32_t resetTime; // minimum time (in usec) between pulse trains uint32_t txEndMask; // mask for end-of-transmission interrupt uint32_t txThrMask; // mask for threshold interrupt + int pin=-1; // pin number to which pixel is connected const int memSize=sizeof(RMTMEM.chan[0].data32)/4; // determine size (in pulses) of one channel @@ -41,7 +42,7 @@ class Pixel { void setHSV(float h, float s, float v, uint32_t nPixels=1); // sets color of nPixels to HSV values where h=[0,360], s=[0,100], v=[0,100] void setColors(const uint32_t *data, uint32_t nPixels, bool multiColor=true); // sets colors of nPixels from array of colors stored in data - int getPin(){return(rf->getPin());} // returns pixel pin if valid, else returns -1 + int getPin(){return(pin);} // returns pixel pin (or -1 if initialization failed) static uint32_t getColorRGB(uint8_t r, uint8_t g, uint8_t b); // return pixel Color from RGB values static uint32_t getColorHSV(float h, float s, float v); // return pixel Color from HSV values diff --git a/src/extras/RFControl.cpp b/src/extras/RFControl.cpp index 182cefb..b556a24 100644 --- a/src/extras/RFControl.cpp +++ b/src/extras/RFControl.cpp @@ -33,21 +33,18 @@ RFControl::RFControl(uint8_t pin, boolean refClock, boolean installDriver){ if(installDriver) rmt_driver_install(config->channel,0,0); - // If specified, set the base clock to 1 MHz so tick-units are in microseconds (before any CLK_DIV is applied), otherwise default will be 80 MHz APB clock - this->refClock=refClock; - - if(refClock) -#ifdef CONFIG_IDF_TARGET_ESP32C3 - REG_SET_FIELD(RMT_SYS_CONF_REG,RMT_SCLK_DIV_NUM,79); // ESP32-C3 does not have a 1 MHz REF Tick Clock, but allows the 80 MHz APB clock to be scaled by an additional RMT-specific divider -#else - rmt_set_source_clk(config->channel,RMT_BASECLK_REF); // use 1 MHz REF Tick Clock for ESP32 and ESP32-S2 -#endif - nChannels++; + if(refClock) +#if SOC_RMT_SUPPORT_REF_TICK + rmt_set_source_clk(config->channel,RMT_BASECLK_REF); // use 1 MHz REF Tick Clock for ESP32 and ESP32-S2 instead of 80 MHz APB clock +#elif SOC_RMT_SUPPORT_XTAL + REG_SET_FIELD(RMT_SYS_CONF_REG,RMT_SCLK_DIV_NUM,79); // ESP32-C3 does not have a 1 MHz REF Tick Clock, but allows the 80 MHz APB clock to be scaled by an additional RMT-specific divider +#endif + } - + /////////////////// void RFControl::start(uint8_t nCycles, uint8_t tickTime){ // starts transmission of pulses from internal data structure, repeated for nCycles, where each tick in pulse is tickTime microseconds long @@ -60,8 +57,8 @@ void RFControl::start(uint32_t *data, int nData, uint8_t nCycles, uint8_t tickTi if(!config || nData==0) return; - - rmt_set_clk_div(config->channel,tickTime); // set clock divider + + rmt_set_clk_div(config->channel,tickTime); // set clock divider for(int i=0;ichannel, (rmt_item32_t *) data, nData, true); // start transmission and wait until completed before returning diff --git a/src/extras/extras.ino b/src/extras/extras.ino index e248795..407ed81 100644 --- a/src/extras/extras.ino +++ b/src/extras/extras.ino @@ -81,13 +81,12 @@ struct Effect2 { #define PIN 21 #endif -Pixel px2(2); Pixel px(PIN); +Pixel px2(2); +Pixel px5(5); Pixel px3(3); Pixel px4(4); -Pixel px5(5); Pixel px6(6); -Pixel px7(7); Effect1 effect1(&px,5); Effect2 effect2(&px,100); @@ -99,6 +98,13 @@ void setup() { delay(1000); // wait for interface to flush Serial.println("\n\nHomeSpan Pixel Example\n"); + + Serial.println(px.getPin()); + Serial.println(px2.getPin()); + Serial.println(px3.getPin()); + Serial.println(px4.getPin()); + Serial.println(px5.getPin()); + Serial.println(px6.getPin()); } // end of setup()