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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions