Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does it also work with CST816T? #1

Open
Fischkopppp opened this issue Jan 26, 2022 · 9 comments
Open

Does it also work with CST816T? #1

Fischkopppp opened this issue Jan 26, 2022 · 9 comments

Comments

@Fischkopppp
Copy link

I hope it is ok to write my question under the issue field. Has someone tried this library with CST816T chips?
With best regards!

@modi12jin
Copy link

modi12jin commented Jul 11, 2022

CST816T.cpp

#include "CST816T.h"

CST816T::CST816T(int8_t sda_pin, int8_t scl_pin, int8_t rst_pin, int8_t int_pin)
{
    _sda = sda_pin;
    _scl = scl_pin;
    _rst = rst_pin;
    _int = int_pin;
}

void CST816T::begin(void)
{
    // Initialize I2C
    if (_sda != -1 && _scl != -1)
    {
        Wire.begin(_sda, _scl);
    }
    else
    {
        Wire.begin();
    }

    // Int Pin Configuration
    if (_int != -1)
    {
        pinMode(_int, OUTPUT);
        digitalWrite(_int, HIGH); //高电平
        delay(1);
        digitalWrite(_int, LOW); //低电平
        delay(1);
    }

    // Reset Pin Configuration
    if (_rst != -1)
    {
        pinMode(_rst, OUTPUT);
        digitalWrite(_rst, LOW);
        delay(10);
        digitalWrite(_rst, HIGH);
        delay(300);
    }

    // Initialize Touch
    i2c_write(0xFE, 0XFF); //禁止自动进入低功耗模式。
}

bool CST816T::getTouch(uint16_t *x, uint16_t *y, uint8_t *gesture)
{
    bool FingerIndex = false;
    FingerIndex = (bool)i2c_read(0x02);

    *gesture = i2c_read(0x01);
    if (!(*gesture == SlideUp || *gesture == SlideDown))
    {
        *gesture = None;
    }

    uint8_t data[4];
    i2c_read_continuous(0x03,data,4);
    *x = ((data[0] & 0x0f) << 8) | data[1];
    *y = ((data[2] & 0x0f) << 8) | data[3];

    return FingerIndex;
}

uint8_t CST816T::i2c_read(uint8_t addr)
{
    uint8_t rdData;
    uint8_t rdDataCount;
    do
    {
        Wire.beginTransmission(I2C_ADDR_CST816T);
        Wire.write(addr);
        Wire.endTransmission(false); // Restart
        rdDataCount = Wire.requestFrom(I2C_ADDR_CST816T, 1);
    } while (rdDataCount == 0);
    while (Wire.available())
    {
        rdData = Wire.read();
    }
    return rdData;
}

uint8_t CST816T::i2c_read_continuous(uint8_t addr, uint8_t *data, uint32_t length)
{
  Wire.beginTransmission(I2C_ADDR_CST816T);
  Wire.write(addr);
  if ( Wire.endTransmission(true))return -1;
  Wire.requestFrom(I2C_ADDR_CST816T, length);
  for (int i = 0; i < length; i++) {
    *data++ = Wire.read();
  }
  return 0;
}

void CST816T::i2c_write(uint8_t addr, uint8_t data)
{
    Wire.beginTransmission(I2C_ADDR_CST816T);
    Wire.write(addr);
    Wire.write(data);
    Wire.endTransmission();
}

uint8_t CST816T::i2c_write_continuous(uint8_t addr, const uint8_t *data, uint32_t length)
{
  Wire.beginTransmission(I2C_ADDR_CST816T);
  Wire.write(addr);
  for (int i = 0; i < length; i++) {
    Wire.write(*data++);
  }
  if ( Wire.endTransmission(true))return -1;
  return 0;
}

CST816T.h

#ifndef _CST816T_H
#define _CST816T_H

#include <Wire.h>

#define I2C_ADDR_CST816T 0x15

//手势
enum GESTURE
{
    None = 0x00,       //无手势
    SlideDown = 0x01,  //向下滑动
    SlideUp = 0x02,    //向上滑动
    SlideLeft = 0x03,  //向左滑动
    SlideRight = 0x04, //向右滑动
    SingleTap = 0x05,  //单击
    DoubleTap = 0x0B,  //双击
    LongPress = 0x0C   //长按
};

/**************************************************************************/
/*!
    @brief  CST816T I2C CTP controller driver
*/
/**************************************************************************/
class CST816T
{
public:
    CST816T(int8_t sda_pin = -1, int8_t scl_pin = -1, int8_t rst_pin = -1, int8_t int_pin = -1);

    void begin(void);
    bool getTouch(uint16_t *x, uint16_t *y, uint8_t *gesture);

private:
    int8_t _sda, _scl, _rst, _int;

