194 lines
6.0 KiB
C++
194 lines
6.0 KiB
C++
/**
|
|
* @file ft3267.c
|
|
* @brief ft3267 Capacitive Touch Panel Controller Driver
|
|
* @version 0.1
|
|
* @date 2021-01-13
|
|
*
|
|
* @copyright Copyright 2021 Espressif Systems (Shanghai) Co. Ltd.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "ft3267.h"
|
|
#include "Arduino.h"
|
|
#include "Wire.h"
|
|
#include "esp_err.h"
|
|
#include "esp_log.h"
|
|
|
|
/** @brief FT5x06 register map and function codes */
|
|
#define FT5x06_ADDR (0x38)
|
|
|
|
#define FT5x06_DEVICE_MODE (0x00)
|
|
#define FT5x06_GESTURE_ID (0x01)
|
|
#define FT5x06_TOUCH_POINTS (0x02)
|
|
|
|
#define FT5x06_TOUCH1_EV_FLAG (0x03)
|
|
#define FT5x06_TOUCH1_XH (0x03)
|
|
#define FT5x06_TOUCH1_XL (0x04)
|
|
#define FT5x06_TOUCH1_YH (0x05)
|
|
#define FT5x06_TOUCH1_YL (0x06)
|
|
|
|
#define FT5x06_TOUCH2_EV_FLAG (0x09)
|
|
#define FT5x06_TOUCH2_XH (0x09)
|
|
#define FT5x06_TOUCH2_XL (0x0A)
|
|
#define FT5x06_TOUCH2_YH (0x0B)
|
|
#define FT5x06_TOUCH2_YL (0x0C)
|
|
|
|
#define FT5x06_TOUCH3_EV_FLAG (0x0F)
|
|
#define FT5x06_TOUCH3_XH (0x0F)
|
|
#define FT5x06_TOUCH3_XL (0x10)
|
|
#define FT5x06_TOUCH3_YH (0x11)
|
|
#define FT5x06_TOUCH3_YL (0x12)
|
|
|
|
#define FT5x06_TOUCH4_EV_FLAG (0x15)
|
|
#define FT5x06_TOUCH4_XH (0x15)
|
|
#define FT5x06_TOUCH4_XL (0x16)
|
|
#define FT5x06_TOUCH4_YH (0x17)
|
|
#define FT5x06_TOUCH4_YL (0x18)
|
|
|
|
#define FT5x06_TOUCH5_EV_FLAG (0x1B)
|
|
#define FT5x06_TOUCH5_XH (0x1B)
|
|
#define FT5x06_TOUCH5_XL (0x1C)
|
|
#define FT5x06_TOUCH5_YH (0x1D)
|
|
#define FT5x06_TOUCH5_YL (0x1E)
|
|
|
|
#define FT5x06_ID_G_THGROUP (0x80)
|
|
#define FT5x06_ID_G_THPEAK (0x81)
|
|
#define FT5x06_ID_G_THCAL (0x82)
|
|
#define FT5x06_ID_G_THWATER (0x83)
|
|
#define FT5x06_ID_G_THTEMP (0x84)
|
|
#define FT5x06_ID_G_THDIFF (0x85)
|
|
#define FT5x06_ID_G_CTRL (0x86)
|
|
#define FT5x06_ID_G_TIME_ENTER_MONITOR (0x87)
|
|
#define FT5x06_ID_G_PERIODACTIVE (0x88)
|
|
#define FT5x06_ID_G_PERIODMONITOR (0x89)
|
|
#define FT5x06_ID_G_AUTO_CLB_MODE (0xA0)
|
|
#define FT5x06_ID_G_LIB_VERSION_H (0xA1)
|
|
#define FT5x06_ID_G_LIB_VERSION_L (0xA2)
|
|
#define FT5x06_ID_G_CIPHER (0xA3)
|
|
#define FT5x06_ID_G_MODE (0xA4)
|
|
#define FT5x06_ID_G_PMODE (0xA5)
|
|
#define FT5x06_ID_G_FIRMID (0xA6)
|
|
#define FT5x06_ID_G_STATE (0xA7)
|
|
#define FT5x06_ID_G_FT5201ID (0xA8)
|
|
#define FT5x06_ID_G_ERR (0xA9)
|
|
|
|
TwoWire *_Wrie = NULL;
|
|
|
|
static inline esp_err_t ft3267_read_byte(uint8_t reg_addr, uint8_t *data)
|
|
{
|
|
// return i2c_bus_read_byte(ft3267_handle, reg_addr, data);
|
|
_Wrie->beginTransmission(FT5x06_ADDR);
|
|
_Wrie->write(reg_addr);
|
|
_Wrie->endTransmission();
|
|
uint8_t bytesReceived = _Wrie->requestFrom(FT5x06_ADDR, 1);
|
|
if (bytesReceived)
|
|
_Wrie->readBytes(data, bytesReceived);
|
|
return 0;
|
|
}
|
|
|
|
static inline esp_err_t ft3267_read_bytes(uint8_t reg_addr, size_t data_len, uint8_t *data)
|
|
{
|
|
// return i2c_bus_read_bytes(ft3267_handle, reg_addr, data_len, data);
|
|
_Wrie->beginTransmission(FT5x06_ADDR);
|
|
_Wrie->write(reg_addr);
|
|
_Wrie->endTransmission();
|
|
uint8_t bytesReceived = _Wrie->requestFrom(FT5x06_ADDR, data_len);
|
|
uint8_t index = 0;
|
|
while (_Wrie->available())
|
|
data[index++] = _Wrie->read();
|
|
return 0;
|
|
}
|
|
|
|
static inline esp_err_t ft3267_write_byte(uint8_t reg_addr, uint8_t data)
|
|
{
|
|
_Wrie->beginTransmission(FT5x06_ADDR);
|
|
_Wrie->write(reg_addr);
|
|
_Wrie->write(data);
|
|
_Wrie->endTransmission();
|
|
return 0;
|
|
}
|
|
|
|
esp_err_t ft3267_init(TwoWire &Wrie)
|
|
{
|
|
|
|
_Wrie = &Wrie;
|
|
|
|
if (NULL == _Wrie) {
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
esp_err_t ret_val = ESP_OK;
|
|
|
|
// Valid touching detect threshold
|
|
ft3267_write_byte(FT5x06_ID_G_THGROUP, 70);
|
|
|
|
// valid touching peak detect threshold
|
|
ft3267_write_byte(FT5x06_ID_G_THPEAK, 60);
|
|
|
|
// Touch focus threshold
|
|
ft3267_write_byte(FT5x06_ID_G_THCAL, 16);
|
|
|
|
// threshold when there is surface water
|
|
ft3267_write_byte(FT5x06_ID_G_THWATER, 60);
|
|
|
|
// threshold of temperature compensation
|
|
ft3267_write_byte(FT5x06_ID_G_THTEMP, 10);
|
|
|
|
// Touch difference threshold
|
|
ft3267_write_byte(FT5x06_ID_G_THDIFF, 20);
|
|
|
|
// Delay to enter 'Monitor' status (s)
|
|
ft3267_write_byte(FT5x06_ID_G_TIME_ENTER_MONITOR, 2);
|
|
|
|
// Period of 'Active' status (ms)
|
|
ft3267_write_byte(FT5x06_ID_G_PERIODACTIVE, 12);
|
|
|
|
// Timer to enter 'idle' when in 'Monitor' (ms)
|
|
ft3267_write_byte(FT5x06_ID_G_PERIODMONITOR, 40);
|
|
|
|
//setting interrupt
|
|
ft3267_write_byte(FT5x06_ID_G_MODE, 0);
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t ft3267_get_touch_points_num(uint8_t *touch_points_num)
|
|
{
|
|
|
|
return ft3267_read_byte(FT5x06_TOUCH_POINTS, touch_points_num);
|
|
}
|
|
|
|
esp_err_t ft3267_read_pos(uint8_t *touch_points_num, uint16_t *x, uint16_t *y)
|
|
{
|
|
esp_err_t ret_val = ESP_OK;
|
|
static uint8_t data[4];
|
|
|
|
ret_val |= ft3267_get_touch_points_num(touch_points_num);
|
|
*touch_points_num = (*touch_points_num) & 0x0f;
|
|
if (0 == *touch_points_num) {
|
|
} else {
|
|
ret_val |= ft3267_read_bytes(FT5x06_TOUCH1_XH, 4, data);
|
|
|
|
*x = ((data[0] & 0x0f) << 8) + data[1];
|
|
*y = ((data[2] & 0x0f) << 8) + data[3];
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
esp_err_t fx5x06_read_gesture(ft3267_gesture_t *gesture)
|
|
{
|
|
return ft3267_read_byte(FT5x06_GESTURE_ID, (uint8_t *)gesture);
|
|
}
|