diff --git a/components/driver/rmt.c b/components/driver/rmt.c index 7a5443eba5..54ec46da8f 100644 --- a/components/driver/rmt.c +++ b/components/driver/rmt.c @@ -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) { - uint32_t intr_st = RMT.int_st.val; - uint32_t i = 0; + const uint32_t intr_st = RMT.int_st.val; + uint32_t status = intr_st; uint8_t channel; 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(intr_st & BIT(i)) { - channel = i / 3; - rmt_obj_t* p_rmt = p_rmt_obj[channel]; - if(NULL == p_rmt) { - RMT.int_clr.val = BIT(i); - continue; - } - switch(i % 3) { - //TX END - case 0: - xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken); - RMT.conf_ch[channel].conf1.mem_rd_rst = 1; - RMT.conf_ch[channel].conf1.mem_rd_rst = 0; - p_rmt->tx_data = NULL; - p_rmt->tx_len_rem = 0; - p_rmt->tx_offset = 0; - p_rmt->tx_sub_len = 0; - p_rmt->sample_cur = NULL; - p_rmt->translator = false; - if(rmt_tx_end_callback.function != NULL) { - rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg); - } - break; - //RX_END - case 1: - RMT.conf_ch[channel].conf1.rx_en = 0; - int item_len = rmt_get_mem_len(channel); - //change memory owner to protect data. - RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX; - if(p_rmt->rx_buf) { - BaseType_t res = xRingbufferSendFromISR(p_rmt->rx_buf, (void*) RMTMEM.chan[channel].data32, item_len * 4, &HPTaskAwoken); - if(res == pdFALSE) { - ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER FULL"); - } else { - - } + channel = i / 3; + rmt_obj_t* p_rmt = p_rmt_obj[channel]; + if(NULL == p_rmt) { + continue; + } + switch(i % 3) { + //TX END + case 0: + xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken); + RMT.conf_ch[channel].conf1.mem_rd_rst = 1; + RMT.conf_ch[channel].conf1.mem_rd_rst = 0; + p_rmt->tx_data = NULL; + p_rmt->tx_len_rem = 0; + p_rmt->tx_offset = 0; + p_rmt->tx_sub_len = 0; + p_rmt->sample_cur = NULL; + p_rmt->translator = false; + if(rmt_tx_end_callback.function != NULL) { + rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg); + } + break; + //RX_END + case 1: + RMT.conf_ch[channel].conf1.rx_en = 0; + int item_len = rmt_get_mem_len(channel); + //change memory owner to protect data. + RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX; + if(p_rmt->rx_buf) { + BaseType_t res = xRingbufferSendFromISR(p_rmt->rx_buf, (void*) RMTMEM.chan[channel].data32, item_len * 4, &HPTaskAwoken); + if(res == pdFALSE) { + ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER FULL"); } else { - ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER ERROR\n"); + } - RMT.conf_ch[channel].conf1.mem_wr_rst = 1; - RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX; - RMT.conf_ch[channel].conf1.rx_en = 1; - break; - //ERR - case 2: - ESP_EARLY_LOGE(RMT_TAG, "RMT[%d] ERR", channel); - ESP_EARLY_LOGE(RMT_TAG, "status: 0x%08x", RMT.status_ch[channel]); - RMT.int_ena.val &= (~(BIT(i))); - break; - default: - break; - } - RMT.int_clr.val = BIT(i); + } else { + ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER ERROR\n"); + } + RMT.conf_ch[channel].conf1.mem_wr_rst = 1; + RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX; + RMT.conf_ch[channel].conf1.rx_en = 1; + break; + //ERR + case 2: + ESP_EARLY_LOGE(RMT_TAG, "RMT[%d] ERR", channel); + ESP_EARLY_LOGE(RMT_TAG, "status: 0x%08x", RMT.status_ch[channel]); + RMT.int_ena.val &= (~(BIT(i))); + break; + default: + break; } } else { - if(intr_st & (BIT(i))) { - channel = i - 24; - rmt_obj_t* p_rmt = p_rmt_obj[channel]; - RMT.int_clr.val = BIT(i); + channel = i - 24; + rmt_obj_t* p_rmt = p_rmt_obj[channel]; - if(p_rmt->tx_data == NULL) { - //skip + if(p_rmt->tx_data == NULL) { + //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 { - 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 { - 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_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) { portYIELD_FROM_ISR(); } @@ -959,4 +955,4 @@ esp_err_t rmt_get_channel_status(rmt_channel_status_result_t *channel_status) } } return ESP_OK; -} \ No newline at end of file +}