22#ifdef ARDUINO_ARCH_ESP32
23#include <hal/rmt_ll.h>
27#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
28 #include <driver/rmt_tx.h>
29 #include "driver/rmt_common.h"
30 #include "driver/rmt_encoder.h"
31 #define rmt_item32_t rmt_symbol_word_t
39 #include <driver/rmt.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;
63#ifdef CONFIG_IDF_TARGET_ESP32S3
64#define MAX_NUM_RMT_CHANNELS 4
66#define MAX_NUM_RMT_CHANNELS 8
69#define RMT_INT_BIT uint32_t(1 << uint32_t (OutputRmtConfig.RmtChannelId))
70#define InterrupsAreEnabled (0 != (RMT.int_ena.val & RMT_INT_BIT))
72#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
73 #define _NUM_RMT_SLOTS 48
75 #define _NUM_RMT_SLOTS (sizeof(RMTMEM.chan[0].data32) / sizeof(RMTMEM.chan[0].data32[0]))
79 const uint32_t NUM_RMT_SLOTS = _NUM_RMT_SLOTS;
80 OutputRmtConfig_t OutputRmtConfig;
81 bool OutputIsPaused =
false;
82 uint32_t NumRmtSlotOverruns = 0;
83 const uint32_t MaxNumRmtSlotsPerInterrupt = (_NUM_RMT_SLOTS/2);
85 #define NumSendBufferSlots 64
86 rmt_item32_t SendBuffer[NumSendBufferSlots];
87 uint32_t RmtBufferWriteIndex = 0;
88 uint32_t SendBufferWriteIndex = 0;
89 uint32_t SendBufferReadIndex = 0;
90 uint32_t NumUsedEntriesInSendBuffer = 0;
92 uint32_t TxIntensityDataStartingMask = 0x80;
94 inline void IRAM_ATTR ISR_TransferIntensityDataToRMT (uint32_t NumEntriesToTransfer);
95 inline void IRAM_ATTR ISR_CreateIntensityData ();
96 inline void IRAM_ATTR ISR_WriteToBuffer(uint32_t value);
97 inline bool IRAM_ATTR ISR_MoreDataToSend();
99 inline void StartNewDataFrame();
100 inline void ISR_ResetRmtBlockPointers();
102#ifndef HasBeenInitialized
103 bool HasBeenInitialized =
false;
106 TaskHandle_t SendIntensityDataTaskHandle = NULL;
110 virtual ~c_OutputRmt ();
113 bool StartNewFrame ();
114 bool StartNextFrame () {
return ((
nullptr != pParent) & (!OutputIsPaused)) ? pParent->RmtPoll() :
false; }
115 void GetStatus (ArduinoJson::JsonObject& jsonStatus);
116 void PauseOutput (
bool State);
118 void SetBitDuration (
double BitLenNs, rmt_item32_t & OutputBit, uint32_t & OutputNumBits);
120#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
121#define RMT_TX_BITS RMT_LL_EVENT_TX_THRES(OutputRmtConfig.RmtChannelId) | \
122 RMT_LL_EVENT_TX_DONE(OutputRmtConfig.RmtChannelId) | \
123 RMT_LL_EVENT_TX_ERROR(OutputRmtConfig.RmtChannelId)
127inline void IRAM_ATTR DisableRmtInterrupts()
129#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
130 rmt_ll_enable_interrupt(&RMT, RMT_TX_BITS,
false);
132 rmt_ll_enable_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
133 rmt_ll_enable_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
134 rmt_ll_enable_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
false);
137 ClearRmtInterrupts();
141inline void IRAM_ATTR EnableRmtInterrupts()
143#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
144 rmt_ll_enable_interrupt(&RMT, RMT_TX_BITS,
true);
146 rmt_ll_enable_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
147 rmt_ll_enable_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
148 rmt_ll_enable_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId,
true);
153inline void IRAM_ATTR ClearRmtInterrupts()
155#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
156 rmt_ll_clear_interrupt_status(&RMT, RMT_TX_BITS);
158 rmt_ll_clear_tx_thres_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
159 rmt_ll_clear_tx_end_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
160 rmt_ll_clear_tx_err_interrupt(&RMT, OutputRmtConfig.RmtChannelId);
164 bool DriverIsSendingIntensityData() {
return 0 != InterrupsAreEnabled;}
166#define RMT_ClockRate 80000000.0
167#define RMT_Clock_Divisor 2.0
168#define RMT_TickLengthNS float ( (1/ (RMT_ClockRate/RMT_Clock_Divisor)) * float(NanoSecondsInASecond))
170 bool ThereIsDataToSend =
false;
172 void IRAM_ATTR ISR_Handler (isrTxFlags_t isrFlags);
176#ifdef USE_RMT_DEBUG_COUNTERS
179 uint32_t DataCallbackCounter = 0;
180 uint32_t DataTaskcounter = 0;
181 uint32_t ISRcounter = 0;
182 uint32_t FrameStartCounter = 0;
183 uint32_t SendBlockIsrCounter = 0;
184 uint32_t RanOutOfData = 0;
185 uint32_t UnknownISRcounter = 0;
186 uint32_t IntTxEndIsrCounter = 0;
187 uint32_t IntTxThrIsrCounter = 0;
189 uint32_t ErrorIsr = 0;
190 uint32_t IntensityValuesSent = 0;
191 uint32_t IntensityBitsSent = 0;
192 uint32_t IntensityValuesSentLastFrame = 0;
193 uint32_t IntensityBitsSentLastFrame = 0;
194 uint32_t IncompleteFrame = 0;
195 uint32_t RmtEntriesTransfered = 0;
196 uint32_t RmtXmtFills = 0;
197 uint32_t RmtWhiteDetected = 0;
198 uint32_t FailedToSendAllData = 0;
200#define RMT_DEBUG_COUNTER(p) p
204#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