Merge branch 'feature/optimized_gpio_intr_service' into 'master'

driver: Add optimization by speed in ISR functions for gpio, rmt, pcnt

Closes IDF-328

See merge request idf/esp-idf!4241
This commit is contained in:
Angus Gratton
2019-03-20 14:19:17 +08:00
3 changed files with 128 additions and 131 deletions

View File

@@ -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);
//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;
}
GPIO.status_w1tc = BIT(gpio_num);
//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;
}
} 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);
}
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void* args)

View File

@@ -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))) {
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 = BIT(unit);
}
}
PCNT.int_clr.val = intr_status;
}
esp_err_t pcnt_isr_handler_add(pcnt_unit_t unit, void(*isr_handler)(void *), void *args)

View File

@@ -555,17 +555,17 @@ 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) {
@@ -613,13 +613,9 @@ static void IRAM_ATTR rmt_driver_isr_default(void* arg)
default:
break;
}
RMT.int_clr.val = BIT(i);
}
} 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
@@ -664,7 +660,7 @@ static void IRAM_ATTR rmt_driver_isr_default(void* arg)
}
}
}
}
RMT.int_clr.val = intr_st;
if(HPTaskAwoken == pdTRUE) {
portYIELD_FROM_ISR();
}