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;
65#ifdef CONFIG_IDF_TARGET_ESP32S3
66# define MAX_NUM_RMT_CHANNELS 4
68# define MAX_NUM_RMT_CHANNELS 8
71#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
72 #define _NUM_RMT_SLOTS 64
73 rmt_channel_handle_t rmt_channel_handle;
74 rmt_encoder_handle_t rmt_encoder_handle;
75 rmt_transmit_config_t tx_config =
80 .eot_level = OutputRmtConfig.idle_level,
81 .queue_nonblocking =
true
85 #define RMT_INT_BIT uint32_t(1 << uint32_t (OutputRmtConfig.RmtChannelId))
86 #define InterrupsAreEnabled (0 != (RMT.int_ena.val & RMT_INT_BIT))
88 #define _NUM_RMT_SLOTS (sizeof(RMTMEM.chan[0].data32) / sizeof(RMTMEM.chan[0].data32[0]))
93 const uint32_t NUM_RMT_SLOTS = _NUM_RMT_SLOTS;
94 OutputRmtConfig_t OutputRmtConfig;
95 bool OutputIsPaused =
false;
96 uint32_t NumRmtSlotOverruns = 0;
97 const uint32_t MaxNumRmtSlotsPerInterrupt = (_NUM_RMT_SLOTS/2);
99 #define NumSendBufferSlots _NUM_RMT_SLOTS
100 rmt_item32_t SendBuffer[NumSendBufferSlots];
101 uint32_t RmtBufferWriteIndex = 0;
102 uint32_t SendBufferWriteIndex = 0;
103 uint32_t SendBufferReadIndex = 0;
104 uint32_t NumUsedEntriesInSendBuffer = 0;
106 void ISR_TransferIntensityDataToRMT (uint32_t NumEntriesToTransfer);
107 size_t ISR_TransferIntensityDataToRMT (rmt_item32_t *symbols, uint32_t MaxNumEntriesToTransfer);
108 void ISR_CreateIntensityData ();
109 void ISR_WriteToBuffer(rmt_item32_t value);
110 bool ISR_MoreDataToSend();
111 void StartNewDataFrame();
112 void ISR_ResetRmtBlockPointers();
114#ifndef HasBeenInitialized
115 bool HasBeenInitialized =
false;
118 TaskHandle_t SendIntensityDataTaskHandle = NULL;
122 virtual ~c_OutputRmt ();
125 bool StartNewFrame ();
126 bool StartNextFrame () {
return ((
nullptr != pParent) & (!OutputIsPaused)) ? pParent->RmtPoll() :
false; }
127 void GetStatus (ArduinoJson::JsonObject& jsonStatus);
128 void PauseOutput (
bool State);
130 void SetBitDuration (
double BitLenNs, rmt_item32_t & OutputBit, uint32_t & OutputNumBits);
133inline void IRAM_ATTR DisableRmtInterrupts()
135 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
136 rmt_ll_enable_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
137 rmt_ll_enable_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
138 rmt_ll_enable_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
139 ClearRmtInterrupts();
144inline void IRAM_ATTR EnableRmtInterrupts()
146 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
147 rmt_ll_enable_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
148 rmt_ll_enable_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
149 rmt_ll_enable_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
154inline void IRAM_ATTR ClearRmtInterrupts()
156 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
157 rmt_ll_clear_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
158 rmt_ll_clear_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
159 rmt_ll_clear_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
163#define RMT_ClockRate 80000000.0
164#define RMT_Clock_Divisor 2.0
165#define RMT_TICK_RESOLUTION_HZ (RMT_ClockRate / RMT_Clock_Divisor)
166#define RMT_TickLengthNS uint32_t((1.0 / RMT_TICK_RESOLUTION_HZ) * float(NanoSecondsInASecond))
168 void ISR_Handler (isrTxFlags_t isrFlags);
169 size_t ISR_Handler (
const void *data,
size_t data_size,
170 size_t symbols_written,
size_t symbols_free,
171 rmt_item32_t *symbols,
bool *done);
174#define USE_RMT_DEBUG_COUNTERS
175#ifdef USE_RMT_DEBUG_COUNTERS
178 uint32_t DataCallbackCounter = 0;
179 uint32_t DataTaskcounter = 0;
180 uint32_t ISRcounter = 0;
181 uint32_t FrameStartCounter = 0;
182 uint32_t SendBlockIsrCounter = 0;
183 uint32_t RanOutOfData = 0;
184 uint32_t UnknownISRcounter = 0;
185 uint32_t IntTxEndIsrCounter = 0;
186 uint32_t IntTxThrIsrCounter = 0;
188 uint32_t ErrorIsr = 0;
189 uint32_t IntensityValuesSent = 0;
190 uint32_t IntensityBitsSent = 0;
191 uint32_t IntensityValuesSentLastFrame = 0;
192 uint32_t IntensityBitsSentLastFrame = 0;
193 uint32_t IncompleteFrame = 0;
194 uint32_t RmtEntriesTransfered = 0;
195 uint32_t RmtXmtFills = 0;
196 uint32_t ISRpaused = 0;
197 uint32_t RmtWhiteDetected = 0;
198 uint32_t FailedToSendAllData = 0;
199 uint32_t WriteToBuffer = 0;
200 uint32_t WriteToRmt = 0;
202#define RMT_DEBUG_COUNTER(p) p
206#define RMT_DEBUG_COUNTER(p)
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