22#ifdef ARDUINO_ARCH_ESP32
23#include <driver/rmt.h>
30 enum RmtDataBitIdType_t
32 RMT_DATA_BIT_ZERO_ID = 0,
35 RMT_DATA_BIT_THREE_ID,
36 RMT_INTERFRAME_GAP_ID,
42 RMT_NUM_BIT_TYPES = RMT_LIST_END,
43 RMT_STOP_START_BIT_ID = RMT_STOPBIT_ID,
46 struct ConvertIntensityToRmtDataStreamEntry_t
48 rmt_item32_t Translation;
49 RmtDataBitIdType_t Id;
51 typedef ConvertIntensityToRmtDataStreamEntry_t CitrdsArray_t;
53 struct OutputRmtConfig_t
55 rmt_channel_t RmtChannelId = rmt_channel_t(-1);
56 gpio_num_t DataPin = gpio_num_t(-1);
57 rmt_idle_level_t idle_level = rmt_idle_level_t::RMT_IDLE_LEVEL_LOW;
58 uint32_t IntensityDataWidth = 8;
59 bool SendInterIntensityBits =
false;
60 bool SendEndOfFrameBits =
false;
61 uint8_t NumFrameStartBits = 1;
62 uint8_t NumFrameStopBits = 1;
63 uint8_t NumIdleBits = 6;
69 DataDirection_t DataDirection = DataDirection_t::MSB2LSB;
70 const CitrdsArray_t *CitrdsArray =
nullptr;
73#if defined(SUPPORT_OutputType_DMX) || defined(SUPPORT_OutputType_Serial) || defined(SUPPORT_OutputType_Renard)
74 c_OutputSerial *pSerialDataSource =
nullptr;
79#define MAX_NUM_RMT_CHANNELS 8
80#define RMT_INT_TX_END (1)
81#define RMT_INT_RX_END (2)
82#define RMT_INT_ERROR (4)
83#define RMT_BITS_PER_CHAN (3)
85#define RMT_INT_THR_EVNT_BIT (1 << (24 + uint32_t (OutputRmtConfig.RmtChannelId)))
87#define RMT_INT_TX_END_BIT (RMT_INT_TX_END << (uint32_t (OutputRmtConfig.RmtChannelId)*RMT_BITS_PER_CHAN))
88#define RMT_INT_RX_END_BIT (RMT_INT_RX_END << (uint32_t (OutputRmtConfig.RmtChannelId)*RMT_BITS_PER_CHAN))
89#define RMT_INT_ERROR_BIT (RMT_INT_ERROR << (uint32_t (OutputRmtConfig.RmtChannelId)*RMT_BITS_PER_CHAN))
90#define NUM_RMT_SLOTS (sizeof(RMTMEM.chan[0].data32) / sizeof(RMTMEM.chan[0].data32[0]))
92 OutputRmtConfig_t OutputRmtConfig;
94 rmt_item32_t Intensity2Rmt[RmtDataBitIdType_t::RMT_LIST_END];
95 bool OutputIsPaused =
false;
97 uint32_t NumRmtSlotsPerIntensityValue = 8;
98 uint32_t NumRmtSlotOverruns = 0;
99 uint32_t MaxNumRmtSlotsPerInterrupt = (NUM_RMT_SLOTS/2);
101 rmt_item32_t SendBuffer[NUM_RMT_SLOTS * 2];
102 uint32_t RmtBufferWriteIndex = 0;
103 uint32_t SendBufferWriteIndex = 0;
104 uint32_t SendBufferReadIndex = 0;
105 uint32_t NumUsedEntriesInSendBuffer = 0;
107#define MIN_FRAME_TIME_MS 25
109 uint32_t TxIntensityDataStartingMask = 0x80;
110 RmtDataBitIdType_t InterIntensityValueId = RMT_INVALID_VALUE;
112 inline void IRAM_ATTR ISR_TransferIntensityDataToRMT (uint32_t NumEntriesToTransfer);
113 inline void IRAM_ATTR ISR_CreateIntensityData ();
114 inline void IRAM_ATTR ISR_WriteToBuffer(uint32_t value);
115 inline bool IRAM_ATTR ISR_MoreDataToSend();
116 inline bool IRAM_ATTR ISR_GetNextIntensityToSend(uint32_t &DataToSend);
117 inline void IRAM_ATTR ISR_StartNewDataFrame();
118 inline void IRAM_ATTR ISR_ResetRmtBlockPointers();
120#ifndef HasBeenInitialized
121 bool HasBeenInitialized =
false;
124 TaskHandle_t SendIntensityDataTaskHandle = NULL;
128 virtual ~c_OutputRmt ();
131 bool StartNewFrame ();
132 bool StartNextFrame () {
return ((
nullptr != pParent) & (!OutputIsPaused)) ? pParent->RmtPoll() :
false; }
133 void GetStatus (ArduinoJson::JsonObject& jsonStatus);
134 void set_pin (gpio_num_t _DataPin) { OutputRmtConfig.DataPin = _DataPin; rmt_set_gpio (OutputRmtConfig.RmtChannelId, rmt_mode_t::RMT_MODE_TX, OutputRmtConfig.DataPin,
false); }
135 void PauseOutput (
bool State);
136 inline uint32_t IRAM_ATTR GetRmtIntMask () {
return ((RMT_INT_TX_END_BIT | RMT_INT_ERROR_BIT | RMT_INT_ERROR_BIT)); }
139#define RMT_ISR_BITS (RMT_INT_TX_END_BIT | RMT_INT_THR_EVNT_BIT)
140#define DisableRmtInterrupts RMT.int_ena.val &= ~(RMT_ISR_BITS)
141#define EnableRmtInterrupts RMT.int_ena.val |= (RMT_ISR_BITS)
142#define ClearRmtInterrupts RMT.int_clr.val = (RMT_ISR_BITS)
143#define InterrupsAreEnabled (RMT.int_ena.val & (RMT_ISR_BITS))
145 bool DriverIsSendingIntensityData() {
return 0 != InterrupsAreEnabled;}
147#define RMT_ClockRate 80000000.0
148#define RMT_Clock_Divisor 2.0
149#define RMT_TickLengthNS float ( (1/ (RMT_ClockRate/RMT_Clock_Divisor)) * float(NanoSecondsInASecond))
151 void SetIntensity2Rmt (rmt_item32_t NewValue, RmtDataBitIdType_t ID) { Intensity2Rmt[ID] = NewValue; }
153 bool ThereIsDataToSend =
false;
154 bool NoFrameInProgress () {
return (0 == (RMT.int_ena.val & (RMT_ISR_BITS))); }
156 void IRAM_ATTR ISR_Handler (uint32_t isrFlags);
160#ifdef USE_RMT_DEBUG_COUNTERS
163 uint32_t DataCallbackCounter = 0;
164 uint32_t DataTaskcounter = 0;
165 uint32_t ISRcounter = 0;
166 uint32_t FrameStartCounter = 0;
167 uint32_t SendBlockIsrCounter = 0;
168 uint32_t RanOutOfData = 0;
169 uint32_t UnknownISRcounter = 0;
170 uint32_t IntTxEndIsrCounter = 0;
171 uint32_t IntTxThrIsrCounter = 0;
173 uint32_t ErrorIsr = 0;
174 uint32_t IntensityValuesSent = 0;
175 uint32_t IntensityBitsSent = 0;
176 uint32_t IntensityValuesSentLastFrame = 0;
177 uint32_t IntensityBitsSentLastFrame = 0;
178 uint32_t IncompleteFrame = 0;
179 uint32_t BitTypeCounters[RmtDataBitIdType_t::RMT_NUM_BIT_TYPES];
180 uint32_t RmtEntriesTransfered = 0;
181 uint32_t RmtXmtFills = 0;
182 uint32_t RmtWhiteDetected = 0;
183 uint32_t FailedToSendAllData = 0;
185#define RMT_DEBUG_COUNTER(p) p
189#define RMT_DEBUG_COUNTER(p)
const CN_PROGMEM char CN_RMT[]
Definition ConstNames.cpp:179
Definition OutputCommon.hpp:31
Definition OutputPixel.hpp:28
config_t config
Definition main.cpp:93
void GetDriverName(String &Name)
Definition main.cpp:115