Thanks for the quick reply.
Sure I can put some codes here. For the sake of readability the pasted code is simplified.
First a brief description of the configuration.
GPIO26 used as INPUT, rising edge and falling edge are enabled for receiving interrupt. Internal pull-up enabled, I add one external 10k pull-up resistor as well.
GPIO18 used as OUTPUT, initial output = 0.
GPIO26 is connected to GPIO18 using a button. When the button is pressed, GPIO26 changes to low(falling edge), button released, GPIO changes to high(rising edge).
Macro definition:
Code: Select all
#define GPIO_IN_KEY_ROW_0 GPIO_NUM_26
#define GPIO_IN_KEY_ROW_1 GPIO_NUM_34
#define GPIO_IN_KEY_ROW_2 GPIO_NUM_35
#define GPIO_IN_KEY_ROW_3 GPIO_NUM_36
#define GPIO_IN_KEY_ROW_4 GPIO_NUM_39
#define GPIO_IN_PIN_SEL (((uint64_t)1<<GPIO_IN_KEY_ROW_0) | ((uint64_t)1<<GPIO_IN_KEY_ROW_1) | \
((uint64_t)1<<GPIO_IN_KEY_ROW_2) | ((uint64_t)1<<GPIO_IN_KEY_ROW_3) | \
((uint64_t)1<<GPIO_IN_KEY_ROW_4))
#define GPIO_OUT_KEY_COL_0 GPIO_NUM_18
#define GPIO_OUT_KEY_COL_1 GPIO_NUM_19
#define GPIO_OUT_KEY_COL_2 GPIO_NUM_21
#define GPIO_OUT_KEY_COL_3 GPIO_NUM_22
#define GPIO_OUT_PIN_SEL (((uint64_t)1<<GPIO_OUT_KEY_COL_0) | ((uint64_t)1<<GPIO_OUT_KEY_COL_1) | \
((uint64_t)1<<GPIO_OUT_KEY_COL_2) | ((uint64_t)1<<GPIO_OUT_KEY_COL_3))
appMain:
Code: Select all
void app_main()
{
gpio_config_t io_conf_out, io_conf_in;
//disable interrupt
io_conf_out.intr_type = GPIO_PIN_INTR_DISABLE;
//set as output mode
io_conf_out.mode = GPIO_MODE_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf_out.pin_bit_mask = GPIO_OUT_PIN_SEL;
//disable pull-down mode
io_conf_out.pull_down_en = 0;
//disable pull-up mode
io_conf_out.pull_up_en = 0;
//configure GPIO with the given settings
gpio_config(&io_conf_out);
//interrupt of rising and falling edge
io_conf_in.intr_type = GPIO_INTR_ANYEDGE;
//bit mask of the pins
io_conf_in.pin_bit_mask = GPIO_IN_PIN_SEL;
//set as input mode
io_conf_in.mode = GPIO_MODE_INPUT;
//disable pull-down mode
io_conf_in.pull_down_en = 0;
//enable pull-up mode
io_conf_in.pull_up_en = 1;
gpio_config(&io_conf_in);
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//start gpio task
xTaskCreate(gpio_task, "gpio_task", 2048, NULL, 10, NULL);
//install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_IN_KEY_ROW_0, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_0);
gpio_isr_handler_add(GPIO_IN_KEY_ROW_1, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_1);
gpio_isr_handler_add(GPIO_IN_KEY_ROW_2, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_2);
gpio_isr_handler_add(GPIO_IN_KEY_ROW_3, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_3);
gpio_isr_handler_add(GPIO_IN_KEY_ROW_4, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_4);
//init button COL GPIO pins to low
gpio_set_level(GPIO_OUT_KEY_COL_0, 0);
gpio_set_level(GPIO_OUT_KEY_COL_1, 0);
gpio_set_level(GPIO_OUT_KEY_COL_2, 0);
gpio_set_level(GPIO_OUT_KEY_COL_3, 0);
int cnt = 0;
while(1) {
printf("cnt: %d\n", cnt++);
vTaskDelay(1000 / portTICK_RATE_MS);
printf("row 0 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_0));
printf("row 1 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_1));
printf("row 2 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_2));
printf("row 3 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_3));
printf("row 4 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_4));
}
}
ISR code:
Code: Select all
static void gpio_isr_handler(void* arg)
{
static uint32_t isr_counter = 0;
uint32_t gpio_num = (uint32_t) arg;
gpio_intr_disable(26);
gpio_num += ((isr_counter++)<<24);
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
task code:
Code: Select all
static void gpio_task(void* arg)
{
uint32_t row = 0;
uint32_t col = 0;
uint32_t gpio_num = 0;
uint32_t isr_counter = 0;
char *button_pressed = "pressed";
char *button_released = "released";
for(;;)
{
if(xQueueReceive(gpio_evt_queue, &gpio_num, portMAX_DELAY))
{
//in case of falling edge
if(gpio_get_level(row) == 0)
{
// col = find_pressed_buttons_col(row);
gpio_set_level(18, 1);
vTaskDelay(200 / portTICK_RATE_MS);
gpio_set_level(18, 0);
}
//in case of rising edge
else
{
col = find_released_buttons_col(row);
}
isr_counter = gpio_num >> 24;
printf(" ISR counter %d \n", isr_counter);
gpio_intr_enable(26);
}
}
}
I made some simple modification to the GPIO example. So hopefully it is still readable.
The weird behavior is that when I pressed the button, and kept it pressed. I saw ISR counter kept incrementing, although interrupt of GPIO26 has been disabled.