    uint8_t i2c_read(uint8_t addr);
    uint8_t i2c_read_continuous(uint8_t addr, uint8_t *data, uint32_t length);
    void i2c_write(uint8_t addr, uint8_t data);
    uint8_t i2c_write_continuous(uint8_t addr, const uint8_t *data, uint32_t length);
};
#endif

touch_text.ino

#include "CST816T.h"

#define I2C_SDA 8
#define I2C_SCL 9
#define TP_INT 38
#define TP_RST 39

CST816T touch(I2C_SDA, I2C_SCL,TP_RST,TP_INT); 

void setup() {
    Serial.begin(115200); 
    touch.begin(); 
}

bool FingerNum;
uint8_t gesture;
uint16_t touchX,touchY;
void loop() {
    FingerNum=touch.getTouch(&touchX,&touchY,&gesture);
    if(FingerNum){
              Serial.printf("X:%d,Y:%d,gesture:%x\n",touchX,touchY,gesture);
    }
    
    delay(100);
}

CST816T.zip

@modi12jin
Copy link

modi12jin commented Jul 11, 2022

ESP32S3_ST7789_CST816T_LVGL.ino

#include <lvgl.h>
#include "demos/lv_demos.h"
#include <LovyanGFX.hpp>
#include "CST816T.h"

#define I2C_SDA 8
#define I2C_SCL 9
#define TP_INT 38
#define TP_RST 39

class LGFX : public lgfx::LGFX_Device {

  lgfx::Panel_ST7789 _panel_instance;

  lgfx::Bus_SPI _bus_instance;

public:
  LGFX(void) {
    {
      auto cfg = _bus_instance.config();

      // SPIバスの設定
      cfg.spi_host = SPI2_HOST;  // 使用するSPIを選択  ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
      // ※ ESP-IDFバージョンアップに伴い、VSPI_HOST , HSPI_HOSTの記述は非推奨になるため、エラーが出る場合は代わりにSPI2_HOST , SPI3_HOSTを使用してください。
      cfg.spi_mode = 0;                   // SPI通信モードを設定 (0 ~ 3)
      cfg.freq_write = 80000000;          // 传输时的SPI时钟(最高80MHz,四舍五入为80MHz除以整数得到的值)
      cfg.freq_read = 20000000;           // 接收时的SPI时钟
      cfg.spi_3wire = true;               // 受信をMOSIピンで行う場合はtrueを設定
      cfg.use_lock = true;                // 使用事务锁时设置为 true
      cfg.dma_channel = SPI_DMA_CH_AUTO;  // 使用するDMAチャンネルを設定 (0=DMA不使用 / 1=1ch / 2=ch / SPI_DMA_CH_AUTO=自動設定)
      // ※ ESP-IDFバージョンアップに伴い、DMAチャンネルはSPI_DMA_CH_AUTO(自動設定)が推奨になりました。1ch,2chの指定は非推奨になります。
      cfg.pin_sclk = 12;  // SPIのSCLKピン番号を設定
      cfg.pin_mosi = 11;  // SPIのCLKピン番号を設定
      cfg.pin_miso = -1;  // SPIのMISOピン番号を設定 (-1 = disable)
      cfg.pin_dc = 6;     // SPIのD/Cピン番号を設定  (-1 = disable)

      _bus_instance.config(cfg);               // 設定値をバスに反映します。
      _panel_instance.setBus(&_bus_instance);  // バスをパネルにセットします。
    }

    {                                       // 表示パネル制御の設定を行います。
      auto cfg = _panel_instance.config();  // 表示パネル設定用の構造体を取得します。

      cfg.pin_cs = 10;    // CSが接続されているピン番号   (-1 = disable)
      cfg.pin_rst = -1;   // RSTが接続されているピン番号  (-1 = disable)
      cfg.pin_busy = -1;  // BUSYが接続されているピン番号 (-1 = disable)

      // ※ 以下の設定値はパネル毎に一般的な初期値が設定さ BUSYが接続されているピン番号 (-1 = disable)れていますので、不明な項目はコメントアウトして試してみてください。

      cfg.memory_width = 240;    // ドライバICがサポートしている最大の幅
      cfg.memory_height = 280;   // ドライバICがサポートしている最大の高さ
      cfg.panel_width = 240;     // 実際に表示可能な幅
      cfg.panel_height = 280;    // 実際に表示可能な高さ
      cfg.offset_x = 0;          // パネルのX方向オフセット量
      cfg.offset_y = 20;         // パネルのY方向オフセット量
      cfg.offset_rotation = 0;   //值在旋转方向的偏移0~7(4~7是倒置的)
      cfg.dummy_read_pixel = 8;  // 在读取像素之前读取的虚拟位数
      cfg.dummy_read_bits = 1;   // 读取像素以外的数据之前的虚拟读取位数
      cfg.readable = false;      // 如果可以读取数据,则设置为 true
      cfg.invert = true;         // 如果面板的明暗反转,则设置为 true
      cfg.rgb_order = true;      // 如果面板的红色和蓝色被交换,则设置为 true
      cfg.dlen_16bit = false;    // 对于以 16 位单位发送数据长度的面板,设置为 true
      cfg.bus_shared = false;    // 如果总线与 SD 卡共享,则设置为 true(使用 drawJpgFile 等执行总线控制)

      _panel_instance.config(cfg);
    }

    setPanel(&_panel_instance);  // 使用するパネルをセットします。
  }
};

