22#ifdef ARDUINO_ARCH_ESP32
26#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
27 #include <driver/rmt_tx.h>
28 #include "driver/rmt_common.h"
29 #include "driver/rmt_encoder.h"
30 #define rmt_item32_t rmt_symbol_word_t
38 #include <driver/rmt.h>
39 #include <hal/rmt_ll.h>
45 struct OutputRmtConfig_t
47 uint32_t RmtChannelId = uint32_t(-1);
48 gpio_num_t DataPin = gpio_num_t(-1);
49 rmt_idle_level_t idle_level = rmt_idle_level_t::RMT_IDLE_LEVEL_LOW;
51 bool (*ISR_GetNextIntensityBit) (
void*arg, rmt_item32_t&data) =
nullptr;
52 void (*StartNewDataFrame) (
void*arg) =
nullptr;
53 void *BufferStart =
nullptr;
54 size_t NumBytesInFrame = 0;
66#define MAX_NUM_RMT_CHANNELS SOC_RMT_TX_CANDIDATES_PER_GROUP
67#define NUM_RMT_SLOTS SOC_RMT_MEM_WORDS_PER_CHANNEL
69#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
70 rmt_channel_handle_t rmt_channel_handle;
71 rmt_encoder_handle_t rmt_encoder_handle;
72 rmt_transmit_config_t tx_config =
77 .eot_level = OutputRmtConfig.idle_level,
78 .queue_nonblocking =
true
82 #define RMT_INT_BIT uint32_t(1 << uint32_t (OutputRmtConfig.RmtChannelId))
83 #define InterrupsAreEnabled (0 != (RMT.int_ena.val & RMT_INT_BIT))
84 rmt_item32_t * RmtChanData =
nullptr;
89 OutputRmtConfig_t OutputRmtConfig;
90 bool OutputIsPaused =
false;
91 uint32_t NumRmtSlotOverruns = 0;
92 const uint32_t MaxNumRmtSlotsPerInterrupt = (NUM_RMT_SLOTS/2);
94 #define NumSendBufferSlots 64
95 rmt_item32_t SendBuffer[NumSendBufferSlots];
96 uint32_t RmtBufferWriteIndex = 0;
97 uint32_t SendBufferWriteIndex = 0;
98 uint32_t SendBufferReadIndex = 0;
99 uint32_t NumUsedEntriesInSendBuffer = 0;
101 void ISR_TransferIntensityDataToRMT (uint32_t NumEntriesToTransfer);
102 size_t ISR_TransferIntensityDataToRMT (rmt_item32_t *symbols, uint32_t MaxNumEntriesToTransfer);
103 void ISR_CreateIntensityData ();
104 bool ISR_MoreDataToSend();
105 void StartNewDataFrame();
106 void ISR_ResetRmtBlockPointers();
108#ifndef HasBeenInitialized
109 bool HasBeenInitialized =
false;
112 TaskHandle_t SendIntensityDataTaskHandle = NULL;
116 virtual ~c_OutputRmt ();
119 bool StartNewFrame ();
120 bool StartNextFrame () {
return ((
nullptr != pParent) & (!OutputIsPaused)) ? pParent->RmtPoll() :
false; }
121 void GetStatus (ArduinoJson::JsonObject& jsonStatus);
122 void PauseOutput (
bool State);
124 void SetBitDuration (
double BitLenNs, rmt_item32_t & OutputBit, uint32_t & OutputNumBits);
126#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
128inline void DisableRmtInterrupts()
130 rmt_ll_enable_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
131 rmt_ll_enable_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
132 rmt_ll_enable_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
136inline void EnableRmtInterrupts()
138 rmt_ll_enable_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
139 rmt_ll_enable_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
140 rmt_ll_enable_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
144inline void ClearRmtInterrupts()
146 rmt_ll_clear_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
147 rmt_ll_clear_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
148 rmt_ll_clear_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
152#define RMT_ClockRate 80000000.0
153#define RMT_Clock_Divisor 2.0
154#define RMT_TICK_RESOLUTION_HZ (RMT_ClockRate / RMT_Clock_Divisor)
155#define RMT_TickLengthNS uint32_t((1.0 / RMT_TICK_RESOLUTION_HZ) * float(NanoSecondsInASecond))
157 void ISR_Handler (isrTxFlags_t isrFlags);
158 size_t ISR_Handler (
const void *data,
size_t data_size,
159 size_t symbols_written,
size_t symbols_free,
160 rmt_item32_t *symbols,
bool *done);
164#ifdef USE_RMT_DEBUG_COUNTERS
167 struct RmtDebugCounters_t
169 uint32_t DataCallbackCounter = 0;
170 uint32_t DataTaskcounter = 0;
171 uint32_t ISRcounter = 0;
172 uint32_t FrameStartCounter = 0;
173 uint32_t SendBlockIsrCounter = 0;
174 uint32_t RanOutOfData = 0;
175 uint32_t UnknownISRcounter = 0;
176 uint32_t IntTxEndIsrCounter = 0;
177 uint32_t IntTxThrIsrCounter = 0;
179 uint32_t ErrorIsr = 0;
180 uint32_t IntensityValuesSent = 0;
181 uint32_t IntensityBitsSent = 0;
182 uint32_t IntensityValuesSentLastFrame = 0;
183 uint32_t IntensityBitsSentLastFrame = 0;
184 uint32_t IncompleteFrame = 0;
185 uint32_t RmtEntriesTransfered = 0;
186 uint32_t RmtXmtFills = 0;
187 uint32_t ISRpaused = 0;
188 uint32_t RmtWhiteDetected = 0;
189 uint32_t FailedToSendAllData = 0;
190 uint32_t WriteToBuffer = 0;
191 uint32_t WriteToRmt = 0;
193 RmtDebugCounters_t RmtDebugCounters;
195#define RMT_DEBUG_INC_COUNTER(p) (++RmtDebugCounters.p)
196#define RMT_DEBUG_COUNTER(p) (RmtDebugCounters.p)
200#define RMT_DEBUG_INC_COUNTER(p)
201#define RMT_DEBUG_COUNTER(p)
207inline void WriteToBuffer(rmt_item32_t value)
209 RMT_DEBUG_INC_COUNTER(WriteToBuffer);
211 SendBuffer[SendBufferWriteIndex] = value;
212 if(++SendBufferWriteIndex >= NumSendBufferSlots) {SendBufferWriteIndex = 0;}
213 ++NumUsedEntriesInSendBuffer;
const CN_PROGMEM char CN_RMT[]
Definition ConstNames.cpp:193
Definition OutputCommon.hpp:32
struct FSEQParsedRangeEntry __attribute__
config_t config
Definition main.cpp:98
void GetDriverName(String &Name)
Definition main.cpp:121