+#ifdef SUPPORT_I2S
+ #include "output/OutputI2S.hpp"
+#endif // def SUPPORT_I2S
+
class c_OutputCommon; ///< forward declaration to the pure virtual output class that will be defined later.
#ifdef UART_LAST
@@ -44,6 +48,9 @@ class c_OutputMgr
#else // ARDUINO_ARCH_ESP32
#define OM_MAX_NUM_CHANNELS (3000 * 3)
#endif // !def ARDUINO_ARCH_ESP32
+#ifdef SUPPORT_I2S
+ c_OutputI2S OutputI2S;
+#endif // def SUPPORT_I2S
public:
c_OutputMgr ();
@@ -58,7 +65,7 @@ class c_OutputMgr
void SetConfig (const char * NewConfig); ///< Save the current configuration data to nvram
void SetConfig (ArduinoJson::JsonDocument & NewConfig); ///< Save the current configuration data to nvram
void GetStatus (JsonObject & jsonStatus);
- uint8_t* GetBufferAddress () { return pOutputBuffer; } ///< Get the address of the buffer into which the E1.31 handler will stuff data
+ IRAM_ATTR uint8_t * ISR_GetBufferAddress () { return pOutputBuffer; } ///< Get the address of the buffer into which the E1.31 handler will stuff data
uint32_t GetBufferUsedSize () { return UsedBufferSize; } ///< Get the size (in intensities) of the buffer into which the E1.31 handler will stuff data
uint32_t GetBufferSize () { return uint32_t(OM_MAX_NUM_CHANNELS); } ///< Get the size (in intensities) of the buffer into which the E1.31 handler will stuff data
void DeleteConfig () { FileMgr.DeleteFlashFile (ConfigFileName); }
@@ -71,8 +78,11 @@ class c_OutputMgr
void RelayUpdate (uint8_t RelayId, String & NewValue, String & Response);
void ClearStatistics (void);
uint8_t GetNumPorts () {return NumOutputPorts;}
+ #ifdef SUPPORT_I2S
+ c_OutputI2S * GetI2sDriver () {return &OutputI2S;}
+ #endif // def SUPPORT_I2S
- // do NOT insert into the middle of this list. Always add new types to the end of the list
+// do NOT insert into the middle of this list. Always add new types to the end of the list
enum e_OutputProtocolType
{
OutputProtocol_Disabled = 0,
diff --git a/include/output/OutputPixel.hpp b/include/output/OutputPixel.hpp
index 4c47d6df2..33975f4b5 100644
--- a/include/output/OutputPixel.hpp
+++ b/include/output/OutputPixel.hpp
@@ -99,6 +99,9 @@ class c_OutputPixel : public c_OutputCommon
uint32_t GetNextIntensityToSendFailedCounter = 0;
uint32_t LastGECEdataSent = uint32_t(-1);
uint32_t NumGECEdataSent = 0;
+#define INC_PIXEL_DEBUG_COUNTER(c) ++c
+#else
+#define INC_PIXEL_DEBUG_COUNTER(c)
#endif // def USE_PIXEL_DEBUG_COUNTERS
// functions used to implement pixel FSM
@@ -164,8 +167,8 @@ class c_OutputPixel : public c_OutputCommon
virtual void ReadChannelData (uint32_t StartChannelId, uint32_t ChannelCount, byte *pTargetData);
inline void SetIntensityBitTimeInUS (float value) { IntensityBitTimeInUs = value; }
void SetIntensityDataWidth(uint32_t value);
- virtual void StartNewFrame();
- inline bool IRAM_ATTR ISR_MoreDataToSend () {return (&c_OutputPixel::ISR_FrameDone != FrameStateFuncPtr);}
+ void ISR_StartNewFrame();
+ inline bool ISR_MoreDataToSend () {return (&c_OutputPixel::ISR_FrameDone != FrameStateFuncPtr);}
bool ISR_GetNextIntensityToSend (uint32_t &DataToSend);
void SetPixelCount(uint32_t value) {pixel_count = value;}
inline uint32_t GetPixelCount() {return pixel_count;}
diff --git a/include/output/OutputRmt.hpp b/include/output/OutputRmt.hpp
index d55c686b7..4075ddca0 100644
--- a/include/output/OutputRmt.hpp
+++ b/include/output/OutputRmt.hpp
@@ -19,7 +19,7 @@
*/
#include "ESPixelStick.h"
-#ifdef ARDUINO_ARCH_ESP32
+#ifdef SUPPORT_RMT
#include "OutputPixel.hpp"
#include "OutputSerial.hpp"
@@ -214,4 +214,4 @@ inline void WriteToBuffer(rmt_item32_t value)
} // WriteToBuffer
};
-#endif // def #ifdef ARDUINO_ARCH_ESP32
\ No newline at end of file
+#endif // def #ifdef SUPPORT_RMT
\ No newline at end of file
diff --git a/include/output/OutputSerial.hpp b/include/output/OutputSerial.hpp
index 79a1b5111..a066838c4 100644
--- a/include/output/OutputSerial.hpp
+++ b/include/output/OutputSerial.hpp
@@ -43,10 +43,10 @@ class c_OutputSerial : public c_OutputCommon
uint32_t GetNumOutputBufferChannelsServiced () { return OutputBufferSize; };
void SetOutputBufferSize (uint32_t NumChannelsAvailable);
uint32_t Poll = 0;
- void StartNewFrame();
+ void ISR_StartNewFrame();
- bool IRAM_ATTR ISR_GetNextIntensityToSend(uint32_t &DataToSend);
- bool IRAM_ATTR ISR_MoreDataToSend() { return (SerialFrameState_t::SerialIdle != SerialFrameState); }
+ bool ISR_GetNextIntensityToSend(uint32_t &DataToSend);
+ IRAM_ATTR bool ISR_MoreDataToSend() { return (SerialFrameState_t::SerialIdle != SerialFrameState); }
protected:
void SetFrameDurration();
diff --git a/include/output/OutputSerialRmt.hpp b/include/output/OutputSerialRmt.hpp
index 954768a69..eee21f36a 100644
--- a/include/output/OutputSerialRmt.hpp
+++ b/include/output/OutputSerialRmt.hpp
@@ -22,7 +22,7 @@
*
*/
#include "ESPixelStick.h"
-#if (defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(ARDUINO_ARCH_ESP32)
+#if (defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(SUPPORT_RMT)
#include "OutputSerial.hpp"
#include "OutputRmt.hpp"
@@ -43,7 +43,7 @@ class c_OutputSerialRmt : public c_OutputSerial
void GetStatus (ArduinoJson::JsonObject& jsonStatus);
void SetOutputBufferSize (uint32_t NumChannelsAvailable);
void PauseOutput(bool State);
- void StartNewDataFrame();
+ void ISR_StartNewDataFrame();
bool ISR_GetNextBitToSend(rmt_item32_t & DataToSend);
private:
@@ -85,4 +85,4 @@ class c_OutputSerialRmt : public c_OutputSerial
}; // c_OutputSerialRmt
-#endif // defined(SUPPORT_OutputProtocol_FireGod) || (defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_FireGod) || (defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(SUPPORT_RMT)
diff --git a/include/output/OutputSerialUart.hpp b/include/output/OutputSerialUart.hpp
index ac8bd9edc..62af1fcea 100644
--- a/include/output/OutputSerialUart.hpp
+++ b/include/output/OutputSerialUart.hpp
@@ -23,7 +23,7 @@ GNU General Public License for more details.
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)
+#if (defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(SUPPORT_UART)
#include "OutputSerial.hpp"
#include "OutputUart.hpp"
@@ -42,9 +42,6 @@ class c_OutputSerialUart : public c_OutputSerial
virtual void GetConfig(ArduinoJson::JsonObject &jsonConfig); ///< Set a new config in the driver
virtual void GetStatus(ArduinoJson::JsonObject &jsonStatus);
uint32_t Poll();
-#if defined(ARDUINO_ARCH_ESP32)
- bool RmtPoll () {return false;}
-#endif // defined(ARDUINO_ARCH_ESP32)
void PauseOutput (bool NewState);
private:
@@ -52,4 +49,4 @@ class c_OutputSerialUart : public c_OutputSerial
}; // c_OutputSerialUart
-#endif // defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)
+#endif // defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard) && defined(SUPPORT_UART)
diff --git a/include/output/OutputTLS3001Rmt.hpp b/include/output/OutputTLS3001Rmt.hpp
index c35987d76..75891c6e0 100644
--- a/include/output/OutputTLS3001Rmt.hpp
+++ b/include/output/OutputTLS3001Rmt.hpp
@@ -22,7 +22,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_TLS3001) && defined (ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_TLS3001) && defined (SUPPORT_RMT)
#include "OutputTLS3001.hpp"
#include "OutputRmt.hpp"
@@ -117,4 +117,4 @@ class c_OutputTLS3001Rmt : public c_OutputTLS3001
}; // c_OutputTLS3001Rmt
-#endif // defined(SUPPORT_OutputProtocol_TLS3001) && defined (ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_TLS3001) && defined (SUPPORT_RMT)
diff --git a/include/output/OutputTLS3001RmtFsm.hpp b/include/output/OutputTLS3001RmtFsm.hpp
index d1dd4e54c..fc60af808 100644
--- a/include/output/OutputTLS3001RmtFsm.hpp
+++ b/include/output/OutputTLS3001RmtFsm.hpp
@@ -22,7 +22,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_TLS3001) && defined (ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_TLS3001) && defined (SUPPORT_RMT)
// forward declaration
class c_OutputTLS3001Rmt;
@@ -126,4 +126,4 @@ class fsm_RMT_state_SendDataIdle : public fsm_RMT_state
private:
}; // fsm_RMT_state_SendData
-#endif // defined(SUPPORT_OutputProtocol_TLS3001) && defined (ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_TLS3001) && defined (SUPPORT_RMT)
diff --git a/include/output/OutputTM1814Rmt.hpp b/include/output/OutputTM1814Rmt.hpp
index 06e8ec9f9..05f50b94b 100644
--- a/include/output/OutputTM1814Rmt.hpp
+++ b/include/output/OutputTM1814Rmt.hpp
@@ -22,7 +22,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined (SUPPORT_OutputProtocol_TM1814) && defined (ARDUINO_ARCH_ESP32)
+#if defined (SUPPORT_OutputProtocol_TM1814) && defined (SUPPORT_RMT)
#include "OutputTM1814.hpp"
#include "OutputRmt.hpp"
@@ -44,7 +44,7 @@ class c_OutputTM1814Rmt : public c_OutputTM1814
void SetOutputBufferSize (uint32_t NumChannelsAvailable);
void PauseOutput(bool State);
bool ISR_GetNextBitToSend (rmt_item32_t &DataToSend);
- void StartNewDataFrame();
+ void ISR_StartNewDataFrame();
private:
@@ -86,4 +86,4 @@ class c_OutputTM1814Rmt : public c_OutputTM1814
}; // c_OutputTM1814Rmt
-#endif // defined (SUPPORT_OutputProtocol_TM1814) && defined (ARDUINO_ARCH_ESP32)
+#endif // defined (SUPPORT_OutputProtocol_TM1814) && defined (SUPPORT_RMT)
diff --git a/include/output/OutputTM1814Uart.hpp b/include/output/OutputTM1814Uart.hpp
index a1d8b2354..2dd7cecf1 100644
--- a/include/output/OutputTM1814Uart.hpp
+++ b/include/output/OutputTM1814Uart.hpp
@@ -23,7 +23,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_TM1814)
+#if defined(SUPPORT_OutputProtocol_TM1814) && defined(SUPPORT_UART)
#include "OutputTM1814.hpp"
#include "OutputUart.hpp"
@@ -40,9 +40,6 @@ class c_OutputTM1814Uart : public c_OutputTM1814
// functions to be provided by the derived class
void Begin (); ///< set up the operating environment based on the current config (or defaults)
uint32_t Poll (); ///< Call from loop(), renders output data
-#if defined(ARDUINO_ARCH_ESP32)
- bool RmtPoll () {return false;}
-#endif // defined(ARDUINO_ARCH_ESP32)
void PauseOutput (bool State);
bool SetConfig (ArduinoJson::JsonObject& jsonConfig);
void GetConfig (ArduinoJson::JsonObject& jsonConfig);
@@ -59,4 +56,4 @@ class c_OutputTM1814Uart : public c_OutputTM1814
}; // c_OutputTM1814Uart
-#endif // defined(SUPPORT_OutputProtocol_TM1814)
+#endif // defined(SUPPORT_OutputProtocol_TM1814) && defined(SUPPORT_UART)
diff --git a/include/output/OutputUCS1903Rmt.hpp b/include/output/OutputUCS1903Rmt.hpp
index d5e55cb98..a7bdcda76 100644
--- a/include/output/OutputUCS1903Rmt.hpp
+++ b/include/output/OutputUCS1903Rmt.hpp
@@ -23,7 +23,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_UCS1903) && defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_UCS1903) && defined(SUPPORT_RMT)
#include "OutputUCS1903.hpp"
#include "OutputRmt.hpp"
@@ -89,4 +89,4 @@ class c_OutputUCS1903Rmt : public c_OutputUCS1903
}; // c_OutputUCS1903Rmt
-#endif // defined(SUPPORT_OutputProtocol_UCS1903) && defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_UCS1903) && defined(SUPPORT_RMT)
diff --git a/include/output/OutputUCS1903Uart.hpp b/include/output/OutputUCS1903Uart.hpp
index 610cca321..948210c0d 100644
--- a/include/output/OutputUCS1903Uart.hpp
+++ b/include/output/OutputUCS1903Uart.hpp
@@ -22,8 +22,8 @@
*
*/
+#if defined(SUPPORT_OutputProtocol_UCS1903) && defined(SUPPORT_UART)
#include "OutputCommon.hpp"
-#if defined(SUPPORT_OutputProtocol_UCS1903)
#include "OutputUCS1903.hpp"
#include "OutputUart.hpp"
@@ -39,9 +39,6 @@ class c_OutputUCS1903Uart : public c_OutputUCS1903
// functions to be provided by the derived class
void Begin (); ///< set up the operating environment based on the current config (or defaults)
uint32_t Poll (); ///< Call from loop(), renders output data
-#if defined(ARDUINO_ARCH_ESP32)
- bool RmtPoll () {return false;}
-#endif // defined(ARDUINO_ARCH_ESP32)
void PauseOutput (bool State);
bool SetConfig (ArduinoJson::JsonObject& jsonConfig);
void GetConfig (ArduinoJson::JsonObject& jsonConfig);
@@ -55,4 +52,4 @@ class c_OutputUCS1903Uart : public c_OutputUCS1903
}; // c_OutputUCS1903Uart
-#endif // defined(SUPPORT_OutputProtocol_UCS1903)
+#endif // defined(SUPPORT_OutputProtocol_UCS1903) && defined(SUPPORT_UART)
diff --git a/include/output/OutputUCS8903Rmt.hpp b/include/output/OutputUCS8903Rmt.hpp
index 484c53498..8347ecdd8 100644
--- a/include/output/OutputUCS8903Rmt.hpp
+++ b/include/output/OutputUCS8903Rmt.hpp
@@ -23,7 +23,7 @@
*/
#include "ESPixelStick.h"
#ifdef SUPPORT_OutputProtocol_UCS8903
-#ifdef ARDUINO_ARCH_ESP32
+#ifdef SUPPORT_RMT
#include "OutputUCS8903.hpp"
#include "OutputRmt.hpp"
@@ -45,7 +45,7 @@ class c_OutputUCS8903Rmt : public c_OutputUCS8903
void SetOutputBufferSize (uint32_t NumChannelsAvailable);
void PauseOutput(bool State);
bool ISR_GetNextBitToSend (rmt_item32_t &DataToSend);
- void StartNewDataFrame();
+ void ISR_StartNewDataFrame();
private:
// The adjustments compensate for rounding errors in the calculations
@@ -86,5 +86,5 @@ class c_OutputUCS8903Rmt : public c_OutputUCS8903
}; // c_OutputUCS8903Rmt
-#endif // def ARDUINO_ARCH_ESP32
+#endif // def SUPPORT_RMT
#endif // def SUPPORT_OutputProtocol_UCS8903
diff --git a/include/output/OutputUCS8903Uart.hpp b/include/output/OutputUCS8903Uart.hpp
index f945bab70..c1bbab8af 100644
--- a/include/output/OutputUCS8903Uart.hpp
+++ b/include/output/OutputUCS8903Uart.hpp
@@ -24,7 +24,7 @@
#include "OutputCommon.hpp"
-#if defined(SUPPORT_OutputProtocol_UCS8903)
+#if defined(SUPPORT_OutputProtocol_UCS8903) && defined(SUPPORT_UART)
#include "OutputUCS8903.hpp"
#include "OutputUart.hpp"
@@ -40,9 +40,6 @@ class c_OutputUCS8903Uart : public c_OutputUCS8903
// functions to be provided by the derived class
void Begin ();
uint32_t Poll ();
-#if defined(ARDUINO_ARCH_ESP32)
- bool RmtPoll () {return false;}
-#endif // defined(ARDUINO_ARCH_ESP32)
void PauseOutput (bool State);
bool SetConfig (ArduinoJson::JsonObject& jsonConfig);
void GetConfig (ArduinoJson::JsonObject& jsonConfig);
@@ -58,4 +55,4 @@ class c_OutputUCS8903Uart : public c_OutputUCS8903
}; // c_OutputUCS8903Uart
-#endif // defined(SUPPORT_OutputProtocol_UCS8903)
+#endif // defined(SUPPORT_OutputProtocol_UCS8903) && defined(SUPPORT_UART)
diff --git a/include/output/OutputUart.hpp b/include/output/OutputUart.hpp
index f2d69db4f..10c892de2 100644
--- a/include/output/OutputUart.hpp
+++ b/include/output/OutputUart.hpp
@@ -19,8 +19,9 @@
*/
#include "ESPixelStick.h"
+#if defined(SUPPORT_UART)
-#ifdef ARDUINO_ARCH_ESP32
+#if defined(ARDUINO_ARCH_ESP32)
# include
# include
# include
@@ -117,7 +118,7 @@ class c_OutputUart
void set_pin ();
void TerminateSerialPortOperation ();
void RestoreSerialPortOperation ();
- void ReportNewFrame ();
+ void ISR_ReportNewFrame ();
void StartBreak ();
void EndBreak ();
void GenerateBreak (uint32_t DurationInUs, uint32_t MarkDurationInUs);
@@ -223,3 +224,4 @@ class c_OutputUart
#endif // defined(ARDUINO_ARCH_ESP8266)
};
+#endif // defined(SUPPORT_UART)
diff --git a/include/output/OutputWS2811.hpp b/include/output/OutputWS2811.hpp
index 1abb46898..d067fecb3 100644
--- a/include/output/OutputWS2811.hpp
+++ b/include/output/OutputWS2811.hpp
@@ -55,9 +55,9 @@ class c_OutputWS2811 : public c_OutputPixel
// #define WS2811_PIXEL_NS_BIT_1_HIGH 975.0 // = 937 on logic analyzer 580ns - 1.6us per datasheet
// #define WS2811_PIXEL_NS_BIT_1_LOW 300.0 // = 312 on logic analyzer 220ns - 380ns per datasheet
#define WS2811_PIXEL_NS_BIT_0_HIGH 300.0 // 220ns - 380ns per datasheet
- #define WS2811_PIXEL_NS_BIT_0_LOW (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_0_HIGH)
- #define WS2811_PIXEL_NS_BIT_1_HIGH WS2811_PIXEL_NS_BIT_0_LOW
- #define WS2811_PIXEL_NS_BIT_1_LOW WS2811_PIXEL_NS_BIT_0_HIGH
+ #define WS2811_PIXEL_NS_BIT_0_LOW 900.0
+ #define WS2811_PIXEL_NS_BIT_1_HIGH 700.0
+ #define WS2811_PIXEL_NS_BIT_1_LOW 600.0
#else
#define WS2811_PIXEL_NS_BIT_0_HIGH 312.0 // 220ns - 380ns per datasheet
#define WS2811_PIXEL_NS_BIT_0_LOW (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_0_HIGH)
diff --git a/include/output/OutputWS2811I2S.hpp b/include/output/OutputWS2811I2S.hpp
new file mode 100644
index 000000000..569b84e97
--- /dev/null
+++ b/include/output/OutputWS2811I2S.hpp
@@ -0,0 +1,103 @@
+#pragma once
+/*
+* OutputWS2811I2S.h - WS2811 driver code for ESPixelStick I2S Channel
+*
+* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver
+* Copyright (c) 2015, 2025 Shelby Merrick
+* http://www.forkineye.com
+*
+* This program is provided free for you to use in any way that you wish,
+* subject to the laws and regulations where you are using it. Due diligence
+* is strongly suggested before using this code. Please give credit where due.
+*
+* The Author makes no warranty of any kind, express or implied, with regard
+* to this program or the documentation contained in this document. The
+* Author shall not be liable in any event for incidental or consequential
+* damages in connection with, or arising out of, the furnishing, performance
+* or use of these programs.
+*
+* This is a derived class that converts data in the output buffer into
+* pixel intensities and then transmits them through the configured serial
+* interface.
+*
+*/
+#include "ESPixelStick.h"
+#if defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_I2S)
+
+#include "OutputWS2811.hpp"
+#include "OutputI2S.hpp"
+
+class c_OutputWS2811I2S : public c_OutputWS2811
+{
+public:
+ // These functions are inherited from c_OutputCommon
+ c_OutputWS2811I2S (OM_OutputPortDefinition_t & OutputPortDefinition,
+ c_OutputMgr::e_OutputProtocolType outputType);
+ virtual ~c_OutputWS2811I2S ();
+
+ // functions to be provided by the derived class
+ void Begin (); ///< set up the operating environment based on the current config (or defaults)
+ bool SetConfig (ArduinoJson::JsonObject& jsonConfig); ///< Set a new config in the driver
+ uint32_t Poll () {return 0;} ///< Call from loop (), renders output data
+ void GetStatus (ArduinoJson::JsonObject& jsonStatus);
+ void SetOutputBufferSize (uint32_t NumChannelsAvailable);
+ void PauseOutput(bool State);
+ void ISR_GetNextDataSlicesToSend (c_OutputI2S::I2S_Item_t * DataToSend, uint32_t numSlices);
+ void ISR_StartNewDataFrame();
+
+ // to be removed when the I2S driver is fully implemented
+ virtual bool RmtPoll() {return false;}
+
+private:
+ void CalculateFrameBitSlices ();
+
+ // The adjustments compensate for rounding errors in the calculations
+ c_OutputI2S *I2Sdriver;
+
+ uint32_t DataBitMask;
+ uint32_t DataBit;
+
+ uint32_t ZeroHighBitSliceCount;
+ uint32_t ZeroLowBitSliceCount;
+
+ uint32_t OneHighBitSliceCount;
+ uint32_t OneLowBitSliceCount;
+
+ uint32_t HighBitCurrentSliceCount;
+ uint32_t LowBitCurrentSliceCount;
+
+ uint32_t FrameResetSliceCount;
+ uint32_t FrameResetCurrentSliceCount;
+
+ uint32_t IdleSliceCount;
+ uint32_t IdleCurrentSliceCount;
+
+ uint32_t DataPattern;
+ uint32_t DataPatternMask;
+
+ #define WS2811_I2S_DEBUG_COUNTERS
+ #ifdef WS2811_I2S_DEBUG_COUNTERS
+ #define INC_WS2811_I2S_DEBUG_COUNTERS(c) (++I2SDebugCounters.c)
+ struct
+ {
+ uint32_t GetDataSlices;
+ uint32_t FrameStarts;
+ uint32_t FrameEnds;
+ uint32_t IdleBitSlices;
+ uint32_t FrameResetBitSlices;
+ uint32_t DataBitSlices;
+ uint32_t DataBytes;
+ uint32_t BitSliceHigh;
+ uint32_t BitSliceLow;
+ uint32_t NextDataBit;
+ uint32_t DataBits;
+ uint32_t DataBitEnd;
+ uint32_t DataByteEnd;
+ } I2SDebugCounters;
+ #else
+ #define INC_WS2811_I2S_DEBUG_COUNTERS(c)
+ #endif // def WS2811_I2S_DEBUG_COUNTERS
+
+}; // c_OutputWS2811I2S
+
+#endif // defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_I2S)
diff --git a/include/output/OutputWS2811Rmt.hpp b/include/output/OutputWS2811Rmt.hpp
index ee73bb67a..ce85c2a95 100644
--- a/include/output/OutputWS2811Rmt.hpp
+++ b/include/output/OutputWS2811Rmt.hpp
@@ -22,7 +22,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_WS2811) && defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_RMT)
#include "OutputWS2811.hpp"
#include "OutputRmt.hpp"
@@ -88,4 +88,4 @@ class c_OutputWS2811Rmt : public c_OutputWS2811
}; // c_OutputWS2811Rmt
-#endif // defined(SUPPORT_OutputProtocol_WS2811) && defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_RMT)
diff --git a/include/output/OutputWS2811Uart.hpp b/include/output/OutputWS2811Uart.hpp
index c87158a58..9c6562f41 100644
--- a/include/output/OutputWS2811Uart.hpp
+++ b/include/output/OutputWS2811Uart.hpp
@@ -23,7 +23,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_WS2811)
+#if defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_UART)
#include "OutputWS2811.hpp"
#include "OutputUart.hpp"
@@ -39,9 +39,6 @@ class c_OutputWS2811Uart : public c_OutputWS2811
// functions to be provided by the derived class
void Begin (); ///< set up the operating environment based on the current config (or defaults)
uint32_t Poll ();
-#if defined(ARDUINO_ARCH_ESP32)
- bool RmtPoll () {return false;}
-#endif // defined(ARDUINO_ARCH_ESP32)
void PauseOutput (bool State);
bool SetConfig (ArduinoJson::JsonObject& jsonConfig);
void GetConfig (ArduinoJson::JsonObject& jsonConfig);
@@ -59,4 +56,4 @@ class c_OutputWS2811Uart : public c_OutputWS2811
}; // c_OutputWS2811Uart
-#endif // defined(SUPPORT_OutputProtocol_WS2811)
+#endif // defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_UART)
diff --git a/include/platforms/GPIO_Defs_ESP32_QUINLED_Dig-Octa.hpp b/include/platforms/GPIO_Defs_ESP32_QUINLED_Dig-Octa.hpp
index d503abe7c..71cb6872d 100644
--- a/include/platforms/GPIO_Defs_ESP32_QUINLED_Dig-Octa.hpp
+++ b/include/platforms/GPIO_Defs_ESP32_QUINLED_Dig-Octa.hpp
@@ -77,11 +77,11 @@ const OM_OutputPortDefinition_t OM_OutputPortDefinitions[] =
// Output Types
#define SUPPORT_OutputProtocol_TLS3001 // OM_SERIAL
#define SUPPORT_OutputProtocol_APA102 // OM_SPI
-// #define SUPPORT_OutputProtocol_DMX // OM_SERIAL
+#define SUPPORT_OutputProtocol_DMX // OM_SERIAL
#define SUPPORT_OutputProtocol_GECE // OM_SERIAL
#define SUPPORT_OutputProtocol_GS8208 // OM_SERIAL
-// #define SUPPORT_OutputProtocol_Renard // OM_SERIAL
-// #define SUPPORT_OutputProtocol_Serial // OM_SERIAL
+#define SUPPORT_OutputProtocol_Renard // OM_SERIAL
+#define SUPPORT_OutputProtocol_Serial // OM_SERIAL
#define SUPPORT_OutputProtocol_TM1814 // OM_SERIAL
#define SUPPORT_OutputProtocol_UCS1903 // OM_SERIAL
#define SUPPORT_OutputProtocol_UCS8903 // OM_SERIAL
@@ -89,5 +89,5 @@ const OM_OutputPortDefinition_t OM_OutputPortDefinitions[] =
#define SUPPORT_OutputProtocol_WS2811 // OM_SERIAL
#define SUPPORT_OutputProtocol_Relay // OM_RELAY
#define SUPPORT_OutputProtocol_Servo_PCA9685 // OM_I2C
-// #define SUPPORT_OutputProtocol_FireGod // OM_SERIAL
-// #define SUPPORT_OutputProtocol_GRINCH // OM_SPI
+#define SUPPORT_OutputProtocol_FireGod // OM_SERIAL
+#define SUPPORT_OutputProtocol_GRINCH // OM_SPI
diff --git a/platformio.ini b/platformio.ini
index 5c082a1fc..90a51897a 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -4,7 +4,7 @@
; Local configuration should be done in platformio_user.ini
[platformio]
-default_envs = esp32_idftest, esp8266_espsv3, esp8266_wemos_d1_mini, esp8266_wemos_d1_mini_pro, esp8266_esp01s, esp32_lolin_d1_pro, esp32_lolin_d1_pro_eth, esp32_cam, esp32_ttgo_t8, esp32_bong69, esp32_wt32eth01, esp32_quinled_quad, esp32_quinled_quad_p5, esp32_quinled_quad_ae_plus, esp32_quinled_quad_ae_plus_8, esp32_quinled_quad_eth, esp32_quinled_quad_eth_p5, esp32_quinled_uno, esp32_quinled_uno_ae_plus, esp32_quinled_uno_eth, esp32_quinled_dig_octa, esp32_d1_mini_mhetesp32minikit, esp32_olimex_gw, esp32_d1_mini_twilightlord, esp32_d1_mini_twilightlord_eth, esp32_devkitc, esp32_devkitc6, esp32_quinled_uno_eth_espsv3, esp32_quinled_uno_espsv3, esp32_m5stack_atom, esp32_deuxquatro_dmx, esp32_wasatch, esp32_tetra2go, esp32_tetra2go_eth, esp32_octa2go, esp32_octa2go_eth, esp32_solo2go, esp32_solo2go_eth, esp32_kr_lights_msm, esp32_ka, esp32_ka_4, esp32_breakdancev2, esp32_foo, esp32s3_seeed_xiao, esp32_wemos_d1_mini32, esp32_wemos_d1_mini32_eth, esp32s3_devkitc, esp32s3_devkitc_Internal_SD, esp32_devkitv_eth, esp32s3_fh4r2, esp32_relayboardx8
+default_envs = esp8266_espsv3, esp8266_wemos_d1_mini, esp8266_wemos_d1_mini_pro, esp8266_esp01s, esp32_lolin_d1_pro, esp32_lolin_d1_pro_eth, esp32_cam, esp32_ttgo_t8, esp32_bong69, esp32_wt32eth01, esp32_quinled_quad, esp32_quinled_quad_p5, esp32_quinled_quad_ae_plus, esp32_quinled_quad_ae_plus_8, esp32_quinled_quad_eth, esp32_quinled_quad_eth_p5, esp32_quinled_uno, esp32_quinled_uno_ae_plus, esp32_quinled_uno_eth, esp32_quinled_dig_octa, esp32_d1_mini_mhetesp32minikit, esp32_olimex_gw, esp32_d1_mini_twilightlord, esp32_d1_mini_twilightlord_eth, esp32_devkitc, esp32_devkitc6, esp32_quinled_uno_eth_espsv3, esp32_quinled_uno_espsv3, esp32_m5stack_atom, esp32_deuxquatro_dmx, esp32_wasatch, esp32_tetra2go, esp32_tetra2go_eth, esp32_octa2go, esp32_octa2go_eth, esp32_solo2go, esp32_solo2go_eth, esp32_kr_lights_msm, esp32_ka, esp32_ka_4, esp32_breakdancev2, esp32_foo, esp32s3_seeed_xiao, esp32_wemos_d1_mini32, esp32_wemos_d1_mini32_eth, esp32s3_devkitc, esp32s3_devkitc_Internal_SD, esp32_devkitv_eth, esp32s3_fh4r2, esp32_relayboardx8
;default_envs = esp32_idftest
src_dir = ./src
@@ -102,6 +102,11 @@ build_flags =
-D VTABLES_IN_FLASH
-D DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266=2
-D DEFAULT_STORAGE_TYPE_ESP8266=2
+ ;----------------------
+ ; Only one of these can be enabled at a time
+ -D SUPPORT_UART=1
+ ;-D SUPPORT_I2S=1
+
lib_ignore =
Ethernet ; Remove once Art-Net is fixed / replaced to not depend on Ethernet in lib config
; ESPAsyncTCP
@@ -137,6 +142,18 @@ build_flags =
-D CONFIG_RMT_ISR_IRAM_SAFE=yes
; -D USE_RMT_DEBUG_COUNTERS=1
; -D DEBUG_RMT_XLAT_ISSUES=1
+ ;----------------------
+ ; Only one of these can be enabled at a time
+ ; -D SUPPORT_UART=1
+ ; -D SUPPORT_I2S=1
+ -D SUPPORT_RMT=1
+ -D PIN_I2S_SD_IN=-1
+ -D PIN_I2S_SD_OUT=-1
+ -D PIN_I2S_SD=-1
+ -D PIN_I2S_FS=-1
+ -D PIN_I2S_SCK=-1
+ ;----------------------
+ -I ./include/service
build_unflags =
${env.build_unflags}
@@ -151,6 +168,7 @@ lib_deps =
mathieucarbou/OneWire @ ^2.3.9
https://github.com/MartinMueller2003/DS18B20
https://github.com/bitbank2/unzipLIB
+ ; https://github.com/MartinMueller2003/esp_i2s_parallel
lib_ignore =
${env.lib_ignore}
@@ -185,6 +203,12 @@ build_flags =
-D CONFIG_RMT_ENCODER_FUNC_IN_IRAM=1
; -D USE_RMT_DEBUG_COUNTERS=1
; -D DEBUG_RMT_XLAT_ISSUES=1
+ ;----------------------
+ ; Only one of these can be enabled at a time
+ ; -D SUPPORT_UART=1
+ ; -D SUPPORT_I2S=1
+ -D SUPPORT_RMT=1
+ ;----------------------
build_unflags =
${env.build_unflags}
diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp
index 06da79939..531b54b61 100644
--- a/src/FileMgr.cpp
+++ b/src/FileMgr.cpp
@@ -1625,7 +1625,7 @@ void c_FileMgr::CloseSdFile (FileId& FileHandle)
if (nullptr != FileList[FileListIndex].buffer.DataBuffer)
{
- if(FileList[FileListIndex].buffer.DataBuffer != OutputMgr.GetBufferAddress())
+ if(FileList[FileListIndex].buffer.DataBuffer != OutputMgr.ISR_GetBufferAddress())
{
// only free the buffer if it is not malloc'd
free(FileList[FileListIndex].buffer.DataBuffer);
@@ -2368,7 +2368,7 @@ void c_FileMgr::handleFileUploadNewFile (const String & filename)
// DEBUG_V("Use the output buffer as a data buffer");
FileList[FileListIndex].buffer.offset = 0;
FileList[FileListIndex].buffer.size = min(uint32_t(OutputMgr.GetBufferSize() & ~(SD_BLOCK_SIZE - 1)), uint32_t(MAX_SD_BUFFER_SIZE));
- FileList[FileListIndex].buffer.DataBuffer = OutputMgr.GetBufferAddress();
+ FileList[FileListIndex].buffer.DataBuffer = OutputMgr.ISR_GetBufferAddress();
OutputMgr.PauseOutputs(true);
InputMgr.SetOperationalState(false);
OutputMgr.ClearBuffer();
diff --git a/src/UnzipFiles.cpp b/src/UnzipFiles.cpp
index 8f288921a..c8bda5034 100644
--- a/src/UnzipFiles.cpp
+++ b/src/UnzipFiles.cpp
@@ -117,6 +117,8 @@ void UnzipFiles::ProcessZipFile(String & ArchiveFileName)
if (returnCode == UNZ_OK)
{
bool IsSpecialxLightsZipFile = (-1 != ArchiveFileName.indexOf(".xlz"));
+ // DEBUG_V(String("IsSpecialxLightsZipFile: ") + String(IsSpecialxLightsZipFile));
+
// logcon(String("Opened zip file: '") + FileName + "'");
// Display the global comment and all of the FileNames within
@@ -140,15 +142,19 @@ void UnzipFiles::ProcessZipFile(String & ArchiveFileName)
// DEBUG_V("Modifying File Name");
String Temp = ArchiveFileName;
Temp.replace(".xlz", ".fseq");
- // DEBUG_V(String(" Temp: ") + Temp);
+ // DEBUG_V(String(" Temp: ") + Temp);
if(FinalFileName.equals(Temp))
{
IsSpecialxLightsZipFile = false;
}
+ else
+ {
+ FinalFileName = Temp;
+ }
}
// DEBUG_V(String("IsSpecialxLightsZipFile: ") + String(IsSpecialxLightsZipFile));
- // DEBUG_V(String("ArchiveSubFileName: ") + ArchiveSubFileName);
- // DEBUG_V(String(" FinalFileName: ") + FinalFileName);
+ // DEBUG_V(String(" ArchiveSubFileName: ") + ArchiveSubFileName);
+ // DEBUG_V(String(" FinalFileName: ") + FinalFileName);
c_FileMgr::SdInfo info;
FileMgr.GetSdInfo(info);
diff --git a/src/WebMgr.cpp b/src/WebMgr.cpp
index be0347db8..ae99c1fae 100644
--- a/src/WebMgr.cpp
+++ b/src/WebMgr.cpp
@@ -319,7 +319,7 @@ void c_WebMgr::init ()
// DEBUG_V(String("NumBytesAvailableToSend: ") + String(NumBytesAvailableToSend));
if(0 != NumBytesAvailableToSend)
{
- memcpy(buffer, OutputMgr.GetBufferAddress () + index, NumBytesAvailableToSend);
+ memcpy(buffer, OutputMgr.ISR_GetBufferAddress () + index, NumBytesAvailableToSend);
}
return NumBytesAvailableToSend;
});
diff --git a/src/output/OutputAPA102Spi.cpp b/src/output/OutputAPA102Spi.cpp
index 8b93db44e..db9693f6e 100644
--- a/src/output/OutputAPA102Spi.cpp
+++ b/src/output/OutputAPA102Spi.cpp
@@ -97,7 +97,7 @@ uint32_t c_OutputAPA102Spi::Poll ()
{
if (Spi.Poll ())
{
- ReportNewFrame ();
+ ISR_ReportNewFrame ();
}
}
else
diff --git a/src/output/OutputCommon.cpp b/src/output/OutputCommon.cpp
index 21d0369af..58ab0de2d 100644
--- a/src/output/OutputCommon.cpp
+++ b/src/output/OutputCommon.cpp
@@ -32,8 +32,10 @@ c_OutputCommon::c_OutputCommon (OM_OutputPortDefinition_t & _OutputPortDefinitio
HasBeenInitialized = false;
OutputPortDefinition = _OutputPortDefinition;
OutputType = outputProtocol;
- pOutputBuffer = OutputMgr.GetBufferAddress ();
+ pOutputBuffer = OutputMgr.ISR_GetBufferAddress ();
+ #ifndef SUPPORT_I2S
FrameStartTimeInMicroSec = 0;
+ #endif // ndef SUPPORT_I2S
// logcon (String ("UartId: '") + UartId + "'");
// logcon (String ("OutputPortId: '") + OutputPortId + "'");
@@ -63,16 +65,18 @@ void c_OutputCommon::BaseGetStatus (JsonObject & jsonStatus)
} // GetStatus
//----------------------------------------------------------------------------
-void c_OutputCommon::ReportNewFrame ()
+void IRAM_ATTR c_OutputCommon::ISR_ReportNewFrame ()
{
// DEBUG_START;
+ #ifndef SUPPORT_I2S
FrameStartTimeInMicroSec = micros ();
+ #endif // ndef SUPPORT_I2S
FrameCount++;
// DEBUG_END;
-} // ReportNewFrame
+} // ISR_ReportNewFrame
//----------------------------------------------------------------------------
bool c_OutputCommon::SetConfig (JsonObject & jsonConfig)
@@ -111,9 +115,9 @@ void c_OutputCommon::WriteChannelData (uint32_t StartChannelId, uint32_t Channel
if((StartChannelId + ChannelCount) > OutputBufferSize)
{
- DEBUG_V("ERROR: Writting beyond the end of the output buffer");
- DEBUG_V(String("StartChannelId: 0x") + String(StartChannelId, HEX));
- DEBUG_V(String(" ChannelCount: 0x") + String(ChannelCount));
+ // DEBUG_V("ERROR: Writting beyond the end of the output buffer");
+ // DEBUG_V(String("StartChannelId: 0x") + String(StartChannelId, HEX));
+ // DEBUG_V(String(" ChannelCount: 0x") + String(ChannelCount));
}
else
{
diff --git a/src/output/OutputGECERmt.cpp b/src/output/OutputGECERmt.cpp
index 1362afa9e..6cecee4c2 100644
--- a/src/output/OutputGECERmt.cpp
+++ b/src/output/OutputGECERmt.cpp
@@ -17,7 +17,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_GECE) && defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_GECE) && defined(SUPPORT_RMT)
#include "output/OutputGECERmt.hpp"
@@ -30,7 +30,7 @@ static bool IRAM_ATTR ISR_GetNextBitToSendBase (void * arg, rmt_item32_t & DataT
//----------------------------------------------------------------------------
static void StartNewDataFrameBase(void * arg)
{
- return reinterpret_cast(arg)->StartNewDataFrame();
+ return reinterpret_cast(arg)->ISR_StartNewDataFrame();
}
//----------------------------------------------------------------------------
@@ -87,7 +87,7 @@ bool c_OutputGECERmt::SetConfig (ArduinoJson::JsonObject& jsonConfig)
OutputRmtConfig.arg = this;
OutputRmtConfig.ISR_GetNextIntensityBit = ISR_GetNextBitToSendBase;
OutputRmtConfig.StartNewDataFrame = StartNewDataFrameBase;
- OutputRmtConfig.BufferStart = GetBufferAddress();
+ OutputRmtConfig.BufferStart = ISR_GetBufferAddress();
OutputRmtConfig.NumBytesInFrame = OM_MAX_NUM_CHANNELS;
Rmt.Begin(OutputRmtConfig, this);
@@ -170,13 +170,13 @@ bool c_OutputGECERmt::RmtPoll ()
} // Poll
//----------------------------------------------------------------------------
-void c_OutputGECERmt::StartNewDataFrame()
+void IRAM_ATTR c_OutputGECERmt::ISR_StartNewDataFrame()
{
// DEBUG_START;
// DEBUG_V(String("frame started on ") + String(OutputPortDefinition.gpios.data));
INC_GECE_RMT_DEBUG_COUNTERS(FrameStarts);
StartBitCount = 1;
- StartNewFrame();
+ ISR_StartNewFrame();
// DEBUG_END;
} // StartNewDataFrame
@@ -240,4 +240,4 @@ void c_OutputGECERmt::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_GECE) && defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_GECE) && defined(SUPPORT_RMT)
diff --git a/src/output/OutputGECEUart.cpp b/src/output/OutputGECEUart.cpp
index 9bf71eb24..29f76111a 100644
--- a/src/output/OutputGECEUart.cpp
+++ b/src/output/OutputGECEUart.cpp
@@ -18,7 +18,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_GECE)
+#if defined(SUPPORT_OutputProtocol_GECE) && defined(SUPPORT_UART)
#include "output/OutputGECEUart.hpp"
@@ -185,4 +185,4 @@ void c_OutputGECEUart::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_GECE)
+#endif // defined(SUPPORT_OutputProtocol_GECE) && defined(SUPPORT_UART)
diff --git a/src/output/OutputGS8208Rmt.cpp b/src/output/OutputGS8208Rmt.cpp
index 67e48fb2b..18079a79b 100644
--- a/src/output/OutputGS8208Rmt.cpp
+++ b/src/output/OutputGS8208Rmt.cpp
@@ -18,7 +18,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_GS8208) && defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_GS8208) && defined(SUPPORT_RMT)
#include "output/OutputGS8208Rmt.hpp"
@@ -31,7 +31,7 @@ static bool IRAM_ATTR ISR_GetNextBitToSendBase (void * arg, rmt_item32_t & DataT
//----------------------------------------------------------------------------
static void StartNewDataFrameBase(void * arg)
{
- return reinterpret_cast(arg)->StartNewDataFrame();
+ return reinterpret_cast(arg)->ISR_StartNewDataFrame();
}
//----------------------------------------------------------------------------
@@ -96,7 +96,7 @@ bool c_OutputGS8208Rmt::SetConfig (ArduinoJson::JsonObject& jsonConfig)
OutputRmtConfig.arg = this;
OutputRmtConfig.ISR_GetNextIntensityBit = ISR_GetNextBitToSendBase;
OutputRmtConfig.StartNewDataFrame = StartNewDataFrameBase;
- OutputRmtConfig.BufferStart = GetBufferAddress();
+ OutputRmtConfig.BufferStart = ISR_GetBufferAddress();
OutputRmtConfig.NumBytesInFrame = OM_MAX_NUM_CHANNELS;
Rmt.Begin(OutputRmtConfig, this);
@@ -179,13 +179,13 @@ bool c_OutputGS8208Rmt::RmtPoll ()
} // Poll
//----------------------------------------------------------------------------
-void c_OutputGS8208Rmt::StartNewDataFrame()
+void IRAM_ATTR c_OutputGS8208Rmt::ISR_StartNewDataFrame()
{
// DEBUG_START;
// DEBUG_V(String("frame started on ") + String(OutputPortDefinition.gpios.data));
INC_GS8208_RMT_DEBUG_COUNTERS(FrameStarts);
ifgBitCurrentCount = ifgBitCount;
- StartNewFrame();
+ ISR_StartNewFrame();
// DEBUG_END;
} // StartNewDataFrame
@@ -245,4 +245,4 @@ void c_OutputGS8208Rmt::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_GS8208) && defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_GS8208) && defined(SUPPORT_RMT)
diff --git a/src/output/OutputGS8208Uart.cpp b/src/output/OutputGS8208Uart.cpp
index e0557d79d..d0ad33e92 100644
--- a/src/output/OutputGS8208Uart.cpp
+++ b/src/output/OutputGS8208Uart.cpp
@@ -19,7 +19,7 @@
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_GS8208)
+#if defined(SUPPORT_OutputProtocol_GS8208) && defined(SUPPORT_UART)
#include "output/OutputGS8208Uart.hpp"
@@ -186,4 +186,4 @@ void c_OutputGS8208Uart::PauseOutput(bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_GS8208)
+#endif // defined(SUPPORT_OutputProtocol_GS8208) && defined(SUPPORT_UART)
diff --git a/src/output/OutputGrinch.cpp b/src/output/OutputGrinch.cpp
index f71c5d94c..3b67c4c5d 100644
--- a/src/output/OutputGrinch.cpp
+++ b/src/output/OutputGrinch.cpp
@@ -129,7 +129,7 @@ void c_OutputGrinch::StartNewFrame()
// build the data frame
uint32_t NumChannelsToProcess = GetNumOutputBufferBytesNeeded();
- uint8_t * pInputData = GetBufferAddress();
+ uint8_t * pInputData = ISR_GetBufferAddress();
uint8_t OutputData = 0;
uint8_t OutputDataByteIndex = 0;
uint8_t bitCounter = 0;
@@ -156,7 +156,7 @@ void c_OutputGrinch::StartNewFrame()
}
SpiOutputDataByteIndex = NumberOfGrinchDataBytes;
- ReportNewFrame();
+ ISR_ReportNewFrame();
// DEBUG_END;
} // StartNewFrame
diff --git a/src/output/OutputGrinchSpi.cpp b/src/output/OutputGrinchSpi.cpp
index 3ba25524f..4d005d094 100644
--- a/src/output/OutputGrinchSpi.cpp
+++ b/src/output/OutputGrinchSpi.cpp
@@ -93,7 +93,7 @@ uint32_t c_OutputGrinchSpi::Poll ()
{
if (Spi.Poll ())
{
- ReportNewFrame ();
+ ISR_ReportNewFrame ();
}
}
else
diff --git a/src/output/OutputI2S.cpp b/src/output/OutputI2S.cpp
new file mode 100644
index 000000000..7d489bcfd
--- /dev/null
+++ b/src/output/OutputI2S.cpp
@@ -0,0 +1,315 @@
+/*
+* OutputI2S.cpp - driver code for ESPixelStick I2S Channel
+*
+* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver
+* Copyright (c) 2026, 2026 Shelby Merrick
+* http://www.forkineye.com
+*
+* This program is provided free for you to use in any way that you wish,
+* subject to the laws and regulations where you are using it. Due diligence
+* is strongly suggested before using this code. Please give credit where due.
+*
+* The Author makes no warranty of any kind, express or implied, with regard
+* to this program or the documentation contained in this document. The
+* Author shall not be liable in any event for incidental or consequential
+* damages in connection with, or arising out of, the furnishing, performance
+* or use of these programs.
+*
+*/
+#include "ESPixelStick.h"
+#if defined (SUPPORT_I2S)
+
+#include "output/OutputI2S.hpp"
+#include "driver/gpio.h"
+#include "esp_rom_gpio.h"
+#include
+#include "esp_attr.h"
+
+//----------------------------------------------------------------------------
+// array of transmit buffers that get chained into a ring
+static c_OutputI2S::TransmitDmaBuffer_t TransmitDmaBuffers[I2S_NumSendBuffers] DRAM_ATTR __attribute__ ( (aligned (4)));
+
+//----------------------------------------------------------------------------
+static void IRAM_ATTR IRQ_Handler (void * arg, void * buffer)
+{
+ static_cast (arg)->ISR_Handler (buffer);
+} // IRQ_Handler
+
+//----------------------------------------------------------------------------
+void IRAM_ATTR c_OutputI2S::ISR_Handler (void * _TransmitDmaBuffer)
+{
+ I2S_DEBUG_INC_COUNTER (ISR_handler_count);
+
+ TransmitDmaBuffer_t * TransmitDmaBuffer = (TransmitDmaBuffer_t*)_TransmitDmaBuffer;
+
+ #ifdef USE_I2S_DEBUG_COUNTERS
+ // show we have used the buffer
+ TransmitDmaBuffer->UsageCounter++;
+
+ if (TransmitDmaBuffer->header.owner == I2sParallelDmaBufferOwnerDMA)
+ {
+ I2S_DEBUG_INC_COUNTER (BufferOwnerFlagError);
+ }
+ #endif // def USE_I2S_DEBUG_COUNTERS
+
+ I2S_DEBUG_INC_COUNTER (ISR_FillBuffer);
+
+ // reset the buffer management fields
+ TransmitDmaBuffer->header.length = TransmitDmaBuffer->header.size;
+ TransmitDmaBuffer->header.offset = 0; // Always start to the begining of the buffer
+
+ // fill in the new data
+ for (auto & CurrentPort : OutputI2SSlotConfigs)
+ {
+ if (CurrentPort.IsActive)
+ {
+ CurrentPort.GetNextIntensityBitSlices (CurrentPort.arg, (I2S_Item_t *) (TransmitDmaBuffer->header.buf), TransmitDmaBuffer->header.size);
+ }
+ }
+
+ // hand the buffer back to the dma engine
+ TransmitDmaBuffer->header.eof = true; // cause an end of buffer interrupt
+ TransmitDmaBuffer->header.owner = I2sParallelDmaBufferOwnerDMA;
+
+} // ISR_Handler
+
+//----------------------------------------------------------------------------
+c_OutputI2S::c_OutputI2S ()
+{
+ // DEBUG_START;
+
+ int id = 0;
+ for (auto & CurrentChannel : OutputI2SSlotConfigs)
+ {
+ CurrentChannel.I2SChannelId = id++;
+ CurrentChannel.DataPin = gpio_num_t (I2S_PIN_NO_CHANGE);
+ CurrentChannel.arg = nullptr;
+ CurrentChannel.GetNextIntensityBitSlices = nullptr;
+ CurrentChannel.IsActive = false;
+ }
+
+ uint BufferId = 0;
+ for (auto &CurrentDmaBuffer : TransmitDmaBuffers)
+ {
+ #ifdef USE_I2S_DEBUG_COUNTERS
+ CurrentDmaBuffer.id = BufferId;
+ CurrentDmaBuffer.UsageCounter = 0;
+ #endif // def USE_I2S_DEBUG_COUNTERS
+ CurrentDmaBuffer.header.size = sizeof (CurrentDmaBuffer.data);
+ CurrentDmaBuffer.header.length = sizeof (CurrentDmaBuffer.data);
+ CurrentDmaBuffer.header.offset = 0; // Always start to the begining of the buffer
+ CurrentDmaBuffer.header.sosf = false;
+ CurrentDmaBuffer.header.eof = true; // cause an end of buffer interrupt
+ CurrentDmaBuffer.header.buf = (uint8_t*)&CurrentDmaBuffer.data[0];
+ CurrentDmaBuffer.header.qe.stqe_next = & (TransmitDmaBuffers[BufferId + 1].header);
+ CurrentDmaBuffer.header.owner = I2sParallelDmaBufferOwnerDMA;
+
+ // clear the data space
+ memset (CurrentDmaBuffer.data, 0xff, CurrentDmaBuffer.header.size);
+
+ // next buffer ID
+ ++BufferId;
+ }
+
+ // link last buffer to the first buffer
+ TransmitDmaBuffers[I2S_NumSendBuffers-1].header.qe.stqe_next = & (TransmitDmaBuffers[0].header);
+
+ // DEBUG_END;
+} // c_OutputI2S
+
+//----------------------------------------------------------------------------
+c_OutputI2S::~c_OutputI2S ()
+{
+ // DEBUG_START;
+
+ // DEBUG_END;
+} // ~c_OutputI2S
+
+//----------------------------------------------------------------------------
+void c_OutputI2S::Begin ()
+{
+ // DEBUG_START;
+
+ do // once
+ {
+ // 1. Configure the core I2S settings
+ i2s_parallel_config_t i2s_config;
+ i2s_config.port = i2s_port_t::I2S_NUM_1;
+ i2s_config.gpio_clk = I2S_PIN_NO_CHANGE;
+ i2s_config.sample_width = i2s_parallel_sample_width_t::I2S_PARALLEL_WIDTH_8;
+ i2s_config.sample_rate = 800000 * 4; // 800khz divided into 4 time slices
+ i2s_config.invert_clk = false;
+ i2s_config.irq_hndlr = IRQ_Handler;
+ i2s_config.arg1 = this;
+ memset (i2s_config.gpios_bus, I2S_PIN_NO_CHANGE, sizeof (i2s_config.gpios_bus));
+
+ // DEBUG_V (String ("Install driver onto I2S Port ") + String (I2S_DeviceID));
+ if (ESP_OK != i2sParallel.driver_install (i2s_config))
+ {
+ String FailReason = (F ("Failed to install I2S driver"));
+ RequestReboot (FailReason, 10000, true);
+ break;
+ }
+ // DEBUG_V ();
+
+ // start the outputs
+ if (ESP_OK != i2sParallel.send_dma (& (TransmitDmaBuffers[0].header)))
+ {
+ logcon (F ("Could not start the I2S DMA channel"));
+ }
+
+ // DEBUG_V ();
+
+ } while (false);
+
+ // DEBUG_END;
+
+} // Begin
+
+//----------------------------------------------------------------------------
+void c_OutputI2S::GetStatus (ArduinoJson::JsonObject& jsonStatus)
+{
+ // // DEBUG_START;
+
+ #ifdef USE_I2S_DEBUG_COUNTERS
+ JsonObject debugStatus = jsonStatus["I2S Debug"].to ();
+
+ debugStatus["ISR_handler_count"] = I2S_DEBUG_COUNTER (ISR_handler_count);
+ debugStatus["ISR_NullBufferPointer"] = String (I2S_DEBUG_COUNTER (ISR_NullBufferPointer));
+ debugStatus["BufferOwnerFlagError"] = I2S_DEBUG_COUNTER (BufferOwnerFlagError);
+ debugStatus["ISR_FillBuffer"] = I2S_DEBUG_COUNTER (ISR_FillBuffer);
+ debugStatus["IntensityBitsSent"] = I2S_DEBUG_COUNTER (IntensityBitsSent);
+ debugStatus["I2SEntriesTransfered"] = I2S_DEBUG_COUNTER (I2SEntriesTransfered);
+ debugStatus["I2SXmtFills"] = I2S_DEBUG_COUNTER (I2SXmtFills);
+ #endif // def USE_I2S_DEBUG_COUNTERS
+ // // DEBUG_END;
+} // GetStatus
+
+//----------------------------------------------------------------------------
+void c_OutputI2S::RegisterSlotDevice (OutputI2SChannelConfig_t config, uint32_t * DataBit, uint32_t * DataBitMask)
+{
+ // DEBUG_START;
+
+ do // once
+ {
+ if (config.I2SChannelId >= I2S_MAX_NUM_PORTS)
+ {
+ logcon (F ("Invalid I2S channel ID"));
+ break;
+ }
+ if (nullptr == config.GetNextIntensityBitSlices)
+ {
+ logcon (F ("Invalid GetNextIntensityBit function pointer"));
+ break;
+ }
+
+ auto & currentConfig = OutputI2SSlotConfigs[config.I2SChannelId];
+ currentConfig.arg = config.arg;
+ currentConfig.GetNextIntensityBitSlices = config.GetNextIntensityBitSlices;
+
+ *DataBit = 1 << config.I2SChannelId;
+ *DataBitMask = ~(1 << config.I2SChannelId);
+ // DEBUG_V (String ("DataBit: 0x") + String (*DataBit, HEX));
+ SetGpio (config.I2SChannelId, config.DataPin);
+ } while (false);
+
+ // DEBUG_END;
+} // RegisterSlotDevice
+
+//----------------------------------------------------------------------------
+void c_OutputI2S::RemoveSlotDevice (uint32_t I2SChannelId)
+{
+ // DEBUG_START;
+
+ do // once
+ {
+ if (I2SChannelId >= I2S_MAX_NUM_PORTS)
+ {
+ logcon (F ("Invalid I2S channel ID"));
+ break;
+ }
+ auto & currentConfig = OutputI2SSlotConfigs[I2SChannelId];
+
+ // must be first
+ currentConfig.IsActive = false;
+ currentConfig.arg = nullptr;
+ currentConfig.GetNextIntensityBitSlices = nullptr;
+
+ SetGpio (I2SChannelId, gpio_num_t (I2S_PIN_NO_CHANGE));
+
+ } while (false);
+
+ // DEBUG_END;
+} // RemoveSlotDevice
+
+//----------------------------------------------------------------------------
+void c_OutputI2S::SetGpio (uint32_t I2SChannelId, gpio_num_t NewGpio)
+{
+ // DEBUG_START;
+
+ do // once
+ {
+ if (I2SChannelId >= I2S_MAX_NUM_PORTS)
+ {
+ logcon (F ("ERROR: Invalid I2S channel ID"));
+ break;
+ }
+
+ // DEBUG_V (String ("I2SChannelId: ") + String (I2SChannelId));
+ // DEBUG_V (String (" NewGpio: ") + String (NewGpio));
+ // DEBUG_V (String (" DataPin: ") + String (OutputI2SSlotConfigs[I2SChannelId].DataPin));
+
+ if (NewGpio == OutputI2SSlotConfigs[I2SChannelId].DataPin)
+ {
+ // DEBUG_V ("GPIO did not change. Ignore the request");
+ break;
+ }
+
+ if (I2S_PIN_NO_CHANGE != OutputI2SSlotConfigs[I2SChannelId].DataPin)
+ {
+ // DEBUG_V ("release the old GPIO from the matrix");
+ ResetGpio (OutputI2SSlotConfigs[I2SChannelId].DataPin);
+ }
+
+ // DEBUG_V ("attach the new GPIO");
+ OutputI2SSlotConfigs[I2SChannelId].DataPin = NewGpio;
+ i2sParallel.iomux_set_signal (NewGpio, I2S1O_DATA_OUT0_IDX + I2SChannelId);
+
+ } while (false);
+
+ // DEBUG_END;
+} // SetGpio
+
+//----------------------------------------------------------------------------
+void c_OutputI2S::SetOutputState (uint32_t I2SChannelId, bool NewState)
+{
+ // DEBUG_START;
+
+ // DEBUG_V (String ("I2SChannelId: ") + String (I2SChannelId));
+ // DEBUG_V (String (" NewState: ") + String (NewState));
+ OutputI2SSlotConfigs[I2SChannelId].IsActive = NewState;
+
+ // DEBUG_END;
+} // SetOutputState
+
+//----------------------------------------------------------------------------
+uint32_t c_OutputI2S::GetNumTimeSlicesForTargetTimeNS (uint32_t TargetTimeInNanoSec)
+{
+ // DEBUG_START;
+
+ uint32_t Result = 0;
+ double I2S_TickTimeInNS = i2sParallel.get_clockNS ();
+
+ // round up
+ Result = ( (TargetTimeInNanoSec + int (I2S_TickTimeInNS)) - 1) / int (I2S_TickTimeInNS);
+ if (0 == Result) Result = 1;
+
+ // DEBUG_V (String ("TargetTimeInNanoSec: ") + String (TargetTimeInNanoSec));
+ // DEBUG_V (String (" I2S_TickTimeInNS: ") + String (I2S_TickTimeInNS));
+ // DEBUG_V (String (" Result: ") + String (Result));
+
+ // DEBUG_END;
+ return Result;
+}
+
+#endif // defined (SUPPORT_I2S)
diff --git a/src/output/OutputMgr.cpp b/src/output/OutputMgr.cpp
index 9fbaf1c91..b495ebda2 100644
--- a/src/output/OutputMgr.cpp
+++ b/src/output/OutputMgr.cpp
@@ -41,6 +41,7 @@
#include "output/OutputUCS1903Rmt.hpp"
#include "output/OutputUCS1903Uart.hpp"
#include "output/OutputWS2801Spi.hpp"
+#include "output/OutputWS2811I2S.hpp"
#include "output/OutputWS2811Rmt.hpp"
#include "output/OutputWS2811Uart.hpp"
#include "output/OutputGS8208Uart.hpp"
@@ -53,11 +54,21 @@
#include "input/InputMgr.hpp"
-#ifdef ARDUINO_ARCH_ESP32
+#ifdef SUPPORT_I2S
+ #define CLASS_TYPE_NAME(n) n ## I2S
+ #define AddToProtocolClassList(name) \
+ c_ ## name ## I2S ClassList_ ## name;
+#elif defined(SUPPORT_RMT)
#define CLASS_TYPE_NAME(n) n ## Rmt
-#else
+ #define AddToProtocolClassList(name) \
+ c_ ## name ## Rmt ClassList_ ## name;
+#elif defined(SUPPORT_UART)
#define CLASS_TYPE_NAME(n) n ## Uart
-#endif // def ARDUINO_ARCH_ESP32
+ #define AddToProtocolClassList(name) \
+ c_ ## name ## Uart ClassList_ ## name;
+#else
+ #error "No Output Driver has been selected. Update Platform IO to select an output driver"
+#endif
#define CLASS_TYPE_NO_NAME(n) n
#define AllocatePort(ClassType, Output, OutputType) \
@@ -145,34 +156,23 @@ static const SupportedOutputProtocol_t SupportedOutputProtocolList[] =
#endif // def SUPPORT_OutputProtocol_FireGod
};
-
-
-#ifdef ARDUINO_ARCH_ESP8266
-#define AddUartRmtToProtocolClassList(name) \
- c_ ## name ## Uart name ## Uart;
-#else
-#define AddUartRmtToProtocolClassList(name) \
- c_ ## name ## Uart name ## Uart; \
- c_ ## name ## Uart name ## Rmt;
-#endif // def ARDUINO_ARCH_ESP32
-
union alignas(32) OutputProtocolClasses_t
{
c_OutputDisabled OutputDisabled;
#ifdef SUPPORT_OutputProtocol_WS2811
- AddUartRmtToProtocolClassList(OutputWS2811);
+ AddToProtocolClassList(OutputWS2811);
#endif // def SUPPORT_OutputProtocol_WS2811
#ifdef SUPPORT_OutputProtocol_GECE
- AddUartRmtToProtocolClassList(OutputGECE);
+ AddToProtocolClassList(OutputGECE);
#endif // def SUPPORT_OutputProtocol_GECE
#if defined(SUPPORT_OutputProtocol_DMX) || \
defined(SUPPORT_OutputProtocol_Renard) || \
defined(SUPPORT_OutputProtocol_Serial) || \
defined(SUPPORT_OutputProtocol_FireGod)
- AddUartRmtToProtocolClassList(OutputSerial);
+ AddToProtocolClassList(OutputSerial);
#endif
#ifdef SUPPORT_OutputProtocol_Relay
@@ -184,11 +184,11 @@ union alignas(32) OutputProtocolClasses_t
#endif // def SUPPORT_OutputProtocol_Servo_PCA9685
#ifdef SUPPORT_OutputProtocol_UCS1903
- AddUartRmtToProtocolClassList(OutputUCS1903);
+ AddToProtocolClassList(OutputUCS1903);
#endif // def SUPPORT_OutputProtocol_UCS1903
#ifdef SUPPORT_OutputProtocol_TM1814
- AddUartRmtToProtocolClassList(OutputTM1814);
+ AddToProtocolClassList(OutputTM1814);
#endif // def SUPPORT_OutputProtocol_TM1814
#ifdef SUPPORT_OutputProtocol_WS2801
@@ -200,11 +200,11 @@ union alignas(32) OutputProtocolClasses_t
#endif // def SUPPORT_OutputProtocol_APA102
#ifdef SUPPORT_OutputProtocol_GS8208
- AddUartRmtToProtocolClassList(OutputGS8208);
+ AddToProtocolClassList(OutputGS8208);
#endif // def SUPPORT_OutputProtocol_GS8208
#ifdef SUPPORT_OutputProtocol_UCS8903
- AddUartRmtToProtocolClassList(OutputUCS8903);
+ AddToProtocolClassList(OutputUCS8903);
#endif // def SUPPORT_OutputProtocol_UCS8903
#ifdef SUPPORT_OutputProtocol_TLS3001
@@ -240,6 +240,7 @@ struct alignas(32) DriverInfo_t
static DriverInfo_t * pOutputChannelDrivers = nullptr;;
static uint8_t OutputBuffer[OM_MAX_NUM_CHANNELS];
+
//-----------------------------------------------------------------------------
// Methods
//-----------------------------------------------------------------------------
@@ -352,6 +353,10 @@ void c_OutputMgr::Begin ()
digitalWrite (LED_FLASH_GPIO, LED_FLASH_OFF);
#endif // def LED_FLASH_GPIO
+ #ifdef SUPPORT_I2S
+ OutputI2S.Begin();
+ #endif // def SUPPORT_I2S
+
// make sure the pointers are set up properly
for (uint8_t index = 0; index < NumOutputPorts; ++index)
{
@@ -601,9 +606,9 @@ void c_OutputMgr::GetStatus (JsonObject & jsonStatus)
{
// DEBUG_START;
-#if defined(ARDUINO_ARCH_ESP32)
- // jsonStatus["PollCount"] = PollCount;
-#endif // defined(ARDUINO_ARCH_ESP32)
+ #if defined(SUPPORT_I2S)
+ OutputI2S.GetStatus(jsonStatus);
+ #endif // defined(SUPPORT_I2S)
JsonArray OutputStatus = jsonStatus[(char*)CN_output].to ();
for (uint8_t index = 0; index < NumOutputPorts; ++index)
@@ -623,10 +628,6 @@ void c_OutputMgr::ClearStatistics ()
{
// DEBUG_START;
-#if defined(ARDUINO_ARCH_ESP32)
- // PollCount = 0;
-#endif // defined(ARDUINO_ARCH_ESP32)
-
for (uint8_t index = 0; index < NumOutputPorts; ++index)
{
DriverInfo_t & CurrentOutput = pOutputChannelDrivers[index];
@@ -1821,7 +1822,7 @@ void c_OutputMgr::ClearBuffer()
{
// DEBUG_START;
- memset(GetBufferAddress(), 0x00, OutputMgr.GetBufferSize());
+ memset(ISR_GetBufferAddress(), 0x00, OutputMgr.GetBufferSize());
// DEBUG_END;
diff --git a/src/output/OutputPixel.cpp b/src/output/OutputPixel.cpp
index 3bac9a1b4..4c0605ce4 100644
--- a/src/output/OutputPixel.cpp
+++ b/src/output/OutputPixel.cpp
@@ -180,6 +180,7 @@ bool c_OutputPixel::SetConfig (ArduinoJson::JsonObject& jsonConfig)
// DEBUG_START;
// PrettyPrint(jsonConfig, "SetConfig");
+ c_OutputCommon::SetConfig (jsonConfig);
// enums need to be converted to uints for json
setFromJSON (color_order, jsonConfig, CN_color_order);
@@ -195,8 +196,6 @@ bool c_OutputPixel::SetConfig (ArduinoJson::JsonObject& jsonConfig)
setFromJSON (PrependNullPixelCount, jsonConfig, CN_prependnullcount);
setFromJSON (AppendNullPixelCount, jsonConfig, CN_appendnullcount);
- c_OutputCommon::SetConfig (jsonConfig);
-
// DEBUG_V (String ( "gamma: ") + String (gamma));
// DEBUG_V (String ("PrependNullPixelCount: ") + String (PrependNullPixelCount));
// DEBUG_V (String (" AppendNullPixelCount: ") + String (AppendNullPixelCount));
@@ -382,7 +381,7 @@ void IRAM_ATTR c_OutputPixel::ISR_SetStartingSendPixelState()
}
else
{
-#ifdef SUPPORT_OutputProtocol_GECE
+ #ifdef SUPPORT_OutputProtocol_GECE
if (OutputType == OTYPE_t::OutputProtocol_GECE)
{
FrameStateFuncPtr = &c_OutputPixel::ISR_PixelSendGECEIntensity;
@@ -391,27 +390,25 @@ void IRAM_ATTR c_OutputPixel::ISR_SetStartingSendPixelState()
{
FrameStateFuncPtr = &c_OutputPixel::ISR_PixelSendIntensity;
}
-#else
+ #else
FrameStateFuncPtr = &c_OutputPixel::ISR_PixelSendIntensity;
-#endif // def SUPPORT_OutputProtocol_GECE
+ #endif // def SUPPORT_OutputProtocol_GECE
}
// DEBUG_END;
} // SetStartingSendPixelState
//----------------------------------------------------------------------------
-void c_OutputPixel::StartNewFrame ()
+void IRAM_ATTR c_OutputPixel::ISR_StartNewFrame ()
{
// DEBUG_START;
-#ifdef USE_PIXEL_DEBUG_COUNTERS
if (ISR_MoreDataToSend ())
{
- AbortFrameCounter++;
+ INC_PIXEL_DEBUG_COUNTER(AbortFrameCounter);
}
- FrameStartCounter++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(FrameStartCounter);
- NextPixelToSend = GetBufferAddress();
+ NextPixelToSend = ISR_GetBufferAddress();
FramePrependDataCurrentIndex = 0;
FrameAppendDataCurrentIndex = 0;
SentPixelsCount = 0;
@@ -435,14 +432,14 @@ void c_OutputPixel::StartNewFrame ()
ISR_SetStartingSendPixelState ();
}
-#ifdef USE_PIXEL_DEBUG_COUNTERS
+ #ifdef USE_PIXEL_DEBUG_COUNTERS
SentPixels = SentPixelsCount;
PixelsToSend = pixel_count;
IntensityBytesSent = 0;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ #endif // def USE_PIXEL_DEBUG_COUNTERS
// NumIntensityBytesPerPixel = 1;
- ReportNewFrame();
+ c_OutputCommon::ISR_ReportNewFrame();
// DEBUG_END;
} // StartNewFrame
@@ -458,9 +455,7 @@ void c_OutputPixel::SetIntensityDataWidth(uint32_t DataWidth)
//----------------------------------------------------------------------------
uint32_t IRAM_ATTR c_OutputPixel::ISR_FramePrependData()
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- FramePrependDataCounter++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(FramePrependDataCounter);
uint32_t response = pFramePrependData[FramePrependDataCurrentIndex];
if (++FramePrependDataCurrentIndex >= FramePrependDataSize)
@@ -488,9 +483,7 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelPrependNulls()
uint32_t response = 0x00;
do // once
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- PixelPrependNullsCounter++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(PixelPrependNullsCounter);
if (PixelPrependDataCurrentIndex < PixelPrependDataSize)
{
@@ -526,10 +519,8 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelPrependNulls()
//----------------------------------------------------------------------------
uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelSendPrependIntensity()
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- PixelSendIntensityCounter++;
- IntensityBytesSent++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(PixelSendIntensityCounter);
+ INC_PIXEL_DEBUG_COUNTER(IntensityBytesSent);
uint32_t response = PixelPrependData[PixelPrependDataCurrentIndex++];
@@ -542,10 +533,10 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelSendPrependIntensity()
#ifdef SUPPORT_OutputProtocol_GECE
if (OutputType == OTYPE_t::OutputProtocol_GECE)
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
+ #ifdef USE_PIXEL_DEBUG_COUNTERS
LastGECEdataSent = response;
- NumGECEdataSent++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ #endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(NumGECEdataSent);
FrameStateFuncPtr = &c_OutputPixel::ISR_PixelSendGECEIntensity;
}
else
@@ -566,10 +557,8 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelSendGECEIntensity()
{
uint32_t response = 0x00;
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- PixelSendIntensityCounter++;
- IntensityBytesSent++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(PixelSendIntensityCounter);
+ INC_PIXEL_DEBUG_COUNTER(IntensityBytesSent);
// build a GECE intensity frame
response = GECEBrightness;
@@ -579,8 +568,8 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelSendGECEIntensity()
response |= GECE_SET_BLUE(ISR_GetIntensityData());
#ifdef USE_PIXEL_DEBUG_COUNTERS
LastGECEdataSent = response;
- NumGECEdataSent++;
#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(NumGECEdataSent);
return response;
}
@@ -589,10 +578,8 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelSendGECEIntensity()
//----------------------------------------------------------------------------
uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelSendIntensity()
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- PixelSendIntensityCounter++;
- IntensityBytesSent++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(PixelSendIntensityCounter);
+ INC_PIXEL_DEBUG_COUNTER(IntensityBytesSent);
return ISR_GetIntensityData();
} // fPixelSendIntensity
@@ -603,10 +590,9 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelAppendNulls()
uint32_t response = 0x00;
do // once
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- PixelAppendNullsCounter++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
-// pixel prepend goes here
+ INC_PIXEL_DEBUG_COUNTER(PixelAppendNullsCounter);
+
+ // pixel prepend goes here
if (PixelPrependDataCurrentIndex < PixelPrependDataSize)
{
response = PixelPrependData[PixelPrependDataCurrentIndex++];
@@ -643,9 +629,7 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_PixelAppendNulls()
//----------------------------------------------------------------------------
uint32_t IRAM_ATTR c_OutputPixel::ISR_FrameAppendData()
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- FrameAppendDataCounter++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(FrameAppendDataCounter)
uint32_t response = pFrameAppendData[FrameAppendDataCurrentIndex];
@@ -660,23 +644,18 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_FrameAppendData()
//----------------------------------------------------------------------------
uint32_t IRAM_ATTR c_OutputPixel::ISR_FrameDone()
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- FrameDoneCounter++;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ INC_PIXEL_DEBUG_COUNTER(FrameDoneCounter);
return 0x00;
}
//----------------------------------------------------------------------------
bool IRAM_ATTR c_OutputPixel::ISR_GetNextIntensityToSend (uint32_t &DataToSend)
{
-
-#ifdef USE_PIXEL_DEBUG_COUNTERS
- GetNextIntensityToSendCounter++;
+ INC_PIXEL_DEBUG_COUNTER(GetNextIntensityToSendCounter);
if(!ISR_MoreDataToSend())
{
- GetNextIntensityToSendFailedCounter++;
+ INC_PIXEL_DEBUG_COUNTER(GetNextIntensityToSendFailedCounter);
}
-#endif // def USE_PIXEL_DEBUG_COUNTERS
DataToSend = (this->*FrameStateFuncPtr)();
@@ -715,9 +694,9 @@ uint32_t IRAM_ATTR c_OutputPixel::ISR_GetIntensityData()
}
else
{
-#ifdef USE_PIXEL_DEBUG_COUNTERS
+ #ifdef USE_PIXEL_DEBUG_COUNTERS
IntensityBytesSentLastFrame = IntensityBytesSent;
-#endif // def USE_PIXEL_DEBUG_COUNTERS
+ #endif // def USE_PIXEL_DEBUG_COUNTERS
FrameStateFuncPtr = &c_OutputPixel::ISR_FrameDone;
}
@@ -829,7 +808,7 @@ void c_OutputPixel::WriteChannelData(uint32_t StartChannelId, uint32_t ChannelCo
break;
}
- if(uint32_t(pBuffer) >= uint32_t(&(OutputMgr.GetBufferAddress()[OutputMgr.GetBufferSize()])))
+ if(uint32_t(pBuffer) >= uint32_t(&(OutputMgr.ISR_GetBufferAddress()[OutputMgr.GetBufferSize()])))
{
// DEBUG_V("This write is beyond the end of the Global Output buffer");
// DEBUG_V(String(" CalculatedChannelId: ") + String(CalculatedChannelId));
diff --git a/src/output/OutputRelay.cpp b/src/output/OutputRelay.cpp
index abfb4deae..fb313ef22 100644
--- a/src/output/OutputRelay.cpp
+++ b/src/output/OutputRelay.cpp
@@ -329,7 +329,7 @@ uint32_t c_OutputRelay::Poll ()
OutputValue(pOutputBuffer[0]);
}
- ReportNewFrame ();
+ ISR_ReportNewFrame ();
// DEBUG_END;
return 0;
diff --git a/src/output/OutputRmtV4.cpp b/src/output/OutputRmtV4.cpp
index 1392a74bb..92476fc82 100644
--- a/src/output/OutputRmtV4.cpp
+++ b/src/output/OutputRmtV4.cpp
@@ -17,7 +17,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_RMT)
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
#include "output/OutputRmt.hpp"
@@ -604,4 +604,4 @@ bool c_OutputRmt::StartNewFrame ()
} // StartNewFrame
#endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
-#endif // defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_RMT)
diff --git a/src/output/OutputRmtV5.cpp b/src/output/OutputRmtV5.cpp
index fb2ca5683..2e3ccac61 100644
--- a/src/output/OutputRmtV5.cpp
+++ b/src/output/OutputRmtV5.cpp
@@ -17,7 +17,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_RMT)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "output/OutputRmt.hpp"
@@ -514,4 +514,4 @@ bool c_OutputRmt::StartNewFrame ()
} // StartNewFrame
#endif // ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
-#endif // defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_RMT)
diff --git a/src/output/OutputSerial.cpp b/src/output/OutputSerial.cpp
index afe7b59c4..06a9d5cc6 100644
--- a/src/output/OutputSerial.cpp
+++ b/src/output/OutputSerial.cpp
@@ -322,7 +322,7 @@ void c_OutputSerial::SetFrameDurration ()
} // SetFrameDurration
//----------------------------------------------------------------------------
-void c_OutputSerial::StartNewFrame ()
+void IRAM_ATTR c_OutputSerial::ISR_StartNewFrame ()
{
// DEBUG_START;
@@ -334,7 +334,7 @@ void c_OutputSerial::StartNewFrame ()
FrameStartCounter++;
#endif // def USE_SERIAL_DEBUG_COUNTERS
- NextIntensityToSend = GetBufferAddress();
+ NextIntensityToSend = ISR_GetBufferAddress();
intensity_count = Num_Channels;
SentIntensityCount = 0;
SerialHeaderIndex = 0;
@@ -385,7 +385,7 @@ void c_OutputSerial::StartNewFrame ()
} // end switch (OutputType)
- ReportNewFrame();
+ ISR_ReportNewFrame();
// DEBUG_END;
diff --git a/src/output/OutputSerialRmt.cpp b/src/output/OutputSerialRmt.cpp
index 754661b56..3fb5ad2ab 100644
--- a/src/output/OutputSerialRmt.cpp
+++ b/src/output/OutputSerialRmt.cpp
@@ -17,7 +17,7 @@
*
*/
#include "ESPixelStick.h"
-#if (defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(ARDUINO_ARCH_ESP32)
+#if (defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(SUPPORT_RMT)
#include "output/OutputSerialRmt.hpp"
@@ -30,7 +30,7 @@ static bool IRAM_ATTR ISR_GetNextBitToSendBase (void * arg, rmt_item32_t & DataT
//----------------------------------------------------------------------------
static void StartNewDataFrameBase(void * arg)
{
- return reinterpret_cast(arg)->StartNewDataFrame();
+ return reinterpret_cast(arg)->ISR_StartNewDataFrame();
}
//----------------------------------------------------------------------------
@@ -81,7 +81,7 @@ bool c_OutputSerialRmt::SetConfig (ArduinoJson::JsonObject& jsonConfig)
OutputRmtConfig.arg = this;
OutputRmtConfig.ISR_GetNextIntensityBit = ISR_GetNextBitToSendBase;
OutputRmtConfig.StartNewDataFrame = StartNewDataFrameBase;
- OutputRmtConfig.BufferStart = GetBufferAddress();
+ OutputRmtConfig.BufferStart = ISR_GetBufferAddress();
OutputRmtConfig.NumBytesInFrame = OM_MAX_NUM_CHANNELS;
Rmt.Begin(OutputRmtConfig, this);
@@ -231,7 +231,7 @@ bool c_OutputSerialRmt::RmtPoll ()
} // Poll
//----------------------------------------------------------------------------
-void c_OutputSerialRmt::StartNewDataFrame()
+void IRAM_ATTR c_OutputSerialRmt::ISR_StartNewDataFrame()
{
// DEBUG_START;
// DEBUG_V(String("frame started on ") + String(OutputPortDefinition.gpios.data));
@@ -243,7 +243,7 @@ void c_OutputSerialRmt::StartNewDataFrame()
}
#endif // defined(SUPPORT_OutputProtocol_DMX)
StartBitCount = 1;
- StartNewFrame();
+ ISR_StartNewFrame();
// DEBUG_END;
} // StartNewDataFrame
@@ -322,4 +322,4 @@ void c_OutputSerialRmt::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // (defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(ARDUINO_ARCH_ESP32)
+#endif // (defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(SUPPORT_RMT)
diff --git a/src/output/OutputSerialUart.cpp b/src/output/OutputSerialUart.cpp
index 81fb27920..99acfd18a 100644
--- a/src/output/OutputSerialUart.cpp
+++ b/src/output/OutputSerialUart.cpp
@@ -16,7 +16,7 @@ GNU General Public License for more details.
******************************************************************/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)
+#if (defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)) && defined(SUPPORT_UART)
#include "output/OutputSerialUart.hpp"
@@ -140,4 +140,4 @@ void c_OutputSerialUart::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)
+#endif // defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard) && defined(SUPPORT_UART)
diff --git a/src/output/OutputServoPCA9685.cpp b/src/output/OutputServoPCA9685.cpp
index 9b4d507b8..c1b98cc62 100644
--- a/src/output/OutputServoPCA9685.cpp
+++ b/src/output/OutputServoPCA9685.cpp
@@ -84,7 +84,7 @@ void c_OutputServoPCA9685::ClearBuffer ()
// memset(GetBufferAddress(), 0x00, GetBufferUsedSize());
for (ServoPCA9685Channel_t & currentServoPCA9685Channel : OutputList)
{
- GetBufferAddress()[currentServoPCA9685Channel.Id] =
+ ISR_GetBufferAddress()[currentServoPCA9685Channel.Id] =
currentServoPCA9685Channel.HomeValue;
}
@@ -233,7 +233,7 @@ uint32_t c_OutputServoPCA9685::Poll ()
yield();
}
*/
- ReportNewFrame ();
+ ISR_ReportNewFrame ();
for (ServoPCA9685Channel_t & currentServoPCA9685 : OutputList)
{
diff --git a/src/output/OutputSpi.cpp b/src/output/OutputSpi.cpp
index f727f36b6..d807e8e4d 100644
--- a/src/output/OutputSpi.cpp
+++ b/src/output/OutputSpi.cpp
@@ -292,7 +292,7 @@ void c_OutputSpi::StartNewFrame()
if(OutputPixel)
{
- OutputPixel->StartNewFrame ();
+ OutputPixel->ISR_StartNewFrame ();
}
#if defined(SUPPORT_OutputProtocol_GRINCH)
else if(OutputGrinch)
diff --git a/src/output/OutputTLS3001Rmt.cpp b/src/output/OutputTLS3001Rmt.cpp
index 7036c0449..7e15048c7 100644
--- a/src/output/OutputTLS3001Rmt.cpp
+++ b/src/output/OutputTLS3001Rmt.cpp
@@ -17,7 +17,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_TLS3001) && defined (ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_TLS3001) && defined (SUPPORT_RMT)
#include "output/OutputTLS3001Rmt.hpp"
@@ -97,7 +97,7 @@ bool c_OutputTLS3001Rmt::SetConfig (ArduinoJson::JsonObject& jsonConfig)
OutputRmtConfig.arg = this;
OutputRmtConfig.ISR_GetNextIntensityBit = ISR_GetNextBitToSendBase;
OutputRmtConfig.StartNewDataFrame = StartNewDataFrameBase;
- OutputRmtConfig.BufferStart = GetBufferAddress();
+ OutputRmtConfig.BufferStart = ISR_GetBufferAddress();
OutputRmtConfig.NumBytesInFrame = OM_MAX_NUM_CHANNELS;
// DEBUG_V();
@@ -226,7 +226,7 @@ uint32_t c_OutputTLS3001Rmt::Poll ()
} // Poll
//----------------------------------------------------------------------------
-void c_OutputTLS3001Rmt::StartNewDataFrame()
+void IRAM_ATTR c_OutputTLS3001Rmt::StartNewDataFrame()
{
// DEBUG_START;
// DEBUG_V(String("frame started on ") + String(OutputPortDefinition.gpios.data));
@@ -240,7 +240,7 @@ void c_OutputTLS3001Rmt::StartNewDataFrame()
{
fsm_RMT_state_SendDataStart_imp.Init();
}
- c_OutputTLS3001::StartNewFrame();
+ c_OutputTLS3001::ISR_StartNewFrame();
// DEBUG_END;
} // StartNewDataFrame
@@ -583,4 +583,4 @@ bool IRAM_ATTR fsm_RMT_state_SendDataIdle::ISR_GetNextBitToSend (rmt_item32_t &D
return false;
} // fsm_RMT_state_SendDataIdle
-#endif // defined(SUPPORT_OutputProtocol_TLS3001) && defined (ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_TLS3001) && defined (SUPPORT_RMT)
diff --git a/src/output/OutputTM1814Rmt.cpp b/src/output/OutputTM1814Rmt.cpp
index f1ea0f2fc..dc8009687 100644
--- a/src/output/OutputTM1814Rmt.cpp
+++ b/src/output/OutputTM1814Rmt.cpp
@@ -18,7 +18,7 @@
*/
#include "ESPixelStick.h"
-#if defined (SUPPORT_OutputProtocol_TM1814) && defined (ARDUINO_ARCH_ESP32)
+#if defined (SUPPORT_OutputProtocol_TM1814) && defined (SUPPORT_RMT)
#include "output/OutputTM1814Rmt.hpp"
@@ -31,7 +31,7 @@ static bool IRAM_ATTR ISR_GetNextBitToSendBase (void * arg, rmt_item32_t & DataT
//----------------------------------------------------------------------------
static void StartNewDataFrameBase(void * arg)
{
- return reinterpret_cast(arg)->StartNewDataFrame();
+ return reinterpret_cast(arg)->ISR_StartNewDataFrame();
}
//----------------------------------------------------------------------------
@@ -96,7 +96,7 @@ bool c_OutputTM1814Rmt::SetConfig (ArduinoJson::JsonObject& jsonConfig)
OutputRmtConfig.arg = this;
OutputRmtConfig.ISR_GetNextIntensityBit = ISR_GetNextBitToSendBase;
OutputRmtConfig.StartNewDataFrame = StartNewDataFrameBase;
- OutputRmtConfig.BufferStart = GetBufferAddress();
+ OutputRmtConfig.BufferStart = ISR_GetBufferAddress();
OutputRmtConfig.NumBytesInFrame = OM_MAX_NUM_CHANNELS;
Rmt.Begin(OutputRmtConfig, this);
@@ -182,13 +182,13 @@ bool c_OutputTM1814Rmt::RmtPoll ()
} // Poll
//----------------------------------------------------------------------------
-void c_OutputTM1814Rmt::StartNewDataFrame()
+void IRAM_ATTR c_OutputTM1814Rmt::ISR_StartNewDataFrame()
{
// DEBUG_START;
// DEBUG_V(String("frame started on ") + String(OutputPortDefinition.gpios.data));
INC_TM1814_RMT_DEBUG_COUNTERS(FrameStarts);
IfgBitCurrentCount = IfgBitCount;
- StartNewFrame();
+ ISR_StartNewFrame();
// DEBUG_END;
} // StartNewDataFrame
@@ -248,4 +248,4 @@ void c_OutputTM1814Rmt::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined (SUPPORT_OutputProtocol_TM1814) && defined (ARDUINO_ARCH_ESP32)
+#endif // defined (SUPPORT_OutputProtocol_TM1814) && defined (SUPPORT_RMT)
diff --git a/src/output/OutputTM1814Uart.cpp b/src/output/OutputTM1814Uart.cpp
index caabec3da..bec599785 100644
--- a/src/output/OutputTM1814Uart.cpp
+++ b/src/output/OutputTM1814Uart.cpp
@@ -18,7 +18,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_TM1814)
+#if defined(SUPPORT_OutputProtocol_TM1814) && defined(SUPPORT_UART)
#include "output/OutputTM1814Uart.hpp"
@@ -167,4 +167,4 @@ void c_OutputTM1814Uart::PauseOutput(bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_TM1814)
+#endif // defined(SUPPORT_OutputProtocol_TM1814) && defined(SUPPORT_UART)
diff --git a/src/output/OutputUCS1903Rmt.cpp b/src/output/OutputUCS1903Rmt.cpp
index 79d91cf9f..aa3d0f6ae 100644
--- a/src/output/OutputUCS1903Rmt.cpp
+++ b/src/output/OutputUCS1903Rmt.cpp
@@ -18,7 +18,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_UCS1903) && defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_UCS1903) && defined(SUPPORT_RMT)
#include "output/OutputUCS1903Rmt.hpp"
@@ -95,7 +95,7 @@ bool c_OutputUCS1903Rmt::SetConfig (ArduinoJson::JsonObject& jsonConfig)
OutputRmtConfig.arg = this;
OutputRmtConfig.ISR_GetNextIntensityBit = ISR_GetNextBitToSendBase;
OutputRmtConfig.StartNewDataFrame = StartNewDataFrameBase;
- OutputRmtConfig.BufferStart = GetBufferAddress();
+ OutputRmtConfig.BufferStart = ISR_GetBufferAddress();
OutputRmtConfig.NumBytesInFrame = OM_MAX_NUM_CHANNELS;
Rmt.Begin(OutputRmtConfig, this);
@@ -177,13 +177,13 @@ bool c_OutputUCS1903Rmt::RmtPoll ()
} // Poll
//----------------------------------------------------------------------------
-void c_OutputUCS1903Rmt::StartNewDataFrame()
+void IRAM_ATTR c_OutputUCS1903Rmt::StartNewDataFrame()
{
// DEBUG_START;
// DEBUG_V(String("frame started on ") + String(OutputPortDefinition.gpios.data));
INC_UCS1903_RMT_DEBUG_COUNTERS(FrameStarts);
IfgBitCurrentCount = IfgBitCount;
- StartNewFrame();
+ ISR_StartNewFrame();
// DEBUG_END;
} // StartNewDataFrame
@@ -243,4 +243,4 @@ void c_OutputUCS1903Rmt::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_UCS1903) && defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_UCS1903) && defined(SUPPORT_RMT)
diff --git a/src/output/OutputUCS1903Uart.cpp b/src/output/OutputUCS1903Uart.cpp
index 9eaef3534..c2d9a0e7d 100644
--- a/src/output/OutputUCS1903Uart.cpp
+++ b/src/output/OutputUCS1903Uart.cpp
@@ -18,7 +18,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_UCS1903)
+#if defined(SUPPORT_OutputProtocol_UCS1903) && defined(SUPPORT_UART)
#include "output/OutputUCS1903Uart.hpp"
@@ -153,4 +153,4 @@ void c_OutputUCS1903Uart::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_UCS1903)
+#endif // defined(SUPPORT_OutputProtocol_UCS1903) && defined(SUPPORT_UART)
diff --git a/src/output/OutputUCS8903Rmt.cpp b/src/output/OutputUCS8903Rmt.cpp
index 4b8900abf..997c1eeba 100644
--- a/src/output/OutputUCS8903Rmt.cpp
+++ b/src/output/OutputUCS8903Rmt.cpp
@@ -18,7 +18,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_UCS8903) && defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_UCS8903) && defined(SUPPORT_RMT)
#include "output/OutputUCS8903Rmt.hpp"
@@ -31,7 +31,7 @@ static bool IRAM_ATTR ISR_GetNextBitToSendBase (void * arg, rmt_item32_t & DataT
//----------------------------------------------------------------------------
static void StartNewDataFrameBase(void * arg)
{
- return reinterpret_cast(arg)->StartNewDataFrame();
+ return reinterpret_cast(arg)->ISR_StartNewDataFrame();
} // StartNewDataFrameBase
//----------------------------------------------------------------------------
@@ -96,7 +96,7 @@ bool c_OutputUCS8903Rmt::SetConfig (ArduinoJson::JsonObject& jsonConfig)
OutputRmtConfig.arg = this;
OutputRmtConfig.ISR_GetNextIntensityBit = ISR_GetNextBitToSendBase;
OutputRmtConfig.StartNewDataFrame = StartNewDataFrameBase;
- OutputRmtConfig.BufferStart = GetBufferAddress();
+ OutputRmtConfig.BufferStart = ISR_GetBufferAddress();
OutputRmtConfig.NumBytesInFrame = OM_MAX_NUM_CHANNELS;
Rmt.Begin(OutputRmtConfig, this);
@@ -178,13 +178,13 @@ bool c_OutputUCS8903Rmt::RmtPoll ()
} // Poll
//----------------------------------------------------------------------------
-void c_OutputUCS8903Rmt::StartNewDataFrame()
+void IRAM_ATTR c_OutputUCS8903Rmt::ISR_StartNewDataFrame()
{
// DEBUG_START;
// DEBUG_V(String("frame started on ") + String(OutputPortDefinition.gpios.data));
INC_UCS8903_RMT_DEBUG_COUNTERS(FrameStarts);
IfgBitCurrentCount = IfgBitCount;
- StartNewFrame();
+ ISR_StartNewFrame();
// DEBUG_END;
} // StartNewDataFrame
@@ -244,4 +244,4 @@ void c_OutputUCS8903Rmt::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_UCS8903) && defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_UCS8903) && defined(SUPPORT_RMT)
diff --git a/src/output/OutputUCS8903Uart.cpp b/src/output/OutputUCS8903Uart.cpp
index 23dcf6e61..032baa2e0 100644
--- a/src/output/OutputUCS8903Uart.cpp
+++ b/src/output/OutputUCS8903Uart.cpp
@@ -19,7 +19,7 @@
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_UCS8903)
+#if defined(SUPPORT_OutputProtocol_UCS8903) && defined(SUPPORT_UART)
#include "output/OutputUCS8903Uart.hpp"
@@ -191,4 +191,4 @@ void c_OutputUCS8903Uart::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_UCS8903)
+#endif // defined(SUPPORT_OutputProtocol_UCS8903) && defined(SUPPORT_UART)
diff --git a/src/output/OutputUart.cpp b/src/output/OutputUart.cpp
index 0d2c63537..77469c009 100644
--- a/src/output/OutputUart.cpp
+++ b/src/output/OutputUart.cpp
@@ -17,7 +17,7 @@
*
*/
#include "ESPixelStick.h"
-
+#if defined(SUPPORT_UART)
#include "output/OutputUart.hpp"
extern "C"
@@ -585,12 +585,12 @@ void IRAM_ATTR c_OutputUart::ISR_StartNewDataFrame()
{
if (nullptr != OutputUartConfig.pPixelDataSource)
{
- OutputUartConfig.pPixelDataSource->StartNewFrame();
+ OutputUartConfig.pPixelDataSource->ISR_StartNewFrame();
}
#if defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)
else
{
- OutputUartConfig.pSerialDataSource->StartNewFrame();
+ OutputUartConfig.pSerialDataSource->ISR_StartNewFrame();
}
#endif // defined(SUPPORT_OutputProtocol_FireGod) || defined(SUPPORT_OutputProtocol_DMX) || defined(SUPPORT_OutputProtocol_Serial) || defined(SUPPORT_OutputProtocol_Renard)
} // StartNewDataFrame
@@ -1255,4 +1255,6 @@ void c_OutputUart::RestoreSerialPortOperation()
// DEBUG_END;
-} // RestoreSerialPortOperation
\ No newline at end of file
+} // RestoreSerialPortOperation
+
+#endif // defined(SUPPORT_UART)
\ No newline at end of file
diff --git a/src/output/OutputWS2801Spi.cpp b/src/output/OutputWS2801Spi.cpp
index 096102c33..1e380e2ad 100644
--- a/src/output/OutputWS2801Spi.cpp
+++ b/src/output/OutputWS2801Spi.cpp
@@ -94,7 +94,7 @@ uint32_t c_OutputWS2801Spi::Poll ()
{
if (Spi.Poll ())
{
- ReportNewFrame ();
+ ISR_ReportNewFrame ();
}
}
else
diff --git a/src/output/OutputWS2811I2S.cpp b/src/output/OutputWS2811I2S.cpp
new file mode 100644
index 000000000..26a3aeeac
--- /dev/null
+++ b/src/output/OutputWS2811I2S.cpp
@@ -0,0 +1,379 @@
+/*
+* OutputWS2811I2S.cpp - WS2811 driver code for ESPixelStick I2S Channel
+*
+* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver
+* Copyright (c) 2015, 2026 Shelby Merrick
+* http://www.forkineye.com
+*
+* This program is provided free for you to use in any way that you wish,
+* subject to the laws and regulations where you are using it. Due diligence
+* is strongly suggested before using this code. Please give credit where due.
+*
+* The Author makes no warranty of any kind, express or implied, with regard
+* to this program or the documentation contained in this document. The
+* Author shall not be liable in any event for incidental or consequential
+* damages in connection with, or arising out of, the furnishing, performance
+* or use of these programs.
+*
+*/
+#include "ESPixelStick.h"
+#if defined (SUPPORT_OutputProtocol_WS2811) && defined (SUPPORT_I2S)
+
+#include "output/OutputWS2811I2S.hpp"
+#include "output/OutputMgr.hpp"
+
+//----------------------------------------------------------------------------
+static void IRAM_ATTR GetDataSlicesToSendBase (void * arg, c_OutputI2S::I2S_Item_t * DataToSend, uint32_t numSlices)
+{
+ reinterpret_cast (arg)->ISR_GetNextDataSlicesToSend (DataToSend, numSlices);
+} // ISR_GetNextBitToSend
+
+//----------------------------------------------------------------------------
+c_OutputWS2811I2S::c_OutputWS2811I2S (OM_OutputPortDefinition_t & OutputPortDefinition,
+ c_OutputMgr::e_OutputProtocolType outputType) :
+ c_OutputWS2811 (OutputPortDefinition, outputType)
+{
+ // DEBUG_START;
+
+ // DEBUG_V (String ("WS2811_PIXEL_I2S_TICKS_BIT_0_H: 0x") + String (WS2811_PIXEL_I2S_TICKS_BIT_0_HIGH, HEX));
+ // DEBUG_V (String ("WS2811_PIXEL_I2S_TICKS_BIT_0_L: 0x") + String (WS2811_PIXEL_I2S_TICKS_BIT_0_LOW, HEX));
+ // DEBUG_V (String ("WS2811_PIXEL_I2S_TICKS_BIT_1_H: 0x") + String (WS2811_PIXEL_I2S_TICKS_BIT_1_HIGH, HEX));
+ // DEBUG_V (String ("WS2811_PIXEL_I2S_TICKS_BIT_1_L: 0x") + String (WS2811_PIXEL_I2S_TICKS_BIT_1_LOW, HEX));
+
+ // DEBUG_END;
+
+} // c_OutputWS2811I2S
+
+//----------------------------------------------------------------------------
+c_OutputWS2811I2S::~c_OutputWS2811I2S ()
+{
+ // DEBUG_START;
+
+ I2Sdriver->RemoveSlotDevice(OutputPortDefinition.PortId);
+
+ // DEBUG_END;
+} // ~c_OutputWS2811I2S
+
+//----------------------------------------------------------------------------
+void c_OutputWS2811I2S::Begin ()
+{
+ // DEBUG_START;
+
+ I2Sdriver = OutputMgr.GetI2sDriver ();
+
+ c_OutputWS2811::Begin ();
+
+ // DEBUG_V (String ("DataPin: ") + String (DataPin));
+
+ ZeroHighBitSliceCount = I2Sdriver->GetNumTimeSlicesForTargetTimeNS (WS2811_PIXEL_NS_BIT_0_HIGH);
+ ZeroLowBitSliceCount = I2Sdriver->GetNumTimeSlicesForTargetTimeNS (WS2811_PIXEL_NS_BIT_0_LOW);
+ OneHighBitSliceCount = I2Sdriver->GetNumTimeSlicesForTargetTimeNS (WS2811_PIXEL_NS_BIT_1_HIGH);
+ OneLowBitSliceCount = I2Sdriver->GetNumTimeSlicesForTargetTimeNS (WS2811_PIXEL_NS_BIT_1_LOW);
+
+ // DEBUG_V (String ("ZeroHighBitSliceCount: ") + String (ZeroHighBitSliceCount));
+ // DEBUG_V (String (" ZeroLowBitSliceCount: ") + String (ZeroLowBitSliceCount));
+ // DEBUG_V (String (" OneHighBitSliceCount: ") + String (OneHighBitSliceCount));
+ // DEBUG_V (String (" OneLowBitSliceCount: ") + String (OneLowBitSliceCount));
+
+ FrameResetSliceCount = 0;
+ FrameResetCurrentSliceCount = 0;
+ HighBitCurrentSliceCount = 0;
+ LowBitCurrentSliceCount = 0;
+ IdleSliceCount = 0;
+ IdleCurrentSliceCount = 0;
+
+ DataBit = 0; // no data bit assigned yet
+ DataBitMask = ~DataBit;
+
+ c_OutputI2S::OutputI2SChannelConfig_t OutputI2SConfig;
+ OutputI2SConfig.I2SChannelId = uint32_t (OutputPortDefinition.PortId);
+ OutputI2SConfig.DataPin = gpio_num_t (OutputPortDefinition.gpios.data);
+ OutputI2SConfig.arg = this;
+ OutputI2SConfig.GetNextIntensityBitSlices = GetDataSlicesToSendBase;
+ OutputI2SConfig.IsActive = false; // do not output data
+
+ I2Sdriver->RegisterSlotDevice (OutputI2SConfig, &DataBit, &DataBitMask);
+
+ // DEBUG_V (String (" DataBit: 0x") + String (DataBit, HEX));
+ // DEBUG_V (String ("DataBitMask: 0x") + String (DataBitMask, HEX));
+
+ HasBeenInitialized = true;
+
+ // DEBUG_END;
+
+} // Begin
+
+//----------------------------------------------------------------------------
+void c_OutputWS2811I2S::CalculateFrameBitSlices ()
+{
+ DEBUG_START;
+
+ uint32_t MinFrameLenNS = 25 * NanoSecondsInAMilliSecond;
+ uint32_t FrameDurationInNanoSec = ActualFrameDurationMicroSec * NanoSecondsInAMicroSecond;
+ // DEBUG_V (String (" ActualFrameDurationMicroSec: ") + String (ActualFrameDurationMicroSec));
+ // DEBUG_V (String (" FrameDurationInNanoSec: ") + String (FrameDurationInNanoSec));
+ // DEBUG_V (String (" InterFrameGapInMicroSec: ") + String (InterFrameGapInMicroSec));
+
+ FrameDurationInNanoSec -= (InterFrameGapInMicroSec * NanoSecondsInAMicroSecond);
+ // DEBUG_V (String (" new FrameDurationInNanoSec: ") + String (FrameDurationInNanoSec));
+ // DEBUG_V (String (" MinFrameLenNS: ") + String (MinFrameLenNS));
+
+ uint32_t IdleLenNS = (MinFrameLenNS > FrameDurationInNanoSec) ? MinFrameLenNS - FrameDurationInNanoSec : NanoSecondsInAMicroSecond;
+ // DEBUG_V (String (" IdleLenNS: ") + String (IdleLenNS));
+
+ IdleSliceCount = I2Sdriver->GetNumTimeSlicesForTargetTimeNS (IdleLenNS);
+ // DEBUG_V (String (" IdleSliceCount: ") + String (IdleSliceCount));
+
+ FrameResetSliceCount = I2Sdriver->GetNumTimeSlicesForTargetTimeNS (InterFrameGapInMicroSec * NanoSecondsInAMicroSecond);
+ // DEBUG_V (String (" FrameResetSliceCount: ") + String (FrameResetSliceCount));
+
+ // DEBUG_END;
+
+} // CalculateFrameBits
+
+//----------------------------------------------------------------------------
+bool c_OutputWS2811I2S::SetConfig (ArduinoJson::JsonObject& jsonConfig)
+{
+ // DEBUG_START;
+
+ PauseOutput(true);
+
+ bool response = c_OutputWS2811::SetConfig (jsonConfig);
+
+ // update the output GPIO
+ I2Sdriver->SetGpio (OutputPortDefinition.PortId, OutputPortDefinition.gpios.data);
+
+ if(OutputBufferSize)
+ {
+ // DEBUG_V("start the transmiter");
+ CalculateFrameBitSlices ();
+ ISR_StartNewDataFrame ();
+ PauseOutput (false);
+ }
+ else
+ {
+ // DEBUG_V("stop the transmiter");
+ PauseOutput (true);
+ }
+
+ // DEBUG_END;
+ return response;
+
+} // SetConfig
+
+//----------------------------------------------------------------------------
+void c_OutputWS2811I2S::SetOutputBufferSize (uint32_t NumChannelsToOutput)
+{
+ // DEBUG_START;
+
+ // DEBUG_V (String ("NumChannelsToOutput: ") + String (NumChannelsToOutput));
+ c_OutputWS2811::SetOutputBufferSize (NumChannelsToOutput);
+
+ if(OutputBufferSize)
+ {
+ // DEBUG_V("start the transmiter");
+ CalculateFrameBitSlices ();
+ ISR_StartNewDataFrame ();
+ PauseOutput (false);
+ }
+ else
+ {
+ // DEBUG_V("stop the transmiter");
+ PauseOutput (true);
+ }
+
+ // DEBUG_END;
+
+} // SetBufferSize
+
+//----------------------------------------------------------------------------
+void c_OutputWS2811I2S::GetStatus (ArduinoJson::JsonObject& jsonStatus)
+{
+ // // DEBUG_START;
+ c_OutputWS2811::GetStatus (jsonStatus);
+
+ #ifdef USE_I2S_DEBUG_COUNTERS
+ jsonStatus[F ("FrameDurationInMicroSec")] = FrameDurationInMicroSec;
+ #endif // def USE_I2S_DEBUG_COUNTERS
+
+ #ifdef WS2811_I2S_DEBUG_COUNTERS
+ JsonObject JsonCounters = jsonStatus["JsonCounters"].to ();
+ JsonWrite (JsonCounters, "GetDataSlices", I2SDebugCounters.GetDataSlices);
+ JsonWrite (JsonCounters, "FrameStarts", I2SDebugCounters.FrameStarts);
+ JsonWrite (JsonCounters, "FrameEnds", I2SDebugCounters.FrameEnds);
+ JsonWrite (JsonCounters, "FrameResetBitSlices", I2SDebugCounters.FrameResetBitSlices);
+ JsonWrite (JsonCounters, "IdleBitSlices", I2SDebugCounters.IdleBitSlices);
+ JsonWrite (JsonCounters, "DataBitSlices", I2SDebugCounters.DataBitSlices);
+ JsonWrite (JsonCounters, "DataBits", I2SDebugCounters.DataBits);
+ JsonWrite (JsonCounters, "DataBytes", I2SDebugCounters.DataBytes);
+ JsonWrite (JsonCounters, "BitSliceHigh", I2SDebugCounters.BitSliceHigh);
+ JsonWrite (JsonCounters, "BitSliceLow", I2SDebugCounters.BitSliceLow);
+ JsonWrite (JsonCounters, "DataBitEnd", I2SDebugCounters.DataBitEnd);
+ JsonWrite (JsonCounters, "DataByteEnd", I2SDebugCounters.DataByteEnd);
+ JsonWrite (JsonCounters, "IdleSliceCount", IdleSliceCount);
+
+ JsonWrite (JsonCounters, "DataBitMask", String(DataBitMask,HEX));
+ JsonWrite (JsonCounters, "DataBit", String(DataBit,HEX));
+ JsonWrite (JsonCounters, "ZeroHighBitSliceCount", ZeroHighBitSliceCount);
+ JsonWrite (JsonCounters, "ZeroLowBitSliceCount", ZeroLowBitSliceCount);
+ JsonWrite (JsonCounters, "OneHighBitSliceCount", OneHighBitSliceCount);
+ JsonWrite (JsonCounters, "OneLowBitSliceCount", OneLowBitSliceCount);
+ JsonWrite (JsonCounters, "HighBitCurrentSliceCount", HighBitCurrentSliceCount);
+ JsonWrite (JsonCounters, "LowBitCurrentSliceCount", LowBitCurrentSliceCount);
+ JsonWrite (JsonCounters, "FrameResetSliceCount", FrameResetSliceCount);
+ JsonWrite (JsonCounters, "FrameResetCurrentSliceCount", FrameResetCurrentSliceCount);
+ JsonWrite (JsonCounters, "IdleSliceCount", IdleSliceCount);
+ JsonWrite (JsonCounters, "IdleCurrentSliceCount", IdleCurrentSliceCount);
+ JsonWrite (JsonCounters, "DataPattern", String(DataPattern, HEX));
+ JsonWrite (JsonCounters, "DataPatternMask", String(DataPatternMask, HEX));
+
+ #endif // def WS2811_I2S_DEBUG_COUNTERS
+
+ // // DEBUG_END;
+} // GetStatus
+
+//----------------------------------------------------------------------------
+void IRAM_ATTR c_OutputWS2811I2S::ISR_StartNewDataFrame ()
+{
+ // DEBUG_START;
+
+ c_OutputWS2811::ISR_StartNewFrame ();
+
+ // DEBUG_V (String ("frame started on ") + String (OutputPortDefinition.gpios.data));
+ INC_WS2811_I2S_DEBUG_COUNTERS (FrameStarts);
+
+ IdleCurrentSliceCount = IdleSliceCount;
+ FrameResetCurrentSliceCount = FrameResetSliceCount;
+
+ // set up for the next data byte
+ INC_WS2811_I2S_DEBUG_COUNTERS (DataBytes);
+
+ // restore c_OutputPixel::ISR_GetNextIntensityToSend (DataPattern);
+ DataPatternMask = 0x80;
+
+ if (DataPattern & DataPatternMask)
+ {
+ // send a one bit
+ HighBitCurrentSliceCount = OneHighBitSliceCount;
+ LowBitCurrentSliceCount = OneLowBitSliceCount;
+ }
+ else // send a zero bit
+ {
+ HighBitCurrentSliceCount = ZeroHighBitSliceCount;
+ LowBitCurrentSliceCount = ZeroLowBitSliceCount;
+ }
+
+ // DEBUG_END;
+} // StartNewDataFrame
+
+//----------------------------------------------------------------------------
+void IRAM_ATTR c_OutputWS2811I2S::ISR_GetNextDataSlicesToSend (c_OutputI2S::I2S_Item_t * pDataToSend, uint32_t numSlices)
+{
+ INC_WS2811_I2S_DEBUG_COUNTERS (GetDataSlices);
+
+ for (int CurrentSliceId = 0; CurrentSliceId < numSlices; ++CurrentSliceId, ++pDataToSend)
+ {
+ if (IdleCurrentSliceCount)
+ {
+ INC_WS2811_I2S_DEBUG_COUNTERS (IdleBitSlices);
+ *pDataToSend |= uint8_t(DataBit); // output high
+ --IdleCurrentSliceCount;
+ continue;
+ }
+
+ if (FrameResetCurrentSliceCount)
+ {
+ INC_WS2811_I2S_DEBUG_COUNTERS (FrameResetBitSlices);
+ *pDataToSend &= uint8_t(DataBitMask); // output low
+ --FrameResetCurrentSliceCount;
+ continue;
+ }
+
+ INC_WS2811_I2S_DEBUG_COUNTERS (DataBitSlices);
+
+ if (HighBitCurrentSliceCount)
+ {
+ INC_WS2811_I2S_DEBUG_COUNTERS (BitSliceHigh);
+
+ --HighBitCurrentSliceCount;
+ *pDataToSend |= uint8_t(DataBit); // output high
+ continue;
+ }
+
+ if (LowBitCurrentSliceCount)
+ {
+ INC_WS2811_I2S_DEBUG_COUNTERS (BitSliceLow);
+ *pDataToSend &= uint8_t(DataBitMask); // output low
+ --LowBitCurrentSliceCount;
+ if (LowBitCurrentSliceCount)
+ {
+ // more low bits to send
+ continue;
+ }
+ }
+
+ INC_WS2811_I2S_DEBUG_COUNTERS (DataBitEnd);
+
+ // 1 bit of data has completed
+ DataPatternMask = DataPatternMask >> 1;
+
+ // do we need to set up the next data byte to send?
+ if (0 == DataPatternMask)
+ {
+ // entire data byte has been sent
+ INC_WS2811_I2S_DEBUG_COUNTERS (DataByteEnd);
+
+ // is there another data byte to send?
+ if (c_OutputPixel::ISR_MoreDataToSend ())
+ {
+ INC_WS2811_I2S_DEBUG_COUNTERS (FrameEnds);
+
+ ISR_StartNewDataFrame ();
+
+ // force a huge idle gap
+ // IdleCurrentSliceCount = -1;
+ continue;
+ }
+
+ // there is more data to send
+ INC_WS2811_I2S_DEBUG_COUNTERS (DataBytes);
+
+ // set up to output the next data byte
+ c_OutputPixel::ISR_GetNextIntensityToSend (DataPattern);
+ DataPatternMask = 0x80;
+ }
+
+ // more bits to send in the current data byte
+ INC_WS2811_I2S_DEBUG_COUNTERS (DataBits);
+ if (DataPattern & DataPatternMask)
+ {
+ // send a one bit
+ HighBitCurrentSliceCount = OneHighBitSliceCount;
+ LowBitCurrentSliceCount = OneLowBitSliceCount;
+ }
+ else
+ {
+ // send a zero bit
+ HighBitCurrentSliceCount = ZeroHighBitSliceCount;
+ LowBitCurrentSliceCount = ZeroLowBitSliceCount;
+ }
+ };
+
+ return;
+} // ISR_GetNextBitToSend
+
+//----------------------------------------------------------------------------
+void c_OutputWS2811I2S::PauseOutput (bool State)
+{
+ // DEBUG_START;
+
+ // DEBUG_V (String ("PortId: ") + String (OutputPortDefinition.PortId));
+ // DEBUG_V (String (" State: ") + String (State));
+
+ c_OutputWS2811::PauseOutput (State);
+ I2Sdriver->SetOutputState (OutputPortDefinition.PortId, !State);
+
+ // DEBUG_END;
+} // PauseOutput
+
+#endif // defined (SUPPORT_OutputProtocol_WS2811) && defined (ARDUINO_ARCH_ESP32)
diff --git a/src/output/OutputWS2811Rmt.cpp b/src/output/OutputWS2811Rmt.cpp
index 528937ddc..ac75741e9 100644
--- a/src/output/OutputWS2811Rmt.cpp
+++ b/src/output/OutputWS2811Rmt.cpp
@@ -17,7 +17,7 @@
*
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_WS2811) && defined(ARDUINO_ARCH_ESP32)
+#if defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_RMT)
#include "output/OutputWS2811Rmt.hpp"
@@ -95,7 +95,7 @@ bool c_OutputWS2811Rmt::SetConfig (ArduinoJson::JsonObject& jsonConfig)
OutputRmtConfig.arg = this;
OutputRmtConfig.ISR_GetNextIntensityBit = ISR_GetNextBitToSendBase;
OutputRmtConfig.StartNewDataFrame = StartNewDataFrameBase;
- OutputRmtConfig.BufferStart = GetBufferAddress();
+ OutputRmtConfig.BufferStart = ISR_GetBufferAddress();
OutputRmtConfig.NumBytesInFrame = OM_MAX_NUM_CHANNELS;
// DEBUG_V();
@@ -195,7 +195,7 @@ void c_OutputWS2811Rmt::StartNewDataFrame()
{
// DEBUG_START;
- StartNewFrame();
+ ISR_StartNewFrame();
// DEBUG_V(String("frame started on ") + String(OutputPortDefinition.gpios.data));
INC_WS2811_RMT_DEBUG_COUNTERS(FrameStarts);
@@ -262,4 +262,4 @@ void c_OutputWS2811Rmt::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_WS2811) && defined(ARDUINO_ARCH_ESP32)
+#endif // defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_RMT)
diff --git a/src/output/OutputWS2811Uart.cpp b/src/output/OutputWS2811Uart.cpp
index 43f32f359..612075dca 100644
--- a/src/output/OutputWS2811Uart.cpp
+++ b/src/output/OutputWS2811Uart.cpp
@@ -18,7 +18,7 @@
*/
#include "ESPixelStick.h"
-#if defined(SUPPORT_OutputProtocol_WS2811)
+#if defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_UART)
#include "output/OutputWS2811Uart.hpp"
@@ -179,4 +179,4 @@ void c_OutputWS2811Uart::PauseOutput (bool State)
// DEBUG_END;
} // PauseOutput
-#endif // defined(SUPPORT_OutputProtocol_WS2811)
+#endif // defined(SUPPORT_OutputProtocol_WS2811) && defined(SUPPORT_UART)