Skip to content

cant add interrupt function to touch screen, using the componet function board.configCallback. st7789 touch ic: cst816 #256

@AI-Tipto

Description

@AI-Tipto
#include <chrono>
#include <print>
#include <future>
#include <thread>
#include "esp_pthread.h"
// #include "esp_log.h"
#include "Arduino.h"
#include "DNSServer.h"
#include "ESPAsyncWebServer.h"
#include "Preferences.h"
#include "WiFi.h"
#include "nlohmann/json.hpp"

#include "lv_adapter_port.h"
#include "lvgl.h"

#include "lv_demos.h"
#include "ui.h"

DNSServer dns;
AsyncWebServer server(80);

// static const uint8_t TX = 43;
// static const uint8_t RX = 44;

// static const uint8_t SDA = 8;
// static const uint8_t SCL = 9;

// static const uint8_t SS = 10;
// static const uint8_t MOSI = 11;
// static const uint8_t MISO = 13;
// static const uint8_t SCK = 12;

// #define I2C_SDA 8
// #define I2C_SCL 9
// #define TP_INT 40
// #define TP_RST 41

// #define TFT_BL 1

// #define off_pin 35
// #define buf_size 100

using namespace std::chrono;

esp_panel::board::Board board;
using namespace esp_panel::drivers;
std::vector<TouchPoint> points;
// std::string mms;
// TouchPoint tpoint;

volatile bool touchEventFlag = false;
QueueHandle_t myQueue;

TaskHandle_t BlinkyTaskHandle = NULL;
uint8_t led_state = LOW;

void touch_task(void *arg)
{
  while(1)
    {
      // if(xQueueReceive(myQueue, &led_state, portMAX_DELAY))
      // {
      digitalWrite(6, led_state);
      // }
      vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}
IRAM_ATTR static bool touch_interrupt(void *user_data)
{
  led_state = !led_state;
  // xQueueSendFromISR(myQueue, &led_state, NULL);
  // touchEventFlag = true;
  // auto point = reinterpret_cast<TouchPoint *>(user_data);
  // esp_rom_printf("Touch interrupt callback\n");
  // auto status = digitalRead(6);
  // digitalWrite(6, !status);
  // auto mms = DRAM_STR("hello this is a test");
  // ESP_LOGI("main", "{}", mms);
  // std::println("{}", mms);
  // Serial.write(mms);
  // lv_indev_data_t *indev{nullptr};

  // indev->state = LV_INDEV_STATE_PRESSED;
  // indev->point.x = point->x;
  // indev->point.y = point->y;
  // esp_lv_adapter_unlock();
  // std::println("x: {}, y: {}", point->x, point->y);
  // delay(300);
  return true;
}

// esp_panel::drivers::Touch *touch{nullptr};

extern "C" void app_main()
{
  auto tpoint = new TouchPoint;
  // std::function<bool(void *data)> touch_callback = touch_interrupt;
  initArduino();
  pinMode(6, OUTPUT);

  // Serial.begin(115200);

  // if(!touch->isOverState(Touch::State::INIT)) { touch->init(); }

  // if(touch->isInterruptEnabled())
  //   {
  //     std::println("Interrupt enabled");
  //     // gpio_uninstall_isr_service();
  //     if(touch->attachInterruptCallback(touch_interrupt))
  //       {
  //         std::println("Interrupt attached");
  //       }
  //   }
  // else { std::println("Interrupt not enabled"); }

  // delay(2000);
  // gpio_uninstall_isr_service();
  // board.configCallback(
  //    esp_panel::board::BoardConfig::STAGE_CALLBACK_POST_TOUCH_BEGIN,
  //    touch_interrupt);


  board.configCallback(
     esp_panel::board::BoardConfig::STAGE_CALLBACK_PRE_TOUCH_BEGIN,
     touch_interrupt);
  board.init();

  gpio_isr_handler_remove(GPIO_NUM_48);
  board.begin();

  lvgl_port_init(board.getLCD(), board.getTouch());

  // if(auto err = gpio_install_isr_service(ESP_INTR_FLAG_EDGE);
  //    err != ESP_OK && err != ESP_ERR_INVALID_STATE)
  //   {
  //     switch(err)
  //       {
  //       case ESP_ERR_NO_MEM:
  //         std::println("No memory to install this service");
  //         break;
  //       case ESP_ERR_INVALID_STATE:
  //         std::println("ISR service already installed");
  //         break;
  //       case ESP_ERR_NOT_FOUND:
  //         std::println("No free interrupt found with the specified flags");
  //         break;
  //       case ESP_ERR_INVALID_ARG: std::println("GPIO error"); break;
  //       }
  //   }
  // else
  //   {
  //     esp_rom_gpio_pad_select_gpio(GPIO_NUM_48);
  //     gpio_set_direction(GPIO_NUM_48, GPIO_MODE_INPUT);
  //     gpio_pullup_en(GPIO_NUM_48);

  //     // gpio_isr_handler_remove(GPIO_NUM_48);
  //     err = gpio_set_intr_type(GPIO_NUM_48, GPIO_INTR_POSEDGE);

  //     if(err != ESP_OK) { std::println("Failed to set interrupt type"); }

  //     err = gpio_isr_handler_add(GPIO_NUM_48, touch_interrupt, nullptr);
  //     if(err == ESP_ERR_INVALID_STATE)
  //       {
  //         std::println(
  //            "Wrong state, the ISR service has not been initialized.");
  //       }
  //     gpio_intr_enable(GPIO_NUM_48);
  //   }

  ui_init();

  xTaskCreatePinnedToCore(touch_task, "touch_task", 4096 * 4, nullptr, 10,
                          &BlinkyTaskHandle, 1);

  auto touch = board.getTouch();

  pinMode(5, OUTPUT);

  digitalWrite(5, HIGH);

  // esp_lv_adapter_lock(-1);
  // lv_demo_widgets();
  // lv_demo_benchmark();

  // gpio_dump_io_configuration(stdout, (1ULL << 8) | (1ULL << 9) | (1ULL <<
  // 48)); esp_lv_adapter_unlock();

  // std::this_thread::sleep_for(1s);

  // Preferences nvs;
  // nvs.begin("storage", false);

  // auto start = high_resolution_clock::now();

  // WiFi.STA.begin();
  // WiFi.STA.connect("NETGEAR", "8309292003");

  // while(WiFi.STA.status() != WL_CONNECTED) {}

  // WiFi.AP.create("ESP32-AsyncDNSServer");
  // WiFi.AP.begin();
  // WiFi.AP.enableDhcpCaptivePortal();

  // server.onNotFound(
  //    [](AsyncWebServerRequest *request) { request->redirect("/"); });

  // server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
  //   request->send(200, "text/plain", R"(
  //               "Hello, worldHello,
  //                worldHello,
  //                 worldHello,
  //                 worldHello,
  //                  worldHello, "
  //               "worldHello, worldHello, world)");
  // });

  // dns.start();
  // server.begin();

  // auto key = WiFi.AP.ifkey();

  // std::println("AP Key: {}", key);

  // int i;
  // float f;

  // using namespace nlohmann;
  // auto json = json::array();

  auto cfg = esp_pthread_get_default_config();
  cfg.pin_to_core = 0;
  cfg.stack_size = 4096 * 4;
  esp_pthread_set_cfg(&cfg);
  // std::future<void> panel_touch = std::async(std::launch::async, [] {
  //   using namespace esp_panel::drivers;

  //   auto touch = board.getTouch();
  //   std::vector<TouchPoint> points;
  //   auto id = std::this_thread::get_id();

  //   std::println("Touch thread: {}", id);

  //   while(1)
  //     {
  //       if(!touch->getPoints(points))
  //         {
  //           std::println("Failed to get Touch points");
  //         }

  //       // int i = 0;
  //       // for(auto &point : points)
  //       //   {
  //       //     std::println("Point(%d): x(%d), y(%d), strength(%d)", i++,
  //       point.x,
  //       //                  point.y, point.strength);
  //       //   }
  //         std::this_thread::sleep_for(500ms);
  //     }
  // });

  // touch->configInterruptActiveLevel(1);
  // digitalWrite(GPIO_NUM_7, HIGH);
  std::thread touch_thread([&]() {
    // initArduino();
    pinMode(7, OUTPUT);
    auto onOff = digitalRead(7);
    while(1)
      {
        esp_lv_adapter_lock(-1);
        lv_timer_handler_run_in_period(5);
        // lv_task_handler(); // let the GUI do its work
        // lv_tick_inc(5);
        esp_lv_adapter_unlock();
        ui_tick();

        touch->readRawData(-1, -1, 0);
        if(!touch->getPoints(points))
          {
            std::println("Failed to get Touch points");
          }
        else
          {
            // std::println("Get Touch Point");

            auto count = points.size();

            // std::println("Count: {}", count);
            // int i = 0;
            for(auto &point : points)
              {
                tpoint = &point;
                point.print();

                auto level = gpio_get_level(GPIO_NUM_48);
                std::println("level: {}", level);

                // gpio_set_level(GPIO_NUM_7, !onOff);
                // onOff = !onOff;
                // digitalWrite(7, onOff);

                // if(touchEventFlag) { std::println("{}", mms); }
                // else { std::println("touchEventFlag not set"); }

                // std::println("Point(%d): x(%d), y(%d), strength(%d)", i++,
                //              point.x, point.y, point.strength);
              }
          }
        // if(!touch->isInterruptEnabled()) delay(500);

        // std::println("Touch Interrupt enabled: {}",
        // touch->isInterruptEnabled());
        delay(1000);
      }
  });

  std::println("Done");

  touch_thread.join();

  std::println("Done 2");
}
`

Error
E (2389) gpio: gpio_install_isr_service(526): GPIO isr service already installed

but if i enable the interrupt , use the base gpio componet the code run OK!

` // if(auto err = gpio_install_isr_service(ESP_INTR_FLAG_EDGE);
  //    err != ESP_OK && err != ESP_ERR_INVALID_STATE)
  //   {
  //     switch(err)
  //       {
  //       case ESP_ERR_NO_MEM:
  //         std::println("No memory to install this service");
  //         break;
  //       case ESP_ERR_INVALID_STATE:
  //         std::println("ISR service already installed");
  //         break;
  //       case ESP_ERR_NOT_FOUND:
  //         std::println("No free interrupt found with the specified flags");
  //         break;
  //       case ESP_ERR_INVALID_ARG: std::println("GPIO error"); break;
  //       }
  //   }
  // else
  //   {
  //     esp_rom_gpio_pad_select_gpio(GPIO_NUM_48);
  //     gpio_set_direction(GPIO_NUM_48, GPIO_MODE_INPUT);
  //     gpio_pullup_en(GPIO_NUM_48);

  //     // gpio_isr_handler_remove(GPIO_NUM_48);
  //     err = gpio_set_intr_type(GPIO_NUM_48, GPIO_INTR_POSEDGE);

  //     if(err != ESP_OK) { std::println("Failed to set interrupt type"); }

  //     err = gpio_isr_handler_add(GPIO_NUM_48, touch_interrupt, nullptr);
  //     if(err == ESP_ERR_INVALID_STATE)
  //       {
  //         std::println(
  //            "Wrong state, the ISR service has not been initialized.");
  //       }
  //     gpio_intr_enable(GPIO_NUM_48);
  //   }`

all touch ic init call
ESP_UTILS_CHECK_FALSE_RETURN(touch_device->begin(), false, "Touch device begin failed");

this is virtual function ,then will call the IC's begin func, eg:CST816

bool TouchCST816S::begin()
{
    ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS();

    ESP_UTILS_CHECK_FALSE_RETURN(!isOverState(State::BEGIN), false, "Already begun");

    // Initialize the touch if not initialized
    if (!isOverState(State::INIT)) {
        ESP_UTILS_CHECK_FALSE_RETURN(init(), false, "Init failed");
    }

    // Create touch panel
    ESP_UTILS_CHECK_ERROR_RETURN(
        esp_lcd_touch_new_i2c_cst816s(
            getBus()->getControlPanelHandle(), getConfig().getDeviceFullConfig(), &touch_panel
        ), false, "Create touch panel failed"
    );
    ESP_UTILS_LOGD("Create touch panel(@%p)", touch_panel);

    setState(State::BEGIN);

    ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS();

    return true;
}


esp_lcd_touch_new_i2c_cst816s -----> call

if (cst816s->config.interrupt_callback) {
            esp_lcd_touch_register_interrupt_callback(cst816s, cst816s->config.interrupt_callback);
        } 

the issue is esp_lcd_touch_register_interrupt_callback

if (callback != NULL) {
        ret = gpio_install_isr_service(0);

this func call
GPIO_CHECK(gpio_context.gpio_isr_func == NULL, "GPIO isr service already installed", ESP_ERR_INVALID_STATE);

Could you tell When the gpio_context.gpio_isr_func is set before board.begin();

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions