21
21
*/
22
22
#define MAX_CHANNELS 8
23
23
#define MAX_DATA_PER_CHANNEL 64
24
- #define MAX_DATA_PER_ITTERATION 40
24
+ #define MAX_DATA_PER_ITTERATION 62
25
25
#define _ABS (a ) (a>0?a:-a)
26
26
#define _LIMIT (a ,b ) (a>b?b:a)
27
27
#define __INT_TX_END (1)
42
42
# define RMT_MUTEX_UNLOCK (channel ) xSemaphoreGive(g_rmt_objlocks[channel])
43
43
#endif /* CONFIG_DISABLE_HAL_LOCKS */
44
44
45
+ #define _RMT_INTERNAL_DEBUG
46
+ #ifdef _RMT_INTERNAL_DEBUG
47
+ # define DEBUG_INTERRUPT_START (pin ) digitalWrite(pin, 1);
48
+ # define DEBUG_INTERRUPT_END (pin ) digitalWrite(pin, 0);
49
+ #else
50
+ # define DEBUG_INTERRUPT_START (pin )
51
+ # define DEBUG_INTERRUPT_END (pin )
52
+ #endif /* _RMT_INTERNAL_DEBUG */
53
+
45
54
/**
46
55
* Typedefs for internal stuctures, enums
47
56
*/
@@ -118,6 +127,10 @@ static void _initPin(int pin, int channel, bool tx_not_rx);
118
127
119
128
static int IRAM_ATTR _rmt_get_mem_len (uint8_t channel );
120
129
130
+ static void IRAM_ATTR _rmt_tx_mem_first (uint8_t ch );
131
+
132
+ static void IRAM_ATTR _rmt_tx_mem_second (uint8_t ch );
133
+
121
134
122
135
/**
123
136
* Public method definitions
@@ -234,7 +247,7 @@ bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
234
247
rmt -> tx_state = E_SET_CONTI | E_FIRST_HALF ;
235
248
236
249
// init the tx limit for interruption
237
- RMT .tx_lim_ch [channel ].limit = half_tx_nr ;
250
+ RMT .tx_lim_ch [channel ].limit = half_tx_nr + 2 ;
238
251
// reset memory pointer
239
252
RMT .conf_ch [channel ].conf1 .apb_mem_rst = 1 ;
240
253
RMT .conf_ch [channel ].conf1 .apb_mem_rst = 0 ;
@@ -588,15 +601,13 @@ static void _initPin(int pin, int channel, bool tx_not_rx)
588
601
589
602
static void IRAM_ATTR _rmt_isr (void * arg )
590
603
{
591
- digitalWrite (4 , 1 );
592
-
593
604
int intr_val = RMT .int_st .val ;
594
605
size_t ch ;
595
606
for (ch = 0 ; ch < MAX_CHANNELS ; ch ++ ) {
596
607
597
608
if (intr_val & _INT_RX_END (ch )) {
598
609
// clear the flag
599
- RMT .int_clr .val = _INT_RX_END (ch ); // TODO: replace clear interrupts
610
+ RMT .int_clr .val = _INT_RX_END (ch );
600
611
RMT .int_ena .val &= ~_INT_RX_END (ch );
601
612
602
613
if ((g_rmt_objects [ch ].intr_mode ) & E_RX_INTR ) {
@@ -606,6 +617,7 @@ static void IRAM_ATTR _rmt_isr(void* arg)
606
617
if (g_rmt_objects [ch ].data_ptr && g_rmt_objects [ch ].data_size > 0 ) {
607
618
size_t i ;
608
619
uint32_t * data = g_rmt_objects [ch ].data_ptr ;
620
+ // in case of callback, provide switching between memories
609
621
if (g_rmt_objects [ch ].cb ) {
610
622
if (g_rmt_objects [ch ].tx_state & E_FIRST_HALF ) {
611
623
g_rmt_objects [ch ].tx_state &= ~E_FIRST_HALF ;
@@ -617,7 +629,6 @@ static void IRAM_ATTR _rmt_isr(void* arg)
617
629
for (i = 0 ; i < g_rmt_objects [ch ].data_size ; i ++ ) {
618
630
* data ++ = RMTMEM .chan [ch ].data32 [i ].val ;
619
631
}
620
- // configured callback
621
632
if (g_rmt_objects [ch ].cb ) {
622
633
// actually received data ptr
623
634
uint32_t * data = g_rmt_objects [ch ].data_ptr ;
@@ -662,33 +673,7 @@ static void IRAM_ATTR _rmt_isr(void* arg)
662
673
if (intr_val & _INT_TX_END (ch )) {
663
674
664
675
RMT .int_clr .val = _INT_TX_END (ch );
665
-
666
- if (g_rmt_objects [ch ].tx_state & E_LAST_DATA ) {
667
- g_rmt_objects [ch ].tx_state = E_END_TRANS ;
668
- RMT .conf_ch [ch ].conf1 .tx_conti_mode = 0 ;
669
- int half_tx_nr = MAX_DATA_PER_ITTERATION /2 ;
670
- int i ;
671
- if (g_rmt_objects [ch ].tx_state & E_FIRST_HALF ) {
672
- for (i = 0 ; i < half_tx_nr ; i ++ ) {
673
- RMTMEM .chan [ch ].data32 [i ].val = 0x000F000F ;
674
- }
675
- RMTMEM .chan [ch ].data32 [i ].val = 0 ;
676
- g_rmt_objects [ch ].tx_state &= ~E_FIRST_HALF ;
677
- } else {
678
- for (i = 0 ; i < half_tx_nr ; i ++ ) {
679
- RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = 0x000F000F ;
680
- }
681
- RMTMEM .chan [ch ].data32 [i ].val = 0 ;
682
- g_rmt_objects [ch ].tx_state |= E_FIRST_HALF ;
683
- }
684
-
685
- } else if (g_rmt_objects [ch ].tx_state & E_END_TRANS ) {
686
- RMT .conf_ch [ch ].conf1 .tx_conti_mode = 0 ;
687
- RMT .int_ena .val &= ~_INT_TX_END (ch );
688
- RMT .int_ena .val &= ~_INT_THR_EVNT (ch );
689
- g_rmt_objects [ch ].intr_mode = E_NO_INTR ;
690
- g_rmt_objects [ch ].tx_state = E_INACTIVE ;
691
- }
676
+ _rmt_tx_mem_second (ch );
692
677
}
693
678
694
679
if (intr_val & _INT_THR_EVNT (ch )) {
@@ -700,75 +685,112 @@ static void IRAM_ATTR _rmt_isr(void* arg)
700
685
RMT .conf_ch [ch ].conf1 .tx_conti_mode = 1 ;
701
686
g_rmt_objects [ch ].intr_mode &= ~E_SET_CONTI ;
702
687
}
688
+ _rmt_tx_mem_first (ch );
689
+ }
690
+ }
691
+ }
703
692
704
- // check if still any data to be sent
705
- uint32_t * data = g_rmt_objects [ ch ]. data_ptr ;
706
- if ( data )
707
- {
708
- int remaining_size = g_rmt_objects [ ch ]. data_size ;
709
- int half_tx_nr = MAX_DATA_PER_ITTERATION / 2 ;
710
- int i ;
711
-
712
- // will the remaining data occupy the entire halfbuffer
713
- if ( remaining_size > half_tx_nr ) {
714
- if ( g_rmt_objects [ ch ]. tx_state & E_FIRST_HALF ) {
715
- // ets_printf("first\n") ;
716
- RMTMEM . chan [ ch ]. data32 [ 0 ]. val = data [ 0 ] - 1 ;
717
- for ( i = 1 ; i < half_tx_nr ; i ++ ) {
718
- RMTMEM . chan [ch ].data32 [ i ]. val = data [ i ] ;
719
- }
720
- g_rmt_objects [ ch ]. tx_state &= ~ E_FIRST_HALF ;
721
- } else {
722
- // ets_printf("second\n") ;
723
- for ( i = 0 ; i < half_tx_nr ; i ++ ) {
724
- RMTMEM . chan [ch ].data32 [ half_tx_nr + i ]. val = data [ i ] ;
725
- }
726
- g_rmt_objects [ ch ]. tx_state |= E_FIRST_HALF ;
727
- }
728
- g_rmt_objects [ ch ]. data_size -= half_tx_nr ;
729
- g_rmt_objects [ch ].data_ptr += half_tx_nr ;
693
+ static void IRAM_ATTR _rmt_tx_mem_second ( uint8_t ch )
694
+ {
695
+ DEBUG_INTERRUPT_START ( 4 )
696
+ uint32_t * data = g_rmt_objects [ ch ]. data_ptr ;
697
+ int half_tx_nr = MAX_DATA_PER_ITTERATION / 2 ;
698
+ int i ;
699
+
700
+ RMT . tx_lim_ch [ ch ]. limit = half_tx_nr + 2 ;
701
+ RMT . int_clr . val = _INT_THR_EVNT ( ch );
702
+ RMT . int_ena . val |= _INT_THR_EVNT ( ch );
703
+
704
+ g_rmt_objects [ ch ]. tx_state |= E_FIRST_HALF ;
705
+
706
+ if ( data ) {
707
+ int remaining_size = g_rmt_objects [ch ].data_size ;
708
+ // will the remaining data occupy the entire halfbuffer
709
+ if ( remaining_size > half_tx_nr ) {
710
+ for ( i = 0 ; i < half_tx_nr ; i ++ ) {
711
+ RMTMEM . chan [ ch ]. data32 [ half_tx_nr + i ]. val = data [ i ] ;
712
+ }
713
+ g_rmt_objects [ch ].data_size -= half_tx_nr ;
714
+ g_rmt_objects [ ch ]. data_ptr += half_tx_nr ;
715
+ } else {
716
+ for ( i = 0 ; i < half_tx_nr ; i ++ ) {
717
+ if ( i < remaining_size ) {
718
+ RMTMEM . chan [ch ].data32 [ half_tx_nr + i ]. val = data [ i ] ;
730
719
} else {
731
- // less remaining data than buffer size -> fill in with fake (inactive) pulses
732
- //ets_printf("last chunk...");
733
- if (g_rmt_objects [ch ].tx_state & E_FIRST_HALF ) {
734
- //ets_printf("first\n");
735
- RMTMEM .chan [ch ].data32 [0 ].val = data [0 ] - 1 ;
736
- for (i = 1 ; i < half_tx_nr ; i ++ ) {
737
- if (i < remaining_size ) {
738
- RMTMEM .chan [ch ].data32 [i ].val = data [i ];
739
- } else {
740
- RMTMEM .chan [ch ].data32 [i ].val = 0x000F000F ;
741
- }
742
- }
743
- g_rmt_objects [ch ].tx_state &= ~E_FIRST_HALF ;
744
- } else {
745
- //ets_printf("second\n");
746
- for (i = 0 ; i < half_tx_nr ; i ++ ) {
747
- if (i < remaining_size ) {
748
- RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = data [i ];
749
- } else {
750
- RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = 0x000F000F ;
751
- }
752
- }
753
- g_rmt_objects [ch ].tx_state |= E_FIRST_HALF ;
754
- }
755
- RMTMEM .chan [ch ].data32 [MAX_DATA_PER_ITTERATION ].val = 0 ;
756
- // mark
757
- g_rmt_objects [ch ].data_ptr = NULL ;
720
+ RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = 0x000F000F ;
758
721
}
759
- } else {
760
- // no data left, just copy the fake (inactive) pulses
761
- if ( (!(g_rmt_objects [ch ].tx_state & E_LAST_DATA )) &&
762
- (!(g_rmt_objects [ch ].tx_state & E_END_TRANS )) ) {
763
- g_rmt_objects [ch ].tx_state |= E_END_TRANS ;
722
+ }
723
+ g_rmt_objects [ch ].data_ptr = NULL ;
724
+
725
+ }
726
+ } else if ((!(g_rmt_objects [ch ].tx_state & E_LAST_DATA )) &&
727
+ (!(g_rmt_objects [ch ].tx_state & E_END_TRANS ))) {
728
+ for (i = 0 ; i < half_tx_nr ; i ++ ) {
729
+ RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = 0x000F000F ;
730
+ }
731
+ RMTMEM .chan [ch ].data32 [half_tx_nr + i ].val = 0 ;
732
+ g_rmt_objects [ch ].tx_state |= E_LAST_DATA ;
733
+ RMT .conf_ch [ch ].conf1 .tx_conti_mode = 0 ;
734
+ } else {
735
+ log_d ("RMT Tx finished %d!\n" , ch );
736
+ RMT .conf_ch [ch ].conf1 .tx_conti_mode = 0 ;
737
+ RMT .int_ena .val &= ~_INT_TX_END (ch );
738
+ RMT .int_ena .val &= ~_INT_THR_EVNT (ch );
739
+ g_rmt_objects [ch ].intr_mode = E_NO_INTR ;
740
+ g_rmt_objects [ch ].tx_state = E_INACTIVE ;
741
+ }
742
+ DEBUG_INTERRUPT_END (4 );
743
+ }
744
+
745
+ static void IRAM_ATTR _rmt_tx_mem_first (uint8_t ch )
746
+ {
747
+ DEBUG_INTERRUPT_START (2 );
748
+ uint32_t * data = g_rmt_objects [ch ].data_ptr ;
749
+ int half_tx_nr = MAX_DATA_PER_ITTERATION /2 ;
750
+ int i ;
751
+ RMT .int_ena .val &= ~_INT_THR_EVNT (ch );
752
+ RMT .tx_lim_ch [ch ].limit = 0 ;
753
+
754
+ if (data ) {
755
+ int remaining_size = g_rmt_objects [ch ].data_size ;
756
+
757
+ // will the remaining data occupy the entire halfbuffer
758
+ if (remaining_size > half_tx_nr ) {
759
+ RMTMEM .chan [ch ].data32 [0 ].val = data [0 ] - 1 ;
760
+ for (i = 1 ; i < half_tx_nr ; i ++ ) {
761
+ RMTMEM .chan [ch ].data32 [i ].val = data [i ];
762
+ }
763
+ g_rmt_objects [ch ].tx_state &= ~E_FIRST_HALF ;
764
+ // turn off the treshold interrupt
765
+ RMT .int_ena .val &= ~_INT_THR_EVNT (ch );
766
+ RMT .tx_lim_ch [ch ].limit = 0 ;
767
+ g_rmt_objects [ch ].data_size -= half_tx_nr ;
768
+ g_rmt_objects [ch ].data_ptr += half_tx_nr ;
769
+ } else {
770
+ RMTMEM .chan [ch ].data32 [0 ].val = data [0 ] - 1 ;
771
+ for (i = 1 ; i < half_tx_nr ; i ++ ) {
772
+ if (i < remaining_size ) {
773
+ RMTMEM .chan [ch ].data32 [i ].val = data [i ];
764
774
} else {
765
- // ...do_nothing
775
+ RMTMEM . chan [ ch ]. data32 [ i ]. val = 0x000F000F ;
766
776
}
767
777
}
778
+
779
+ g_rmt_objects [ch ].tx_state &= ~E_FIRST_HALF ;
780
+ g_rmt_objects [ch ].data_ptr = NULL ;
768
781
}
782
+ } else {
783
+ for (i = 0 ; i < half_tx_nr ; i ++ ) {
784
+ RMTMEM .chan [ch ].data32 [i ].val = 0x000F000F ;
785
+ }
786
+ RMTMEM .chan [ch ].data32 [i ].val = 0 ;
787
+
788
+ g_rmt_objects [ch ].tx_state &= ~E_FIRST_HALF ;
789
+ RMT .tx_lim_ch [ch ].limit = 0 ;
790
+ g_rmt_objects [ch ].tx_state |= E_LAST_DATA ;
791
+ RMT .conf_ch [ch ].conf1 .tx_conti_mode = 0 ;
769
792
}
770
- digitalWrite (4 , 0 );
771
- digitalWrite (2 , 0 );
793
+ DEBUG_INTERRUPT_END (2 );
772
794
}
773
795
774
796
static int IRAM_ATTR _rmt_get_mem_len (uint8_t channel )
0 commit comments