diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 302aa850fc..0c9f553883 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -327,37 +327,37 @@ esp_err_t gpio_reset_pin(gpio_num_t gpio_num) return ESP_OK; } -void IRAM_ATTR gpio_intr_service(void* arg) +static inline void IRAM_ATTR gpio_isr_loop(uint32_t status, const uint32_t gpio_num_start) { + while (status) { + int nbit = __builtin_ffs(status) - 1; + status &= ~(1 << nbit); + int gpio_num = gpio_num_start + nbit; + if (gpio_isr_func[gpio_num].fn != NULL) { + gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args); + } + } +} + +static void IRAM_ATTR gpio_intr_service(void* arg) { //GPIO intr process - uint32_t gpio_num = 0; - //read status to get interrupt status for GPIO0-31 - uint32_t gpio_intr_status; - gpio_intr_status = GPIO.status; - //read status1 to get interrupt status for GPIO32-39 - uint32_t gpio_intr_status_h; - gpio_intr_status_h = GPIO.status1.intr_st; - if (gpio_isr_func == NULL) { return; } - do { - if (gpio_num < 32) { - if (gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31 - if (gpio_isr_func[gpio_num].fn != NULL) { - gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args); - } - GPIO.status_w1tc = BIT(gpio_num); - } - } else { - if (gpio_intr_status_h & BIT(gpio_num - 32)) { - if (gpio_isr_func[gpio_num].fn != NULL) { - gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args); - } - GPIO.status1_w1tc.intr_st = BIT(gpio_num - 32); - } - } - } while (++gpio_num < GPIO_PIN_COUNT); + + //read status to get interrupt status for GPIO0-31 + const uint32_t gpio_intr_status = GPIO.status; + if (gpio_intr_status) { + gpio_isr_loop(gpio_intr_status, 0); + GPIO.status_w1tc = gpio_intr_status; + } + + //read status1 to get interrupt status for GPIO32-39 + const uint32_t gpio_intr_status_h = GPIO.status1.intr_st; + if (gpio_intr_status_h) { + gpio_isr_loop(gpio_intr_status_h, 32); + GPIO.status1_w1tc.intr_st = gpio_intr_status_h; + } } esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void* args) diff --git a/components/driver/pcnt.c b/components/driver/pcnt.c index 6fcc2b5525..b91cb5965b 100644 --- a/components/driver/pcnt.c +++ b/components/driver/pcnt.c @@ -296,15 +296,16 @@ esp_err_t pcnt_isr_register(void (*fun)(void*), void * arg, int intr_alloc_flags // pcnt interrupt service static void IRAM_ATTR pcnt_intr_service(void* arg) { - uint32_t intr_status = PCNT.int_st.val; - for (int unit = 0; unit < PCNT_UNIT_MAX; unit++) { - if (intr_status & (BIT(unit))) { - if (pcnt_isr_func[unit].fn != NULL) { - (pcnt_isr_func[unit].fn)(pcnt_isr_func[unit].args); - } - PCNT.int_clr.val = BIT(unit); + const uint32_t intr_status = PCNT.int_st.val; + uint32_t status = intr_status; + while (status) { + int unit = __builtin_ffs(status) - 1; + status &= ~(1 << unit); + if (pcnt_isr_func[unit].fn != NULL) { + (pcnt_isr_func[unit].fn)(pcnt_isr_func[unit].args); } } + PCNT.int_clr.val = intr_status; } esp_err_t pcnt_isr_handler_add(pcnt_unit_t unit, void(*isr_handler)(void *), void *args) 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 +}