Capacitive Touch Screen (GT911) for SKR SE BX (#21843)
Co-authored-by: Msq001 <alansayyeah@gmail.com> Co-authored-by: Scott Lahteine <github@thinkyhead.com>
This commit is contained in:
202
Marlin/src/HAL/STM32/tft/gt911.cpp
Normal file
202
Marlin/src/HAL/STM32/tft/gt911.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(TFT_TOUCH_DEVICE_GT911)
|
||||
|
||||
#include "gt911.h"
|
||||
#include "pinconfig.h"
|
||||
|
||||
SW_IIC::SW_IIC(uint16_t sda, uint16_t scl) {
|
||||
scl_pin = scl;
|
||||
sda_pin = sda;
|
||||
}
|
||||
|
||||
// Software I2C hardware io init
|
||||
void SW_IIC::init() {
|
||||
OUT_WRITE(scl_pin, HIGH);
|
||||
OUT_WRITE(sda_pin, HIGH);
|
||||
}
|
||||
|
||||
// Software I2C start signal
|
||||
void SW_IIC::start() {
|
||||
write_sda(HIGH); // SDA = 1
|
||||
write_scl(HIGH); // SCL = 1
|
||||
iic_delay(2);
|
||||
write_sda(LOW); // SDA = 0
|
||||
iic_delay(1);
|
||||
write_scl(LOW); // SCL = 0 // keep SCL low, avoid false stop caused by level jump caused by SDA switching IN/OUT
|
||||
}
|
||||
|
||||
// Software I2C stop signal
|
||||
void SW_IIC::stop() {
|
||||
write_scl(LOW); // SCL = 0
|
||||
iic_delay(2);
|
||||
write_sda(LOW); // SDA = 0
|
||||
iic_delay(2);
|
||||
write_scl(HIGH); // SCL = 1
|
||||
iic_delay(2);
|
||||
write_sda(HIGH); // SDA = 1
|
||||
}
|
||||
|
||||
// Software I2C sends ACK or NACK signal
|
||||
void SW_IIC::send_ack(bool ack) {
|
||||
write_sda(ack ? LOW : HIGH); // SDA = !ack
|
||||
iic_delay(2);
|
||||
write_scl(HIGH); // SCL = 1
|
||||
iic_delay(2);
|
||||
write_scl(LOW); // SCL = 0
|
||||
}
|
||||
|
||||
// Software I2C read ACK or NACK signal
|
||||
bool SW_IIC::read_ack() {
|
||||
bool error = 0;
|
||||
set_sda_in();
|
||||
|
||||
iic_delay(2);
|
||||
|
||||
write_scl(HIGH); // SCL = 1
|
||||
error = read_sda();
|
||||
|
||||
iic_delay(2);
|
||||
|
||||
write_scl(LOW); // SCL = 0
|
||||
|
||||
set_sda_out();
|
||||
return error;
|
||||
}
|
||||
|
||||
void SW_IIC::send_byte(uint8_t txd) {
|
||||
LOOP_L_N(i, 8) {
|
||||
write_sda(txd & 0x80); // write data bit
|
||||
txd <<= 1;
|
||||
iic_delay(1);
|
||||
write_scl(HIGH); // SCL = 1
|
||||
iic_delay(2);
|
||||
write_scl(LOW); // SCL = 0
|
||||
iic_delay(1);
|
||||
}
|
||||
|
||||
read_ack(); // wait ack
|
||||
}
|
||||
|
||||
uint8_t SW_IIC::read_byte(bool ack) {
|
||||
uint8_t data = 0;
|
||||
|
||||
set_sda_in();
|
||||
LOOP_L_N(i, 8) {
|
||||
write_scl(HIGH); // SCL = 1
|
||||
iic_delay(1);
|
||||
data <<= 1;
|
||||
if (read_sda()) data++;
|
||||
write_scl(LOW); // SCL = 0
|
||||
iic_delay(2);
|
||||
}
|
||||
set_sda_out();
|
||||
|
||||
send_ack(ack);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
GT911_REG_MAP GT911::reg;
|
||||
SW_IIC GT911::sw_iic = SW_IIC(GT911_SW_I2C_SDA_PIN, GT911_SW_I2C_SCL_PIN);
|
||||
|
||||
void GT911::write_reg(uint16_t reg, uint8_t reg_len, uint8_t* w_data, uint8_t w_len) {
|
||||
sw_iic.start();
|
||||
sw_iic.send_byte(gt911_slave_address); // Set IIC Slave address
|
||||
LOOP_L_N(i, reg_len) { // Set reg address
|
||||
uint8_t r = (reg >> (8 * (reg_len - 1 - i))) & 0xFF;
|
||||
sw_iic.send_byte(r);
|
||||
}
|
||||
|
||||
LOOP_L_N(i, w_len) { // Write data to reg
|
||||
sw_iic.send_byte(w_data[i]);
|
||||
}
|
||||
sw_iic.stop();
|
||||
}
|
||||
|
||||
void GT911::read_reg(uint16_t reg, uint8_t reg_len, uint8_t* r_data, uint8_t r_len) {
|
||||
sw_iic.start();
|
||||
sw_iic.send_byte(gt911_slave_address); // Set IIC Slave address
|
||||
LOOP_L_N(i, reg_len) { // Set reg address
|
||||
uint8_t r = (reg >> (8 * (reg_len - 1 - i))) & 0xFF;
|
||||
sw_iic.send_byte(r);
|
||||
}
|
||||
|
||||
sw_iic.start();
|
||||
sw_iic.send_byte(gt911_slave_address + 1); // Set read mode
|
||||
|
||||
LOOP_L_N(i, r_len) {
|
||||
r_data[i] = sw_iic.read_byte(1); // Read data from reg
|
||||
}
|
||||
sw_iic.stop();
|
||||
}
|
||||
|
||||
void GT911::Init() {
|
||||
OUT_WRITE(GT911_RST_PIN, LOW);
|
||||
OUT_WRITE(GT911_INT_PIN, LOW);
|
||||
delay(20);
|
||||
WRITE(GT911_RST_PIN, HIGH);
|
||||
SET_INPUT(GT911_INT_PIN);
|
||||
|
||||
sw_iic.init();
|
||||
|
||||
uint8_t clear_reg = 0x0000;
|
||||
write_reg(0x814E, 2, &clear_reg, 2); // Reset to 0 for start
|
||||
}
|
||||
|
||||
bool GT911::getFirstTouchPoint(int16_t *x, int16_t *y) {
|
||||
read_reg(0x814E, 2, ®.REG.status, 1);
|
||||
|
||||
if (reg.REG.status & 0x80) {
|
||||
uint8_t clear_reg = 0x00;
|
||||
write_reg(0x814E, 2, &clear_reg, 1); // Reset to 0 for start
|
||||
read_reg(0x8150, 2, reg.map + 2, 8 * (reg.REG.status & 0x0F));
|
||||
|
||||
// First touch point
|
||||
*x = ((reg.REG.point[0].xh & 0x0F) << 8) | reg.REG.point[0].xl;
|
||||
*y = ((reg.REG.point[0].yh & 0x0F) << 8) | reg.REG.point[0].yl;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GT911::getPoint(int16_t *x, int16_t *y) {
|
||||
static bool touched = 0;
|
||||
static int16_t read_x = 0, read_y = 0;
|
||||
static millis_t next_time = 0;
|
||||
|
||||
if (ELAPSED(millis(), next_time)) {
|
||||
touched = getFirstTouchPoint(&read_x, &read_y);
|
||||
next_time = millis() + 20;
|
||||
}
|
||||
|
||||
*x = read_x;
|
||||
*y = read_y;
|
||||
return touched;
|
||||
}
|
||||
|
||||
#endif // TFT_TOUCH_DEVICE_GT911
|
||||
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
|
||||
Reference in New Issue
Block a user