-
-
Save igrr/5c4617b99d3cfa840cb88feeb3b58bff to your computer and use it in GitHub Desktop.
Code to reproduce "interrupt is not triggered during the light sleep" on ESP32-C3 (updated)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include "freertos/FreeRTOS.h" | |
#include "freertos/task.h" | |
#include "freertos/queue.h" | |
#include "driver/gpio.h" | |
#include "esp_pm.h" | |
#include "esp_log.h" | |
#include "esp_sleep.h" | |
#include "esp_intr_alloc.h" | |
// LED pin info | |
#define LED_PIN 2 | |
#define LED_PIN_MSK (1ULL<<LED_PIN) | |
// Button pin info | |
#define BUTTON_PIN 9 | |
#define BUTTON_PIN_MSK (1ULL<<BUTTON_PIN) | |
// Interrupt flags | |
#define ESP_INTR_FLAG_DEFAULT 0 | |
static QueueHandle_t gpio_evt_queue = NULL; | |
static void IRAM_ATTR gpio_isr_handler(void* arg) { | |
uint32_t gpio_num = (uint32_t) arg; | |
int in_level = gpio_get_level(gpio_num); | |
if (in_level == 0) { | |
gpio_set_intr_type(gpio_num, GPIO_INTR_HIGH_LEVEL); | |
} else { | |
gpio_set_intr_type(gpio_num, GPIO_INTR_LOW_LEVEL); | |
} | |
// On any GPIO interrupt send the data using queue | |
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); | |
// And toggle the LED gpio | |
static uint32_t level = 0; | |
gpio_set_level(LED_PIN, level); | |
level = level ? 0 : 1; | |
portYIELD_FROM_ISR(); | |
} | |
static void gpio_task_example(void* arg) { | |
uint32_t io_num; | |
for(;;) { | |
// Try to receive data from the ISR | |
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { | |
printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num)); | |
} | |
} | |
} | |
void app_main(void) { | |
esp_err_t err; | |
// Init LED GPIO | |
static const gpio_config_t led_cfg= { | |
.mode = GPIO_MODE_OUTPUT, | |
.pin_bit_mask = LED_PIN_MSK, | |
}; | |
err = gpio_config(&led_cfg); | |
assert(err == ESP_OK); | |
// Init button GPIO | |
static const gpio_config_t button_cfg = { | |
.intr_type = GPIO_INTR_LOW_LEVEL, | |
.pin_bit_mask = BUTTON_PIN_MSK, | |
.mode = GPIO_MODE_INPUT, | |
}; | |
err = gpio_config(&button_cfg); | |
assert(err == ESP_OK); | |
// Create queue and task to process GPIO ISR events | |
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t)); | |
assert(gpio_evt_queue); | |
xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL); | |
// Enable button GPIO interrupt | |
err = gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); | |
assert(err == ESP_OK); | |
err = gpio_isr_handler_add(BUTTON_PIN, gpio_isr_handler, (void*) BUTTON_PIN); | |
assert(err == ESP_OK); | |
// Enable power manager | |
static const esp_pm_config_esp32c3_t pm_config = { | |
.max_freq_mhz = 80, | |
.min_freq_mhz = 80, | |
.light_sleep_enable = true, | |
}; | |
err = esp_pm_configure(&pm_config); | |
assert(err == ESP_OK); | |
esp_sleep_enable_gpio_wakeup(); | |
gpio_wakeup_enable(BUTTON_PIN, GPIO_INTR_LOW_LEVEL); | |
// Block current task forever | |
vTaskDelay(portMAX_DELAY); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment