Created
December 24, 2018 10:46
-
-
Save egeltje/db23f8c7b22002a30c68dad9b55c0f4d to your computer and use it in GitHub Desktop.
handling M5stack button interrupts in FreeRTOS
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 <freertos/FreeRTOS.h> | |
#include <freertos/task.h> | |
#include <driver/gpio.h> | |
#include <M5Stack.h> | |
#include <esp_log.h> | |
//#include <Arduino.h> | |
#include "sdkconfig.h" | |
#define ESP_INTR_FLAG_DEFAULT 0 | |
#define CONFIG_LOG_DEFAULT_LEVEL 5 // set to debug, check with serial monitor | |
static const char* TAG = "gpio_button"; // tag for logging | |
static TaskHandle_t xButtonHandle = NULL; // task handle for interrupt callback | |
static void IRAM_ATTR vfnButtonISR(void* vpArg) { | |
/*** | |
Interrupt routine for handling GPIO interrupts. | |
vpArg is a pointer to the GPIO number. | |
***/ | |
uint32_t ulGPIONumber = (uint32_t) vpArg; // get the triggering GPIO | |
if (gpio_get_level( (gpio_num_t) ulGPIONumber) == 0) { // only when pressed | |
xTaskNotifyFromISR(xButtonHandle, // task to notify | |
ulGPIONumber - 37, // 32 bit integer for passing a value | |
eSetBits, // notify action (pass value in this case) | |
NULL); // wake a higher prio task (default behavior) | |
} | |
portYIELD_FROM_ISR(); // if notified task has higher prio then current interrupted task, set it to the head of the task queue | |
} | |
static void vfnButtonTask(void* vpArg) { | |
/*** | |
Task for handling interrupts generated by button presses on the M5Stack | |
vpArg is a pointer to the passed arguments. Not used in this task. | |
***/ | |
uint32_t ulNotifiedValue = 0; | |
BaseType_t xResult; | |
while (1) { | |
m5.Lcd.setCursor(0, 0); | |
m5.Lcd.printf("running on core %d", xPortGetCoreID()); | |
m5.Lcd.setCursor(0, 40); | |
xResult = xTaskNotifyWait(pdFALSE, // don't clear bits on entry | |
0xFFFFFFFF, // clear all bits on exit | |
&ulNotifiedValue, // stores the notified value | |
portMAX_DELAY); // wait forever | |
if (xResult == pdPASS) { // if a notification is received | |
m5.Lcd.printf("button %d", ulNotifiedValue); | |
switch (ulNotifiedValue) { // to demonstrate the use of the switch statement | |
case 0: | |
ESP_LOGD(TAG, "button 0"); | |
break; | |
case 1: | |
ESP_LOGD(TAG, "button 1"); | |
break; | |
case 2: | |
ESP_LOGD(TAG, "button 2"); | |
break; | |
default: | |
ESP_LOGD(TAG, "This should not happen..."); | |
break; | |
} | |
} | |
} | |
vTaskDelete(NULL); // remove the task whene done | |
} | |
extern "C" void app_main() { // ESP32 FreeRTOS application entry point | |
ESP_LOGD(TAG, "Starting..."); | |
gpio_config_t xButtonConfig; | |
xButtonConfig.pin_bit_mask = GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39; | |
xButtonConfig.mode = GPIO_MODE_INPUT; | |
xButtonConfig.pull_up_en = GPIO_PULLUP_DISABLE; | |
xButtonConfig.pull_down_en = GPIO_PULLDOWN_ENABLE; | |
xButtonConfig.intr_type = GPIO_INTR_ANYEDGE; | |
gpio_config(&xButtonConfig); | |
m5.begin(); | |
m5.Lcd.setTextSize(3); | |
xTaskCreatePinnedToCore(vfnButtonTask, // function with task's code | |
"Button task", // name | |
2048, // stack size | |
(void *) NULL, // input parameters | |
10, // priority | |
&xButtonHandle, // task handle (for callback from ISR) | |
1); // core to run on | |
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); | |
gpio_isr_handler_add(GPIO_NUM_39, // GPIO to attach to | |
vfnButtonISR, // ISR to call | |
(void*) GPIO_NUM_39); // Parameters to pass | |
gpio_isr_handler_add(GPIO_NUM_38, vfnButtonISR, (void*) GPIO_NUM_38); | |
gpio_isr_handler_add(GPIO_NUM_37, vfnButtonISR, (void*) GPIO_NUM_37); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note the different notation styles between FreeRTOS (Hungarian notation) and the M5 library (COBOL notation (kebab-case :-) ).