Is this how I should develop my TFT ISR code ?

wolfrose
Posts: 14
Joined: Mon Oct 26, 2020 2:58 pm

Is this how I should develop my TFT ISR code ?

Postby wolfrose » Fri Apr 14, 2023 9:09 am

Hi,

I'm using a simple ESP32 devkit with a 4" TFT module.

I started working on a polling code, but the button press response isn't immediate, I have to press it several to many times to get the right response. I don't know what I'm doing wrong but I used the same code provided in the library examples.

So, I thought of using the TFT_IRQ pin to get the ESP32 to respond immediately to any press on the TFT module.

I developed this basic code, which is about a main page that have two buttons for two other pages and each page have couple function buttons. And it's working and I'm happy.

My question now, is this how an isr code should be done ?

Code: Select all

// names enumerations
enum : uint8_t {NO_PAGE_SELECTED, MAIN_PAGE , PAGE1, PAGE2} TEST_PAGES_T;
enum : uint8_t {NO_BUTTON_SELECTED, F1B1, F1B2, F2B1, F2B2} TEST_FUNCTIONS_BUTTONS_T;

// buttons and text objects
text   t_main_menu  = {CENTERED_MAIN, 20, TFT_WHITE, "main menu", CENTERED};
button b_f1         = {40, 80 , 250, 30, TFT_BLUE, TFT_WHITE, "FUNCTION1", FUNCTION1};
button b_f2         = {40, 130, 250, 30, TFT_BLUE, TFT_WHITE, "FUNCTION2", FUNCTION2};
button b_main_menu  = {40, 160, 250, 30, TFT_BLUE, TFT_WHITE, "main menu", MAIN_MENU};

text   t_f1         = {CENTERED_MAIN, 20, TFT_WHITE, "FUNCTION1", CENTERED};
button b_f1b1       = {40, 60 , 250, 30, TFT_BLUE, TFT_WHITE, "f1b1", F1B1};
button b_f1b2       = {40, 110, 250, 30, TFT_BLUE, TFT_WHITE, "f1b2", F1B2};

text   t_f2         = {CENTERED_MAIN, 20, TFT_WHITE, "FUNCTION2", CENTERED};
button b_f2b1       = {40, 60 , 250, 30, TFT_BLUE, TFT_WHITE, "f2b1", F2B1};
button b_f2b2       = {40, 110, 250, 30, TFT_BLUE, TFT_WHITE, "f2b2", F2B2};

// isr control struct
struct TFT_ISR_CONTROL{
  const uint8_t tft_irq_pin;
  bool buttonLock;
  bool tftTouchLock;
  unsigned long irq_request_count;
  uint8_t   page_index;
  uint8_t   button_index;
  bool      page_update;
  bool      button_update;
  unsigned long buttonTimer;
};

// struct object
TFT_ISR_CONTROL tft_irq = {36, 0, 0, 0, MAIN_MENU, 0, 0, 0, millis()};

// pages functions
void p_main_menu(void){
  tft.fillScreen(TFT_BLACK);
  draw_text(t_main_menu);
  draw_button(b_f1);
  draw_button(b_f2);
}

void p_function1(void) {
  tft.fillScreen(TFT_BLACK);
  draw_text(t_f1);
  draw_button(b_f1b1);
  draw_button(b_f1b2);
  draw_button(b_main_menu);
}

void p_function2(void) {
  tft.fillScreen(TFT_BLACK);
  draw_text(t_f2);
  draw_button(b_f2b1);
  draw_button(b_f2b2);
  draw_button(b_main_menu);
}

void tft_start_setting(void){
  tft_irq.page_index    = MAIN_MENU;
  tft_irq.page_update   = false;
  tft_irq.button_index  = NO_BUTTON_SELECTED;
  tft_irq.button_update = false;
  tft_irq.tftTouchLock  = false;
}


