udisplay parallel support

This commit is contained in:
gemu2015 2022-10-03 12:24:27 +02:00
parent baace8c133
commit 43c6cf6e26
7 changed files with 1050 additions and 167 deletions

View File

@ -639,6 +639,9 @@ void Renderer::ep_update_mode(uint8_t mode) {
void Renderer::ep_update_area(uint16_t xp, uint16_t yp, uint16_t width, uint16_t height, uint8_t mode) {
}
uint32_t Renderer::get_sr_touch(uint32_t xp, uint32_t xm, uint32_t yp, uint32_t ym) {
return 0;
}
// #ifndef USE_DISPLAY_LVGL_ONLY

View File

@ -90,6 +90,7 @@ public:
virtual LVGL_PARAMS *lvgl_pars(void);
virtual void ep_update_mode(uint8_t mode);
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);
void setDrawMode(uint8_t mode);
uint8_t drawmode;

File diff suppressed because it is too large Load Diff

View File

@ -5,12 +5,38 @@
#include <renderer.h>
#include <Wire.h>
#include <SPI.h>
#ifdef ESP32
#ifdef CONFIG_IDF_TARGET_ESP32S3
#define USE_ESP32_S3
#endif
#endif
#ifdef ESP32
#include "driver/spi_master.h"
#endif
#ifdef USE_ESP32_S3
#include <esp_lcd_panel_io.h>
#include "esp_private/gdma.h"
#include <hal/gpio_ll.h>
#include <hal/lcd_hal.h>
#include <soc/lcd_cam_reg.h>
#include <soc/lcd_cam_struct.h>
static inline volatile uint32_t* get_gpio_hi_reg(int_fast8_t pin) { return (pin & 32) ? &GPIO.out1_w1ts.val : &GPIO.out_w1ts; }
//static inline volatile uint32_t* get_gpio_hi_reg(int_fast8_t pin) { return (volatile uint32_t*)((pin & 32) ? 0x60004014 : 0x60004008) ; } // workaround Eratta
static inline volatile uint32_t* get_gpio_lo_reg(int_fast8_t pin) { return (pin & 32) ? &GPIO.out1_w1tc.val : &GPIO.out_w1tc; }
//static inline volatile uint32_t* get_gpio_lo_reg(int_fast8_t pin) { return (volatile uint32_t*)((pin & 32) ? 0x60004018 : 0x6000400C) ; }
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
#define _UDSP_I2C 1
#define _UDSP_SPI 2
#define _UDSP_PAR8 3
#define _UDSP_PAR16 4
#define UDISP1_WHITE 1
#define UDISP1_BLACK 0
@ -76,6 +102,22 @@ enum uColorType { uCOLOR_BW, uCOLOR_COLOR };
#define LUTMAXSIZE 64
#ifdef USE_ESP32_S3
struct esp_lcd_i80_bus_t {
int bus_id; // Bus ID, index from 0
portMUX_TYPE spinlock; // spinlock used to protect i80 bus members(hal, device_list, cur_trans)
lcd_hal_context_t hal; // Hal object
size_t bus_width; // Number of data lines
intr_handle_t intr; // LCD peripheral interrupt handle
void* pm_lock; // Power management lock
size_t num_dma_nodes; // Number of DMA descriptors
uint8_t *format_buffer; // The driver allocates an internal buffer for DMA to do data format transformer
size_t resolution_hz; // LCD_CLK resolution, determined by selected clock source
gdma_channel_handle_t dma_chan; // DMA channel handle
};
#endif
class uDisplay : public Renderer {
public:
uDisplay(char *);
@ -110,11 +152,11 @@ class uDisplay : public Renderer {
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
uint32_t str2c(char **sp, char *vp, uint32_t len);
void i2c_command(uint8_t val);
void spi_command_one(uint8_t val);
void spi_command(uint8_t val);
void spi_data8(uint8_t val);
void spi_data16(uint16_t val);
void spi_data32(uint32_t val);
void ulcd_command_one(uint8_t val);
void ulcd_command(uint8_t val);
void ulcd_data8(uint8_t val);
void ulcd_data16(uint16_t val);
void ulcd_data32(uint32_t val);
void write8(uint8_t val);
void write8_slow(uint8_t val);
void write9(uint8_t val, uint8_t dc);
@ -226,6 +268,44 @@ class uDisplay : public Renderer {
int16_t rotmap_ymin;
int16_t rotmap_ymax;
void pushColorsMono(uint16_t *data, uint16_t len, bool rgb16_swap = false);
#ifdef USE_ESP32_S3
int8_t par_cs;
int8_t par_rs;
int8_t par_wr;
int8_t par_rd;
int8_t par_dbl[8];
int8_t par_dbh[8];
esp_lcd_i80_bus_handle_t _i80_bus = nullptr;
gdma_channel_handle_t _dma_chan;
lldesc_t *_dmadesc = nullptr;
uint32_t _dmadesc_size = 0;
uint32_t _clock_reg_value;
void calcClockDiv(uint32_t* div_a, uint32_t* div_b, uint32_t* div_n, uint32_t* clkcnt, uint32_t baseClock, uint32_t targetFreq);
void _alloc_dmadesc(size_t len);
void _setup_dma_desc_links(const uint8_t *data, int32_t len);
void pb_beginTransaction(void);
void pb_endTransaction(void);
void pb_wait(void);
bool pb_busy(void);
void _pb_init_pin(bool);
bool pb_writeCommand(uint32_t data, uint_fast8_t bit_length);
void pb_writeData(uint32_t data, uint_fast8_t bit_length);
void pb_pushPixels(uint16_t* data, uint32_t length, bool swap_bytes, bool use_dma);
void pb_writeBytes(const uint8_t* data, uint32_t length, bool use_dma);
void _send_align_data(void);
volatile lcd_cam_dev_t* _dev;
uint32_t* _cache_flip;
static constexpr size_t CACHE_SIZE = 256;
uint32_t _cache[2][CACHE_SIZE / sizeof(uint32_t)];
bool _has_align_data;
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);
#endif
#ifdef ESP32
// dma section
bool DMA_Enabled = false;

View File

@ -582,7 +582,6 @@ void DisplayText(void)
// pad field with spaces fxx
var = atoiv(cp, &fill);
cp += var;
linebuf[fill] = 0;
break;
#ifdef USE_UFILESYS
case 'P':

View File

@ -1,5 +1,5 @@
/*
xdrv_55_touch.ino - Touch contolers
xdrv_55_touch.ino - Touch controllers
Copyright (C) 2021 Gerhard Mutz, Theo Arends & Stephan Hadinger
@ -19,24 +19,24 @@
/*******************************************************************************************\
* Universal TouchScreen driver, extensible via Berry
*
*
* API:
* void Touch_Init() - TODO
*
*
* uint32_t Touch_Status(int32_t sel)
* 0: return 1 if TSGlobal.touched
* 1: return x
* 2: return y
* -1: return raw x (before conersion for resistive)
* -1: return raw x (before conversion for resistive)
* -2: return raw y
*
*
* void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y))
*
*
* void TS_RotConvert(int16_t *x, int16_t *y) - calls the renderer's rotation converter
\*******************************************************************************************/
#if defined(USE_LVGL_TOUCHSCREEN) || defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_LILYGO47) || defined(USE_TOUCH_BUTTONS)
#if defined(USE_LVGL_TOUCHSCREEN) || defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_LILYGO47) || defined(USE_TOUCH_BUTTONS) || defined(SIMPLE_RES_TOUCH)
#ifdef USE_DISPLAY_LVGL_ONLY
#undef USE_TOUCH_BUTTONS
@ -73,6 +73,7 @@ TSGlobal_t TSGlobal;
bool FT5206_found = false;
bool XPT2046_found = false;
bool SRES_found = false;
#ifndef MAX_TOUCH_BUTTONS
#define MAX_TOUCH_BUTTONS 16
@ -131,6 +132,58 @@ uint32_t Touch_Status(int32_t sel) {
uint8_t tbstate[3];
#endif // USE_M5STACK_CORE2
// simple resistive touch pins
// with dma it should check for active transfers
// so currently dont use dma
#ifdef SIMPLE_RES_TOUCH
struct RES_TOUCH {
int8_t xplus;
int8_t xminus;
int8_t yplus;
int8_t yminus;
uint16_t xp;
uint16_t yp;
} sres_touch;
void Simple_ResTouch_Init(int8_t xp, int8_t xm, int8_t yp, int8_t ym) {
sres_touch.xplus = xp; // d1
sres_touch.xminus = xm; // cs
sres_touch.yplus = yp; // rs
sres_touch.yminus = ym; // d0
SRES_found = true;
AddLog(LOG_LEVEL_INFO, PSTR("TS: simple resistive touch init"));
}
#define SRES_THRESHOLD 500
bool SRES_touched() {
uint32_t val = renderer->get_sr_touch(sres_touch.xplus, sres_touch.xminus, sres_touch.yplus, sres_touch.yminus);
if (val == 0) {
return false;
}
sres_touch.xp = val >> 16;
sres_touch.yp = val & 0xffff;
int16_t xp = sres_touch.xp;
int16_t yp = sres_touch.yp;
//AddLog(LOG_LEVEL_INFO, "TS x=%i y=%i)", xp, yp);
if (xp > SRES_THRESHOLD && yp > SRES_THRESHOLD) {
return 1;
}
return 0;
}
int16_t SRES_x() {
return sres_touch.xp;
}
int16_t SRES_y() {
return sres_touch.yp;
}
#endif
#ifdef USE_FT5206
#include <FT5206.h>
// touch panel controller
@ -189,11 +242,20 @@ int16_t XPT2046_y() {
}
#endif // USE_XPT2046
void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
static bool was_touched = false; // flag used to log the data sent when the screen was just released
#ifdef SIMPLE_RES_TOUCH
if (SRES_found) {
TSGlobal.touched = SRES_touched();
if (TSGlobal.touched) {
TSGlobal.raw_touch_xp = SRES_x();
TSGlobal.raw_touch_yp = SRES_y();
}
}
#endif
#ifdef USE_FT5206
if (FT5206_found) {
TSGlobal.touched = FT5206_touched();
@ -213,6 +275,7 @@ void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
}
}
#endif // USE_XPT2046
TSGlobal.touch_xp = TSGlobal.raw_touch_xp;
TSGlobal.touch_yp = TSGlobal.raw_touch_yp;
@ -270,6 +333,8 @@ 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
@ -277,12 +342,20 @@ void Touch_MQTT(uint8_t index, const char *cp, uint32_t val) {
#endif
#ifdef USE_XPT2046
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);
#endif // USE_XPT2046
MqttPublishTeleSensor();
}
void EP_Drawbutton(uint32_t count) {
renderer->ep_update_area(buttons[count]->spars.xp, buttons[count]->spars.yp, buttons[count]->spars.xs, buttons[count]->spars.ys, 3);
}
void Touch_RDW_BUTT(uint32_t count, uint32_t pwr) {
buttons[count]->xdrawButton(pwr);
EP_Drawbutton(count);
if (pwr) buttons[count]->vpower.on_off = 1;
else buttons[count]->vpower.on_off = 0;
}
@ -293,8 +366,8 @@ void CheckTouchButtons(bool touched, int16_t touch_x, int16_t touch_y) {
uint8_t vbutt=0;
if (!renderer) return;
if (TSGlobal.touched) {
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("touch after convert %d - %d"), pLoc.x, pLoc.y);
if (touched) {
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("touch after convert %d - %d"), touch_x, touch_y);
// now must compare with defined buttons
for (uint8_t count = 0; count < MAX_TOUCH_BUTTONS; count++) {
if (buttons[count]) {
@ -307,8 +380,8 @@ void CheckTouchButtons(bool touched, int16_t touch_x, int16_t touch_y) {
if (!buttons[count]->vpower.is_virtual) {
uint8_t pwr=bitRead(TasmotaGlobal.power, rbutt);
if (!SendKey(KEY_BUTTON, rbutt+1, POWER_TOGGLE)) {
ExecuteCommandPower(rbutt+1, POWER_TOGGLE, SRC_BUTTON);
Touch_RDW_BUTT(count, !pwr);
ExecuteCommandPower(rbutt+1, POWER_TOGGLE, SRC_BUTTON);
}
} else {
// virtual button
@ -323,7 +396,9 @@ void CheckTouchButtons(bool touched, int16_t touch_x, int16_t touch_y) {
cp="PBT";
}
buttons[count]->xdrawButton(buttons[count]->vpower.on_off);
EP_Drawbutton(count);
Touch_MQTT(count, cp, buttons[count]->vpower.on_off);
}
}
}
@ -337,6 +412,7 @@ void CheckTouchButtons(bool touched, int16_t touch_x, int16_t touch_y) {
// slider
if (buttons[count]->didhit(touch_x, touch_y)) {
uint16_t value = buttons[count]->UpdateSlider(touch_x, touch_y);
EP_Drawbutton(count);
Touch_MQTT(count, "SLD", value);
}
}
@ -356,6 +432,7 @@ void CheckTouchButtons(bool touched, int16_t touch_x, int16_t touch_y) {
buttons[count]->vpower.on_off = 0;
Touch_MQTT(count,"PBT", buttons[count]->vpower.on_off);
buttons[count]->xdrawButton(buttons[count]->vpower.on_off);
EP_Drawbutton(count);
}
}
}
@ -371,8 +448,6 @@ void CheckTouchButtons(bool touched, int16_t touch_x, int16_t touch_y) {
}
}
}
TSGlobal.raw_touch_xp = TSGlobal.touch_xp = 0;
TSGlobal.raw_touch_yp = TSGlobal.touch_yp = 0;
}
}
#endif // USE_TOUCH_BUTTONS
@ -391,7 +466,7 @@ bool Xdrv55(uint8_t function) {
case FUNC_INIT:
break;
case FUNC_EVERY_100_MSECOND:
if (FT5206_found || XPT2046_found) {
if (FT5206_found || XPT2046_found || SRES_found) {
Touch_Check(TS_RotConvert);
}
break;

View File

@ -33,6 +33,10 @@ uint8_t ctouch_counter;
extern FS *ffsp;
#endif
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};
#ifndef USE_DISPLAY
uint8_t color_type;
uint16_t fg_color;
@ -46,7 +50,6 @@ extern uint16_t bg_color;
#define DISPDESC_SIZE 1000
void Core2DisplayPower(uint8_t on);
void Core2DisplayDim(uint8_t dim);
@ -228,6 +231,44 @@ int8_t cs;
}
}
#ifdef CONFIG_IDF_TARGET_ESP32S3
int8_t xp, xm, yp, ym;
cp = strstr(ddesc, "PAR,");
if (cp) {
cp += 4;
// 8 or 16 bus
uint8_t mode = strtol(cp, &cp, 10);
cp++;
replacepin(&cp, Pin(GPIO_DP_RES));
xm = replacepin(&cp, Pin(GPIO_DP_CS));
yp = replacepin(&cp, Pin(GPIO_DP_RS));
replacepin(&cp, Pin(GPIO_DP_WR));
replacepin(&cp, Pin(GPIO_DP_RD));
replacepin(&cp, Pin(GPIO_BACKLIGHT));
ym = replacepin(&cp, Pin(GPIO_DPAR0));
xp = replacepin(&cp, Pin(GPIO_DPAR1));
replacepin(&cp, Pin(GPIO_DPAR2));
replacepin(&cp, Pin(GPIO_DPAR3));
replacepin(&cp, Pin(GPIO_DPAR4));
replacepin(&cp, Pin(GPIO_DPAR5));
replacepin(&cp, Pin(GPIO_DPAR6));
replacepin(&cp, Pin(GPIO_DPAR7));
if (mode == 16) {
replacepin(&cp, Pin(GPIO_DPAR8));
replacepin(&cp, Pin(GPIO_DPAR9));
replacepin(&cp, Pin(GPIO_DPAR10));
replacepin(&cp, Pin(GPIO_DPAR11));
replacepin(&cp, Pin(GPIO_DPAR12));
replacepin(&cp, Pin(GPIO_DPAR13));
replacepin(&cp, Pin(GPIO_DPAR14));
replacepin(&cp, Pin(GPIO_DPAR15));
}
}
#endif // CONFIG_IDF_TARGET_ESP32S3
/*
File fp;
fp = ffsp->open("/dump.txt", "w");
@ -293,6 +334,16 @@ int8_t cs;
}
#endif // USE_XPT2046
#ifdef CONFIG_IDF_TARGET_ESP32S3
#ifdef SIMPLE_RES_TOUCH
cp = strstr(ddesc, ":TR,");
if (cp) {
cp += 4;
Simple_ResTouch_Init(xp, xm, yp, ym);
}
#endif
#endif
uint8_t inirot = Settings->display_rotate;
cp = strstr(ddesc, ":r,");