GPIO Interrupt from a class file
Posted: Wed Feb 02, 2022 7:56 pm
I want to use GPIO Interrupts from a .cpp class file and so far, everything I've tested isn't working properly.
Checking the return from the gpio_isr_handler_add function, it's always 0 (ESP_OK).
I've tried:
static function outside the class;
static method inside the class;
Here's the minimum working project if you want to test it out.
So my question is, am I doing something wrong in the code or is it impossible to use interrupts inside a class file?
Checking the return from the gpio_isr_handler_add function, it's always 0 (ESP_OK).
I've tried:
static function outside the class;
static method inside the class;
Here's the minimum working project if you want to test it out.
Code: rotary_encoder_example_main.cpp Select all
#include "esp_event.h"
#include "driver/gpio.h"
#include "RotaryEncoder.hpp"
#define ESP_INTR_FLAG_DEFAULT 0
uint32_t cnt;
static void IRAM_ATTR main_isr_handler(void* arg)
{
cnt++;
}
extern "C" void app_main(void)
{
encoder_t encoder;
encoder_config_t conf;
conf.enc1_pin = GPIO_NUM_34;
conf.enc2_pin = GPIO_NUM_35;
/* Interrupt = 0 -> Interrupt in Main
* Interrupt = 1 -> Interrupt Inside Class
* Interrupt = 2 -> Interrupt Outside Class
*/
conf.interrupt = 0;
if(conf.interrupt == 0) {
gpio_config_t gpio_conf;
gpio_conf.intr_type = GPIO_INTR_ANYEDGE;
gpio_conf.mode = GPIO_MODE_INPUT;
gpio_conf.pin_bit_mask = 1ULL<<conf.enc1_pin | 1ULL<<conf.enc2_pin;
gpio_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
gpio_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&gpio_conf);
printf("----Install ISR Service %x----\n",
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT));
printf("----Install Main ISR Handler 1: %x----\n",
gpio_isr_handler_add(GPIO_NUM_34, main_isr_handler, (void*) 34));
printf("----Install Main ISR Handler 1: %x----\n",
gpio_isr_handler_add(GPIO_NUM_35, main_isr_handler, (void*) 35));
}
else {
encoder.encoder_init(&conf);
}
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
int level = 0;
while (true) {
gpio_set_level(GPIO_NUM_32, level);
gpio_set_level(GPIO_NUM_33, !level);
level = !level;
printf("Counter Main: %d\t\tCounter Class: %d\n", cnt, enc_cnt);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
Code: RotaryEncoder.hpp Select all
/*
* RotaryEncoder.hpp
*
* Created on: 30 de jan. de 2022
* Author: igor_
*/
#ifndef _ROTARYENCODER_HPP_
#define _ROTARYENCODER_HPP_
#include "driver/gpio.h"
static uint32_t enc_cnt;
/* ^^^^^^^^^^^^^
* RotaryEncoder
* ^^^^^^^^^^^^^ */
namespace RotaryEncoder {
class encoder;
} /* namespace RotaryEncoder */
// TB6612FNG type
using encoder_t = RotaryEncoder::encoder;
typedef struct {
gpio_num_t enc1_pin;
gpio_num_t enc2_pin;
int interrupt;
} encoder_config_t;
typedef struct {
gpio_num_t gpio_num;
encoder_t* encoder_ptr;
} encoder_isr_config_t;
namespace RotaryEncoder {
class encoder {
public:
static void inside_class_isr_handler(void* arg);
gpio_num_t
enc1_pin,
enc2_pin;
void encoder_init(encoder_config_t *enc_conf);
}; /* Class encoder */
} /* Namespace RotaryEncoder */
#endif /* ROTARYENCODER_SRC_ROTARYENCODER_HPP_ */
Code: RotaryEncoder.cpp Select all
/*
* RotaryEncoder.cpp
*
* Created on: 30 de jan. de 2022
* Author: igor_
*/
#include "RotaryEncoder.hpp"
#include "esp_timer.h"
#include "driver/gpio.h"
#define ESP_INTR_FLAG_DEFAULT 0
static void outside_class_isr_handler(void* arg) {
enc_cnt++;
}
namespace RotaryEncoder{
void encoder::inside_class_isr_handler(void* arg) {
enc_cnt++;
}
void encoder::encoder_init(encoder_config_t *enc_conf) {
printf("Printing Encoder Configs:\n"
"\tEnc1: %d\n"
"\tEnc2: %d\n"
"\tPtr: %p\n", enc_conf->enc1_pin, enc_conf->enc2_pin, this);
this->enc1_pin = enc_conf->enc1_pin;
this->enc2_pin = enc_conf->enc2_pin;
// GPIO configuration structure
gpio_config_t gpio_conf;
gpio_conf.intr_type = GPIO_INTR_ANYEDGE;
gpio_conf.mode = GPIO_MODE_INPUT;
gpio_conf.pin_bit_mask = 1ULL<<this->enc1_pin | 1ULL<<this->enc2_pin;
gpio_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
gpio_conf.pull_up_en = GPIO_PULLUP_ENABLE;
// Configures the GPIOs
gpio_config(&gpio_conf);
//install gpio isr service
printf("----Install ISR Service %x----\n",
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT));
encoder_isr_config_t isr_args;
isr_args.encoder_ptr = this;
//hook isr handler for specific gpio pin
if (enc_conf->interrupt == 1) {
isr_args.gpio_num = enc_conf->enc1_pin;
printf("----Install Inside ISR Handler 1: %x----\n",
gpio_isr_handler_add(this->enc1_pin, this->inside_class_isr_handler, (void*) &isr_args));
isr_args.gpio_num = enc_conf->enc2_pin;
printf("----Install Inside ISR Handler 2: %x----\n",
gpio_isr_handler_add(this->enc2_pin, this->inside_class_isr_handler, (void*) &isr_args));
}
else if (enc_conf->interrupt == 2){
isr_args.gpio_num = enc_conf->enc1_pin;
printf("----Install Outside ISR Handler 1: %x----\n",
gpio_isr_handler_add(this->enc1_pin, outside_class_isr_handler, (void*) &isr_args));
isr_args.gpio_num = enc_conf->enc2_pin;
printf("----Install Outside ISR Handler 2: %x----\n",
gpio_isr_handler_add(this->enc2_pin, outside_class_isr_handler, (void*) &isr_args));
}
}
}