Selaa lähdekoodia

rmt/driver: Sped the rmt_driver_isr_default ISR

Used __builtin_ctz function to sped ISR.
Konstantin Kondrashov 7 vuotta sitten
vanhempi
sitoutus
b1b5849c4c
1 muutettua tiedostoa jossa 93 lisäystä ja 97 poistoa
  1. 93 97
      components/driver/rmt.c

+ 93 - 97
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 {
-
-                            }
-                        } 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);
+            channel = i / 3;
+            rmt_obj_t* p_rmt = p_rmt_obj[channel];
+            if(NULL == p_rmt) {
+                continue;
             }
-        } else {
-            if(intr_st & (BIT(i))) {
-                channel = i - 24;
-                rmt_obj_t* p_rmt = p_rmt_obj[channel];
-                RMT.int_clr.val = BIT(i);
-
-                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;
+            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 {
-                            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;
+                        ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER ERROR\n");
                     }
-                    if(p_rmt->tx_offset == 0) {
-                        p_rmt->tx_offset = p_rmt->tx_sub_len;
+                    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 {
+            channel = i - 24;
+            rmt_obj_t* p_rmt = p_rmt_obj[channel];
+
+            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->tx_offset = 0;
+                        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) {
         portYIELD_FROM_ISR();
     }
@@ -959,4 +955,4 @@ esp_err_t rmt_get_channel_status(rmt_channel_status_result_t *channel_status)
         }
     }
     return ESP_OK;
-}
+}