1+ #ifndef MAIN_ESP32_HAL_RMT_H_
2+ #define MAIN_ESP32_HAL_RMT_H_
3+
14#include "freertos/FreeRTOS.h"
25#include "freertos/event_groups.h"
36#include "freertos/semphr.h"
1316#include "soc/rmt_struct.h"
1417#include "esp_intr_alloc.h"
1518
16-
19+ /**
20+ * Internal macros
21+ */
1722#define MAX_CHANNELS 8
1823#define MAX_DATA_PER_CHANNEL 64
1924#define MAX_DATA_PER_ITTERATION 40
3742# define RMT_MUTEX_UNLOCK (channel ) xSemaphoreGive(g_rmt_objlocks[channel])
3843#endif /* CONFIG_DISABLE_HAL_LOCKS */
3944
45+ /**
46+ * Typedefs for internal stuctures, enums
47+ */
4048typedef enum {
4149 e_no_intr = 0 ,
4250 e_tx_intr = 1 ,
@@ -52,7 +60,6 @@ typedef enum {
5260 e_set_conti = 8 ,
5361} transaction_state_t ;
5462
55-
5663struct rmt_obj_s
5764{
5865 bool allocated ;
@@ -67,6 +74,9 @@ struct rmt_obj_s
6774 transaction_state_t tx_state ;
6875};
6976
77+ /**
78+ * Internal variables for channel descriptors
79+ */
7080static xSemaphoreHandle g_rmt_objlocks [MAX_CHANNELS ] = {
7181 NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL
7282};
@@ -82,20 +92,68 @@ static rmt_obj_t g_rmt_objects[MAX_CHANNELS] = {
8292 { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
8393};
8494
95+ /**
96+ * Internal variables for driver data
97+ */
8598static intr_handle_t intr_handle ;
8699
87100static bool periph_enabled = false;
88101
89102static xSemaphoreHandle g_rmt_block_lock = NULL ;
90103
91-
104+ /**
105+ * Internal method (private) declarations
106+ */
92107static void _initPin (int pin , int channel , bool tx_not_rx );
93108
94109static bool _rmtSendOnce (rmt_obj_t * rmt , uint32_t * data , size_t size );
95110
96-
97111static void IRAM_ATTR _rmt_isr (void * arg );
98112
113+ bool _rmtSendOnce (rmt_obj_t * rmt , uint32_t * data , size_t size );
114+
115+ static rmt_obj_t * _rmtAllocate (int pin , int from , int size );
116+
117+ static void _initPin (int pin , int channel , bool tx_not_rx );
118+
119+
120+ /**
121+ * Public method definitions
122+ */
123+ bool rmtSetCarrier (rmt_obj_t * rmt , bool carrier_en , bool carrier_level , uint32_t low , uint32_t high )
124+ {
125+ if (!rmt || low > 0xFFFF || high > 0xFFFF ) {
126+ return false;
127+ }
128+ size_t channel = rmt -> channel ;
129+
130+ RMT_MUTEX_LOCK (channel );
131+
132+ RMT .carrier_duty_ch [channel ].low = low ;
133+ RMT .carrier_duty_ch [channel ].low = high ;
134+ RMT .conf_ch [channel ].conf0 .carrier_en = carrier_en ;
135+ RMT .conf_ch [channel ].conf0 .carrier_out_lv = carrier_level ;
136+
137+ RMT_MUTEX_UNLOCK (channel );
138+
139+ return true;
140+
141+ }
142+
143+ bool rmtSetRxThreshold (rmt_obj_t * rmt , uint32_t value )
144+ {
145+ if (!rmt || value > 0xFFFF ) {
146+ return false;
147+ }
148+ size_t channel = rmt -> channel ;
149+
150+ RMT_MUTEX_LOCK (channel );
151+ RMT .conf_ch [channel ].conf0 .idle_thres = value ;
152+ RMT_MUTEX_UNLOCK (channel );
153+
154+ return true;
155+ }
156+
99157
100158bool rmtDeinit (rmt_obj_t * rmt )
101159{
@@ -128,7 +186,7 @@ bool rmtDeinit(rmt_obj_t *rmt)
128186 return true;
129187}
130188
131- bool rmtSent (rmt_obj_t * rmt , uint32_t * data , size_t size )
189+ bool rmtSend (rmt_obj_t * rmt , uint32_t * data , size_t size )
132190{
133191 if (!rmt ) {
134192 return false;
@@ -184,7 +242,7 @@ bool rmtSent(rmt_obj_t* rmt, uint32_t* data, size_t size)
184242}
185243
186244
187- bool rmtWaitForData (rmt_obj_t * rmt , uint32_t * data , size_t size )
245+ bool rmtGetData (rmt_obj_t * rmt , uint32_t * data , size_t size )
188246{
189247 if (!rmt ) {
190248 return false;
@@ -195,12 +253,6 @@ bool rmtWaitForData(rmt_obj_t* rmt, uint32_t* data, size_t size)
195253 return false;
196254 }
197255
198- // wait for the interrupt
199- while (!(RMT .int_raw .val & _INT_RX_END (channel ))) {}
200-
201- // clear the interrupt
202- RMT .int_clr .val |= _INT_RX_END (channel );
203-
204256 size_t i ;
205257 volatile uint32_t * rmt_mem_ptr = & (RMTMEM .chan [channel ].data32 [0 ].val );
206258 for (i = 0 ; i < size ; i ++ ) {
@@ -210,28 +262,40 @@ bool rmtWaitForData(rmt_obj_t* rmt, uint32_t* data, size_t size)
210262 return true;
211263}
212264
213- bool rmtReceive (rmt_obj_t * rmt , size_t idle_thres )
265+ bool rmtBeginReceive (rmt_obj_t * rmt )
214266{
215267 if (!rmt ) {
216268 return false;
217269 }
218270 int channel = rmt -> channel ;
219271
220272 RMT .int_clr .val |= _INT_ERROR (channel );
221-
222273 RMT .int_ena .val |= _INT_ERROR (channel );
223274
224275 RMT .conf_ch [channel ].conf1 .mem_owner = 1 ;
225- RMT .conf_ch [channel ].conf0 .idle_thres = idle_thres ;
226-
227276 RMT .conf_ch [channel ].conf1 .mem_wr_rst = 1 ;
228-
229277 RMT .conf_ch [channel ].conf1 .rx_en = 1 ;
230278
231279 return true;
232280}
233281
234- bool rmtReceiveAsync (rmt_obj_t * rmt , size_t idle_thres , uint32_t * data , size_t size , void * eventFlag )
282+ bool rmtReceiveCompleted (rmt_obj_t * rmt )
283+ {
284+ if (!rmt ) {
285+ return false;
286+ }
287+ int channel = rmt -> channel ;
288+
289+ if (RMT .int_raw .val & _INT_RX_END (channel )) {
290+ // RX end flag
291+ RMT .int_clr .val |= _INT_RX_END (channel );
292+ return true;
293+ } else {
294+ return false;
295+ }
296+ }
297+
298+ bool rmtReceive (rmt_obj_t * rmt , uint32_t * data , size_t size , void * eventFlag , bool waitForData , uint32_t timeout )
235299{
236300 if (!rmt ) {
237301 return false;
@@ -256,7 +320,6 @@ bool rmtReceiveAsync(rmt_obj_t* rmt, size_t idle_thres, uint32_t* data, size_t s
256320 rmt -> intr_mode = e_rx_intr ;
257321
258322 RMT .conf_ch [channel ].conf1 .mem_owner = 1 ;
259- RMT .conf_ch [channel ].conf0 .idle_thres = idle_thres ;
260323
261324 RMT .int_clr .val |= _INT_RX_END (channel );
262325 RMT .int_clr .val |= _INT_ERROR (channel );
@@ -269,49 +332,18 @@ bool rmtReceiveAsync(rmt_obj_t* rmt, size_t idle_thres, uint32_t* data, size_t s
269332 RMT .conf_ch [channel ].conf1 .rx_en = 1 ;
270333 RMT_MUTEX_UNLOCK (channel );
271334
272- return true;
273- }
274-
275-
276- bool _rmtSendOnce (rmt_obj_t * rmt , uint32_t * data , size_t size )
277- {
278- if (!rmt ) {
279- return false;
280- }
281- int channel = rmt -> channel ;
282- RMT .apb_conf .fifo_mask = 1 ;
283- if (data && size > 0 ) {
284- size_t i ;
285- volatile uint32_t * rmt_mem_ptr = & (RMTMEM .chan [channel ].data32 [0 ].val );
286- for (i = 0 ; i < size ; i ++ ) {
287- * rmt_mem_ptr ++ = data [i ];
335+ // wait for data if requested so
336+ if (waitForData && eventFlag ) {
337+ uint32_t flags = xEventGroupWaitBits (eventFlag , RMT_FLAGS_ALL ,
338+ pdTRUE /* clear on exit */ , pdFALSE /* wait for all bits */ , timeout );
339+ if (flags & RMT_FLAG_ERROR ) {
340+ return false;
288341 }
289- // tx end mark
290- RMTMEM .chan [channel ].data32 [size ].val = 0 ;
291342 }
292343
293- RMT_MUTEX_LOCK (channel );
294- RMT .conf_ch [channel ].conf1 .mem_rd_rst = 1 ;
295- RMT .conf_ch [channel ].conf1 .tx_start = 1 ;
296- RMT_MUTEX_UNLOCK (channel );
297-
298344 return true;
299345}
300346
301- static rmt_obj_t * _rmtAllocate (int pin , int from , int size )
302- {
303- size_t i ;
304- // setup how many buffers shall we use
305- g_rmt_objects [from ].buffers = size ;
306-
307- for (i = 0 ; i < size ; i ++ ) {
308- // mark the block of channels as used
309- g_rmt_objects [i + from ].allocated = true;
310- }
311- return & (g_rmt_objects [from ]);
312- }
313-
314-
315347float rmtSetTick (rmt_obj_t * rmt , float tick )
316348{
317349 if (!rmt ) {
@@ -400,12 +432,14 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
400432 // Initialize the registers in default mode:
401433 // - no carrier, filter
402434 // - timebase tick of 1us
435+ // - idle threshold set to 0x8000 (max pulse width + 1)
403436 RMT .conf_ch [channel ].conf0 .div_cnt = 1 ;
404437 RMT .conf_ch [channel ].conf0 .mem_size = buffers ;
405438 RMT .conf_ch [channel ].conf0 .carrier_en = 0 ;
406439 RMT .conf_ch [channel ].conf0 .carrier_out_lv = 0 ;
407440 RMT .conf_ch [channel ].conf0 .mem_pd = 0 ;
408441
442+ RMT .conf_ch [channel ].conf0 .idle_thres = 0x8000 ;
409443 RMT .conf_ch [channel ].conf1 .rx_en = 0 ;
410444 RMT .conf_ch [channel ].conf1 .tx_conti_mode = 0 ;
411445 RMT .conf_ch [channel ].conf1 .ref_cnt_rst = 0 ;
@@ -434,6 +468,49 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
434468 return rmt ;
435469}
436470
471+ /**
472+ * Private methods definitions
473+ */
474+ bool _rmtSendOnce (rmt_obj_t * rmt , uint32_t * data , size_t size )
475+ {
476+ if (!rmt ) {
477+ return false;
478+ }
479+ int channel = rmt -> channel ;
480+ RMT .apb_conf .fifo_mask = 1 ;
481+ if (data && size > 0 ) {
482+ size_t i ;
483+ volatile uint32_t * rmt_mem_ptr = & (RMTMEM .chan [channel ].data32 [0 ].val );
484+ for (i = 0 ; i < size ; i ++ ) {
485+ * rmt_mem_ptr ++ = data [i ];
486+ }
487+ // tx end mark
488+ RMTMEM .chan [channel ].data32 [size ].val = 0 ;
489+ }
490+
491+ RMT_MUTEX_LOCK (channel );
492+ RMT .conf_ch [channel ].conf1 .mem_rd_rst = 1 ;
493+ RMT .conf_ch [channel ].conf1 .tx_start = 1 ;
494+ RMT_MUTEX_UNLOCK (channel );
495+
496+ return true;
497+ }
498+
499+
500+ static rmt_obj_t * _rmtAllocate (int pin , int from , int size )
501+ {
502+ size_t i ;
503+ // setup how many buffers shall we use
504+ g_rmt_objects [from ].buffers = size ;
505+
506+ for (i = 0 ; i < size ; i ++ ) {
507+ // mark the block of channels as used
508+ g_rmt_objects [i + from ].allocated = true;
509+ }
510+ return & (g_rmt_objects [from ]);
511+ }
512+
513+
437514static void _initPin (int pin , int channel , bool tx_not_rx )
438515{
439516 if (!periph_enabled ) {
@@ -617,3 +694,5 @@ static void IRAM_ATTR _rmt_isr(void* arg)
617694 digitalWrite (4 , 0 );
618695 digitalWrite (2 , 0 );
619696}
697+
698+ #endif /* MAIN_ESP32_HAL_RMT_H_ */
0 commit comments