1
+ #ifndef MAIN_ESP32_HAL_RMT_H_
2
+ #define MAIN_ESP32_HAL_RMT_H_
3
+
1
4
#include "freertos/FreeRTOS.h"
2
5
#include "freertos/event_groups.h"
3
6
#include "freertos/semphr.h"
13
16
#include "soc/rmt_struct.h"
14
17
#include "esp_intr_alloc.h"
15
18
16
-
19
+ /**
20
+ * Internal macros
21
+ */
17
22
#define MAX_CHANNELS 8
18
23
#define MAX_DATA_PER_CHANNEL 64
19
24
#define MAX_DATA_PER_ITTERATION 40
37
42
# define RMT_MUTEX_UNLOCK (channel ) xSemaphoreGive(g_rmt_objlocks[channel])
38
43
#endif /* CONFIG_DISABLE_HAL_LOCKS */
39
44
45
+ /**
46
+ * Typedefs for internal stuctures, enums
47
+ */
40
48
typedef enum {
41
49
e_no_intr = 0 ,
42
50
e_tx_intr = 1 ,
@@ -52,7 +60,6 @@ typedef enum {
52
60
e_set_conti = 8 ,
53
61
} transaction_state_t ;
54
62
55
-
56
63
struct rmt_obj_s
57
64
{
58
65
bool allocated ;
@@ -67,6 +74,9 @@ struct rmt_obj_s
67
74
transaction_state_t tx_state ;
68
75
};
69
76
77
+ /**
78
+ * Internal variables for channel descriptors
79
+ */
70
80
static xSemaphoreHandle g_rmt_objlocks [MAX_CHANNELS ] = {
71
81
NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL
72
82
};
@@ -82,20 +92,68 @@ static rmt_obj_t g_rmt_objects[MAX_CHANNELS] = {
82
92
{ false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
83
93
};
84
94
95
+ /**
96
+ * Internal variables for driver data
97
+ */
85
98
static intr_handle_t intr_handle ;
86
99
87
100
static bool periph_enabled = false;
88
101
89
102
static xSemaphoreHandle g_rmt_block_lock = NULL ;
90
103
91
-
104
+ /**
105
+ * Internal method (private) declarations
106
+ */
92
107
static void _initPin (int pin , int channel , bool tx_not_rx );
93
108
94
109
static bool _rmtSendOnce (rmt_obj_t * rmt , uint32_t * data , size_t size );
95
110
96
-
97
111
static void IRAM_ATTR _rmt_isr (void * arg );
98
112
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
+
99
157
100
158
bool rmtDeinit (rmt_obj_t * rmt )
101
159
{
@@ -128,7 +186,7 @@ bool rmtDeinit(rmt_obj_t *rmt)
128
186
return true;
129
187
}
130
188
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 )
132
190
{
133
191
if (!rmt ) {
134
192
return false;
@@ -184,7 +242,7 @@ bool rmtSent(rmt_obj_t* rmt, uint32_t* data, size_t size)
184
242
}
185
243
186
244
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 )
188
246
{
189
247
if (!rmt ) {
190
248
return false;
@@ -195,12 +253,6 @@ bool rmtWaitForData(rmt_obj_t* rmt, uint32_t* data, size_t size)
195
253
return false;
196
254
}
197
255
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
-
204
256
size_t i ;
205
257
volatile uint32_t * rmt_mem_ptr = & (RMTMEM .chan [channel ].data32 [0 ].val );
206
258
for (i = 0 ; i < size ; i ++ ) {
@@ -210,28 +262,40 @@ bool rmtWaitForData(rmt_obj_t* rmt, uint32_t* data, size_t size)
210
262
return true;
211
263
}
212
264
213
- bool rmtReceive (rmt_obj_t * rmt , size_t idle_thres )
265
+ bool rmtBeginReceive (rmt_obj_t * rmt )
214
266
{
215
267
if (!rmt ) {
216
268
return false;
217
269
}
218
270
int channel = rmt -> channel ;
219
271
220
272
RMT .int_clr .val |= _INT_ERROR (channel );
221
-
222
273
RMT .int_ena .val |= _INT_ERROR (channel );
223
274
224
275
RMT .conf_ch [channel ].conf1 .mem_owner = 1 ;
225
- RMT .conf_ch [channel ].conf0 .idle_thres = idle_thres ;
226
-
227
276
RMT .conf_ch [channel ].conf1 .mem_wr_rst = 1 ;
228
-
229
277
RMT .conf_ch [channel ].conf1 .rx_en = 1 ;
230
278
231
279
return true;
232
280
}
233
281
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 )
235
299
{
236
300
if (!rmt ) {
237
301
return false;
@@ -256,7 +320,6 @@ bool rmtReceiveAsync(rmt_obj_t* rmt, size_t idle_thres, uint32_t* data, size_t s
256
320
rmt -> intr_mode = e_rx_intr ;
257
321
258
322
RMT .conf_ch [channel ].conf1 .mem_owner = 1 ;
259
- RMT .conf_ch [channel ].conf0 .idle_thres = idle_thres ;
260
323
261
324
RMT .int_clr .val |= _INT_RX_END (channel );
262
325
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
269
332
RMT .conf_ch [channel ].conf1 .rx_en = 1 ;
270
333
RMT_MUTEX_UNLOCK (channel );
271
334
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;
288
341
}
289
- // tx end mark
290
- RMTMEM .chan [channel ].data32 [size ].val = 0 ;
291
342
}
292
343
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
-
298
344
return true;
299
345
}
300
346
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
-
315
347
float rmtSetTick (rmt_obj_t * rmt , float tick )
316
348
{
317
349
if (!rmt ) {
@@ -400,12 +432,14 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
400
432
// Initialize the registers in default mode:
401
433
// - no carrier, filter
402
434
// - timebase tick of 1us
435
+ // - idle threshold set to 0x8000 (max pulse width + 1)
403
436
RMT .conf_ch [channel ].conf0 .div_cnt = 1 ;
404
437
RMT .conf_ch [channel ].conf0 .mem_size = buffers ;
405
438
RMT .conf_ch [channel ].conf0 .carrier_en = 0 ;
406
439
RMT .conf_ch [channel ].conf0 .carrier_out_lv = 0 ;
407
440
RMT .conf_ch [channel ].conf0 .mem_pd = 0 ;
408
441
442
+ RMT .conf_ch [channel ].conf0 .idle_thres = 0x8000 ;
409
443
RMT .conf_ch [channel ].conf1 .rx_en = 0 ;
410
444
RMT .conf_ch [channel ].conf1 .tx_conti_mode = 0 ;
411
445
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)
434
468
return rmt ;
435
469
}
436
470
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
+
437
514
static void _initPin (int pin , int channel , bool tx_not_rx )
438
515
{
439
516
if (!periph_enabled ) {
@@ -617,3 +694,5 @@ static void IRAM_ATTR _rmt_isr(void* arg)
617
694
digitalWrite (4 , 0 );
618
695
digitalWrite (2 , 0 );
619
696
}
697
+
698
+ #endif /* MAIN_ESP32_HAL_RMT_H_ */
0 commit comments