22#ifdef ARDUINO_ARCH_ESP32
23#include <driver/rmt.h>
24#include <hal/rmt_ll.h>
31 enum RmtDataBitIdType_t
33 RMT_DATA_BIT_ZERO_ID = 0,
36 RMT_DATA_BIT_THREE_ID,
37 RMT_INTERFRAME_GAP_ID,
43 RMT_NUM_BIT_TYPES = RMT_LIST_END,
44 RMT_STOP_START_BIT_ID = RMT_STOPBIT_ID,
47 struct ConvertIntensityToRmtDataStreamEntry_t
49 rmt_item32_t Translation;
50 RmtDataBitIdType_t Id;
52 typedef ConvertIntensityToRmtDataStreamEntry_t CitrdsArray_t;
54 struct OutputRmtConfig_t
56 rmt_channel_t RmtChannelId = rmt_channel_t(-1);
57 gpio_num_t DataPin = gpio_num_t(-1);
58 rmt_idle_level_t idle_level = rmt_idle_level_t::RMT_IDLE_LEVEL_LOW;
59 uint32_t IntensityDataWidth = 8;
60 bool SendInterIntensityBits =
false;
61 bool SendEndOfFrameBits =
false;
62 uint8_t NumFrameStartBits = 1;
63 uint8_t NumFrameStopBits = 1;
64 uint8_t NumIdleBits = 6;
70 DataDirection_t DataDirection = DataDirection_t::MSB2LSB;
71 const CitrdsArray_t *CitrdsArray =
nullptr;
74 #if defined(SUPPORT_OutputType_FireGod) || defined(SUPPORT_OutputType_DMX) || defined(SUPPORT_OutputType_Serial) || defined(SUPPORT_OutputType_Renard)
75 c_OutputSerial *pSerialDataSource =
nullptr;
87#ifdef CONFIG_IDF_TARGET_ESP32S3
88#define MAX_NUM_RMT_CHANNELS 4
90#define MAX_NUM_RMT_CHANNELS 8
93#define RMT_INT_BIT uint32_t(1 << uint32_t (OutputRmtConfig.RmtChannelId))
94#define InterrupsAreEnabled (0 != (RMT.int_ena.val & RMT_INT_BIT))
96#define _NUM_RMT_SLOTS (sizeof(RMTMEM.chan[0].data32) / sizeof(RMTMEM.chan[0].data32[0]))
98 const uint32_t NUM_RMT_SLOTS = _NUM_RMT_SLOTS;
99 OutputRmtConfig_t OutputRmtConfig;
101 rmt_item32_t Intensity2Rmt[RmtDataBitIdType_t::RMT_LIST_END];
102 bool OutputIsPaused =
false;
104 uint32_t NumRmtSlotsPerIntensityValue = 8;
105 uint32_t NumRmtSlotOverruns = 0;
106 const uint32_t MaxNumRmtSlotsPerInterrupt = (_NUM_RMT_SLOTS/2);
108 #define NumSendBufferSlots 64
109 rmt_item32_t SendBuffer[NumSendBufferSlots];
110 uint32_t RmtBufferWriteIndex = 0;
111 uint32_t SendBufferWriteIndex = 0;
112 uint32_t SendBufferReadIndex = 0;
113 uint32_t NumUsedEntriesInSendBuffer = 0;
115#define MIN_FRAME_TIME_MS 25
117 uint32_t TxIntensityDataStartingMask = 0x80;
118 RmtDataBitIdType_t InterIntensityValueId = RMT_INVALID_VALUE;
120 inline void IRAM_ATTR ISR_TransferIntensityDataToRMT (uint32_t NumEntriesToTransfer);
121 inline void IRAM_ATTR ISR_CreateIntensityData ();
122 inline void IRAM_ATTR ISR_WriteToBuffer(uint32_t value);
123 inline bool IRAM_ATTR ISR_MoreDataToSend();
124 inline bool IRAM_ATTR ISR_GetNextIntensityToSend(uint32_t &DataToSend);
125 inline void StartNewDataFrame();
126 inline void ResetRmtBlockPointers();
128#ifndef HasBeenInitialized
129 bool HasBeenInitialized =
false;
132 TaskHandle_t SendIntensityDataTaskHandle = NULL;
136 virtual ~c_OutputRmt ();
139 bool StartNewFrame ();
140 bool StartNextFrame () {
return ((
nullptr != pParent) & (!OutputIsPaused)) ? pParent->RmtPoll() :
false; }
141 void GetStatus (ArduinoJson::JsonObject& jsonStatus);
142 void PauseOutput (
bool State);
146inline void IRAM_ATTR DisableRmtInterrupts()
148 rmt_ll_enable_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
149 rmt_ll_enable_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
150 rmt_ll_enable_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
151 ClearRmtInterrupts();
155inline void IRAM_ATTR EnableRmtInterrupts()
157 rmt_ll_enable_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
158 rmt_ll_enable_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
159 rmt_ll_enable_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
163inline void IRAM_ATTR ClearRmtInterrupts()
165 rmt_ll_clear_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
166 rmt_ll_clear_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
167 rmt_ll_clear_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
170 bool DriverIsSendingIntensityData() {
return 0 != InterrupsAreEnabled;}
172#define RMT_ClockRate 80000000.0
173#define RMT_Clock_Divisor 2.0
174#define RMT_TickLengthNS float ( (1/ (RMT_ClockRate/RMT_Clock_Divisor)) * float(NanoSecondsInASecond))
176 void UpdateBitXlatTable(
const CitrdsArray_t * CitrdsArray);
177 bool ValidateBitXlatTable(
const CitrdsArray_t * CitrdsArray);
178 void SetIntensity2Rmt (rmt_item32_t NewValue, RmtDataBitIdType_t ID) { Intensity2Rmt[ID] = NewValue; }
180 bool ThereIsDataToSend =
false;
182 void IRAM_ATTR ISR_Handler (isrTxFlags_t isrFlags);
186#ifdef USE_RMT_DEBUG_COUNTERS
189 uint32_t DataCallbackCounter = 0;
190 uint32_t DataTaskcounter = 0;
191 uint32_t ISRcounter = 0;
192 uint32_t FrameStartCounter = 0;
193 uint32_t SendBlockIsrCounter = 0;
194 uint32_t RanOutOfData = 0;
195 uint32_t UnknownISRcounter = 0;
196 uint32_t IntTxEndIsrCounter = 0;
197 uint32_t IntTxThrIsrCounter = 0;
199 uint32_t ErrorIsr = 0;
200 uint32_t IntensityValuesSent = 0;
201 uint32_t IntensityBitsSent = 0;
202 uint32_t IntensityValuesSentLastFrame = 0;
203 uint32_t IntensityBitsSentLastFrame = 0;
204 uint32_t IncompleteFrame = 0;
205 uint32_t BitTypeCounters[RmtDataBitIdType_t::RMT_NUM_BIT_TYPES];
206 uint32_t RmtEntriesTransfered = 0;
207 uint32_t RmtXmtFills = 0;
208 uint32_t RmtWhiteDetected = 0;
209 uint32_t FailedToSendAllData = 0;
211#define RMT_DEBUG_COUNTER(p) p
215#define RMT_DEBUG_COUNTER(p)
const CN_PROGMEM char CN_RMT[]
Definition ConstNames.cpp:183
Definition OutputCommon.hpp:31
Definition OutputPixel.hpp:28
struct FSEQParsedRangeEntry __attribute__
config_t config
Definition main.cpp:98
void GetDriverName(String &Name)
Definition main.cpp:120