mirror of https://github.com/arendst/Tasmota.git
Udisplay support for rgb displays (#17414)
* add gt911 * add rgb display mode * add gt911 * add gt911 * add gt911 * add sunton descriptor * fix divide by zero crash with sunton
This commit is contained in:
parent
a6602249a3
commit
1cdd5c3f08
|
@ -0,0 +1,290 @@
|
|||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
#include "GT911.h"
|
||||
|
||||
#undef log_d
|
||||
#define log_d
|
||||
#undef log_e
|
||||
#define log_e
|
||||
|
||||
#ifdef ESP8266
|
||||
#define ESP_OK 0
|
||||
#define ESP_FAIL -1
|
||||
#endif
|
||||
|
||||
//#define log_d Serial.printf
|
||||
|
||||
GT911::GT911() {}
|
||||
|
||||
volatile uint8_t gt911_irq_trigger = 0;
|
||||
void ICACHE_RAM_ATTR ___GT911IRQ___()
|
||||
{
|
||||
noInterrupts();
|
||||
gt911_irq_trigger = 1;
|
||||
interrupts();
|
||||
}
|
||||
|
||||
int32_t GT911::begin(TwoWire *use_wire, int8_t pin_int, int8_t pin_res, uint16_t xs, uint16_t ys)
|
||||
{
|
||||
log_d("GT911: Initialization");
|
||||
|
||||
if (pin_int >= 0) {
|
||||
pinMode(pin_int, INPUT); // Startup sequence PIN part
|
||||
}
|
||||
if (pin_res >= 0) {
|
||||
pinMode(pin_res, OUTPUT); // Startup sequence PIN part
|
||||
digitalWrite(pin_res, 0);
|
||||
delay(1);
|
||||
digitalWrite(pin_res, 1);
|
||||
}
|
||||
delay(100);
|
||||
wire = use_wire;
|
||||
|
||||
wire->beginTransmission(0x14);
|
||||
if (wire->endTransmission())
|
||||
{
|
||||
wire->beginTransmission(0x5D);
|
||||
if (wire->endTransmission())
|
||||
{
|
||||
log_e("Touch screen IIC connection error");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
_iic_addr = 0x5D;
|
||||
}
|
||||
|
||||
if (pin_int >= 0) {
|
||||
attachInterrupt(pin_int, ___GT911IRQ___, FALLING);
|
||||
}
|
||||
|
||||
readBlockData(configBuf, GT911_CONFIG_START, GT911_CONFIG_SIZE);
|
||||
|
||||
uint16_t curx = configBuf[GT911_X_OUTPUT_MAX_LOW - GT911_CONFIG_START] | (configBuf[GT911_X_OUTPUT_MAX_HIGH - GT911_CONFIG_START] << 8);
|
||||
uint16_t cury = configBuf[GT911_Y_OUTPUT_MAX_LOW - GT911_CONFIG_START] | (configBuf[GT911_Y_OUTPUT_MAX_HIGH - GT911_CONFIG_START] << 8);
|
||||
|
||||
if (curx != xs || cury != ys) {
|
||||
setResolution(xs, ys);
|
||||
}
|
||||
|
||||
log_d("GT911: initialized");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
void GT911::write(uint16_t addr, uint8_t data)
|
||||
{
|
||||
wire->beginTransmission(_iic_addr);
|
||||
wire->write((uint8_t)(addr >> 8));
|
||||
wire->write((uint8_t)addr);
|
||||
wire->write(data);
|
||||
wire->endTransmission(true);
|
||||
}
|
||||
|
||||
void GT911::write(uint16_t addr, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
wire->beginTransmission(_iic_addr);
|
||||
wire->write((uint8_t)(addr >> 8));
|
||||
wire->write((uint8_t)addr);
|
||||
wire->write(data, len);
|
||||
wire->endTransmission(true);
|
||||
}
|
||||
|
||||
uint8_t GT911::read(uint16_t addr)
|
||||
{
|
||||
wire->flush();
|
||||
wire->beginTransmission(_iic_addr);
|
||||
wire->write((uint8_t)(addr >> 8));
|
||||
wire->write((uint8_t)addr);
|
||||
wire->endTransmission(false);
|
||||
wire->requestFrom((uint8_t)_iic_addr, (uint8_t)1);
|
||||
return wire->read();
|
||||
}
|
||||
|
||||
void GT911::read(uint16_t addr, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
wire->flush();
|
||||
wire->beginTransmission(_iic_addr);
|
||||
wire->write((uint8_t)(addr >> 8));
|
||||
wire->write((uint8_t)addr);
|
||||
wire->endTransmission(false);
|
||||
wire->requestFrom((int)_iic_addr, (int)len);
|
||||
wire->readBytes(buf, len);
|
||||
}
|
||||
|
||||
void GT911::readBlockData(uint8_t *buf, uint16_t reg, uint8_t size) {
|
||||
wire->beginTransmission(_iic_addr);
|
||||
wire->write(highByte(reg));
|
||||
wire->write(lowByte(reg));
|
||||
wire->endTransmission();
|
||||
wire->requestFrom(_iic_addr, size);
|
||||
for (uint8_t i = 0; i < size; i++) {
|
||||
buf[i] = wire->read();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GT911::calculateChecksum() {
|
||||
uint8_t checksum = 0;
|
||||
for (uint8_t i = 0; i < GT911_CONFIG_SIZE - 1 ; i++) {
|
||||
checksum += configBuf[i];
|
||||
}
|
||||
checksum = (~checksum) + 1;
|
||||
configBuf[GT911_CONFIG_CHKSUM - GT911_CONFIG_START] = checksum;
|
||||
}
|
||||
|
||||
void GT911::reflashConfig() {
|
||||
calculateChecksum();
|
||||
write(GT911_X_OUTPUT_MAX_LOW, configBuf[GT911_X_OUTPUT_MAX_LOW - GT911_CONFIG_START]);
|
||||
write(GT911_X_OUTPUT_MAX_HIGH, configBuf[GT911_X_OUTPUT_MAX_HIGH - GT911_CONFIG_START]);
|
||||
write(GT911_Y_OUTPUT_MAX_LOW, configBuf[GT911_Y_OUTPUT_MAX_LOW - GT911_CONFIG_START]);
|
||||
write(GT911_Y_OUTPUT_MAX_HIGH, configBuf[GT911_Y_OUTPUT_MAX_HIGH - GT911_CONFIG_START]);
|
||||
write(GT911_CONFIG_CHKSUM, configBuf[GT911_CONFIG_CHKSUM - GT911_CONFIG_START]);
|
||||
write(GT911_CONFIG_FRESH, 1);
|
||||
}
|
||||
|
||||
void GT911::setResolution(uint16_t _width, uint16_t _height) {
|
||||
configBuf[GT911_X_OUTPUT_MAX_LOW - GT911_CONFIG_START] = lowByte(_width);
|
||||
configBuf[GT911_X_OUTPUT_MAX_HIGH - GT911_CONFIG_START] = highByte(_width);
|
||||
configBuf[GT911_Y_OUTPUT_MAX_LOW - GT911_CONFIG_START] = lowByte(_height);
|
||||
configBuf[GT911_Y_OUTPUT_MAX_HIGH - GT911_CONFIG_START] = highByte(_height);
|
||||
reflashConfig();
|
||||
}
|
||||
|
||||
bool GT911::avaliable()
|
||||
{
|
||||
if(gt911_irq_trigger == 1)
|
||||
{
|
||||
gt911_irq_trigger = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GT911::flush(void)
|
||||
{
|
||||
write(0x814E, 0x00);
|
||||
gt911_irq_trigger = 0;
|
||||
_num = 0;
|
||||
_is_finger_up = 0;
|
||||
}
|
||||
|
||||
void GT911::update()
|
||||
{
|
||||
uint8_t r814e = read(0x814E);
|
||||
uint8_t num = r814e & 0x0F;
|
||||
if(r814e & 0x80)
|
||||
{
|
||||
if(num != 0)
|
||||
{
|
||||
_is_finger_up = false;
|
||||
_num = num;
|
||||
uint8_t data[num * 8];
|
||||
read(0x8150, data, num * 8);
|
||||
for(int j = 0; j < num; j++)
|
||||
{
|
||||
uint8_t *buf = data + j * 8;
|
||||
|
||||
if(_rotate == ROTATE_0)
|
||||
{
|
||||
_fingers[j].x = (buf[3] << 8) | buf[2];
|
||||
_fingers[j].y = 540 - ((buf[1] << 8) | buf[0]);
|
||||
}
|
||||
else if(_rotate == ROTATE_180)
|
||||
{
|
||||
_fingers[j].x = 960 - ((buf[3] << 8) | buf[2]);
|
||||
_fingers[j].y = (buf[1] << 8) | buf[0];
|
||||
}
|
||||
else if(_rotate == ROTATE_270)
|
||||
{
|
||||
_fingers[j].x = 540 - ((buf[1] << 8) | buf[0]);
|
||||
_fingers[j].y = 960 - ((buf[3] << 8) | buf[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fingers[j].x = (buf[1] << 8) | buf[0];
|
||||
_fingers[j].y = (buf[3] << 8) | buf[2];
|
||||
}
|
||||
|
||||
_fingers[j].size = (buf[5] << 8) | buf[4];
|
||||
_fingers[j].id = buf[7];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_is_finger_up = true;
|
||||
}
|
||||
write(0x814E, 0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
_is_finger_up = 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool GT911::isFingerUp(void)
|
||||
{
|
||||
if(_is_finger_up == 1)
|
||||
{
|
||||
_is_finger_up = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GT911::SetRotation(uint16_t rotate)
|
||||
{
|
||||
if(rotate < 4)
|
||||
{
|
||||
this->_rotate = rotate;
|
||||
}
|
||||
else if(rotate < 90)
|
||||
{
|
||||
this->_rotate = ROTATE_0;
|
||||
}
|
||||
else if(rotate < 180)
|
||||
{
|
||||
this->_rotate = ROTATE_90;
|
||||
}
|
||||
else if(rotate < 270)
|
||||
{
|
||||
this->_rotate = ROTATE_180;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_rotate = ROTATE_270;
|
||||
}
|
||||
}
|
||||
|
||||
tp_finger_t GT911::readFinger(uint8_t num)
|
||||
{
|
||||
if(num > 2)
|
||||
{
|
||||
num = 1;
|
||||
}
|
||||
return this->_fingers[num];
|
||||
}
|
||||
|
||||
uint16_t GT911::readFingerID(uint8_t num)
|
||||
{
|
||||
return this->_fingers[num].id;
|
||||
}
|
||||
|
||||
uint16_t GT911::readFingerSize(uint8_t num)
|
||||
{
|
||||
return this->_fingers[num].size;
|
||||
}
|
||||
|
||||
uint16_t GT911::readFingerX(uint8_t num)
|
||||
{
|
||||
return this->_fingers[num].x;
|
||||
}
|
||||
|
||||
uint16_t GT911::readFingerY(uint8_t num)
|
||||
{
|
||||
return this->_fingers[num].y;
|
||||
}
|
||||
|
||||
uint8_t GT911::getFingerNum(void)
|
||||
{
|
||||
return _num;
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
#ifndef GT911_H
|
||||
#define GT911_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Wire.h>
|
||||
|
||||
|
||||
// Real-time command (Write only)
|
||||
#define GT911_COMMAND (uint16_t)0x8040
|
||||
#define GT911_ESD_CHECK (uint16_t)0x8041
|
||||
#define GT911_COMMAND_CHECK (uint16_t)0x8046
|
||||
|
||||
// Configuration information (R/W)
|
||||
#define GT911_CONFIG_START (uint16_t)0x8047
|
||||
#define GT911_CONFIG_VERSION (uint16_t)0x8047
|
||||
#define GT911_X_OUTPUT_MAX_LOW (uint16_t)0x8048
|
||||
#define GT911_X_OUTPUT_MAX_HIGH (uint16_t)0x8049
|
||||
#define GT911_Y_OUTPUT_MAX_LOW (uint16_t)0x804A
|
||||
#define GT911_Y_OUTPUT_MAX_HIGH (uint16_t)0x804B
|
||||
#define GT911_TOUCH_NUMBER (uint16_t)0x804C
|
||||
#define GT911_MODULE_SWITCH_1 (uint16_t)0x804D
|
||||
#define GT911_MODULE_SWITCH_2 (uint16_t)0x804E
|
||||
#define GT911_SHAKE_COUNT (uint16_t)0x804F
|
||||
#define GT911_FILTER (uint16_t)0x8050
|
||||
#define GT911_LARGE_TOUCH (uint16_t)0x8051
|
||||
#define GT911_NOISE_REDUCTION (uint16_t)0x8052
|
||||
#define GT911_SCREEN_TOUCH_LEVEL (uint16_t)0x8053
|
||||
#define GT911_SCREEN_RELEASE_LEVEL (uint16_t)0x8054
|
||||
#define GT911_LOW_POWER_CONTROL (uint16_t)0x8055
|
||||
#define GT911_REFRESH_RATE (uint16_t)0x8056
|
||||
#define GT911_X_THRESHOLD (uint16_t)0x8057
|
||||
#define GT911_Y_THRESHOLD (uint16_t)0x8058
|
||||
#define GT911_X_SPEED_LIMIT (uint16_t)0x8059 //Reserve
|
||||
#define GT911_Y_SPEED_LIMIT (uint16_t)0x805A //Reserve
|
||||
#define GT911_SPACE_TOP_BOTTOM (uint16_t)0x805B
|
||||
#define GT911_SPACE_LEFT_RIGHT (uint16_t)0x805C
|
||||
#define GT911_MINI_FILTER (uint16_t)0x805D
|
||||
#define GT911_STRETCH_R0 (uint16_t)0x805E
|
||||
#define GT911_STRETCH_R1 (uint16_t)0x805F
|
||||
#define GT911_STRETCH_R2 (uint16_t)0x8060
|
||||
#define GT911_STRETCH_RM (uint16_t)0x8061
|
||||
#define GT911_DRV_GROUPA_NUM (uint16_t)0x8062
|
||||
#define GT911_DRV_GROUPB_NUM (uint16_t)0x8063
|
||||
#define GT911_SENSOR_NUM (uint16_t)0x8064
|
||||
#define GT911_FREQ_A_FACTOR (uint16_t)0x8065
|
||||
#define GT911_FREQ_B_FACTOR (uint16_t)0x8066
|
||||
#define GT911_PANEL_BIT_FREQ_L (uint16_t)0x8067
|
||||
#define GT911_PANEL_BIT_FREQ_H (uint16_t)0x8068
|
||||
#define GT911_PANEL_SENSOR_TIME_L (uint16_t)0x8069 //Reserve
|
||||
#define GT911_PANEL_SENSOR_TIME_H (uint16_t)0x806A
|
||||
#define GT911_PANEL_TX_GAIN (uint16_t)0x806B
|
||||
#define GT911_PANEL_RX_GAIN (uint16_t)0x806C
|
||||
#define GT911_PANEL_DUMP_SHIFT (uint16_t)0x806D
|
||||
#define GT911_DRV_FRAME_CONTROL (uint16_t)0x806E
|
||||
#define GT911_CHARGING_LEVEL_UP (uint16_t)0x806F
|
||||
#define GT911_MODULE_SWITCH3 (uint16_t)0x8070
|
||||
#define GT911_GESTURE_DIS (uint16_t)0X8071
|
||||
#define GT911_GESTURE_LONG_PRESS_TIME (uint16_t)0x8072
|
||||
#define GT911_X_Y_SLOPE_ADJUST (uint16_t)0X8073
|
||||
#define GT911_GESTURE_CONTROL (uint16_t)0X8074
|
||||
#define GT911_GESTURE_SWITCH1 (uint16_t)0X8075
|
||||
#define GT911_GESTURE_SWITCH2 (uint16_t)0X8076
|
||||
#define GT911_GESTURE_REFRESH_RATE (uint16_t)0x8077
|
||||
#define GT911_GESTURE_TOUCH_LEVEL (uint16_t)0x8078
|
||||
#define GT911_NEWGREENWAKEUPLEVEL (uint16_t)0x8079
|
||||
#define GT911_FREQ_HOPPING_START (uint16_t)0x807A
|
||||
#define GT911_FREQ_HOPPING_END (uint16_t)0X807B
|
||||
#define GT911_NOISE_DETECT_TIMES (uint16_t)0x807C
|
||||
#define GT911_HOPPING_FLAG (uint16_t)0X807D
|
||||
#define GT911_HOPPING_THRESHOLD (uint16_t)0X807E
|
||||
#define GT911_NOISE_THRESHOLD (uint16_t)0X807F //Reserve
|
||||
#define GT911_NOISE_MIN_THRESHOLD (uint16_t)0X8080
|
||||
#define GT911_HOPPING_SENSOR_GROUP (uint16_t)0X8082
|
||||
#define GT911_HOPPING_SEG1_NORMALIZE (uint16_t)0X8083
|
||||
#define GT911_HOPPING_SEG1_FACTOR (uint16_t)0X8084
|
||||
#define GT911_MAIN_CLOCK_AJDUST (uint16_t)0X8085
|
||||
#define GT911_HOPPING_SEG2_NORMALIZE (uint16_t)0X8086
|
||||
#define GT911_HOPPING_SEG2_FACTOR (uint16_t)0X8087
|
||||
#define GT911_HOPPING_SEG3_NORMALIZE (uint16_t)0X8089
|
||||
#define GT911_HOPPING_SEG3_FACTOR (uint16_t)0X808A
|
||||
#define GT911_HOPPING_SEG4_NORMALIZE (uint16_t)0X808C
|
||||
#define GT911_HOPPING_SEG4_FACTOR (uint16_t)0X808D
|
||||
#define GT911_HOPPING_SEG5_NORMALIZE (uint16_t)0X808F
|
||||
#define GT911_HOPPING_SEG5_FACTOR (uint16_t)0X8090
|
||||
#define GT911_HOPPING_SEG6_NORMALIZE (uint16_t)0X8092
|
||||
#define GT911_KEY_1 (uint16_t)0X8093
|
||||
#define GT911_KEY_2 (uint16_t)0X8094
|
||||
#define GT911_KEY_3 (uint16_t)0X8095
|
||||
#define GT911_KEY_4 (uint16_t)0X8096
|
||||
#define GT911_KEY_AREA (uint16_t)0X8097
|
||||
#define GT911_KEY_TOUCH_LEVEL (uint16_t)0X8098
|
||||
#define GT911_KEY_LEAVE_LEVEL (uint16_t)0X8099
|
||||
#define GT911_KEY_SENS_1_2 (uint16_t)0X809A
|
||||
#define GT911_KEY_SENS_3_4 (uint16_t)0X809B
|
||||
#define GT911_KEY_RESTRAIN (uint16_t)0X809C
|
||||
#define GT911_KEY_RESTRAIN_TIME (uint16_t)0X809D
|
||||
#define GT911_GESTURE_LARGE_TOUCH (uint16_t)0X809E
|
||||
#define GT911_HOTKNOT_NOISE_MAP (uint16_t)0X80A1
|
||||
#define GT911_LINK_THRESHOLD (uint16_t)0X80A2
|
||||
#define GT911_PXY_THRESHOLD (uint16_t)0X80A3
|
||||
#define GT911_GHOT_DUMP_SHIFT (uint16_t)0X80A4
|
||||
#define GT911_GHOT_RX_GAIN (uint16_t)0X80A5
|
||||
#define GT911_FREQ_GAIN0 (uint16_t)0X80A6
|
||||
#define GT911_FREQ_GAIN1 (uint16_t)0X80A7
|
||||
#define GT911_FREQ_GAIN2 (uint16_t)0X80A8
|
||||
#define GT911_FREQ_GAIN3 (uint16_t)0X80A9
|
||||
#define GT911_COMBINE_DIS (uint16_t)0X80B3
|
||||
#define GT911_SPLIT_SET (uint16_t)0X80B4
|
||||
#define GT911_SENSOR_CH0 (uint16_t)0X80B7
|
||||
#define GT911_DRIVER_CH0 (uint16_t)0X80D5
|
||||
#define GT911_CONFIG_CHKSUM (uint16_t)0X80FF
|
||||
#define GT911_CONFIG_FRESH (uint16_t)0X8100
|
||||
#define GT911_CONFIG_SIZE (uint16_t)0xFF-0x46
|
||||
// Coordinate information
|
||||
#define GT911_PRODUCT_ID (uint16_t)0X8140
|
||||
#define GT911_FIRMWARE_VERSION (uint16_t)0X8140
|
||||
#define GT911_RESOLUTION (uint16_t)0X8140
|
||||
#define GT911_VENDOR_ID (uint16_t)0X8140
|
||||
#define GT911_IMFORMATION (uint16_t)0X8140
|
||||
#define GT911_POINT_INFO (uint16_t)0X814E
|
||||
#define GT911_POINT_1 (uint16_t)0X814F
|
||||
#define GT911_POINT_2 (uint16_t)0X8157
|
||||
#define GT911_POINT_3 (uint16_t)0X815F
|
||||
#define GT911_POINT_4 (uint16_t)0X8167
|
||||
#define GT911_POINT_5 (uint16_t)0X816F
|
||||
#define GT911_POINTS_REG {GT911_POINT_1, GT911_POINT_2, GT911_POINT_3, GT911_POINT_4, GT911_POINT_5}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t id;
|
||||
uint16_t size;
|
||||
}tp_finger_t;
|
||||
|
||||
class GT911
|
||||
{
|
||||
public:
|
||||
static const uint8_t ROTATE_0 = 0;
|
||||
static const uint8_t ROTATE_90 = 1;
|
||||
static const uint8_t ROTATE_180 = 2;
|
||||
static const uint8_t ROTATE_270 = 3;
|
||||
|
||||
public:
|
||||
GT911();
|
||||
int32_t begin(TwoWire *use_wire, int8_t pin_int, int8_t pin_res, uint16_t xs, uint16_t ys);
|
||||
bool avaliable();
|
||||
void update();
|
||||
void SetRotation(uint16_t rotate);
|
||||
tp_finger_t readFinger(uint8_t num);
|
||||
uint16_t readFingerX(uint8_t num);
|
||||
uint16_t readFingerY(uint8_t num);
|
||||
uint16_t readFingerID(uint8_t num);
|
||||
uint16_t readFingerSize(uint8_t num);
|
||||
uint8_t getFingerNum(void);
|
||||
bool isFingerUp(void);
|
||||
void flush(void);
|
||||
|
||||
private:
|
||||
void write(uint16_t addr, uint8_t data);
|
||||
void write(uint16_t addr, const uint8_t *data, uint16_t len);
|
||||
uint8_t read(uint16_t addr);
|
||||
void read(uint16_t addr, uint8_t *buf, uint16_t len);
|
||||
uint8_t calcChecksum(const uint8_t *buf, uint8_t len);
|
||||
void reflashConfig();
|
||||
void calculateChecksum();
|
||||
void setResolution(uint16_t _width, uint16_t _height);
|
||||
void readBlockData(uint8_t *buf, uint16_t reg, uint8_t size);
|
||||
|
||||
bool _is_finger_up = false;
|
||||
uint8_t _num = 0;
|
||||
uint8_t _rotate = ROTATE_90;
|
||||
tp_finger_t _fingers[2];
|
||||
uint8_t _iic_addr = 0x14;
|
||||
TwoWire *wire;
|
||||
uint8_t configBuf[GT911_CONFIG_SIZE];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,8 +24,14 @@
|
|||
#include "esp8266toEsp32.h"
|
||||
#endif
|
||||
|
||||
|
||||
extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size);
|
||||
|
||||
|
||||
//#define UDSP_DEBUG
|
||||
|
||||
#define renderer_swap(a, b) { int16_t t = a; a = b; b = t; }
|
||||
|
||||
const uint16_t udisp_colors[]={UDISP_BLACK,UDISP_WHITE,UDISP_RED,UDISP_GREEN,UDISP_BLUE,UDISP_CYAN,UDISP_MAGENTA,\
|
||||
UDISP_YELLOW,UDISP_NAVY,UDISP_DARKGREEN,UDISP_DARKCYAN,UDISP_MAROON,UDISP_PURPLE,UDISP_OLIVE,\
|
||||
UDISP_LIGHTGREY,UDISP_DARKGREY,UDISP_ORANGE,UDISP_GREENYELLOW,UDISP_PINK};
|
||||
|
@ -93,6 +99,10 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
lut_num = 0;
|
||||
lvgl_param.data = 0;
|
||||
lvgl_param.fluslines = 40;
|
||||
rot_t[0] = 0;
|
||||
rot_t[1] = 1;
|
||||
rot_t[2] = 2;
|
||||
rot_t[3] = 3;
|
||||
|
||||
for (uint32_t cnt = 0; cnt < 5; cnt++) {
|
||||
lut_cnt[cnt] = 0;
|
||||
|
@ -199,6 +209,26 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
}
|
||||
}
|
||||
spi_speed = next_val(&lp1);
|
||||
#endif // USE_ESP32_S3
|
||||
section = 0;
|
||||
} else if (!strncmp(ibuff, "RGB", 3)) {
|
||||
#ifdef USE_ESP32_S3
|
||||
interface = _UDSP_RGB;
|
||||
|
||||
de = next_val(&lp1);
|
||||
vsync = next_val(&lp1);
|
||||
hsync = next_val(&lp1);
|
||||
pclk = next_val(&lp1);
|
||||
bpanel = next_val(&lp1);
|
||||
|
||||
for (uint32_t cnt = 0; cnt < 8; cnt ++) {
|
||||
par_dbl[cnt] = next_val(&lp1);
|
||||
}
|
||||
|
||||
for (uint32_t cnt = 0; cnt < 8; cnt ++) {
|
||||
par_dbh[cnt] = next_val(&lp1);
|
||||
}
|
||||
spi_speed = next_val(&lp1);
|
||||
#endif // USE_ESP32_S3
|
||||
section = 0;
|
||||
}
|
||||
|
@ -236,9 +266,23 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
#ifdef USE_ESP32_S3
|
||||
case 'V':
|
||||
hsync_polarity = next_val(&lp1);
|
||||
hsync_front_porch = next_val(&lp1);
|
||||
hsync_pulse_width = next_val(&lp1);
|
||||
hsync_back_porch = next_val(&lp1);
|
||||
vsync_polarity = next_val(&lp1);
|
||||
vsync_front_porch = next_val(&lp1);
|
||||
vsync_pulse_width = next_val(&lp1);
|
||||
vsync_back_porch = next_val(&lp1);
|
||||
pclk_active_neg = next_val(&lp1);
|
||||
break;
|
||||
#endif // USE_ESP32_S3
|
||||
case 'o':
|
||||
dsp_off = next_hex(&lp1);
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
dsp_on = next_hex(&lp1);
|
||||
break;
|
||||
|
@ -247,27 +291,35 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
startline = next_hex(&lp1);
|
||||
break;
|
||||
case '0':
|
||||
rot[0] = next_hex(&lp1);
|
||||
x_addr_offs[0] = next_hex(&lp1);
|
||||
y_addr_offs[0] = next_hex(&lp1);
|
||||
if (interface != _UDSP_RGB) {
|
||||
rot[0] = next_hex(&lp1);
|
||||
x_addr_offs[0] = next_hex(&lp1);
|
||||
y_addr_offs[0] = next_hex(&lp1);
|
||||
}
|
||||
rot_t[0] = next_hex(&lp1);
|
||||
break;
|
||||
case '1':
|
||||
rot[1] = next_hex(&lp1);
|
||||
x_addr_offs[1] = next_hex(&lp1);
|
||||
y_addr_offs[1] = next_hex(&lp1);
|
||||
if (interface != _UDSP_RGB) {
|
||||
rot[1] = next_hex(&lp1);
|
||||
x_addr_offs[1] = next_hex(&lp1);
|
||||
y_addr_offs[1] = next_hex(&lp1);
|
||||
}
|
||||
rot_t[1] = next_hex(&lp1);
|
||||
break;
|
||||
case '2':
|
||||
rot[2] = next_hex(&lp1);
|
||||
x_addr_offs[2] = next_hex(&lp1);
|
||||
y_addr_offs[2] = next_hex(&lp1);
|
||||
if (interface != _UDSP_RGB) {
|
||||
rot[2] = next_hex(&lp1);
|
||||
x_addr_offs[2] = next_hex(&lp1);
|
||||
y_addr_offs[2] = next_hex(&lp1);
|
||||
}
|
||||
rot_t[2] = next_hex(&lp1);
|
||||
break;
|
||||
case '3':
|
||||
rot[3] = next_hex(&lp1);
|
||||
x_addr_offs[3] = next_hex(&lp1);
|
||||
y_addr_offs[3] = next_hex(&lp1);
|
||||
if (interface != _UDSP_RGB) {
|
||||
rot[3] = next_hex(&lp1);
|
||||
x_addr_offs[3] = next_hex(&lp1);
|
||||
y_addr_offs[3] = next_hex(&lp1);
|
||||
}
|
||||
rot_t[3] = next_hex(&lp1);
|
||||
break;
|
||||
case 'A':
|
||||
|
@ -449,9 +501,39 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
#endif // USE_ESP32_S3
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (interface == _UDSP_RGB) {
|
||||
#ifdef USE_ESP32_S3
|
||||
|
||||
Serial.printf("rgb de: %d\n", de);
|
||||
Serial.printf("rgb vsync: %d\n", vsync);
|
||||
Serial.printf("rgb hsync : %d\n", hsync);
|
||||
Serial.printf("rgb pclk : %d\n", pclk);
|
||||
Serial.printf("rgb bp : %d\n", bpanel);
|
||||
|
||||
for (uint32_t cnt = 0; cnt < 8; cnt ++) {
|
||||
Serial.printf("rgb d%d: %d\n", cnt, par_dbl[cnt]);
|
||||
}
|
||||
for (uint32_t cnt = 0; cnt < 8; cnt ++) {
|
||||
Serial.printf("rgb d%d: %d\n", cnt + 8, par_dbh[cnt]);
|
||||
}
|
||||
|
||||
Serial.printf("rgb freq : %d\n", spi_speed);
|
||||
|
||||
Serial.printf("rgb hsync_polarity: %d\n", hsync_polarity);
|
||||
Serial.printf("rgb hsync_front_porch: %d\n", hsync_front_porch);
|
||||
Serial.printf("rgb hsync_pulse_width : %d\n", hsync_pulse_width);
|
||||
Serial.printf("rgb hsync_back_porch : %d\n", hsync_back_porch);
|
||||
Serial.printf("rgb vsync_polarity : %d\n", vsync_polarity);
|
||||
Serial.printf("rgb vsync_front_porch : %d\n", vsync_front_porch);
|
||||
Serial.printf("rgb vsync_pulse_width : %d\n", vsync_pulse_width);
|
||||
Serial.printf("rgb vsync_back_porch : %d\n", vsync_back_porch);
|
||||
Serial.printf("rgb pclk_active_neg : %d\n", pclk_active_neg);
|
||||
|
||||
#endif // USE_ESP32_S3
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Renderer *uDisplay::Init(void) {
|
||||
extern bool UsePSRAM(void);
|
||||
|
@ -553,7 +635,6 @@ Renderer *uDisplay::Init(void) {
|
|||
spiSettings = SPISettings((uint32_t)spi_speed*1000000, MSBFIRST, SPI_MODE3);
|
||||
SPI_BEGIN_TRANSACTION
|
||||
|
||||
|
||||
if (reset >= 0) {
|
||||
pinMode(reset, OUTPUT);
|
||||
digitalWrite(reset, HIGH);
|
||||
|
@ -612,6 +693,69 @@ Renderer *uDisplay::Init(void) {
|
|||
|
||||
}
|
||||
|
||||
if (interface == _UDSP_RGB) {
|
||||
#ifdef USE_ESP32_S3
|
||||
|
||||
if (bpanel >= 0) {
|
||||
analogWrite(bpanel, 32);
|
||||
}
|
||||
esp_lcd_rgb_panel_config_t *_panel_config = (esp_lcd_rgb_panel_config_t *)heap_caps_calloc(1, sizeof(esp_lcd_rgb_panel_config_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
|
||||
_panel_config->clk_src = LCD_CLK_SRC_PLL160M;
|
||||
|
||||
if (spi_speed > 14) {
|
||||
spi_speed = 14;
|
||||
}
|
||||
_panel_config->timings.pclk_hz = spi_speed*1000000;
|
||||
_panel_config->timings.h_res = gxs;
|
||||
_panel_config->timings.v_res = gys;
|
||||
|
||||
_panel_config->timings.hsync_pulse_width = hsync_pulse_width;
|
||||
_panel_config->timings.hsync_back_porch = hsync_back_porch;
|
||||
_panel_config->timings.hsync_front_porch = hsync_front_porch;
|
||||
_panel_config->timings.vsync_pulse_width = vsync_pulse_width;
|
||||
_panel_config->timings.vsync_back_porch = vsync_back_porch;
|
||||
_panel_config->timings.vsync_front_porch = vsync_front_porch;
|
||||
_panel_config->timings.flags.hsync_idle_low = (hsync_polarity == 0) ? 1 : 0;
|
||||
_panel_config->timings.flags.vsync_idle_low = (vsync_polarity == 0) ? 1 : 0;
|
||||
_panel_config->timings.flags.de_idle_high = 0;
|
||||
_panel_config->timings.flags.pclk_active_neg = pclk_active_neg;
|
||||
_panel_config->timings.flags.pclk_idle_high = 0;
|
||||
|
||||
_panel_config->data_width = 16; // RGB565 in parallel mode, thus 16bit in width
|
||||
_panel_config->sram_trans_align = 8;
|
||||
_panel_config->psram_trans_align = 64;
|
||||
_panel_config->hsync_gpio_num = hsync;
|
||||
_panel_config->vsync_gpio_num = vsync;
|
||||
_panel_config->de_gpio_num = de;
|
||||
_panel_config->pclk_gpio_num = pclk;
|
||||
|
||||
for (uint32_t cnt = 0; cnt < 8; cnt ++) {
|
||||
_panel_config->data_gpio_nums[cnt] = par_dbh[cnt];
|
||||
}
|
||||
for (uint32_t cnt = 0; cnt < 8; cnt ++) {
|
||||
_panel_config->data_gpio_nums[cnt + 8] = par_dbl[cnt];
|
||||
}
|
||||
_panel_config->disp_gpio_num = GPIO_NUM_NC;
|
||||
|
||||
_panel_config->flags.disp_active_low = 0;
|
||||
_panel_config->flags.relax_on_idle = 0;
|
||||
_panel_config->flags.fb_in_psram = 1; // allocate frame buffer in PSRAM
|
||||
|
||||
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(_panel_config, &_panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_reset(_panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_init(_panel_handle));
|
||||
|
||||
uint16_t color = random(0xffff);
|
||||
ESP_ERROR_CHECK(_panel_handle->draw_bitmap(_panel_handle, 0, 0, 1, 1, &color));
|
||||
|
||||
_rgb_panel = __containerof(_panel_handle, esp_rgb_panel_t, base);
|
||||
|
||||
rgb_fb = (uint16_t *)_rgb_panel->fb;
|
||||
|
||||
#endif // USE_ESP32_S3
|
||||
}
|
||||
|
||||
if (interface == _UDSP_PAR8 || interface == _UDSP_PAR16) {
|
||||
|
||||
#ifdef USE_ESP32_S3
|
||||
|
@ -760,10 +904,14 @@ Renderer *uDisplay::Init(void) {
|
|||
if (ep_mode == 1) Init_EPD(DISPLAY_INIT_PARTIAL);
|
||||
}
|
||||
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("Dsp Init 1 complete \n");
|
||||
#endif
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void uDisplay::DisplayInit(int8_t p, int8_t size, int8_t rot, int8_t font) {
|
||||
if (p != DISPLAY_INIT_MODE && ep_mode) {
|
||||
if (p == DISPLAY_INIT_PARTIAL) {
|
||||
|
@ -800,7 +948,7 @@ void uDisplay::DisplayInit(int8_t p, int8_t size, int8_t rot, int8_t font) {
|
|||
}
|
||||
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("Dsp Init complete \n");
|
||||
Serial.printf("Dsp Init 2 complete \n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -960,6 +1108,10 @@ void uDisplay::i2c_command(uint8_t val) {
|
|||
|
||||
void uDisplay::Updateframe(void) {
|
||||
|
||||
if (interface == _UDSP_RGB) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ep_mode) {
|
||||
Updateframe_EPD();
|
||||
return;
|
||||
|
@ -1070,6 +1222,7 @@ void uDisplay::Updateframe(void) {
|
|||
|
||||
void uDisplay::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
|
||||
|
||||
|
||||
if (ep_mode) {
|
||||
drawFastVLine_EPD(x, y, h, color);
|
||||
return;
|
||||
|
@ -1084,6 +1237,29 @@ void uDisplay::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
|
|||
if ((x >= _width) || (y >= _height)) return;
|
||||
if ((y + h - 1) >= _height) h = _height - y;
|
||||
|
||||
|
||||
if (interface == _UDSP_RGB) {
|
||||
#ifdef USE_ESP32_S3
|
||||
if (cur_rot > 0) {
|
||||
while (h--) {
|
||||
drawPixel_RGB(x , y , color);
|
||||
y++;
|
||||
}
|
||||
} else {
|
||||
uint16_t *fb = rgb_fb;
|
||||
fb += (int32_t)y * _width;
|
||||
fb += x;
|
||||
while (h--) {
|
||||
*fb = color;
|
||||
Cache_WriteBack_Addr((uint32_t)fb, 2);
|
||||
fb+=_width;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
SPI_BEGIN_TRANSACTION
|
||||
|
||||
SPI_CS_LOW
|
||||
|
@ -1129,7 +1305,30 @@ void uDisplay::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
|
|||
|
||||
// Rudimentary clipping
|
||||
if((x >= _width) || (y >= _height)) return;
|
||||
if((x+w-1) >= _width) w = _width-x;
|
||||
if((x + w - 1) >= _width) w = _width - x;
|
||||
|
||||
|
||||
if (interface == _UDSP_RGB) {
|
||||
#ifdef USE_ESP32_S3
|
||||
if (cur_rot > 0) {
|
||||
while (w--) {
|
||||
drawPixel_RGB(x , y , color);
|
||||
x++;
|
||||
}
|
||||
} else {
|
||||
uint16_t *fb = rgb_fb;
|
||||
fb += (int32_t)y * _width;
|
||||
fb += x;
|
||||
while (w--) {
|
||||
*fb = color;
|
||||
Cache_WriteBack_Addr((uint32_t)fb, 2);
|
||||
fb++;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SPI_BEGIN_TRANSACTION
|
||||
|
@ -1174,6 +1373,13 @@ void uDisplay::fillScreen(uint16_t color) {
|
|||
// fill a rectangle
|
||||
void uDisplay::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
|
||||
|
||||
if (interface == _UDSP_RGB) {
|
||||
for (uint32_t yp = y; yp < y + h; yp++) {
|
||||
drawFastHLine(x, yp, w, color);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ep_mode) {
|
||||
fillRect_EPD(x, y, w, h, color);
|
||||
|
@ -1266,7 +1472,7 @@ void uDisplay::Splash(void) {
|
|||
|
||||
void uDisplay::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
|
||||
if (bpp != 16) {
|
||||
if (bpp != 16 || interface == _UDSP_RGB) {
|
||||
// just save params or update frame
|
||||
if (!x0 && !y0 && !x1 && !y1) {
|
||||
if (!ep_mode) {
|
||||
|
@ -1282,6 +1488,10 @@ void uDisplay::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
|
|||
return;
|
||||
}
|
||||
|
||||
if (interface == _UDSP_RGB) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!x0 && !y0 && !x1 && !y1) {
|
||||
SPI_CS_HIGH
|
||||
SPI_END_TRANSACTION
|
||||
|
@ -1295,6 +1505,11 @@ void uDisplay::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
|
|||
#define udisp_swap(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
|
||||
|
||||
void uDisplay::setAddrWindow_int(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
|
||||
if (interface == _UDSP_RGB) {
|
||||
return;
|
||||
}
|
||||
|
||||
x += x_addr_offs[cur_rot];
|
||||
y += y_addr_offs[cur_rot];
|
||||
|
||||
|
@ -1388,9 +1603,43 @@ void uDisplay::pushColors(uint16_t *data, uint16_t len, boolean not_swapped) {
|
|||
not_swapped = !not_swapped;
|
||||
}
|
||||
|
||||
//Serial.printf("push %x - %d - %d - %d\n", (uint32_t)data, len, not_swapped,lvgl_param.data);
|
||||
//Serial.printf("push %x - %d - %d - %d\n", (uint32_t)data, len, not_swapped, lvgl_param.data);
|
||||
if (not_swapped == false) {
|
||||
// called from LVGL bytes are swapped
|
||||
if (interface == _UDSP_RGB) {
|
||||
#ifdef USE_ESP32_S3
|
||||
if (cur_rot > 0) {
|
||||
for (uint32_t y = seta_yp1; y < seta_yp2; y++) {
|
||||
seta_yp1++;
|
||||
for (uint32_t x = seta_xp1; x < seta_xp2; x++) {
|
||||
uint16_t color = *data++;
|
||||
color = color << 8 | color >> 8;
|
||||
drawPixel_RGB(x, y, color);
|
||||
len--;
|
||||
if (!len) return; // failsafe - exist if len (pixel number) is exhausted
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (uint32_t y = seta_yp1; y < seta_yp2; y++) {
|
||||
seta_yp1++;
|
||||
uint16_t *fb = rgb_fb;
|
||||
fb += (int32_t)y * _width;
|
||||
fb += seta_xp1;
|
||||
for (uint32_t x = seta_xp1; x < seta_xp2; x++) {
|
||||
uint16_t color = *data++;
|
||||
color = color << 8 | color >> 8;
|
||||
*fb = color;
|
||||
Cache_WriteBack_Addr((uint32_t)fb, 2);
|
||||
fb++;
|
||||
len--;
|
||||
if (!len) return; // failsafe - exist if len (pixel number) is exhausted
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (bpp != 16) {
|
||||
// lvgl_color_swap(data, len); -- no need to swap anymore, we have inverted the mask
|
||||
pushColorsMono(data, len, true);
|
||||
|
@ -1464,6 +1713,36 @@ void uDisplay::pushColors(uint16_t *data, uint16_t len, boolean not_swapped) {
|
|||
}
|
||||
} else {
|
||||
// called from displaytext, no byte swap, currently no dma here
|
||||
if (interface == _UDSP_RGB) {
|
||||
#ifdef USE_ESP32_S3
|
||||
if (cur_rot > 0) {
|
||||
for (uint32_t y = seta_yp1; y < seta_yp2; y++) {
|
||||
seta_yp1++;
|
||||
for (uint32_t x = seta_xp1; x < seta_xp2; x++) {
|
||||
drawPixel_RGB(x, y, *data++);
|
||||
len--;
|
||||
if (!len) return; // failsafe - exist if len (pixel number) is exhausted
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (uint32_t y = seta_yp1; y < seta_yp2; y++) {
|
||||
seta_yp1++;
|
||||
uint16_t *fb = rgb_fb;
|
||||
fb += (int32_t)y * _width;
|
||||
fb += seta_xp1;
|
||||
for (uint32_t x = seta_xp1; x < seta_xp2; x++) {
|
||||
*fb = *data++;
|
||||
Cache_WriteBack_Addr((uint32_t)fb, 2);
|
||||
fb++;
|
||||
len--;
|
||||
if (!len) return; // failsafe - exist if len (pixel number) is exhausted
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (bpp != 16) {
|
||||
pushColorsMono(data, len);
|
||||
return;
|
||||
|
@ -1512,8 +1791,49 @@ void uDisplay::WriteColor(uint16_t color) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ESP32_S3
|
||||
void uDisplay::drawPixel_RGB(int16_t x, int16_t y, uint16_t color) {
|
||||
int16_t w = _width, h = _height;
|
||||
|
||||
if ((x < 0) || (x >= w) || (y < 0) || (y >= h)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check rotation, move pixel around if necessary
|
||||
switch (cur_rot) {
|
||||
case 1:
|
||||
renderer_swap(w, h);
|
||||
renderer_swap(x, y);
|
||||
x = w - x - 1;
|
||||
break;
|
||||
case 2:
|
||||
x = w - x - 1;
|
||||
y = h - y - 1;
|
||||
break;
|
||||
case 3:
|
||||
renderer_swap(w, h);
|
||||
renderer_swap(x, y);
|
||||
y = h - y - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t *fb = rgb_fb;
|
||||
fb += (int32_t)y * w;
|
||||
fb += x;
|
||||
*fb = color;
|
||||
Cache_WriteBack_Addr((uint32_t)fb, 2);
|
||||
|
||||
}
|
||||
#endif // USE_ESP32_S3
|
||||
|
||||
void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
|
||||
#ifdef USE_ESP32_S3
|
||||
if (interface == _UDSP_RGB) {
|
||||
drawPixel_RGB(x, y, color);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ep_mode) {
|
||||
drawPixel_EPD(x, y, color);
|
||||
|
@ -2172,7 +2492,7 @@ void uDisplay::SetFrameMemory(
|
|||
}
|
||||
|
||||
#define IF_INVERT_COLOR 1
|
||||
#define renderer_swap(a, b) { int16_t t = a; a = b; b = t; }
|
||||
|
||||
/**
|
||||
* @brief: this draws a pixel by absolute coordinates.
|
||||
* this function won't be affected by the rotate parameter.
|
||||
|
@ -2791,6 +3111,8 @@ uint32_t uDisplay::get_sr_touch(uint32_t _xp, uint32_t _xm, uint32_t _yp, uint32
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
void TFT_eSPI::startWrite(void)
|
||||
{
|
||||
|
|
|
@ -31,12 +31,19 @@ static inline volatile uint32_t* get_gpio_lo_reg(int_fast8_t pin) { return (pin
|
|||
static inline bool gpio_in(int_fast8_t pin) { return ((pin & 32) ? GPIO.in1.data : GPIO.in) & (1 << (pin & 31)); }
|
||||
static inline void gpio_hi(int_fast8_t pin) { if (pin >= 0) *get_gpio_hi_reg(pin) = 1 << (pin & 31); } // ESP_LOGI("LGFX", "gpio_hi: %d", pin); }
|
||||
static inline void gpio_lo(int_fast8_t pin) { if (pin >= 0) *get_gpio_lo_reg(pin) = 1 << (pin & 31); } // ESP_LOGI("LGFX", "gpio_lo: %d", pin); }
|
||||
#endif
|
||||
#include "esp_lcd_panel_interface.h"
|
||||
#include "esp_lcd_panel_rgb.h"
|
||||
#include "esp_pm.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include <hal/dma_types.h>
|
||||
#include <rom/cache.h>
|
||||
#endif // USE_ESP32_S3
|
||||
|
||||
#define _UDSP_I2C 1
|
||||
#define _UDSP_SPI 2
|
||||
#define _UDSP_PAR8 3
|
||||
#define _UDSP_PAR16 4
|
||||
#define _UDSP_RGB 5
|
||||
|
||||
#define UDISP1_WHITE 1
|
||||
#define UDISP1_BLACK 0
|
||||
|
@ -115,6 +122,39 @@ struct esp_lcd_i80_bus_t {
|
|||
size_t resolution_hz; // LCD_CLK resolution, determined by selected clock source
|
||||
gdma_channel_handle_t dma_chan; // DMA channel handle
|
||||
};
|
||||
|
||||
// extract from esp-idf esp_lcd_rgb_panel.c
|
||||
struct esp_rgb_panel_t
|
||||
{
|
||||
esp_lcd_panel_t base; // Base class of generic lcd panel
|
||||
int panel_id; // LCD panel ID
|
||||
lcd_hal_context_t hal; // Hal layer object
|
||||
size_t data_width; // Number of data lines (e.g. for RGB565, the data width is 16)
|
||||
size_t sram_trans_align; // Alignment for framebuffer that allocated in SRAM
|
||||
size_t psram_trans_align; // Alignment for framebuffer that allocated in PSRAM
|
||||
int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off"
|
||||
intr_handle_t intr; // LCD peripheral interrupt handle
|
||||
esp_pm_lock_handle_t pm_lock; // Power management lock
|
||||
size_t num_dma_nodes; // Number of DMA descriptors that used to carry the frame buffer
|
||||
uint8_t *fb; // Frame buffer
|
||||
size_t fb_size; // Size of frame buffer
|
||||
int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; // GPIOs used for data lines, we keep these GPIOs for action like "invert_color"
|
||||
size_t resolution_hz; // Peripheral clock resolution
|
||||
esp_lcd_rgb_timing_t timings; // RGB timing parameters (e.g. pclk, sync pulse, porch width)
|
||||
gdma_channel_handle_t dma_chan; // DMA channel handle
|
||||
esp_lcd_rgb_panel_frame_trans_done_cb_t on_frame_trans_done; // Callback, invoked after frame trans done
|
||||
void *user_ctx; // Reserved user's data of callback functions
|
||||
int x_gap; // Extra gap in x coordinate, it's used when calculate the flush window
|
||||
int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window
|
||||
struct
|
||||
{
|
||||
unsigned int disp_en_level : 1; // The level which can turn on the screen by `disp_gpio_num`
|
||||
unsigned int stream_mode : 1; // If set, the LCD transfers data continuously, otherwise, it stops refreshing the LCD when transaction done
|
||||
unsigned int fb_in_psram : 1; // Whether the frame buffer is in PSRAM
|
||||
} flags;
|
||||
dma_descriptor_t dma_nodes[]; // DMA descriptor pool of size `num_dma_nodes`
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -278,6 +318,26 @@ class uDisplay : public Renderer {
|
|||
int8_t par_dbl[8];
|
||||
int8_t par_dbh[8];
|
||||
|
||||
int8_t de;
|
||||
int8_t vsync;
|
||||
int8_t hsync;
|
||||
int8_t pclk;
|
||||
|
||||
uint16_t hsync_polarity;
|
||||
uint16_t hsync_front_porch;
|
||||
uint16_t hsync_pulse_width;
|
||||
uint16_t hsync_back_porch;
|
||||
uint16_t vsync_polarity;
|
||||
uint16_t vsync_front_porch;
|
||||
uint16_t vsync_pulse_width;
|
||||
uint16_t vsync_back_porch;
|
||||
uint16_t pclk_active_neg;
|
||||
|
||||
esp_lcd_panel_handle_t _panel_handle = NULL;
|
||||
esp_rgb_panel_t *_rgb_panel;
|
||||
uint16_t *rgb_fb;
|
||||
|
||||
|
||||
esp_lcd_i80_bus_handle_t _i80_bus = nullptr;
|
||||
gdma_channel_handle_t _dma_chan;
|
||||
lldesc_t *_dmadesc = nullptr;
|
||||
|
@ -304,6 +364,7 @@ class uDisplay : public Renderer {
|
|||
uint8_t _align_data;
|
||||
void cs_control(bool level);
|
||||
uint32_t get_sr_touch(uint32_t xp, uint32_t xm, uint32_t yp, uint32_t ym);
|
||||
void drawPixel_RGB(int16_t x, int16_t y, uint16_t color);
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
:H,ST7262,800,480,16,RGB,40,41,39,42,2,15,16,4,45,48,47,21,14,8,3,46,9,1,5,6,7,14
|
||||
:S,2,1,1,0,40,20
|
||||
:V,0,8,4,8,0,8,4,8,1
|
||||
:TI1,5a,*,*,-1,38
|
||||
#
|
|
@ -623,6 +623,9 @@ uint32_t ESP_getFreeHeap(void) {
|
|||
|
||||
uint32_t ESP_getMaxAllocHeap(void) {
|
||||
// arduino returns IRAM but we want only DRAM
|
||||
#ifdef RGB_DISPLAY
|
||||
return ESP_getFreeHeap();
|
||||
#endif
|
||||
uint32_t free_block_size = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (free_block_size > 100) { free_block_size -= 100; }
|
||||
return free_block_size;
|
||||
|
@ -1135,4 +1138,4 @@ uint32_t HwRandom(void) {
|
|||
last_ccount = ccount;
|
||||
return result ^ *(volatile uint32_t *)_RAND_ADDR;
|
||||
#undef _RAND_ADDR
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5152,7 +5152,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_M5EPD47)
|
||||
#if defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_LILYGO47) || defined(USE_GT911)
|
||||
if (!strncmp(lp, "wtch(", 5)) {
|
||||
lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv);
|
||||
fvar = Touch_Status(fvar);
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
\*******************************************************************************************/
|
||||
|
||||
|
||||
#if defined(USE_LVGL_TOUCHSCREEN) || defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_LILYGO47) || defined(USE_TOUCH_BUTTONS) || defined(SIMPLE_RES_TOUCH)
|
||||
#if defined(USE_LVGL_TOUCHSCREEN) || defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_GT911) || defined(USE_LILYGO47) || defined(USE_TOUCH_BUTTONS) || defined(SIMPLE_RES_TOUCH)
|
||||
|
||||
#ifdef USE_DISPLAY_LVGL_ONLY
|
||||
#undef USE_TOUCH_BUTTONS
|
||||
|
@ -72,6 +72,7 @@ typedef struct TSGlobal_t {
|
|||
TSGlobal_t TSGlobal;
|
||||
|
||||
bool FT5206_found = false;
|
||||
bool GT911_found = false;
|
||||
bool XPT2046_found = false;
|
||||
bool SRES_found = false;
|
||||
|
||||
|
@ -109,7 +110,7 @@ bool Touch_GetStatus(uint8_t* touches, uint16_t* x, uint16_t* y, uint8_t* gestur
|
|||
}
|
||||
|
||||
uint32_t Touch_Status(int32_t sel) {
|
||||
if (TSGlobal.external_ts || FT5206_found || XPT2046_found) {
|
||||
if (TSGlobal.external_ts || FT5206_found || GT911_found || XPT2046_found || SRES_found) {
|
||||
switch (sel) {
|
||||
case 0:
|
||||
return TSGlobal.touched;
|
||||
|
@ -196,7 +197,7 @@ bool FT5206_Touch_Init(TwoWire &i2c) {
|
|||
FT5206_found = false;
|
||||
FT5206_touchp = new FT5206_Class();
|
||||
if (FT5206_touchp->begin(i2c, FT5206_address)) {
|
||||
I2cSetActiveFound(FT5206_address, "FT5206");
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("TI: FT5206"));
|
||||
FT5206_found = true;
|
||||
}
|
||||
//AddLog(LOG_LEVEL_INFO, PSTR("TS: FT5206 %d"),FT5206_found);
|
||||
|
@ -216,11 +217,36 @@ int16_t FT5206_y() {
|
|||
}
|
||||
#endif // USE_FT5206
|
||||
|
||||
#ifdef USE_GT911
|
||||
#include <GT911.h>
|
||||
// touch panel controller
|
||||
GT911 *GT911_touchp;
|
||||
|
||||
bool GT911_Touch_Init(TwoWire *i2c, int8_t irq_pin, int8_t rst_pin, uint16_t xs, uint16_t ys) {
|
||||
GT911_found = false;
|
||||
GT911_touchp = new GT911();
|
||||
if (ESP_OK == GT911_touchp->begin(i2c, irq_pin, rst_pin, xs, ys)) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("TI: GT911"));
|
||||
GT911_found = true;
|
||||
}
|
||||
return GT911_found;
|
||||
}
|
||||
|
||||
void GT911_CheckTouch(void) {
|
||||
GT911_touchp->update();
|
||||
TSGlobal.touched = !GT911_touchp->isFingerUp();
|
||||
if (TSGlobal.touched) {
|
||||
TSGlobal.raw_touch_xp = GT911_touchp->readFingerX(0);
|
||||
TSGlobal.raw_touch_yp = GT911_touchp->readFingerY(0);
|
||||
}
|
||||
}
|
||||
#endif // USE_GT911
|
||||
|
||||
|
||||
#ifdef USE_XPT2046
|
||||
#include <XPT2046_Touchscreen.h>
|
||||
XPT2046_Touchscreen *XPT2046_touchp;
|
||||
|
||||
|
||||
bool XPT2046_Touch_Init(uint16_t CS) {
|
||||
XPT2046_touchp = new XPT2046_Touchscreen(CS);
|
||||
XPT2046_found = XPT2046_touchp->begin();
|
||||
|
@ -266,6 +292,12 @@ void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
|
|||
}
|
||||
#endif // USE_FT5206
|
||||
|
||||
#ifdef USE_GT911
|
||||
if (GT911_found) {
|
||||
GT911_CheckTouch();
|
||||
}
|
||||
#endif // USE_FT5206
|
||||
|
||||
#ifdef USE_XPT2046
|
||||
if (XPT2046_found) {
|
||||
TSGlobal.touched = XPT2046_touched();
|
||||
|
@ -333,18 +365,17 @@ void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
|
|||
}
|
||||
}
|
||||
|
||||
extern uint8_t GT911_found;
|
||||
|
||||
#ifdef USE_TOUCH_BUTTONS
|
||||
void Touch_MQTT(uint8_t index, const char *cp, uint32_t val) {
|
||||
#ifdef USE_FT5206
|
||||
if (FT5206_found) ResponseTime_P(PSTR(",\"FT5206\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
|
||||
if (FT5206_found) ResponseTime_P(PSTR(",\"FT5206\":{\"%s%d\":\"%d\"}}"), cp, index + 1, val);
|
||||
#endif
|
||||
#ifdef USE_XPT2046
|
||||
if (XPT2046_found) ResponseTime_P(PSTR(",\"XPT2046\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
|
||||
if (XPT2046_found) ResponseTime_P(PSTR(",\"XPT2046\":{\"%s%d\":\"%d\"}}"), cp, index + 1, val);
|
||||
#endif // USE_XPT2046
|
||||
#ifdef USE_GT911
|
||||
if (GT911_found) ResponseTime_P(PSTR(",\"GT911\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
|
||||
if (GT911_found) ResponseTime_P(PSTR(",\"GT911\":{\"%s%d\":\"%d\"}}"), cp, index + 1, val);
|
||||
#endif // USE_XPT2046
|
||||
MqttPublishTeleSensor();
|
||||
}
|
||||
|
@ -466,7 +497,7 @@ bool Xdrv55(uint32_t function) {
|
|||
case FUNC_INIT:
|
||||
break;
|
||||
case FUNC_EVERY_100_MSECOND:
|
||||
if (FT5206_found || XPT2046_found || SRES_found) {
|
||||
if (FT5206_found || XPT2046_found || GT911_found || SRES_found) {
|
||||
Touch_Check(TS_RotConvert);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -33,6 +33,8 @@ uint8_t ctouch_counter;
|
|||
extern FS *ffsp;
|
||||
#endif
|
||||
|
||||
#undef GT911_address
|
||||
#define GT911_address 0x5D
|
||||
|
||||
enum {GPIO_DP_RES=GPIO_SENSOR_END-1,GPIO_DP_CS,GPIO_DP_RS,GPIO_DP_WR,GPIO_DP_RD,GPIO_DPAR0,GPIO_DPAR1,GPIO_DPAR2,GPIO_DPAR3,GPIO_DPAR4,GPIO_DPAR5,GPIO_DPAR6,GPIO_DPAR7,GPIO_DPAR8,GPIO_DPAR9,GPIO_DPAR10,GPIO_DPAR11,GPIO_DPAR12,GPIO_DPAR13,GPIO_DPAR14,GPIO_DPAR15};
|
||||
|
||||
|
@ -231,8 +233,21 @@ int8_t cs;
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t xs, ys;
|
||||
// we need screen size for gt911 touch controler
|
||||
cp = strstr(ddesc, ":H,");
|
||||
if (cp) {
|
||||
cp += 3;
|
||||
cp = strchr(cp, ',');
|
||||
cp++;
|
||||
xs = strtol(cp, &cp, 10);
|
||||
cp++;
|
||||
ys = strtol(cp, &cp, 10);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
||||
int8_t xp, xm, yp, ym;
|
||||
|
||||
cp = strstr(ddesc, "PAR,");
|
||||
if (cp) {
|
||||
cp += 4;
|
||||
|
@ -284,7 +299,7 @@ int8_t cs;
|
|||
udisp = new uDisplay(ddesc);
|
||||
|
||||
// checck for touch option TI1 or TI2
|
||||
#ifdef USE_FT5206
|
||||
#if defined(USE_FT5206) || defined(USE_GT911)
|
||||
cp = strstr(ddesc, ":TI");
|
||||
if (cp) {
|
||||
uint8_t wire_n = 1;
|
||||
|
@ -293,9 +308,21 @@ int8_t cs;
|
|||
cp += 2;
|
||||
|
||||
uint8_t i2caddr = strtol(cp, &cp, 16);
|
||||
int8_t scl, sda;
|
||||
int8_t scl, sda, irq = -1, rst = -1;
|
||||
scl = replacepin(&cp, Pin(GPIO_I2C_SCL, wire_n));
|
||||
sda = replacepin(&cp, Pin(GPIO_I2C_SDA, wire_n));
|
||||
if (*(cp - 1) == ',') {
|
||||
irq = strtol(cp, &cp, 10);
|
||||
} else {
|
||||
irq = -1;
|
||||
}
|
||||
if (*cp == ',') {
|
||||
cp++;
|
||||
rst = strtol(cp, &cp, 10);
|
||||
} else {
|
||||
rst = -1;
|
||||
}
|
||||
|
||||
if (wire_n == 0) {
|
||||
I2cBegin(sda, scl);
|
||||
}
|
||||
|
@ -304,26 +331,54 @@ int8_t cs;
|
|||
I2c2Begin(sda, scl, 400000);
|
||||
}
|
||||
if (I2cSetDevice(i2caddr, wire_n)) {
|
||||
I2cSetActiveFound(i2caddr, "FT5206", wire_n);
|
||||
if (i2caddr == GT911_address) {
|
||||
I2cSetActiveFound(i2caddr, "GT911", wire_n);
|
||||
} else {
|
||||
I2cSetActiveFound(i2caddr, "FT5206", wire_n);
|
||||
}
|
||||
}
|
||||
#endif // ESP32
|
||||
|
||||
#ifdef ESP8266
|
||||
//AddLog(LOG_LEVEL_INFO, PSTR("DSP: touch %x, %d, %d, %d!"), i2caddr, wire_n, scl, sda);
|
||||
if (I2cSetDevice(i2caddr)) {
|
||||
I2cSetActiveFound(i2caddr, "FT5206");
|
||||
if (i2caddr == GT911_address) {
|
||||
I2cSetActiveFound(i2caddr, "GT911");
|
||||
} else {
|
||||
I2cSetActiveFound(i2caddr, "FT5206");
|
||||
}
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
// start digitizer
|
||||
#ifdef ESP32
|
||||
if (!wire_n) FT5206_Touch_Init(Wire);
|
||||
else FT5206_Touch_Init(Wire1);
|
||||
if (i2caddr == GT911_address) {
|
||||
#ifdef USE_GT911
|
||||
if (!wire_n) GT911_Touch_Init(&Wire, irq, rst, xs, ys);
|
||||
else GT911_Touch_Init(&Wire1, irq, rst, xs, ys);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef USE_FT5206
|
||||
if (!wire_n) FT5206_Touch_Init(Wire);
|
||||
else FT5206_Touch_Init(Wire1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (i2caddr == GT911_address) {
|
||||
#ifdef USE_GT911
|
||||
if (!wire_n) GT911_Touch_Init(&Wire, irq, rst, xs, ys);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef USE_FT5206
|
||||
if (!wire_n) FT5206_Touch_Init(Wire);
|
||||
#endif
|
||||
}
|
||||
#endif // ESP32
|
||||
|
||||
}
|
||||
#endif // USE_FT5206
|
||||
#endif // USE_FT5206 || GT911
|
||||
|
||||
#ifdef USE_XPT2046
|
||||
cp = strstr(ddesc, ":TS,");
|
||||
|
|
Loading…
Reference in New Issue