// 準備したクラスのインスタンスを作成します。
LGFX tft;
CST816T touch(I2C_SDA, I2C_SCL,TP_RST,TP_INT); 

/*更改为您的屏幕分辨率*/
static const uint32_t screenWidth = 240;
static const uint32_t screenHeight = 280;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[2][screenWidth * 30];

#if LV_USE_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char *file, uint32_t line, const char *fn_name, const char *dsc) {
  Serial.printf("%s(%s)@%d->%s\r\n", file, fn_name, line, dsc);
  Serial.flush();
}
#endif

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  if (tft.getStartCount() == 0) {
    tft.endWrite();
  }

  tft.pushImageDMA(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1, (lgfx::swap565_t *)&color_p->full);

  lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {

  bool touched;
  uint8_t gesture;
  uint16_t touchX,touchY; 
  
  touched=touch.getTouch(&touchX,&touchY,&gesture); 
  
  if (!touched)
  {
      data->state = LV_INDEV_STATE_REL;
  }
  else
  {
      data->state = LV_INDEV_STATE_PR;

      /*Set the coordinates*/
      data->point.x = touchX;
      data->point.y = touchY;

  }
}

void setup() {
  Serial.begin(115200); /* prepare for possible serial debug */
  Serial.println("Hello Arduino! (V8.2.X)");
  Serial.println("I am LVGL_Arduino");

  tft.init();  
  tft.initDMA();
  tft.startWrite();

  touch.begin();
  
  lv_init();

#if LV_USE_LOG != 0
  lv_log_register_print_cb(my_print); /* register print function for debugging */
#endif

  lv_disp_draw_buf_init(&draw_buf, buf[0], buf[1], screenWidth * 30);

  /*Initialize the display*/
  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  /*Change the following line to your display resolution*/
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  /*Initialize the (dummy) input device driver*/
  static lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;
  lv_indev_drv_register(&indev_drv);

#if 0
   /* Create simple label */
   lv_obj_t *label = lv_label_create( lv_scr_act() );
   lv_label_set_text( label, "Hello Arduino! (V8.0.X)" );
   lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else
  /* Try an example from the lv_examples Arduino library
      make sure to include it as written above.
   lv_example_btn_1();
   */

  // uncomment one of these demos
    lv_demo_widgets(); //小部件
  // lv_demo_keypad_encoder(); //键盘编码器
  // lv_demo_benchmark(); //基准测试
  // lv_demo_stress(); //压力测试
  // lv_demo_music(); //音乐
#endif
  Serial.println("Setup done");
}

void loop() {
  lv_timer_handler(); /* let the GUI do its work */
  delay(5);
}

@modi12jin
Copy link

@Fischkopppp testing successfully

16959_1657567380.mp4

@modi12jin
Copy link

modi12jin commented Sep 29, 2022

@modi12jin
Copy link

modi12jin commented Feb 25, 2023

wx_camera_1676991215694

CST816T code is also applicable to CST816D

CST816D数据手册V1.0.pdf

@modi12jin
Copy link

If you use in ESP IDF please refer to this question

wirano/st77903_demo#1

@marklysze
Copy link

Thanks for the CST816T code, I successfully used it on the LilyGO T-Display-S3 Touch version:
https://github.com/Xinyuan-LilyGO/T-Display-S3

@ArsenseLupin
Copy link

Can only use ESP32S3? Why does esp32 devkit v1 report an error when burning the CST816T routine? The error is as follows:
Warning: Could not auto-detect Flash size (FlashID=0xffffff, SizeID=0xff), defaulting to 4MB
Compressed 8192 bytes to 47...

A fatal error occurred: Timed out waiting for packet content
Failed uploading: uploading error: exit status 2

@ChristianIannella
Copy link

ChristianIannella commented Aug 25, 2023

Dose it also work with CST816D?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants