rmt/driver: Sped the rmt_driver_isr_default ISR

Used __builtin_ctz function to sped ISR.
This commit is contained in:
Konstantin Kondrashov
2019-02-07 21:20:39 +08:00
committed by bot
parent 3307735bc0
commit b1b5849c4c

View File

@@ -555,116 +555,112 @@ static int IRAM_ATTR rmt_get_mem_len(rmt_channel_t channel)
static void IRAM_ATTR rmt_driver_isr_default(void* arg) static void IRAM_ATTR rmt_driver_isr_default(void* arg)
{ {
uint32_t intr_st = RMT.int_st.val; const uint32_t intr_st = RMT.int_st.val;
uint32_t i = 0; uint32_t status = intr_st;
uint8_t channel; uint8_t channel;
portBASE_TYPE HPTaskAwoken = 0; portBASE_TYPE HPTaskAwoken = 0;
for(i = 0; i < 32; i++) { while (status) {
int i = __builtin_ffs(status) - 1;
status &= ~(1 << i);
if(i < 24) { if(i < 24) {
if(intr_st & BIT(i)) { channel = i / 3;
channel = i / 3; rmt_obj_t* p_rmt = p_rmt_obj[channel];
rmt_obj_t* p_rmt = p_rmt_obj[channel]; if(NULL == p_rmt) {
if(NULL == p_rmt) { continue;
RMT.int_clr.val = BIT(i); }
continue; switch(i % 3) {
} //TX END
switch(i % 3) { case 0:
//TX END xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken);
case 0: RMT.conf_ch[channel].conf1.mem_rd_rst = 1;
xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken); RMT.conf_ch[channel].conf1.mem_rd_rst = 0;
RMT.conf_ch[channel].conf1.mem_rd_rst = 1; p_rmt->tx_data = NULL;
RMT.conf_ch[channel].conf1.mem_rd_rst = 0; p_rmt->tx_len_rem = 0;
p_rmt->tx_data = NULL; p_rmt->tx_offset = 0;
p_rmt->tx_len_rem = 0; p_rmt->tx_sub_len = 0;
p_rmt->tx_offset = 0; p_rmt->sample_cur = NULL;
p_rmt->tx_sub_len = 0; p_rmt->translator = false;
p_rmt->sample_cur = NULL; if(rmt_tx_end_callback.function != NULL) {
p_rmt->translator = false; rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg);
if(rmt_tx_end_callback.function != NULL) { }
rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg); break;
} //RX_END
break; case 1:
//RX_END RMT.conf_ch[channel].conf1.rx_en = 0;
case 1: int item_len = rmt_get_mem_len(channel);
RMT.conf_ch[channel].conf1.rx_en = 0; //change memory owner to protect data.
int item_len = rmt_get_mem_len(channel); RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX;
//change memory owner to protect data. if(p_rmt->rx_buf) {
RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX; BaseType_t res = xRingbufferSendFromISR(p_rmt->rx_buf, (void*) RMTMEM.chan[channel].data32, item_len * 4, &HPTaskAwoken);
if(p_rmt->rx_buf) { if(res == pdFALSE) {
BaseType_t res = xRingbufferSendFromISR(p_rmt->rx_buf, (void*) RMTMEM.chan[channel].data32, item_len * 4, &HPTaskAwoken); ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER FULL");
if(res == pdFALSE) {
ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER FULL");
} else {
}
} else { } else {
ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER ERROR\n");
} }
RMT.conf_ch[channel].conf1.mem_wr_rst = 1; } else {
RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX; ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER ERROR\n");
RMT.conf_ch[channel].conf1.rx_en = 1; }
break; RMT.conf_ch[channel].conf1.mem_wr_rst = 1;
//ERR RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX;
case 2: RMT.conf_ch[channel].conf1.rx_en = 1;
ESP_EARLY_LOGE(RMT_TAG, "RMT[%d] ERR", channel); break;
ESP_EARLY_LOGE(RMT_TAG, "status: 0x%08x", RMT.status_ch[channel]); //ERR
RMT.int_ena.val &= (~(BIT(i))); case 2:
break; ESP_EARLY_LOGE(RMT_TAG, "RMT[%d] ERR", channel);
default: ESP_EARLY_LOGE(RMT_TAG, "status: 0x%08x", RMT.status_ch[channel]);
break; RMT.int_ena.val &= (~(BIT(i)));
} break;
RMT.int_clr.val = BIT(i); default:
break;
} }
} else { } else {
if(intr_st & (BIT(i))) { channel = i - 24;
channel = i - 24; rmt_obj_t* p_rmt = p_rmt_obj[channel];
rmt_obj_t* p_rmt = p_rmt_obj[channel];
RMT.int_clr.val = BIT(i);
if(p_rmt->tx_data == NULL) { if(p_rmt->tx_data == NULL) {
//skip //skip
} else {
if(p_rmt->translator) {
if(p_rmt->sample_size_remain > 0) {
size_t translated_size = 0;
p_rmt->sample_to_rmt((void *) p_rmt->sample_cur,
p_rmt->tx_buf,
p_rmt->sample_size_remain,
p_rmt->tx_sub_len,
&translated_size,
&p_rmt->tx_len_rem
);
p_rmt->sample_size_remain -= translated_size;
p_rmt->sample_cur += translated_size;
p_rmt->tx_data = p_rmt->tx_buf;
} else {
p_rmt->sample_cur = NULL;
p_rmt->translator = false;
}
}
const rmt_item32_t* pdata = p_rmt->tx_data;
int len_rem = p_rmt->tx_len_rem;
if(len_rem >= p_rmt->tx_sub_len) {
rmt_fill_memory(channel, pdata, p_rmt->tx_sub_len, p_rmt->tx_offset);
p_rmt->tx_data += p_rmt->tx_sub_len;
p_rmt->tx_len_rem -= p_rmt->tx_sub_len;
} else if(len_rem == 0) {
RMTMEM.chan[channel].data32[p_rmt->tx_offset].val = 0;
} else { } else {
if(p_rmt->translator) { rmt_fill_memory(channel, pdata, len_rem, p_rmt->tx_offset);
if(p_rmt->sample_size_remain > 0) { RMTMEM.chan[channel].data32[p_rmt->tx_offset + len_rem].val = 0;
size_t translated_size = 0; p_rmt->tx_data += len_rem;
p_rmt->sample_to_rmt((void *) p_rmt->sample_cur, p_rmt->tx_len_rem -= len_rem;
p_rmt->tx_buf, }
p_rmt->sample_size_remain, if(p_rmt->tx_offset == 0) {
p_rmt->tx_sub_len, p_rmt->tx_offset = p_rmt->tx_sub_len;
&translated_size, } else {
&p_rmt->tx_len_rem p_rmt->tx_offset = 0;
);
p_rmt->sample_size_remain -= translated_size;
p_rmt->sample_cur += translated_size;
p_rmt->tx_data = p_rmt->tx_buf;
} else {
p_rmt->sample_cur = NULL;
p_rmt->translator = false;
}
}
const rmt_item32_t* pdata = p_rmt->tx_data;
int len_rem = p_rmt->tx_len_rem;
if(len_rem >= p_rmt->tx_sub_len) {
rmt_fill_memory(channel, pdata, p_rmt->tx_sub_len, p_rmt->tx_offset);
p_rmt->tx_data += p_rmt->tx_sub_len;
p_rmt->tx_len_rem -= p_rmt->tx_sub_len;
} else if(len_rem == 0) {
RMTMEM.chan[channel].data32[p_rmt->tx_offset].val = 0;
} else {
rmt_fill_memory(channel, pdata, len_rem, p_rmt->tx_offset);
RMTMEM.chan[channel].data32[p_rmt->tx_offset + len_rem].val = 0;
p_rmt->tx_data += len_rem;
p_rmt->tx_len_rem -= len_rem;
}
if(p_rmt->tx_offset == 0) {
p_rmt->tx_offset = p_rmt->tx_sub_len;
} else {
p_rmt->tx_offset = 0;
}
} }
} }
} }
} }
RMT.int_clr.val = intr_st;
if(HPTaskAwoken == pdTRUE) { if(HPTaskAwoken == pdTRUE) {
portYIELD_FROM_ISR(); portYIELD_FROM_ISR();
} }
@@ -959,4 +955,4 @@ esp_err_t rmt_get_channel_status(rmt_channel_status_result_t *channel_status)
} }
} }
return ESP_OK; return ESP_OK;
} }