Utouch update (#20561)

* toched return int16

* add XPT and more opcodes

* add guesture

* increase code buffer
This commit is contained in:
gemu 2024-01-22 18:21:40 +01:00 committed by GitHub
parent 85c1413eb1
commit 780940d5d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 312 additions and 62 deletions

View File

@ -627,7 +627,7 @@ bool Renderer::utouch_Init(char **name) {
return false;
}
bool Renderer::touched(void) {
uint16_t Renderer::touched(void) {
return false;
}

View File

@ -93,7 +93,7 @@ public:
virtual void ep_update_area(uint16_t xp, uint16_t yp, uint16_t width, uint16_t height, uint8_t mode);
virtual uint32_t get_sr_touch(uint32_t xp, uint32_t xm, uint32_t yp, uint32_t ym);
virtual bool utouch_Init(char **);
virtual bool touched(void);
virtual uint16_t touched(void);
virtual int16_t getPoint_x();
virtual int16_t getPoint_y();

View File

@ -587,17 +587,13 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
} else if (*lp1 == 'S') {
// spi mode
lp1++;
uint8_t ut_mode = *lp1 & 0xf;
ut_spi_nr = *lp1 & 0xf;
lp1 += 2;
ut_reset = -1;
ut_irq = -1;
ut_spi_cs = next_val(&lp1);
ut_reset = next_val(&lp1);
ut_irq = next_val(&lp1);
// assume displays SPI bus
pinMode(ut_spi_cs, OUTPUT);
digitalWrite(ut_spi_cs, HIGH);
ut_spiSettings = SPISettings(2000000, MSBFIRST, SPI_MODE0);
} else {
// simple resistive touch
@ -921,6 +917,17 @@ uint16_t index = 0;
delay_arg(args);
}
} else {
if (spi_dc == -2) {
// pseudo opcodes
switch (iob) {
case UDSP_WRITE_16:
break;
case UDSP_READ_DATA:
break;
case UDSP_READ_STATUS:
break;
}
}
ulcd_command(iob);
uint8_t args = dsp_cmds[cmd_offset++];
index++;
@ -1913,13 +1920,21 @@ bool uDisplay::utouch_Init(char **name) {
delay(10);
}
if (ut_irq >= 0) {
pinMode(ut_irq, INPUT );
attachInterrupt(ut_irq, ut_touch_irq, FALLING);
}
if (ut_spi_nr == spi_nr) {
ut_spi = uspi;
} else {
// not yet
ut_spi = nullptr;
}
return ut_execute(ut_init_code);
}
bool uDisplay::touched(void) {
uint16_t uDisplay::touched(void) {
if (ut_irq >= 0) {
if (!ut_irq_flg) {
return false;
@ -2524,7 +2539,7 @@ void uDisplay::dim10(uint8_t dim, uint16_t dim_gamma) { // dimmer with
}
// the cases are PSEUDO_OPCODES from MODULE_DESCRIPTOR
// and may be exapnded with more opcodes
// and may be expanded with more opcodes
void uDisplay::TS_RotConvert(int16_t *x, int16_t *y) {
int16_t temp;
@ -2588,22 +2603,38 @@ char *uDisplay::devname(void) {
#ifdef USE_UNIVERSAL_TOUCH
uint16_t uDisplay::ut_par(char **lp, uint32_t mode) {
float CharToFloat(const char *str);
uint32_t uDisplay::ut_par(char **lp, uint32_t mode) {
char *cp = *lp;
while (*cp != ' ') {
if (!cp) break;
cp++;
}
cp++;
uint16_t result;
uint32_t result;
if (!mode) {
// hex
result = strtol(cp, &cp, 16);
} else {
} else if (mode == 1) {
// word
result = strtol(cp, &cp, 10);
} else {
// float as 32bit integer
float fval = CharToFloat(cp);
result = *(uint32_t*)&fval;
while (*cp) {
if (*cp == ' ' || *cp =='\n') {
break;
}
cp++;
}
}
*lp = cp;
return result;
}
// translate pseudo opcodes to tokens
void uDisplay::ut_trans(char **sp, uint8_t *ut_code, int32_t size) {
char *cp = *sp;
uint16_t wval;
@ -2611,6 +2642,16 @@ void uDisplay::ut_trans(char **sp, uint8_t *ut_code, int32_t size) {
if (*cp == ':' || *cp == '#') {
break;
}
if (*cp == ';') {
// skip comment line
while (*cp) {
if (*cp == '\n') {
cp++;
break;
}
cp++;
}
}
if (!strncmp(cp, "RDWM", 4)) {
// read word many
*ut_code++ = UT_RDWM;
@ -2663,6 +2704,12 @@ void uDisplay::ut_trans(char **sp, uint8_t *ut_code, int32_t size) {
// return when true
*ut_code++ = UT_RTT;
size -= 1;
} else if (!strncmp(cp, "MVB", 3)) {
// move
*ut_code++ = UT_MVB;
*ut_code++ = ut_par(&cp, 1);
*ut_code++ = ut_par(&cp, 1);
size -= 3;
} else if (!strncmp(cp, "MV", 2)) {
// move
*ut_code++ = UT_MV;
@ -2691,13 +2738,36 @@ void uDisplay::ut_trans(char **sp, uint8_t *ut_code, int32_t size) {
} else if (!strncmp(cp, "AND", 3)) {
*ut_code++ = UT_AND;
wval = ut_par(&cp, 0);
*ut_code++ = wval>>8;
*ut_code++ = wval >> 8;
*ut_code++ = wval;
size -= 3;
} else if (!strncmp(cp, "SCL", 3)) {
*ut_code++ = UT_SCALE;
wval = ut_par(&cp, 1);
*ut_code++ = wval >> 8;
*ut_code++ = wval;
uint32_t lval = ut_par(&cp, 2);
*ut_code++ = lval >> 24;
*ut_code++ = lval >> 16;
*ut_code++ = lval >> 8;
*ut_code++ = lval;
size -= 7;
} else if (!strncmp(cp, "LIM", 3)) {
*ut_code++ = UT_LIM;
wval = ut_par(&cp, 1);
*ut_code++ = wval >> 8;
*ut_code++ = wval;
size -= 3;
} else if (!strncmp(cp, "GSRT", 4)) {
*ut_code++ = UT_GSRT;
wval = ut_par(&cp, 1);
*ut_code++ = wval>>8;
*ut_code++ = wval >> 8;
*ut_code++ = wval;
size -= 3;
} else if (!strncmp(cp, "XPT", 3)) {
*ut_code++ = UT_XPT;
wval = ut_par(&cp, 1);
*ut_code++ = wval >> 8;
*ut_code++ = wval;
size -= 3;
} else if (!strncmp(cp, "DBG", 3)) {
@ -2710,6 +2780,9 @@ void uDisplay::ut_trans(char **sp, uint8_t *ut_code, int32_t size) {
break;
}
cp++;
}
*ut_code++ = UT_END;
@ -2735,16 +2808,20 @@ uint8_t *uDisplay::ut_rd(uint8_t *iop, uint32_t len, uint32_t amode) {
}
} else {
// spi mode
uint16_t val = *iop++;
digitalWrite(ut_spi_cs, LOW);
if (spi_nr <= 2) {
uspi->beginTransaction(ut_spiSettings);
val = uspi->transfer16(val);
uspi->endTransaction();
ut_array[0] = val << 8;
ut_array[1] = val;
if (amode == 1) {
uint16_t val = *iop++;
uint16_t len = *iop++;
if (ut_spi) {
digitalWrite(ut_spi_cs, LOW);
ut_spi->beginTransaction(ut_spiSettings);
ut_spi->transfer(val);
val = ut_spi->transfer16(0);
ut_spi->endTransaction();
ut_array[len] = val << 8;
ut_array[len + 1] = val;
digitalWrite(ut_spi_cs, HIGH);
}
}
digitalWrite(ut_spi_cs, HIGH);
}
return iop;
}
@ -2765,6 +2842,59 @@ uint8_t *uDisplay::ut_wr(uint8_t *iop, uint32_t amode) {
return iop;
}
int16_t uDisplay::besttwoavg( int16_t x , int16_t y , int16_t z ) {
int16_t da, db, dc;
int16_t reta = 0;
if ( x > y ) da = x - y; else da = y - x;
if ( x > z ) db = x - z; else db = z - x;
if ( z > y ) dc = z - y; else dc = y - z;
if ( da <= db && da <= dc ) reta = (x + y) >> 1;
else if ( db <= da && db <= dc ) reta = (x + z) >> 1;
else reta = (y + z) >> 1;
return (reta);
}
uint16_t uDisplay::ut_XPT2046(uint16_t z_th) {
uint16_t result = 0;
if (ut_spi) {
int16_t data[6];
ut_spi->beginTransaction(ut_spiSettings);
digitalWrite(ut_spi_cs, LOW);
ut_spi->transfer(0xB1 /* Z1 */);
int16_t z1 = ut_spi->transfer16(0xC1 /* Z2 */) >> 3;
int16_t z = z1 + 4095;
int16_t z2 = ut_spi->transfer16(0x91 /* X */) >> 3;
z -= z2;
if (z >= z_th) {
ut_spi->transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy
data[0] = ut_spi->transfer16(0xD1 /* Y */) >> 3;
data[1] = ut_spi->transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
data[2] = ut_spi->transfer16(0xD1 /* Y */) >> 3;
data[3] = ut_spi->transfer16(0x91 /* X */) >> 3;
result = 1;
}
else {
data[0] = data[1] = data[2] = data[3] = 0;
}
data[4] = ut_spi->transfer16(0xD0 /* Y */) >> 3; // Last Y touch power down
data[5] = ut_spi->transfer16(0) >> 3;
digitalWrite(ut_spi_cs, HIGH);
ut_spi->endTransaction();
uint16_t x = besttwoavg( data[0], data[2], data[4] );
uint16_t y = besttwoavg( data[1], data[3], data[5] );
ut_array[0] = x >> 8;
ut_array[1] = x;
ut_array[2] = y >> 8;
ut_array[3] = y;
}
return result;
}
int16_t uDisplay::ut_execute(uint8_t *ut_code) {
int16_t result = 0;
uint8_t iob, len;
@ -2777,46 +2907,69 @@ uint16_t wval;
// read 1 byte
ut_code = ut_rd(ut_code, 1, 1);
break;
case UT_RDM:
// read multiple bytes
ut_code = ut_rd(ut_code, 2, 1);
break;
case UT_RDW:
// read 1 byte
ut_code = ut_rd(ut_code, 1, 2);
break;
case UT_RDWM:
// read multiple bytes
ut_code = ut_rd(ut_code, 2, 2);
break;
case UT_WR:
ut_code = ut_wr(ut_code, 1);
break;
case UT_WRW:
ut_code = ut_wr(ut_code, 2);
break;
case UT_CP:
// compare
iob = *ut_code++;
result = (iob == ut_array[0]);
break;
case UT_CPR:
// compare
iob = *ut_code++;
result = (iob == result);
break;
case UT_RTF:
// return when false
if (result == 0) {
return false;
}
break;
case UT_RTT:
// return when true
if (result > 0) {
return false;
}
break;
break;
case UT_MVB:
// move byte from index to high or low result
wval = *ut_code++;
iob = *ut_code++;
if (wval == 0) {
result &= 0xff00;
result |= ut_array[iob];
} else {
result &= 0x00ff;
result |= (ut_array[iob] << 8);
}
break;
case UT_MV:
// move
// source
@ -2835,16 +2988,42 @@ uint16_t wval;
}
result &= 0xfff;
break;
case UT_AND:
case UT_AND:
// and
wval = *ut_code++ << 8;
wval |= *ut_code++;
result &= wval;
break;
case UT_SCALE:
{
wval = *ut_code++ << 8;
wval |= *ut_code++;
result -= wval;
uint32_t lval = (uint32_t)*ut_code++ << 24;
lval |= (uint32_t)*ut_code++ << 16;
lval |= (uint32_t)*ut_code++ << 8;
lval |= (uint32_t)*ut_code++;
float fval = *(float*)&lval;
fval *= (float)result;
result = fval;
}
break;
case UT_LIM:
wval = *ut_code++ << 8;
wval |= *ut_code++;
if (result > wval) {
result = wval;
}
break;
case UT_RT:
// result
return result;
break;
case UT_GSRT:
#ifdef USE_ESP32_S3
{ uint32_t val = get_sr_touch(SIMPLERS_XP, SIMPLERS_XM, SIMPLERS_YP, SIMPLERS_YM);
@ -2867,12 +3046,20 @@ uint16_t wval;
}
#endif // USE_ESP32_S3
break;
case UT_XPT:
wval = *ut_code++ << 8;
wval |= *ut_code++;
result = ut_XPT2046(wval);
break;
case UT_DBG:
// debug show result
//Serial.printf("UTDBG: %d\n", result);
wval = *ut_code++;
AddLog(LOG_LEVEL_INFO, PSTR("UTDBG %d: %02x : %02x,%02x,%02x,%02x"), wval, result, ut_array[0], ut_array[1], ut_array[2], ut_array[3]);
break;
case UT_END:
break;
}
@ -2937,38 +3124,57 @@ uint32_t uDisplay::next_hex(char **sp) {
// we use our own hardware driver for 9 bit spi
void uDisplay::hw_write9(uint8_t val, uint8_t dc) {
uint32_t regvalue = val >> 1;
if (dc) regvalue |= 0x80;
else regvalue &= 0x7f;
if (val & 1) regvalue |= 0x8000;
REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI);
REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1);
uint32_t *dp = (uint32_t*)SPI_W0_REG(3);
*dp = regvalue;
REG_SET_BIT(SPI_CMD_REG(3), SPI_USR);
while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR));
if (spi_dc < -1) {
// RA8876 mode
if (!dc) {
uspi->write(RA8876_CMD_WRITE);
uspi->write(val);
} else {
uspi->write(RA8876_DATA_WRITE);
uspi->write(val);
}
} else {
uint32_t regvalue = val >> 1;
if (dc) regvalue |= 0x80;
else regvalue &= 0x7f;
if (val & 1) regvalue |= 0x8000;
REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI);
REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1);
uint32_t *dp = (uint32_t*)SPI_W0_REG(3);
*dp = regvalue;
REG_SET_BIT(SPI_CMD_REG(3), SPI_USR);
while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR));
}
}
#else
#include "spi_register.h"
void uDisplay::hw_write9(uint8_t val, uint8_t dc) {
uint32_t regvalue;
uint8_t bytetemp;
if (!dc) {
bytetemp = (val>> 1) & 0x7f;
if (spi_dc < -1) {
// RA8876 mode
if (!dc) {
uspi->write(RA8876_CMD_WRITE);
uspi->write(val);
} else {
uspi->write(RA8876_DATA_WRITE);
uspi->write(val);
}
} else {
bytetemp = (val >> 1) | 0x80;
uint32_t regvalue;
uint8_t bytetemp;
if (!dc) {
bytetemp = (val>> 1) & 0x7f;
} else {
bytetemp = (val >> 1) | 0x80;
}
regvalue = ((8 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) | ((uint32)bytetemp); //configure transmission variable,9bit transmission length and first 8 command bit
if (val & 0x01) regvalue |= BIT15; //write the 9th bit
while (READ_PERI_REG(SPI_CMD(1)) & SPI_USR); //waiting for spi module available
WRITE_PERI_REG(SPI_USER2(1), regvalue); //write command and command length into spi reg
SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR); //transmission start
}
regvalue = ((8 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) | ((uint32)bytetemp); //configure transmission variable,9bit transmission length and first 8 command bit
if (val & 0x01) regvalue |= BIT15; //write the 9th bit
while (READ_PERI_REG(SPI_CMD(1)) & SPI_USR); //waiting for spi module available
WRITE_PERI_REG(SPI_USER2(1), regvalue); //write command and command length into spi reg
SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR); //transmission start
}
#endif
@ -2985,6 +3191,26 @@ void USECACHE uDisplay::write8(uint8_t val) {
}
}
uint8_t uDisplay::writeReg16(uint8_t reg, uint16_t wval) {
hw_write9(reg, 0);
hw_write9(wval, 1);
hw_write9(reg + 1, 0);
hw_write9(wval >> 8, 1);
return 0;
}
uint8_t uDisplay::readData(void) {
uspi->write(RA8876_DATA_READ);
uint8_t val = uspi->transfer(0);
return val;
}
uint8_t uDisplay::readStatus(void) {
uspi->write(RA8876_STATUS_READ);
uint8_t val = uspi->transfer(0);
return val;
}
void uDisplay::write8_slow(uint8_t val) {
for (uint8_t bit = 0x80; bit; bit >>= 1) {
GPIO_CLR_SLOW(spi_clk);

View File

@ -17,6 +17,25 @@
#endif // ESP_IDF_VERSION_MAJOR >= 5
#endif
enum {
UT_RD,UT_RDM,UT_CP,UT_RTF,UT_MV,UT_MVB,UT_RT,UT_RTT,UT_RDW,UT_RDWM,UT_WR,UT_WRW,UT_CPR,UT_AND,UT_SCALE,UT_LIM,UT_DBG,UT_GSRT,UT_XPT,UT_END
};
#define RA8876_DATA_WRITE 0x80
#define RA8876_DATA_READ 0xC0
#define RA8876_CMD_WRITE 0x00
#define RA8876_STATUS_READ 0x40
#define UDSP_WRITE_16 0xf0
#define UDSP_READ_DATA 0xf1
#define UDSP_READ_STATUS 0xf2
#define SIMPLERS_XP par_dbl[1]
#define SIMPLERS_XM par_cs
#define SIMPLERS_YP par_rs
#define SIMPLERS_YM par_dbl[0]
#ifdef USE_ESP32_S3
#include <esp_lcd_panel_io.h>
#include "esp_private/gdma.h"
@ -101,14 +120,7 @@ enum uColorType { uCOLOR_BW, uCOLOR_COLOR };
#define GPIO_SET(A) GPIO.out_w1ts = (1 << A)
#endif
enum {
UT_RD,UT_RDM,UT_CP,UT_RTF,UT_MV,UT_RT,UT_RTT,UT_RDW,UT_RDWM,UT_WR,UT_WRW,UT_CPR,UT_AND,UT_DBG,UT_GSRT,UT_END
};
#define SIMPLERS_XP par_dbl[1]
#define SIMPLERS_XM par_cs
#define SIMPLERS_YP par_rs
#define SIMPLERS_YM par_dbl[0]
#define GPIO_CLR_SLOW(A) digitalWrite(A, LOW)
@ -202,7 +214,7 @@ class uDisplay : public Renderer {
#ifdef USE_UNIVERSAL_TOUCH
// universal touch driver
bool utouch_Init(char **name);
bool touched(void);
uint16_t touched(void);
int16_t getPoint_x();
int16_t getPoint_y();
#endif // USE_UNIVERSAL_TOUCH
@ -229,6 +241,9 @@ class uDisplay : public Renderer {
void write16(uint16_t val);
void write32(uint32_t val);
void spi_data9(uint8_t d, uint8_t dc);
uint8_t readData(void);
uint8_t readStatus(void);
uint8_t writeReg16(uint8_t reg, uint16_t wval);
void WriteColor(uint16_t color);
void SetLut(const unsigned char* lut);
void SetLuts(void);
@ -432,22 +447,26 @@ class uDisplay : public Renderer {
// universal touch driver
void ut_trans(char **sp, uint8_t *ut_code, int32_t size);
int16_t ut_execute(uint8_t *ut_code);
uint16_t ut_par(char **cp, uint32_t mode);
uint32_t ut_par(char **cp, uint32_t mode);
uint8_t *ut_rd(uint8_t *io, uint32_t len, uint32_t amode);
uint8_t *ut_wr(uint8_t *io, uint32_t amode);
uint32_t ut_result;
uint16_t ut_XPT2046(uint16_t zh);
int16_t besttwoavg( int16_t x , int16_t y , int16_t z );
uint8_t ut_array[16];
uint8_t ut_i2caddr;
uint8_t ut_spi_cs;
int8_t ut_reset;
int8_t ut_irq;
uint8_t ut_spi_nr;
TwoWire *ut_wire;
SPIClass *ut_spi;
SPISettings ut_spiSettings;
char ut_name[8];
uint8_t ut_init_code[32];
uint8_t ut_touch_code[32];
uint8_t ut_getx_code[16];
uint8_t ut_gety_code[16];
uint8_t ut_getx_code[20];
uint8_t ut_gety_code[20];
#endif // USE_UNIVERSAL_TOUCH
};

View File

@ -5875,7 +5875,7 @@ extern char *SML_GetSVal(uint32_t index);
goto exit;
}
#endif // USE_TTGO_WATCH
#if defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_LILYGO47) || defined(USE_UNIVERSAL_TOUCH) || defined(USE_GT911)
#if defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_LILYGO47) || defined(USE_UNIVERSAL_TOUCH) || defined(USE_CST816S) || defined(SIMPLE_RES_TOUCH) || defined(USE_GT911)
if (!strncmp_XP(lp, XPSTR("wtch("), 5)) {
lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv);
fvar = Touch_Status(fvar);

View File

@ -254,8 +254,13 @@ void utouch_Touch_Init() {
bool utouch_touched() {
if (renderer) {
return renderer->touched();
uint16 status = renderer->touched();
if (status & 1) {
TSGlobal.gesture = status >> 8;
return true;
}
}
return false;
}
int16_t utouch_x() {
if (renderer) {