Skip to content

Commit fc39193

Browse files
committed
refactored tx-conti interrupts to function to make it more readable
1 parent 396ce23 commit fc39193

File tree

1 file changed

+116
-94
lines changed

1 file changed

+116
-94
lines changed

cores/esp32/esp32-hal-rmt.c

Lines changed: 116 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*/
2222
#define MAX_CHANNELS 8
2323
#define MAX_DATA_PER_CHANNEL 64
24-
#define MAX_DATA_PER_ITTERATION 40
24+
#define MAX_DATA_PER_ITTERATION 62
2525
#define _ABS(a) (a>0?a:-a)
2626
#define _LIMIT(a,b) (a>b?b:a)
2727
#define __INT_TX_END (1)
@@ -42,6 +42,15 @@
4242
# define RMT_MUTEX_UNLOCK(channel) xSemaphoreGive(g_rmt_objlocks[channel])
4343
#endif /* CONFIG_DISABLE_HAL_LOCKS */
4444

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+
4554
/**
4655
* Typedefs for internal stuctures, enums
4756
*/
@@ -118,6 +127,10 @@ static void _initPin(int pin, int channel, bool tx_not_rx);
118127

119128
static int IRAM_ATTR _rmt_get_mem_len(uint8_t channel);
120129

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+
121134

122135
/**
123136
* Public method definitions
@@ -234,7 +247,7 @@ bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
234247
rmt->tx_state = E_SET_CONTI | E_FIRST_HALF;
235248

236249
// 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;
238251
// reset memory pointer
239252
RMT.conf_ch[channel].conf1.apb_mem_rst = 1;
240253
RMT.conf_ch[channel].conf1.apb_mem_rst = 0;
@@ -588,15 +601,13 @@ static void _initPin(int pin, int channel, bool tx_not_rx)
588601

589602
static void IRAM_ATTR _rmt_isr(void* arg)
590603
{
591-
digitalWrite(4, 1);
592-
593604
int intr_val = RMT.int_st.val;
594605
size_t ch;
595606
for (ch = 0; ch < MAX_CHANNELS; ch++) {
596607

597608
if (intr_val & _INT_RX_END(ch)) {
598609
// 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);
600611
RMT.int_ena.val &= ~_INT_RX_END(ch);
601612

602613
if ((g_rmt_objects[ch].intr_mode) & E_RX_INTR) {
@@ -606,6 +617,7 @@ static void IRAM_ATTR _rmt_isr(void* arg)
606617
if (g_rmt_objects[ch].data_ptr && g_rmt_objects[ch].data_size > 0) {
607618
size_t i;
608619
uint32_t * data = g_rmt_objects[ch].data_ptr;
620+
// in case of callback, provide switching between memories
609621
if (g_rmt_objects[ch].cb) {
610622
if (g_rmt_objects[ch].tx_state & E_FIRST_HALF) {
611623
g_rmt_objects[ch].tx_state &= ~E_FIRST_HALF;
@@ -617,7 +629,6 @@ static void IRAM_ATTR _rmt_isr(void* arg)
617629
for (i = 0; i < g_rmt_objects[ch].data_size; i++ ) {
618630
*data++ = RMTMEM.chan[ch].data32[i].val;
619631
}
620-
// configured callback
621632
if (g_rmt_objects[ch].cb) {
622633
// actually received data ptr
623634
uint32_t * data = g_rmt_objects[ch].data_ptr;
@@ -662,33 +673,7 @@ static void IRAM_ATTR _rmt_isr(void* arg)
662673
if (intr_val & _INT_TX_END(ch)) {
663674

664675
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);
692677
}
693678

694679
if (intr_val & _INT_THR_EVNT(ch)) {
@@ -700,75 +685,112 @@ static void IRAM_ATTR _rmt_isr(void* arg)
700685
RMT.conf_ch[ch].conf1.tx_conti_mode = 1;
701686
g_rmt_objects[ch].intr_mode &= ~E_SET_CONTI;
702687
}
688+
_rmt_tx_mem_first(ch);
689+
}
690+
}
691+
}
703692

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];
730719
} 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;
758721
}
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];
764774
} else {
765-
// ...do_nothing
775+
RMTMEM.chan[ch].data32[i].val = 0x000F000F;
766776
}
767777
}
778+
779+
g_rmt_objects[ch].tx_state &= ~E_FIRST_HALF;
780+
g_rmt_objects[ch].data_ptr = NULL;
768781
}
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;
769792
}
770-
digitalWrite(4, 0);
771-
digitalWrite(2, 0);
793+
DEBUG_INTERRUPT_END(2);
772794
}
773795

774796
static int IRAM_ATTR _rmt_get_mem_len(uint8_t channel)

0 commit comments

Comments
 (0)