// FSM control functions
void read_page_buttons(void){

  uint8_t page_index_temp = tft_irq.page_index;
  
  if(tft_irq.page_update == true && tft_irq.button_update == false){
    
    if(tft_irq.page_index == MAIN_MENU){
      tft_irq.page_index   |= read_button(b_f1);
      tft_irq.page_index   |= read_button(b_f2);
    }
    else if(tft_irq.page_index == FUNCTION1){
      tft_irq.button_index |= read_button(b_f1b1);
      tft_irq.button_index |= read_button(b_f1b2);
      tft_irq.button_index |= read_button(b_main_menu);
    }
    else if(tft_irq.page_index == FUNCTION2){
      tft_irq.button_index |= read_button(b_f2b1);
      tft_irq.button_index |= read_button(b_f2b2);
      tft_irq.button_index |= read_button(b_main_menu);
    }
  }
  if(tft_irq.button_index == MAIN_MENU){
    tft_irq.page_update  = false;
    tft_irq.button_update = false;
    tft_irq.page_index = MAIN_MENU;
    tft_irq.button_index = NO_BUTTON_SELECTED;
  }
  // execute button actions
  if(tft_irq.button_index != NO_BUTTON_SELECTED){
    tft_irq.button_update = true;
  }
  // execute print page
  if(page_index_temp != tft_irq.page_index){
    tft_irq.page_update  = false;
    tft_irq.button_update = false;
  }
}

void print_page(void){

  if(tft_irq.page_update == false && tft_irq.button_update == false){
    ets_printf("entered print_page ...\n");
    switch(tft_irq.page_index){
      
      case MAIN_MENU:
        p_main_menu();
      break;
  
      case FUNCTION1:
        p_function1();
      break;
  
      case FUNCTION2:
        p_function2();
      break;
    }
    tft_irq.page_update = 1;
  }
}


void execute_button_actions(void){

  if(tft_irq.button_index != NO_BUTTON_SELECTED && tft_irq.button_update == true){
    ets_printf("entered execute_button_actions ...\n");
    switch(tft_irq.button_index){
//      ();
      case F1B1:
        ets_printf("F1B1 executed ...\n");
      break;
  
      case F1B2:
        ets_printf("F1B2 executed ...\n");
      break;
  
      case F2B1:
        ets_printf("F2B1 executed ...\n");
      break;
      
      case F2B2:
        ets_printf("F2B2 executed ...\n");
      break;
    
    }
    tft_irq.button_index = NO_BUTTON_SELECTED;
    tft_irq.button_update = false;
  }
}


// isr vector
void IRAM_ATTR tft_irq_isr(void) {
  if(!tft_irq.tftTouchLock){
    detachInterrupt(tft_irq.tft_irq_pin);
    tft_irq.buttonTimer = millis();
    tft_irq.tftTouchLock = 1;
    tft_irq.irq_request_count++;
    ets_printf("irq issued %u\n", tft_irq.irq_request_count);
  }
}

// main call function
void tft_task_manager(void){
  
  print_page();
  read_page_buttons();
  execute_button_actions();
  
  if(tft_irq.tftTouchLock){
    if(millis() - tft_irq.buttonTimer >= 300){
      tft_irq.tftTouchLock = 0;
      attachInterrupt(tft_irq.tft_irq_pin, tft_irq_isr, FALLING);
    }
  }
}

In the main I'm just calling

Code: Select all

tft_task_manager

Code: Select all

#include <SPI.h>
#include <TFT_eSPI.h>
#include <PNGdec.h>
#include "system_variables.h"

#define TFT_IRQ_PIN   36
void IRAM_ATTR tft_irq_isr(void);

TFT_eSPI tft = TFT_eSPI();

void setup(void) {
  // serial setting
  Serial.begin(9600);
  Serial.println("\n\nStarting...");
  delay(100);

  // tft setting
  tft.init();
  tft.setRotation(0);

  // tft start setting
  tft_start_setting();

  // tft isr setting
  pinMode(TFT_IRQ_PIN, INPUT);
  attachInterrupt(TFT_IRQ_PIN, tft_irq_isr, FALLING);
  ets_printf("isr setup\n");
}

void loop() {
  tft_task_manager();
}

Who is online

Users browsing this forum: Fusion, wolfrose and 91 guests