@@ -72,6 +72,8 @@ struct rmt_obj_s
72
72
uint32_t * remaining_ptr ;
73
73
intr_mode_t intr_mode ;
74
74
transaction_state_t tx_state ;
75
+ rmt_rx_data_cb_t cb ;
76
+ bool data_alloc ;
75
77
};
76
78
77
79
/**
@@ -82,14 +84,14 @@ static xSemaphoreHandle g_rmt_objlocks[MAX_CHANNELS] = {
82
84
};
83
85
84
86
static rmt_obj_t g_rmt_objects [MAX_CHANNELS ] = {
85
- { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
86
- { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
87
- { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
88
- { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
89
- { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
90
- { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
91
- { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
92
- { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive },
87
+ { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive , NULL , false },
88
+ { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive , NULL , false },
89
+ { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive , NULL , false },
90
+ { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive , NULL , false },
91
+ { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive , NULL , false },
92
+ { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive , NULL , false },
93
+ { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive , NULL , false },
94
+ { false, NULL , 0 , 0 , 0 , 0 , 0 , NULL , e_no_intr , e_inactive , NULL , false },
93
95
};
94
96
95
97
/**
@@ -106,16 +108,16 @@ static xSemaphoreHandle g_rmt_block_lock = NULL;
106
108
*/
107
109
static void _initPin (int pin , int channel , bool tx_not_rx );
108
110
109
- static bool _rmtSendOnce (rmt_obj_t * rmt , uint32_t * data , size_t size );
111
+ static bool _rmtSendOnce (rmt_obj_t * rmt , rmt_data_t * data , size_t size );
110
112
111
113
static void IRAM_ATTR _rmt_isr (void * arg );
112
114
113
- bool _rmtSendOnce (rmt_obj_t * rmt , uint32_t * data , size_t size );
114
-
115
115
static rmt_obj_t * _rmtAllocate (int pin , int from , int size );
116
116
117
117
static void _initPin (int pin , int channel , bool tx_not_rx );
118
118
119
+ static int IRAM_ATTR _rmt_get_mem_len (uint8_t channel );
120
+
119
121
120
122
/**
121
123
* Public method definitions
@@ -140,6 +142,24 @@ bool rmtSetCarrier(rmt_obj_t* rmt, bool carrier_en, bool carrier_level, uint32_t
140
142
141
143
}
142
144
145
+ bool rmtSetFilter (rmt_obj_t * rmt , bool filter_en , uint32_t filter_level )
146
+ {
147
+ if (!rmt || filter_level > 0xFF ) {
148
+ return false;
149
+ }
150
+ size_t channel = rmt -> channel ;
151
+
152
+ RMT_MUTEX_LOCK (channel );
153
+
154
+ RMT .conf_ch [channel ].conf1 .rx_filter_thres = filter_level ;
155
+ RMT .conf_ch [channel ].conf1 .rx_filter_en = filter_en ;
156
+
157
+ RMT_MUTEX_UNLOCK (channel );
158
+
159
+ return true;
160
+
161
+ }
162
+
143
163
bool rmtSetRxThreshold (rmt_obj_t * rmt , uint32_t value )
144
164
{
145
165
if (!rmt || value > 0xFFFF ) {
@@ -186,7 +206,7 @@ bool rmtDeinit(rmt_obj_t *rmt)
186
206
return true;
187
207
}
188
208
189
- bool rmtSend (rmt_obj_t * rmt , uint32_t * data , size_t size )
209
+ bool rmtWrite (rmt_obj_t * rmt , rmt_data_t * data , size_t size )
190
210
{
191
211
if (!rmt ) {
192
212
return false;
@@ -205,7 +225,7 @@ bool rmtSend(rmt_obj_t* rmt, uint32_t* data, size_t size)
205
225
}
206
226
207
227
rmt -> remaining_to_send = size - MAX_DATA_PER_ITTERATION ;
208
- rmt -> remaining_ptr = data + MAX_DATA_PER_ITTERATION ;
228
+ rmt -> remaining_ptr = (( uint32_t * ) data ) + MAX_DATA_PER_ITTERATION ;
209
229
rmt -> intr_mode = e_tx_intr | e_txthr_intr ;
210
230
rmt -> tx_state = e_set_conti | e_first_half ;
211
231
@@ -242,7 +262,7 @@ bool rmtSend(rmt_obj_t* rmt, uint32_t* data, size_t size)
242
262
}
243
263
244
264
245
- bool rmtGetData (rmt_obj_t * rmt , uint32_t * data , size_t size )
265
+ bool rmtReadData (rmt_obj_t * rmt , uint32_t * data , size_t size )
246
266
{
247
267
if (!rmt ) {
248
268
return false;
@@ -295,7 +315,41 @@ bool rmtReceiveCompleted(rmt_obj_t* rmt)
295
315
}
296
316
}
297
317
298
- bool rmtReceive (rmt_obj_t * rmt , uint32_t * data , size_t size , void * eventFlag , bool waitForData , uint32_t timeout )
318
+ bool rmtRead (rmt_obj_t * rmt , rmt_rx_data_cb_t cb )
319
+ {
320
+ if (!rmt && !cb ) {
321
+ return false;
322
+ }
323
+ int channel = rmt -> channel ;
324
+
325
+ RMT_MUTEX_LOCK (channel );
326
+ rmt -> intr_mode = e_rx_intr ;
327
+ rmt -> tx_state = e_first_half ;
328
+ rmt -> cb = cb ;
329
+ // allocate internally two buffers which would alternate
330
+ if (!rmt -> data_alloc ) {
331
+ rmt -> remaining_ptr = (uint32_t * )malloc (2 * MAX_DATA_PER_CHANNEL * (rmt -> buffers )* sizeof (uint32_t ));
332
+ rmt -> remaining_to_send = MAX_DATA_PER_CHANNEL * rmt -> buffers ;
333
+ rmt -> data_alloc = true;
334
+ }
335
+
336
+ RMT .conf_ch [channel ].conf1 .mem_owner = 1 ;
337
+
338
+ RMT .int_clr .val = _INT_RX_END (channel );
339
+ RMT .int_clr .val = _INT_ERROR (channel );
340
+
341
+ RMT .int_ena .val |= _INT_RX_END (channel );
342
+ RMT .int_ena .val |= _INT_ERROR (channel );
343
+
344
+ RMT .conf_ch [channel ].conf1 .mem_wr_rst = 1 ;
345
+
346
+ RMT .conf_ch [channel ].conf1 .rx_en = 1 ;
347
+ RMT_MUTEX_UNLOCK (channel );
348
+
349
+ return true;
350
+ }
351
+
352
+ bool rmtReadAsync (rmt_obj_t * rmt , rmt_data_t * data , size_t size , void * eventFlag , bool waitForData , uint32_t timeout )
299
353
{
300
354
if (!rmt ) {
301
355
return false;
@@ -312,7 +366,7 @@ bool rmtReceive(rmt_obj_t* rmt, uint32_t* data, size_t size, void* eventFlag, bo
312
366
}
313
367
314
368
if (data && size > 0 ) {
315
- rmt -> remaining_ptr = data ;
369
+ rmt -> remaining_ptr = ( uint32_t * ) data ;
316
370
rmt -> remaining_to_send = size ;
317
371
}
318
372
@@ -321,8 +375,8 @@ bool rmtReceive(rmt_obj_t* rmt, uint32_t* data, size_t size, void* eventFlag, bo
321
375
322
376
RMT .conf_ch [channel ].conf1 .mem_owner = 1 ;
323
377
324
- RMT .int_clr .val | = _INT_RX_END (channel );
325
- RMT .int_clr .val | = _INT_ERROR (channel );
378
+ RMT .int_clr .val = _INT_RX_END (channel );
379
+ RMT .int_clr .val = _INT_ERROR (channel );
326
380
327
381
RMT .int_ena .val |= _INT_RX_END (channel );
328
382
RMT .int_ena .val |= _INT_ERROR (channel );
@@ -439,7 +493,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
439
493
RMT .conf_ch [channel ].conf0 .carrier_out_lv = 0 ;
440
494
RMT .conf_ch [channel ].conf0 .mem_pd = 0 ;
441
495
442
- RMT .conf_ch [channel ].conf0 .idle_thres = 0x8000 ;
496
+ RMT .conf_ch [channel ].conf0 .idle_thres = 0x80 ;
443
497
RMT .conf_ch [channel ].conf1 .rx_en = 0 ;
444
498
RMT .conf_ch [channel ].conf1 .tx_conti_mode = 0 ;
445
499
RMT .conf_ch [channel ].conf1 .ref_cnt_rst = 0 ;
@@ -448,6 +502,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
448
502
RMT .conf_ch [channel ].conf1 .idle_out_lv = 0 ; // signal level for idle
449
503
RMT .conf_ch [channel ].conf1 .idle_out_en = 1 ; // enable idle
450
504
RMT .conf_ch [channel ].conf1 .ref_always_on = 0 ; // base clock
505
+ RMT .apb_conf .fifo_mask = 1 ;
451
506
452
507
if (tx_not_rx ) {
453
508
// RMT.conf_ch[channel].conf1.rx_en = 0;
@@ -471,7 +526,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
471
526
/**
472
527
* Private methods definitions
473
528
*/
474
- bool _rmtSendOnce (rmt_obj_t * rmt , uint32_t * data , size_t size )
529
+ bool _rmtSendOnce (rmt_obj_t * rmt , rmt_data_t * data , size_t size )
475
530
{
476
531
if (!rmt ) {
477
532
return false;
@@ -482,7 +537,7 @@ bool _rmtSendOnce(rmt_obj_t* rmt, uint32_t* data, size_t size)
482
537
size_t i ;
483
538
volatile uint32_t * rmt_mem_ptr = & (RMTMEM .chan [channel ].data32 [0 ].val );
484
539
for (i = 0 ; i < size ; i ++ ) {
485
- * rmt_mem_ptr ++ = data [i ];
540
+ * rmt_mem_ptr ++ = data [i ]. val ;
486
541
}
487
542
// tx end mark
488
543
RMTMEM .chan [channel ].data32 [size ].val = 0 ;
@@ -534,42 +589,66 @@ static void IRAM_ATTR _rmt_isr(void* arg)
534
589
535
590
int intr_val = RMT .int_st .val ;
536
591
size_t ch ;
537
- for (ch = 0 ; ch < MAX_CHANNELS ; ch ++ ) {
592
+ for (ch = 0 ; ch < MAX_CHANNELS ; ch ++ ) {
538
593
539
- if (intr_val & _INT_RX_END (ch )) {
594
+ if (intr_val & _INT_RX_END (ch )) {
540
595
// clear the flag
541
- RMT .int_clr .val |= _INT_RX_END (ch );
542
- //
543
- if ((g_rmt_objects [ch ].intr_mode )& e_rx_intr ) {
596
+ RMT .int_clr .val = _INT_RX_END (ch ); // TODO: replace clear interrupts
597
+ RMT .int_ena .val &= ~_INT_RX_END (ch );
544
598
599
+ if ((g_rmt_objects [ch ].intr_mode )& e_rx_intr ) {
545
600
if (g_rmt_objects [ch ].events ) {
546
601
xEventGroupSetBits (g_rmt_objects [ch ].events , RMT_FLAG_RX_DONE );
547
602
}
548
603
if (g_rmt_objects [ch ].remaining_ptr && g_rmt_objects [ch ].remaining_to_send > 0 ) {
549
604
size_t i ;
605
+ uint32_t * data = g_rmt_objects [ch ].remaining_ptr ;
606
+ if (g_rmt_objects [ch ].cb ) {
607
+ if (g_rmt_objects [ch ].tx_state & e_first_half ) {
608
+ g_rmt_objects [ch ].tx_state &= ~e_first_half ;
609
+ } else {
610
+ g_rmt_objects [ch ].tx_state |= e_first_half ;
611
+ data += MAX_DATA_PER_CHANNEL * (g_rmt_objects [ch ].buffers );
612
+ }
613
+ }
550
614
for (i = 0 ; i < g_rmt_objects [ch ].remaining_to_send ; i ++ ) {
551
- * (g_rmt_objects [ch ].remaining_ptr )++ = RMTMEM .chan [ch ].data32 [i ].val ;
615
+ * data ++ = RMTMEM .chan [ch ].data32 [i ].val ;
616
+ }
617
+ // configured callback
618
+ if (g_rmt_objects [ch ].cb ) {
619
+ // actually received data ptr
620
+ uint32_t * data = g_rmt_objects [ch ].remaining_ptr ;
621
+ (g_rmt_objects [ch ].cb )(data , _rmt_get_mem_len (ch ));
622
+
623
+ // restart the reception
624
+ RMT .conf_ch [ch ].conf1 .mem_owner = 1 ;
625
+ RMT .conf_ch [ch ].conf1 .mem_wr_rst = 1 ;
626
+ RMT .conf_ch [ch ].conf1 .rx_en = 1 ;
627
+ RMT .int_ena .val |= _INT_RX_END (ch );
628
+ } else {
629
+ // if not callback provide, expect only one Rx
630
+ g_rmt_objects [ch ].intr_mode &= ~e_rx_intr ;
552
631
}
553
632
}
554
- g_rmt_objects [ch ].intr_mode &= ~e_rx_intr ;
555
-
556
633
} else {
557
634
// Report error and disable Rx interrupt
558
- ets_printf ("Unexpected Rx interrupt!\n" );
635
+ log_e ("Unexpected Rx interrupt!\n" ); // TODO: eplace messages with log_X
559
636
RMT .int_ena .val &= ~_INT_RX_END (ch );
560
637
}
638
+
639
+
561
640
}
562
641
563
642
if (intr_val & _INT_ERROR (ch )) {
643
+ digitalWrite (2 , 1 );
564
644
// clear the flag
565
- RMT .int_clr .val | = _INT_ERROR (ch );
645
+ RMT .int_clr .val = _INT_ERROR (ch );
566
646
RMT .int_ena .val &= ~_INT_ERROR (ch );
567
647
// report error
568
- ets_printf ("RMT Error %d!\n" , ch );
648
+ log_e ("RMT Error %d!\n" , ch );
569
649
if (g_rmt_objects [ch ].events ) {
570
650
xEventGroupSetBits (g_rmt_objects [ch ].events , RMT_FLAG_ERROR );
571
651
}
572
-
573
652
// reset memory
574
653
RMT .conf_ch [ch ].conf1 .mem_rd_rst = 1 ;
575
654
RMT .conf_ch [ch ].conf1 .mem_rd_rst = 0 ;
@@ -579,17 +658,29 @@ static void IRAM_ATTR _rmt_isr(void* arg)
579
658
580
659
if (intr_val & _INT_TX_END (ch )) {
581
660
582
- RMT .int_clr .val | = _INT_TX_END (ch );
661
+ RMT .int_clr .val = _INT_TX_END (ch );
583
662
584
663
if (g_rmt_objects [ch ].tx_state & e_last_data ) {
585
664
g_rmt_objects [ch ].tx_state = e_end_trans ;
586
- ets_printf ("Tx_End marked !\n" );
587
665
RMT .conf_ch [ch ].conf1 .tx_conti_mode = 0 ;
588
-
666
+ int half_tx_nr = MAX_DATA_PER_ITTERATION /2 ;
667
+ int i ;
668
+ if (g_rmt_objects [ch ].tx_state & e_first_half ) {
669
+ for (i = 0 ; i < half_tx_nr ; i ++ ) {
670
+ RMTMEM .chan [ch ].data32 [i ].val = 0x000F000F ;
671
+ }
672
+ RMTMEM .chan [ch ].data32 [i ].val = 0 ;
673
+ g_rmt_objects [ch ].tx_state &= ~e_first_half ;
674
+ } else {
675
+ for (i = 0 ; i < half_tx_nr ; i ++ ) {
676
+ RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = 0x000F000F ;
677
+ }
678
+ RMTMEM .chan [ch ].data32 [i ].val = 0 ;
679
+ g_rmt_objects [ch ].tx_state |= e_first_half ;
680
+ }
589
681
590
682
} else if (g_rmt_objects [ch ].tx_state & e_end_trans ) {
591
- ets_printf ("Tx completed !\n" );
592
- // disable interrupts and clear states
683
+ RMT .conf_ch [ch ].conf1 .tx_conti_mode = 0 ;
593
684
RMT .int_ena .val &= ~_INT_TX_END (ch );
594
685
RMT .int_ena .val &= ~_INT_THR_EVNT (ch );
595
686
g_rmt_objects [ch ].intr_mode = e_no_intr ;
@@ -599,7 +690,7 @@ static void IRAM_ATTR _rmt_isr(void* arg)
599
690
600
691
if (intr_val & _INT_THR_EVNT (ch )) {
601
692
// clear the flag
602
- RMT .int_clr .val |= _INT_THR_EVNT (ch );
693
+ RMT .int_clr .val | _INT_THR_EVNT (ch );
603
694
604
695
// initial setup of continuous mode
605
696
if (g_rmt_objects [ch ].tx_state & e_set_conti ) {
@@ -635,9 +726,9 @@ static void IRAM_ATTR _rmt_isr(void* arg)
635
726
g_rmt_objects [ch ].remaining_ptr += half_tx_nr ;
636
727
} else {
637
728
// less remaining data than buffer size -> fill in with fake (inactive) pulses
638
- // ets_printf("last chunk...");
729
+ ets_printf ("last chunk..." );
639
730
if (g_rmt_objects [ch ].tx_state & e_first_half ) {
640
- // ets_printf("first\n");
731
+ ets_printf ("first\n" );
641
732
RMTMEM .chan [ch ].data32 [0 ].val = data [0 ] - 1 ;
642
733
for (i = 1 ; i < half_tx_nr ; i ++ ) {
643
734
if (i < remaining_size ) {
@@ -648,7 +739,7 @@ static void IRAM_ATTR _rmt_isr(void* arg)
648
739
}
649
740
g_rmt_objects [ch ].tx_state &= ~e_first_half ;
650
741
} else {
651
- // ets_printf("second\n");
742
+ ets_printf ("second\n" );
652
743
for (i = 0 ; i < half_tx_nr ; i ++ ) {
653
744
if (i < remaining_size ) {
654
745
RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = data [i ];
@@ -666,27 +757,9 @@ static void IRAM_ATTR _rmt_isr(void* arg)
666
757
// no data left, just copy the fake (inactive) pulses
667
758
if ( (!(g_rmt_objects [ch ].tx_state & e_last_data )) &&
668
759
(!(g_rmt_objects [ch ].tx_state & e_end_trans )) ) {
669
- // ets_printf("tail (empty)");
670
- int half_tx_nr = MAX_DATA_PER_ITTERATION /2 ;
671
- int i ;
672
- if (g_rmt_objects [ch ].tx_state & e_first_half ) {
673
- // ets_printf("...first\n");
674
- for (i = 0 ; i < half_tx_nr ; i ++ ) {
675
- RMTMEM .chan [ch ].data32 [i ].val = 0x000F000F ;
676
- }
677
- RMTMEM .chan [ch ].data32 [i ].val = 0 ;
678
- g_rmt_objects [ch ].tx_state &= ~e_first_half ;
679
- } else {
680
- // ets_printf("...second\n");
681
- for (i = 0 ; i < half_tx_nr ; i ++ ) {
682
- RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = 0x000F000F ;
683
- }
684
- RMTMEM .chan [ch ].data32 [i ].val = 0 ;
685
- g_rmt_objects [ch ].tx_state |= e_first_half ;
686
- }
687
760
g_rmt_objects [ch ].tx_state |= e_last_data ;
688
761
} else {
689
- // ets_printf(" do_nothing\n");
762
+ // ... do_nothing
690
763
}
691
764
}
692
765
}
@@ -695,4 +768,20 @@ static void IRAM_ATTR _rmt_isr(void* arg)
695
768
digitalWrite (2 , 0 );
696
769
}
697
770
771
+ static int IRAM_ATTR _rmt_get_mem_len (uint8_t channel )
772
+ {
773
+ int block_num = RMT .conf_ch [channel ].conf0 .mem_size ;
774
+ int item_block_len = block_num * 64 ;
775
+ volatile rmt_item32_t * data = RMTMEM .chan [channel ].data32 ;
776
+ int idx ;
777
+ for (idx = 0 ; idx < item_block_len ; idx ++ ) {
778
+ if (data [idx ].duration0 == 0 ) {
779
+ return idx ;
780
+ } else if (data [idx ].duration1 == 0 ) {
781
+ return idx + 1 ;
782
+ }
783
+ }
784
+ return idx ;
785
+ }
786
+
698
787
#endif /* MAIN_ESP32_HAL_RMT_H_ */
0 commit comments