diff --git a/examples/Touch_IRQ/Touch_IRQ.ino b/examples/Touch_IRQ/Touch_IRQ.ino index f4e0649..fc399fa 100644 --- a/examples/Touch_IRQ/Touch_IRQ.ino +++ b/examples/Touch_IRQ/Touch_IRQ.ino @@ -1,18 +1,25 @@ -/* +/* * Touch_IRQ.ino - * - * This example shows how to get the number of points and the coordinates of the first touch points detected by the touch controller using interrupts. - * - * The setup() function initializes the serial communication and the touch controller. Whenever a touch event is detcted, the gigaTouchHandler function is called that prints the number of points and first touch co-ordinates to the Serial Monitor. The loop() function is empty because the touch controller is configured to work with interrupts. - * + * + * This example shows how to get the number of points and the coordinates of the + * first touch points detected by the touch controller using interrupts. + * + * The setup() function initializes the serial communication and the touch + * controller. Whenever a touch event is detcted, the gigaTouchHandler function + * is called that prints the number of points and first touch co-ordinates to + * the Serial Monitor. The loop() function is empty because the touch controller + * is configured to work with interrupts. + * * For the polling version of this example, see Touch_Polling.ino - * + * * Instructions: - * 1. Connect your GIGA Display Shield (ASX00039) to a GIGA R1 WiFi (ABX00063) board . + * 1. Connect your GIGA Display Shield (ASX00039) to a GIGA R1 WiFi (ABX00063) + * board . * 2. Upload this sketch to your board. * 3. Open the Serial Monitor. - * 4. Touch the screen with your finger(s) and view the coordinates printed on the Serial Monitor. - * + * 4. Touch the screen with your finger(s) and view the coordinates printed on + * the Serial Monitor. + * * Initial author: Leonardo Cavagnis @leonardocavagnis * Created: 03 May 2023 */ @@ -21,7 +28,7 @@ Arduino_GigaDisplayTouch touchDetector; -void gigaTouchHandler(uint8_t contacts, GDTpoint_t* points) { +void gigaTouchHandler(uint8_t contacts, GDTpoint_t *points) { Serial.print("Contacts: "); Serial.println(contacts); @@ -35,16 +42,18 @@ void gigaTouchHandler(uint8_t contacts, GDTpoint_t* points) { void setup() { Serial.begin(115200); - while(!Serial) {} + while (!Serial) { + } if (touchDetector.begin()) { Serial.println("Touch controller init - OK"); } else { Serial.println("Touch controller init - FAILED"); - while(1) ; + while (1) + ; } touchDetector.onDetect(gigaTouchHandler); } -void loop() { } \ No newline at end of file +void loop() {} \ No newline at end of file diff --git a/examples/Touch_Polling/Touch_Polling.ino b/examples/Touch_Polling/Touch_Polling.ino index 6d6b081..81220c0 100644 --- a/examples/Touch_Polling/Touch_Polling.ino +++ b/examples/Touch_Polling/Touch_Polling.ino @@ -1,18 +1,24 @@ -/* +/* * Touch_Polling.ino - * - * This example shows how to get the number of points and the coordinates of the first touch points detected by the touch controller using polling. - * - * The setup() function initializes the serial communication and the touch controller. The loop() function continuously checks to see if a touch event is detected. Whenever a touch event is detcted, that prints the number of points and first touch co-ordinates to the Serial Monitor. - * + * + * This example shows how to get the number of points and the coordinates of the + * first touch points detected by the touch controller using polling. + * + * The setup() function initializes the serial communication and the touch + * controller. The loop() function continuously checks to see if a touch event + * is detected. Whenever a touch event is detcted, that prints the number of + * points and first touch co-ordinates to the Serial Monitor. + * * For the interrupt version of this example, see Touch_IRQ.ino - * + * * Instructions: - * 1. Connect your GIGA Display Shield (ASX00039) to a GIGA R1 WiFi (ABX00063) board . + * 1. Connect your GIGA Display Shield (ASX00039) to a GIGA R1 WiFi (ABX00063) + * board . * 2. Upload this sketch to your board. * 3. Open the Serial Monitor. - * 4. Touch the screen with your finger(s) and view the coordinates printed on the Serial Monitor. - * + * 4. Touch the screen with your finger(s) and view the coordinates printed on + * the Serial Monitor. + * * Initial author: Leonardo Cavagnis @leonardocavagnis * Created: 03 May 2023 */ @@ -23,20 +29,22 @@ Arduino_GigaDisplayTouch touchDetector; void setup() { Serial.begin(115200); - while(!Serial) {} + while (!Serial) { + } if (touchDetector.begin()) { Serial.print("Touch controller init - OK"); } else { Serial.print("Touch controller init - FAILED"); - while(1) ; + while (1) + ; } } void loop() { uint8_t contacts; GDTpoint_t points[5]; - + contacts = touchDetector.getTouchPoints(points); if (contacts > 0) { diff --git a/src/Arduino_GigaDisplayTouch.cpp b/src/Arduino_GigaDisplayTouch.cpp deleted file mode 100644 index bd6edc3..0000000 --- a/src/Arduino_GigaDisplayTouch.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2023 Arduino SA - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - */ - -/** - * @file Arduino_GigaDisplayTouch.cpp - * @author Leonardo Cavagnis - * @brief Source file for the Arduino Giga Display Touch library. - */ - - /* Includes -----------------------------------------------------------------*/ -#include "Arduino_GigaDisplayTouch.h" - -#if __has_include ("lvgl.h") -#include "lvgl.h" -#endif - -/* Private defines -----------------------------------------------------------*/ -#define GT911_REG_GESTURE_START_POINT 0x814E -#define GT911_REG_CONFIG_VERSION 0x8047 - -/* Private variables ---------------------------------------------------------*/ -rtos::Thread t; -events::EventQueue queue(32 * EVENTS_EVENT_SIZE); -Arduino_GigaDisplayTouch * gThis; - -/* Private function prototypes -----------------------------------------------*/ -#if __has_include ("lvgl.h") -#if (LVGL_VERSION_MAJOR == 9) -void _lvglTouchCb(lv_indev_t * indev, lv_indev_data_t * data); -#else -void _lvglTouchCb(lv_indev_drv_t * indev, lv_indev_data_t * data); -#endif -#endif - -/* Functions -----------------------------------------------------------------*/ -Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch(TwoWire& wire, uint8_t intPin, uint8_t rstPin, uint8_t addr) -: _wire{wire}, _intPin{intPin}, _rstPin{rstPin}, _addr{addr}, _irqInt{digitalPinToPinName(intPin)} -{ } - -Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch() -{ } - -bool Arduino_GigaDisplayTouch::begin() { - _wire.setClock(400000); /* maximum transmission rate of 400K bps */ - _wire.begin(); - - delay(300); - - /* GT911 Power-on timing procedure - Ref. pg10 GT911 Rev09 */ - /** T0: Set output low */ - pinMode(_rstPin, OUTPUT); - pinMode(_intPin, OUTPUT); - digitalWrite(_rstPin, LOW); - digitalWrite(_intPin, LOW); - /** T1+T2: > 10ms */ - delay(11); - /** Address selection: high - 0x28/0x29 (0x14 7bit), low - 0xBA/0xBB (0x5D 7bit) */ - digitalWrite(_intPin, (_addr == GT911_I2C_ADDR_28_29)); - /** T7: > 100us */ - delayMicroseconds(110); - digitalWrite(_rstPin, HIGH); - /** T8: > 5ms */ - delay(6); - digitalWrite(_intPin, LOW); - /** T3: > 50ms */ - delay(51); - pinMode(_intPin, INPUT); - - _gt911TouchHandler = nullptr; - - /* GT911 test communication */ - uint8_t testByte; - uint8_t error = _gt911ReadOp(GT911_REG_CONFIG_VERSION, &testByte, 1); - -#if __has_include ("lvgl.h") -#if (LVGL_VERSION_MAJOR == 9) - static lv_indev_t * indev = lv_indev_create(); - lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); - lv_indev_set_read_cb(indev, _lvglTouchCb); -#else - static lv_indev_drv_t indev_drv; /* Descriptor of a input device driver */ - lv_indev_drv_init(&indev_drv); /* Basic initialization */ - indev_drv.type = LV_INDEV_TYPE_POINTER; /* Touch pad is a pointer-like device */ - indev_drv.read_cb = _lvglTouchCb; /* Set your driver function */ - lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv); /* Register the driver in LVGL and save the created input device object */ -#endif -#endif - - gThis = this; - return (error == 0); -} - -#if __has_include ("lvgl.h") -#if (LVGL_VERSION_MAJOR == 9) -void _lvglTouchCb(lv_indev_t * indev, lv_indev_data_t * data) { - uint8_t contacts; - GDTpoint_t points[5]; - - contacts = gThis->getTouchPoints(points); - - if(contacts > 0) { - data->state = LV_INDEV_STATE_PRESSED; - data->point.x = points[0].x; - data->point.y = points[0].y; - } else { - data->state = LV_INDEV_STATE_RELEASED; - } - - return; -} -#else -void _lvglTouchCb(lv_indev_drv_t * indev, lv_indev_data_t * data) { - uint8_t contacts; - GDTpoint_t points[5]; - - contacts = gThis->getTouchPoints(points); - - if(contacts > 0) { - data->state = LV_INDEV_STATE_PR; - data->point.x = points[0].x; - data->point.y = points[0].y; - } else { - data->state = LV_INDEV_STATE_REL; - } - - return; -} -#endif -#endif - -void Arduino_GigaDisplayTouch::end() -{ } - -uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t* points) { - uint8_t rawpoints[GT911_MAX_CONTACTS * GT911_CONTACT_SIZE]; - uint8_t contacts; - uint8_t error; - - contacts = 0; - error = _gt911ReadInputCoord(rawpoints, contacts); - - if (error) { - return 0; - } - - for (uint8_t i = 0; i < contacts; i++) { - points[i].trackId = rawpoints[1 + 8*i]; - points[i].x = ((uint16_t)rawpoints[3 + 8*i] << 8) + rawpoints[2 + 8*i]; - points[i].y = ((uint16_t)rawpoints[5 + 8*i] << 8) + rawpoints[4 + 8*i]; - points[i].area = ((uint16_t)rawpoints[7 + 8*i] << 8) + rawpoints[6 + 8*i]; - } - - _gt911WriteOp(GT911_REG_GESTURE_START_POINT, 0); /* Reset buffer status to finish the reading */ - - return contacts; -} - -void Arduino_GigaDisplayTouch::onDetect(void (*handler)(uint8_t, GDTpoint_t*)) { - _gt911TouchHandler = handler; - t.start(callback(&queue, &events::EventQueue::dispatch_forever)); - _irqInt.rise(queue.event(mbed::callback(this, &Arduino_GigaDisplayTouch::_gt911onIrq))); -} - -uint8_t Arduino_GigaDisplayTouch::_gt911WriteOp(uint16_t reg, uint8_t data) { - uint8_t status = 0; - status = _gt911WriteBytesOp(reg, &data, 1); - - return status; -} - -uint8_t Arduino_GigaDisplayTouch::_gt911WriteBytesOp(uint16_t reg, uint8_t * data, uint8_t len) { - uint8_t status = 0; - - _wire.beginTransmission(_addr); - _wire.write(reg >> 8); /* Register H */ - _wire.write(reg & 0xFF); /* Register L */ - - /* Data [0..n] */ - for (uint8_t i = 0; i < len; i++) { - _wire.write(data[i]); - } - - status = _wire.endTransmission(); - - return status; -} - -uint8_t Arduino_GigaDisplayTouch::_gt911ReadOp(uint16_t reg, uint8_t * data, uint8_t len) { - uint8_t status = 0; - - _wire.beginTransmission(_addr); - _wire.write(reg >> 8); /* Register H */ - _wire.write(reg & 0xFF); /* Register L */ - status = _wire.endTransmission(); - - if (status) return status; - - _wire.requestFrom(_addr, len); - uint8_t index = 0; - /* Data [0..n] */ - while (_wire.available()) { - data[index++] = _wire.read(); - } - - if (len == index) return 0; - else return 4; /* Other error */ -} - -void Arduino_GigaDisplayTouch::_gt911onIrq() { - uint8_t contacts; - uint8_t rawpoints[GT911_MAX_CONTACTS * GT911_CONTACT_SIZE]; - uint8_t error; - - error = _gt911ReadInputCoord(rawpoints, contacts); - - if (error) { - return; - } - - for (uint8_t i = 0; i < contacts; i++) { - _points[i].trackId = rawpoints[1 + 8*i]; - _points[i].x = ((uint16_t)rawpoints[3 + 8*i] << 8) + rawpoints[2 + 8*i]; - _points[i].y = ((uint16_t)rawpoints[5 + 8*i] << 8) + rawpoints[4 + 8*i]; - _points[i].area = ((uint16_t)rawpoints[7 + 8*i] << 8) + rawpoints[6 + 8*i]; - } - - if (contacts > 0 && _gt911TouchHandler != nullptr) _gt911TouchHandler(contacts, _points); - - _gt911WriteOp(GT911_REG_GESTURE_START_POINT, 0); /* Reset buffer status to finish the reading */ -} - -uint8_t Arduino_GigaDisplayTouch::_gt911ReadInputCoord(uint8_t * pointsbuf, uint8_t& contacts) { - uint8_t error; - - contacts = 0; - error = _gt911ReadOp(GT911_REG_GESTURE_START_POINT, pointsbuf, GT911_CONTACT_SIZE * GT911_MAX_CONTACTS); - - if (error) { - return 1; /* I2C comm error */ - } - - if (!(pointsbuf[0] & 0x80)) { - return 2; /* Data buffer not ready */ - } - - contacts = pointsbuf[0] & 0xF; - return 0; -} - -/**** END OF FILE ****/ \ No newline at end of file diff --git a/src/Arduino_GigaDisplayTouch.h b/src/Arduino_GigaDisplayTouch.h index 6859963..8191ce5 100644 --- a/src/Arduino_GigaDisplayTouch.h +++ b/src/Arduino_GigaDisplayTouch.h @@ -21,25 +21,25 @@ * @author Leonardo Cavagnis * @brief Header file for the Arduino Giga Display Touch library. * - * This library allows to capture up to 5 concurrent touch points on Arduino Giga Display Shield. - * Supported controller: Goodix GT911 + * This library allows to capture up to 5 concurrent touch points on Arduino + * Giga Display Shield. Supported controller: Goodix GT911 */ #ifndef __ARDUINO_GIGADISPLAYTOUCH_H #define __ARDUINO_GIGADISPLAYTOUCH_H /* Includes ------------------------------------------------------------------*/ -#include #include "Wire.h" #include "mbed.h" #include "pinDefinitions.h" +#include /* Exported defines ----------------------------------------------------------*/ -#define GT911_I2C_ADDR_BA_BB (0x5D | 0x80) // 0xBA/0xBB - 0x5D (7bit address) -#define GT911_I2C_ADDR_28_29 (0x14 | 0x80) // 0x28/0x29 - 0x14 (7bit address) +#define GT911_I2C_ADDR_BA_BB (0x5D | 0x80) // 0xBA/0xBB - 0x5D (7bit address) +#define GT911_I2C_ADDR_28_29 (0x14 | 0x80) // 0x28/0x29 - 0x14 (7bit address) -#define GT911_CONTACT_SIZE 8 -#define GT911_MAX_CONTACTS 5 +#define GT911_CONTACT_SIZE 8 +#define GT911_MAX_CONTACTS 5 /* Exported types ------------------------------------------------------------*/ typedef struct GDTpoint_s GDTpoint_t; @@ -52,7 +52,7 @@ typedef struct GDTpoint_s GDTpoint_t; * @brief Struct representing a touch point. */ struct GDTpoint_s { - // 0x814F-0x8156, ... 0x8176 (5 points) + // 0x814F-0x8156, ... 0x8176 (5 points) uint8_t trackId; uint16_t x; uint16_t y; @@ -60,79 +60,80 @@ struct GDTpoint_s { uint8_t reserved; }; -/* Class ----------------------------------------------------------------------*/ +/* Class + * ----------------------------------------------------------------------*/ /** * @class Arduino_GigaDisplayTouch * @brief Class for Giga Display Touch controller driver. */ class Arduino_GigaDisplayTouch { - public: - /** - * @brief Construct a new touch controller for Giga Display Shield. - * - * @param wire A reference to the Wire interface to be used for communication with the touch controller. - * @param intPin The interrupt pin number for the touch controller. - * @param rstPin The reset pin number for the touch controller. - * @param addr The device address for the touch controller. - */ - #if defined(ARDUINO_GIGA) - Arduino_GigaDisplayTouch(TwoWire& wire = Wire1, - uint8_t intPin = PinNameToIndex(PI_1), - uint8_t rstPin = PinNameToIndex(PI_2), - uint8_t addr = GT911_I2C_ADDR_BA_BB); - #elif defined(ARDUINO_PORTENTA_H7_M7) - Arduino_GigaDisplayTouch(TwoWire& wire = Wire, - uint8_t intPin = PinNameToIndex(PD_4), - uint8_t rstPin = PinNameToIndex(PD_5), - uint8_t addr = GT911_I2C_ADDR_BA_BB); - #else - Arduino_GigaDisplayTouch(TwoWire& wire, - uint8_t intPin, - uint8_t rstPin, - uint8_t addr); - #endif - ~Arduino_GigaDisplayTouch(); - - - /** - * @brief Initialize the touch controller. - * - * @return true If the touch controller is successfully initialized, false Otherwise - */ - bool begin(); - - /** - * @brief De-initialize the touch controller. - */ - void end(); - - /** - * @brief Check if a touch event is detected and get the touch points. - * @param points The array containing the coordinates of the touch points. - * @return uint8_t The number of detected touch points. - */ - uint8_t getTouchPoints(GDTpoint_t* points); - - /** - * @brief Attach an interrupt handler function for touch detection callbacks. - * @param handler The pointer to the user-defined handler function. - */ - void onDetect(void (*handler)(uint8_t, GDTpoint_t*)); - private: - TwoWire& _wire; - uint8_t _intPin; - mbed::InterruptIn _irqInt; - uint8_t _rstPin; - uint8_t _addr; - GDTpoint_t _points[GT911_MAX_CONTACTS]; - void (*_gt911TouchHandler)(uint8_t, GDTpoint_t*); - - uint8_t _gt911WriteOp(uint16_t reg, uint8_t data); - uint8_t _gt911WriteBytesOp(uint16_t reg, uint8_t * data, uint8_t len); - uint8_t _gt911ReadOp(uint16_t reg, uint8_t * data, uint8_t len); - void _gt911onIrq(); - uint8_t _gt911ReadInputCoord(uint8_t * pointsbuf, uint8_t& contacts); +public: +/** + * @brief Construct a new touch controller for Giga Display Shield. + * + * @param wire A reference to the Wire interface to be used for communication + * with the touch controller. + * @param intPin The interrupt pin number for the touch controller. + * @param rstPin The reset pin number for the touch controller. + * @param addr The device address for the touch controller. + */ +#if defined(ARDUINO_GIGA) + Arduino_GigaDisplayTouch(TwoWire &wire = Wire1, + uint8_t intPin = PinNameToIndex(PI_1), + uint8_t rstPin = PinNameToIndex(PI_2), + uint8_t addr = GT911_I2C_ADDR_BA_BB); +#elif defined(ARDUINO_PORTENTA_H7_M7) + Arduino_GigaDisplayTouch(TwoWire &wire = Wire, + uint8_t intPin = PinNameToIndex(PD_4), + uint8_t rstPin = PinNameToIndex(PD_5), + uint8_t addr = GT911_I2C_ADDR_BA_BB); +#else + Arduino_GigaDisplayTouch(TwoWire &wire, uint8_t intPin, uint8_t rstPin, + uint8_t addr); +#endif + ~Arduino_GigaDisplayTouch(); + + /** + * @brief Initialize the touch controller. + * + * @return true If the touch controller is successfully initialized, false + * Otherwise + */ + bool begin(); + + /** + * @brief De-initialize the touch controller. + */ + void end(); + + /** + * @brief Check if a touch event is detected and get the touch points. + * @param points The array containing the coordinates of the touch points. + * @return uint8_t The number of detected touch points. + */ + uint8_t getTouchPoints(GDTpoint_t *points); + + /** + * @brief Attach an interrupt handler function for touch detection callbacks. + * @param handler The pointer to the user-defined handler function. + */ + void onDetect(void (*handler)(uint8_t, GDTpoint_t *)); + +private: + TwoWire &_wire; + uint8_t _intPin; + mbed::InterruptIn _irqInt; + uint8_t _rstPin; + uint8_t _addr; + GDTpoint_t _points[GT911_MAX_CONTACTS]; + void (*_gt911TouchHandler)(uint8_t, GDTpoint_t *); + + uint8_t _gt911WriteOp(uint16_t reg, uint8_t data); + uint8_t _gt911WriteBytesOp(uint16_t reg, uint8_t *data, uint8_t len); + uint8_t _gt911ReadOp(uint16_t reg, uint8_t *data, uint8_t len); + void _gt911onIrq(); + uint8_t _gt911ReadInputCoord(uint8_t *pointsbuf, uint8_t &contacts); }; #endif /* __ARDUINO_GIGADISPLAYTOUCH_H */ \ No newline at end of file diff --git a/src/Arduino_GigaDisplayTouchMbed.cpp b/src/Arduino_GigaDisplayTouchMbed.cpp new file mode 100644 index 0000000..a7c930a --- /dev/null +++ b/src/Arduino_GigaDisplayTouchMbed.cpp @@ -0,0 +1,284 @@ +/* + * Copyright 2023 Arduino SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +/** + * @file Arduino_GigaDisplayTouch.cpp + * @author Leonardo Cavagnis + * @brief Source file for the Arduino Giga Display Touch library. + */ + +/* Includes -----------------------------------------------------------------*/ +#include "Arduino_GigaDisplayTouch.h" + +#if __has_include("lvgl.h") +#include "lvgl.h" +#endif + +/* Private defines -----------------------------------------------------------*/ +#define GT911_REG_GESTURE_START_POINT 0x814E +#define GT911_REG_CONFIG_VERSION 0x8047 + +/* Private variables ---------------------------------------------------------*/ +rtos::Thread t; +events::EventQueue queue(32 * EVENTS_EVENT_SIZE); +Arduino_GigaDisplayTouch *gThis; + +/* Private function prototypes -----------------------------------------------*/ +#if __has_include("lvgl.h") +#if (LVGL_VERSION_MAJOR == 9) +void _lvglTouchCb(lv_indev_t *indev, lv_indev_data_t *data); +#else +void _lvglTouchCb(lv_indev_drv_t *indev, lv_indev_data_t *data); +#endif +#endif + +/* Functions -----------------------------------------------------------------*/ +Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch(TwoWire &wire, + uint8_t intPin, + uint8_t rstPin, uint8_t addr) + : _wire{wire}, _intPin{intPin}, _rstPin{rstPin}, _addr{addr}, + _irqInt{digitalPinToPinName(intPin)} {} + +Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch() {} + +bool Arduino_GigaDisplayTouch::begin() { + _wire.setClock(400000); /* maximum transmission rate of 400K bps */ + _wire.begin(); + + delay(300); + + /* GT911 Power-on timing procedure - Ref. pg10 GT911 Rev09 */ + /** T0: Set output low */ + pinMode(_rstPin, OUTPUT); + pinMode(_intPin, OUTPUT); + digitalWrite(_rstPin, LOW); + digitalWrite(_intPin, LOW); + /** T1+T2: > 10ms */ + delay(11); + /** Address selection: high - 0x28/0x29 (0x14 7bit), low - 0xBA/0xBB (0x5D + * 7bit) */ + digitalWrite(_intPin, (_addr == GT911_I2C_ADDR_28_29)); + /** T7: > 100us */ + delayMicroseconds(110); + digitalWrite(_rstPin, HIGH); + /** T8: > 5ms */ + delay(6); + digitalWrite(_intPin, LOW); + /** T3: > 50ms */ + delay(51); + pinMode(_intPin, INPUT); + + _gt911TouchHandler = nullptr; + + /* GT911 test communication */ + uint8_t testByte; + uint8_t error = _gt911ReadOp(GT911_REG_CONFIG_VERSION, &testByte, 1); + +#if __has_include("lvgl.h") +#if (LVGL_VERSION_MAJOR == 9) + static lv_indev_t *indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, _lvglTouchCb); +#else + static lv_indev_drv_t indev_drv; /* Descriptor of a input device driver */ + lv_indev_drv_init(&indev_drv); /* Basic initialization */ + indev_drv.type = + LV_INDEV_TYPE_POINTER; /* Touch pad is a pointer-like device */ + indev_drv.read_cb = _lvglTouchCb; /* Set your driver function */ + lv_indev_t *my_indev = + lv_indev_drv_register(&indev_drv); /* Register the driver in LVGL and save + the created input device object */ +#endif +#endif + + gThis = this; + return (error == 0); +} + +#if __has_include("lvgl.h") +#if (LVGL_VERSION_MAJOR == 9) +void _lvglTouchCb(lv_indev_t *indev, lv_indev_data_t *data) { + uint8_t contacts; + GDTpoint_t points[5]; + + contacts = gThis->getTouchPoints(points); + + if (contacts > 0) { + data->state = LV_INDEV_STATE_PRESSED; + data->point.x = points[0].x; + data->point.y = points[0].y; + } else { + data->state = LV_INDEV_STATE_RELEASED; + } + + return; +} +#else +void _lvglTouchCb(lv_indev_drv_t *indev, lv_indev_data_t *data) { + uint8_t contacts; + GDTpoint_t points[5]; + + contacts = gThis->getTouchPoints(points); + + if (contacts > 0) { + data->state = LV_INDEV_STATE_PR; + data->point.x = points[0].x; + data->point.y = points[0].y; + } else { + data->state = LV_INDEV_STATE_REL; + } + + return; +} +#endif +#endif + +void Arduino_GigaDisplayTouch::end() {} + +uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t *points) { + uint8_t rawpoints[GT911_MAX_CONTACTS * GT911_CONTACT_SIZE]; + uint8_t contacts; + uint8_t error; + + contacts = 0; + error = _gt911ReadInputCoord(rawpoints, contacts); + + if (error) { + return 0; + } + + for (uint8_t i = 0; i < contacts; i++) { + points[i].trackId = rawpoints[1 + 8 * i]; + points[i].x = ((uint16_t)rawpoints[3 + 8 * i] << 8) + rawpoints[2 + 8 * i]; + points[i].y = ((uint16_t)rawpoints[5 + 8 * i] << 8) + rawpoints[4 + 8 * i]; + points[i].area = + ((uint16_t)rawpoints[7 + 8 * i] << 8) + rawpoints[6 + 8 * i]; + } + + _gt911WriteOp(GT911_REG_GESTURE_START_POINT, + 0); /* Reset buffer status to finish the reading */ + + return contacts; +} + +void Arduino_GigaDisplayTouch::onDetect(void (*handler)(uint8_t, + GDTpoint_t *)) { + _gt911TouchHandler = handler; + t.start(callback(&queue, &events::EventQueue::dispatch_forever)); + _irqInt.rise(queue.event( + mbed::callback(this, &Arduino_GigaDisplayTouch::_gt911onIrq))); +} + +uint8_t Arduino_GigaDisplayTouch::_gt911WriteOp(uint16_t reg, uint8_t data) { + uint8_t status = 0; + status = _gt911WriteBytesOp(reg, &data, 1); + + return status; +} + +uint8_t Arduino_GigaDisplayTouch::_gt911WriteBytesOp(uint16_t reg, + uint8_t *data, + uint8_t len) { + uint8_t status = 0; + + _wire.beginTransmission(_addr); + _wire.write(reg >> 8); /* Register H */ + _wire.write(reg & 0xFF); /* Register L */ + + /* Data [0..n] */ + for (uint8_t i = 0; i < len; i++) { + _wire.write(data[i]); + } + + status = _wire.endTransmission(); + + return status; +} + +uint8_t Arduino_GigaDisplayTouch::_gt911ReadOp(uint16_t reg, uint8_t *data, + uint8_t len) { + uint8_t status = 0; + + _wire.beginTransmission(_addr); + _wire.write(reg >> 8); /* Register H */ + _wire.write(reg & 0xFF); /* Register L */ + status = _wire.endTransmission(); + + if (status) + return status; + + _wire.requestFrom(_addr, len); + uint8_t index = 0; + /* Data [0..n] */ + while (_wire.available()) { + data[index++] = _wire.read(); + } + + if (len == index) + return 0; + else + return 4; /* Other error */ +} + +void Arduino_GigaDisplayTouch::_gt911onIrq() { + uint8_t contacts; + uint8_t rawpoints[GT911_MAX_CONTACTS * GT911_CONTACT_SIZE]; + uint8_t error; + + error = _gt911ReadInputCoord(rawpoints, contacts); + + if (error) { + return; + } + + for (uint8_t i = 0; i < contacts; i++) { + _points[i].trackId = rawpoints[1 + 8 * i]; + _points[i].x = ((uint16_t)rawpoints[3 + 8 * i] << 8) + rawpoints[2 + 8 * i]; + _points[i].y = ((uint16_t)rawpoints[5 + 8 * i] << 8) + rawpoints[4 + 8 * i]; + _points[i].area = + ((uint16_t)rawpoints[7 + 8 * i] << 8) + rawpoints[6 + 8 * i]; + } + + if (contacts > 0 && _gt911TouchHandler != nullptr) + _gt911TouchHandler(contacts, _points); + + _gt911WriteOp(GT911_REG_GESTURE_START_POINT, + 0); /* Reset buffer status to finish the reading */ +} + +uint8_t Arduino_GigaDisplayTouch::_gt911ReadInputCoord(uint8_t *pointsbuf, + uint8_t &contacts) { + uint8_t error; + + contacts = 0; + error = _gt911ReadOp(GT911_REG_GESTURE_START_POINT, pointsbuf, + GT911_CONTACT_SIZE * GT911_MAX_CONTACTS); + + if (error) { + return 1; /* I2C comm error */ + } + + if (!(pointsbuf[0] & 0x80)) { + return 2; /* Data buffer not ready */ + } + + contacts = pointsbuf[0] & 0xF; + return 0; +} + +/**** END OF FILE ****/ \ No newline at end of file