|
|
@ -42,9 +42,8 @@ |
|
|
|
|
|
|
|
#include "../../../../inc/MarlinConfig.h" |
|
|
|
|
|
|
|
#if HAS_TOUCH_XPT2046 |
|
|
|
#include "../../../touch/xpt2046.h" |
|
|
|
#endif |
|
|
|
#include HAL_PATH(../../HAL, tft/xpt2046.h) |
|
|
|
XPT2046 touch; |
|
|
|
|
|
|
|
#if ENABLED(POWER_LOSS_RECOVERY) |
|
|
|
#include "../../../../feature/powerloss.h" |
|
|
@ -121,14 +120,14 @@ void tft_set_cursor(uint16_t x, uint16_t y) { |
|
|
|
|
|
|
|
void LCD_WriteRAM_Prepare(void) { |
|
|
|
#if 0 |
|
|
|
if ((DeviceCode == 0x9325) || (DeviceCode == 0x9328) || (DeviceCode == 0x8989)) { |
|
|
|
ClrCs |
|
|
|
LCD->LCD_REG = R34; |
|
|
|
SetCs |
|
|
|
} |
|
|
|
else { |
|
|
|
LCD_WrtReg(0x002C); |
|
|
|
} |
|
|
|
switch (DeviceCode) { |
|
|
|
case 0x9325: case 0x9328: case 0x8989: { |
|
|
|
ClrCs |
|
|
|
LCD->LCD_REG = R34; |
|
|
|
SetCs |
|
|
|
} break; |
|
|
|
default: LCD_WrtReg(0x002C); |
|
|
|
} |
|
|
|
#else |
|
|
|
LCD_IO_WriteReg(0x002C); |
|
|
|
#endif |
|
|
@ -197,8 +196,8 @@ void ili9320_SetWindows(uint16_t StartX, uint16_t StartY, uint16_t width, uint16 |
|
|
|
LCD_WriteReg(0x0053, yEnd);*/ |
|
|
|
LCD_WriteReg(0x0050, StartY); // Specify the start/end positions of the window address in the horizontal direction by an address unit
|
|
|
|
LCD_WriteReg(0x0051, yEnd); // Specify the start positions of the window address in the vertical direction by an address unit
|
|
|
|
LCD_WriteReg(0x0052, 320 - xEnd); |
|
|
|
LCD_WriteReg(0x0053, 320 - StartX - 1); // Specify the end positions of the window address in the vertical direction by an address unit
|
|
|
|
LCD_WriteReg(0x0052, (LCD_FULL_PIXEL_HEIGHT) - xEnd); |
|
|
|
LCD_WriteReg(0x0053, (LCD_FULL_PIXEL_HEIGHT) - StartX - 1); // Specify the end positions of the window address in the vertical direction by an address unit
|
|
|
|
|
|
|
|
} |
|
|
|
else { |
|
|
@ -268,28 +267,10 @@ void LCD_Clear(uint16_t Color) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
extern uint16_t ILI9488_ReadRAM(); |
|
|
|
|
|
|
|
#include HAL_PATH(../../HAL, tft/tft_fsmc.h) |
|
|
|
extern TFT_IO tftio; |
|
|
|
void init_tft() { |
|
|
|
uint16_t i; |
|
|
|
//************* Start Initial Sequence **********//
|
|
|
|
|
|
|
|
//start lcd pins and dma
|
|
|
|
#if PIN_EXISTS(LCD_BACKLIGHT) |
|
|
|
OUT_WRITE(LCD_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT)); // Illuminate after reset or right away
|
|
|
|
#endif |
|
|
|
|
|
|
|
#if PIN_EXISTS(LCD_RESET) |
|
|
|
// Perform a clean hardware reset with needed delays
|
|
|
|
OUT_WRITE(LCD_RESET_PIN, LOW); |
|
|
|
_delay_ms(5); |
|
|
|
WRITE(LCD_RESET_PIN, HIGH); |
|
|
|
_delay_ms(5); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if PIN_EXISTS(LCD_BACKLIGHT) && ENABLED(DELAYED_BACKLIGHT_INIT) |
|
|
|
WRITE(LCD_BACKLIGHT_PIN, HIGH); |
|
|
|
#endif |
|
|
|
|
|
|
|
TERN_(HAS_LCD_CONTRAST, refresh_contrast()); |
|
|
|
|
|
|
@ -303,12 +284,9 @@ void init_tft() { |
|
|
|
|
|
|
|
_delay_ms(5); |
|
|
|
|
|
|
|
LCD_IO_WriteReg(0x00D3); |
|
|
|
DeviceCode = ILI9488_ReadRAM(); //dummy read
|
|
|
|
DeviceCode = ILI9488_ReadRAM(); |
|
|
|
DeviceCode = ILI9488_ReadRAM(); |
|
|
|
DeviceCode <<= 8; |
|
|
|
DeviceCode |= ILI9488_ReadRAM(); |
|
|
|
DeviceCode = tftio.GetID() & 0xFFFF; |
|
|
|
// Chitu and others
|
|
|
|
if (DeviceCode == 0x8066) DeviceCode = 0x9488; |
|
|
|
|
|
|
|
if (DeviceCode == 0x9488) { |
|
|
|
LCD_IO_WriteReg(0x00E0); |
|
|
@ -436,7 +414,7 @@ void tft_lvgl_init() { |
|
|
|
|
|
|
|
//spi_flash_read_test();
|
|
|
|
|
|
|
|
TERN_(HAS_TOUCH_XPT2046, touch.init()); |
|
|
|
touch.Init(); |
|
|
|
|
|
|
|
lv_init(); |
|
|
|
|
|
|
@ -492,35 +470,14 @@ void tft_lvgl_init() { |
|
|
|
void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) { |
|
|
|
#if ENABLED(TFT_LVGL_UI_SPI) |
|
|
|
uint16_t i, width, height; |
|
|
|
uint16_t clr_temp; |
|
|
|
uint8_t tbuf[(LCD_FULL_PIXEL_WIDTH) * 2]; |
|
|
|
|
|
|
|
SPI_TFT.spi_init(SPI_FULL_SPEED); |
|
|
|
|
|
|
|
width = area->x2 - area->x1 + 1; |
|
|
|
height = area->y2 - area->y1 + 1; |
|
|
|
|
|
|
|
for (int j = 0; j < height; j++) { |
|
|
|
SPI_TFT.SetCursor(0, 0); |
|
|
|
SPI_TFT.SetWindows((uint16_t)area->x1, (uint16_t)area->y1 + j, width, 1); |
|
|
|
SPI_TFT.LCD_WriteRAM_Prepare(); |
|
|
|
|
|
|
|
for (i = 0; i < width * 2;) { |
|
|
|
clr_temp = (uint16_t)(((uint16_t)color_p->ch.red << 11) |
|
|
|
| ((uint16_t)color_p->ch.green << 5) |
|
|
|
| ((uint16_t)color_p->ch.blue)); |
|
|
|
|
|
|
|
tbuf[i] = clr_temp >> 8; |
|
|
|
tbuf[i + 1] = clr_temp; |
|
|
|
i += 2; |
|
|
|
color_p++; |
|
|
|
} |
|
|
|
SPI_TFT_CS_L; |
|
|
|
SPI_TFT_DC_H; |
|
|
|
SPI.dmaSend(tbuf, width * 2, true); |
|
|
|
SPI_TFT_CS_H; |
|
|
|
SPI_TFT.SetWindows((uint16_t)area->x1, (uint16_t)area->y1, width, height); |
|
|
|
for (i = 0; i < height; i++) { |
|
|
|
SPI_TFT.tftio.WriteSequence((uint16_t*)(color_p + width * i), width); |
|
|
|
} |
|
|
|
|
|
|
|
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/ |
|
|
|
|
|
|
|
W25QXX.init(SPI_QUARTER_SPEED); |
|
|
@ -556,174 +513,23 @@ unsigned int getTickDiff(unsigned int curTick, unsigned int lastTick) { |
|
|
|
return TICK_CYCLE * (lastTick <= curTick ? (curTick - lastTick) : (0xFFFFFFFF - lastTick + curTick)); |
|
|
|
} |
|
|
|
|
|
|
|
#if ENABLED(TFT_LVGL_UI_SPI) |
|
|
|
|
|
|
|
#ifndef USE_XPT2046 |
|
|
|
#define USE_XPT2046 1 |
|
|
|
#define XPT2046_XY_SWAP 1 |
|
|
|
#define XPT2046_X_INV 1 |
|
|
|
#define XPT2046_Y_INV 0 |
|
|
|
#endif |
|
|
|
|
|
|
|
#if USE_XPT2046 |
|
|
|
#define XPT2046_HOR_RES 480 |
|
|
|
#define XPT2046_VER_RES 320 |
|
|
|
#define XPT2046_X_MIN 201 |
|
|
|
#define XPT2046_Y_MIN 164 |
|
|
|
#define XPT2046_X_MAX 3919 |
|
|
|
#define XPT2046_Y_MAX 3776 |
|
|
|
#define XPT2046_AVG 4 |
|
|
|
#define XPT2046_INV 1 |
|
|
|
#endif |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
#ifndef USE_XPT2046 |
|
|
|
#define USE_XPT2046 1 |
|
|
|
#ifndef XPT2046_XY_SWAP |
|
|
|
#define XPT2046_XY_SWAP 1 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_X_INV |
|
|
|
#define XPT2046_X_INV 0 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_Y_INV |
|
|
|
#define XPT2046_Y_INV 1 |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#if USE_XPT2046 |
|
|
|
#ifndef XPT2046_HOR_RES |
|
|
|
#define XPT2046_HOR_RES 480 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_VER_RES |
|
|
|
#define XPT2046_VER_RES 320 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_X_MIN |
|
|
|
#define XPT2046_X_MIN 201 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_Y_MIN |
|
|
|
#define XPT2046_Y_MIN 164 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_X_MAX |
|
|
|
#define XPT2046_X_MAX 3919 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_Y_MAX |
|
|
|
#define XPT2046_Y_MAX 3776 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_AVG |
|
|
|
#define XPT2046_AVG 4 |
|
|
|
#endif |
|
|
|
#ifndef XPT2046_INV |
|
|
|
#define XPT2046_INV 0 |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
static void xpt2046_corr(uint16_t *x, uint16_t *y) { |
|
|
|
#if XPT2046_XY_SWAP |
|
|
|
int16_t swap_tmp; |
|
|
|
swap_tmp = *x; |
|
|
|
*x = *y; |
|
|
|
*y = swap_tmp; |
|
|
|
#endif |
|
|
|
if ((*x) > XPT2046_X_MIN) (*x) -= XPT2046_X_MIN; else (*x) = 0; |
|
|
|
if ((*y) > XPT2046_Y_MIN) (*y) -= XPT2046_Y_MIN; else (*y) = 0; |
|
|
|
(*x) = uint32_t(uint32_t(*x) * XPT2046_HOR_RES) / (XPT2046_X_MAX - XPT2046_X_MIN); |
|
|
|
(*y) = uint32_t(uint32_t(*y) * XPT2046_VER_RES) / (XPT2046_Y_MAX - XPT2046_Y_MIN); |
|
|
|
#if XPT2046_X_INV |
|
|
|
(*x) = XPT2046_HOR_RES - (*x); |
|
|
|
#endif |
|
|
|
#if XPT2046_Y_INV |
|
|
|
(*y) = XPT2046_VER_RES - (*y); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
#define times 4 |
|
|
|
#define CHX 0x90 |
|
|
|
#define CHY 0xD0 |
|
|
|
|
|
|
|
int SPI2_ReadWrite2Bytes(void) { |
|
|
|
#define SPI_READ_WRITE_BYTE(B) TERN(TFT_LVGL_UI_SPI, SPI_TFT.spi_read_write_byte, W25QXX.spi_flash_read_write_byte)(B) |
|
|
|
const uint16_t t1 = SPI_READ_WRITE_BYTE(0xFF), |
|
|
|
t2 = SPI_READ_WRITE_BYTE(0xFF); |
|
|
|
return (((t1 << 8) | t2) >> 3) & 0x0FFF; |
|
|
|
} |
|
|
|
static bool get_point(int16_t *x, int16_t *y) { |
|
|
|
bool is_touched = touch.getRawPoint(x, y); |
|
|
|
|
|
|
|
uint16_t x_addata[times], y_addata[times]; |
|
|
|
void XPT2046_Rd_Addata(uint16_t *X_Addata, uint16_t *Y_Addata) { |
|
|
|
uint16_t i, j, k; |
|
|
|
|
|
|
|
TERN(TFT_LVGL_UI_SPI, SPI_TFT.spi_init, W25QXX.init)(SPI_SPEED_6); |
|
|
|
|
|
|
|
for (i = 0; i < times; i++) { |
|
|
|
#if ENABLED(TFT_LVGL_UI_SPI) |
|
|
|
OUT_WRITE(TOUCH_CS_PIN, LOW); |
|
|
|
SPI_TFT.spi_read_write_byte(CHX); |
|
|
|
y_addata[i] = SPI2_ReadWrite2Bytes(); |
|
|
|
WRITE(TOUCH_CS_PIN, HIGH); |
|
|
|
|
|
|
|
OUT_WRITE(TOUCH_CS_PIN, LOW); |
|
|
|
SPI_TFT.spi_read_write_byte(CHY); |
|
|
|
x_addata[i] = SPI2_ReadWrite2Bytes(); |
|
|
|
WRITE(TOUCH_CS_PIN, HIGH); |
|
|
|
#else // #if HAS_TOUCH_XPT2046
|
|
|
|
OUT_WRITE(TOUCH_CS_PIN, LOW); |
|
|
|
W25QXX.spi_flash_read_write_byte(CHX); |
|
|
|
y_addata[i] = SPI2_ReadWrite2Bytes(); |
|
|
|
WRITE(TOUCH_CS_PIN, HIGH); |
|
|
|
|
|
|
|
OUT_WRITE(TOUCH_CS_PIN, LOW); |
|
|
|
W25QXX.spi_flash_read_write_byte(CHY); |
|
|
|
x_addata[i] = SPI2_ReadWrite2Bytes(); |
|
|
|
WRITE(TOUCH_CS_PIN, HIGH); |
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
TERN(TFT_LVGL_UI_SPI,,W25QXX.init(SPI_QUARTER_SPEED)); |
|
|
|
|
|
|
|
for (i = 0; i < times; i++) |
|
|
|
for (j = i + 1; j < times; j++) |
|
|
|
if (x_addata[j] > x_addata[i]) { |
|
|
|
k = x_addata[j]; |
|
|
|
x_addata[j] = x_addata[i]; |
|
|
|
x_addata[i] = k; |
|
|
|
} |
|
|
|
if (x_addata[times / 2 - 1] - x_addata[times / 2] > 50) { |
|
|
|
*X_Addata = *Y_Addata = 0; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
*X_Addata = (x_addata[times / 2 - 1] + x_addata[times / 2]) / 2; |
|
|
|
|
|
|
|
for (i = 0; i < times; i++) |
|
|
|
for (j = i + 1; j < times; j++) |
|
|
|
if (y_addata[j] > y_addata[i]) { |
|
|
|
k = y_addata[j]; |
|
|
|
y_addata[j] = y_addata[i]; |
|
|
|
y_addata[i] = k; |
|
|
|
} |
|
|
|
|
|
|
|
if (y_addata[times / 2 - 1] - y_addata[times / 2] > 50) { |
|
|
|
*X_Addata = *Y_Addata = 0; |
|
|
|
return; |
|
|
|
if (is_touched) { |
|
|
|
*x = int16_t((int32_t(*x) * XPT2046_X_CALIBRATION) >> 16) + XPT2046_X_OFFSET; |
|
|
|
*y = int16_t((int32_t(*y) * XPT2046_Y_CALIBRATION) >> 16) + XPT2046_Y_OFFSET; |
|
|
|
} |
|
|
|
|
|
|
|
*Y_Addata = (y_addata[times / 2 - 1] + y_addata[times / 2]) / 2; |
|
|
|
} |
|
|
|
|
|
|
|
#define ADC_VALID_OFFSET 10 |
|
|
|
#if ENABLED(GRAPHICAL_TFT_ROTATE_180) |
|
|
|
x = (LCD_FULL_PIXEL_WIDTH) - x; |
|
|
|
y = (LCD_FULL_PIXEL_HEIGHT) - y; |
|
|
|
#endif |
|
|
|
|
|
|
|
uint8_t TOUCH_PressValid(uint16_t _usX, uint16_t _usY) { |
|
|
|
if ( (_usX <= ADC_VALID_OFFSET) |
|
|
|
|| (_usY <= ADC_VALID_OFFSET) |
|
|
|
|| (_usX >= 4095 - ADC_VALID_OFFSET) |
|
|
|
|| (_usY >= 4095 - ADC_VALID_OFFSET) |
|
|
|
) return 0; |
|
|
|
return 1; |
|
|
|
return is_touched; |
|
|
|
} |
|
|
|
|
|
|
|
static lv_coord_t last_x = 0, last_y = 0; |
|
|
|
static int16_t last_x = 0, last_y = 0; |
|
|
|
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) { |
|
|
|
uint32_t tmpTime, diffTime = 0; |
|
|
|
|
|
|
@ -735,34 +541,24 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) { |
|
|
|
//touchpad_get_xy(&last_x, &last_y);
|
|
|
|
/*Save the pressed coordinates and the state*/ |
|
|
|
if (diffTime > 10) { |
|
|
|
//use marlin touch code if enabled
|
|
|
|
#if HAS_TOUCH_XPT2046 |
|
|
|
touch.getTouchPoint(reinterpret_cast<uint16_t&>(last_x), reinterpret_cast<uint16_t&>(last_y)); |
|
|
|
#else |
|
|
|
XPT2046_Rd_Addata((uint16_t *)&last_x, (uint16_t *)&last_y); |
|
|
|
#endif |
|
|
|
if (TOUCH_PressValid(last_x, last_y)) { |
|
|
|
if (get_point(&last_x, &last_y)) { |
|
|
|
|
|
|
|
data->state = LV_INDEV_STATE_PR; |
|
|
|
|
|
|
|
/* Set the coordinates (if released use the last pressed coordinates) */ |
|
|
|
// Set the coordinates (if released use the last-pressed coordinates)
|
|
|
|
|
|
|
|
// SERIAL_ECHOLNPAIR("antes X: ", last_x, ", y: ", last_y);
|
|
|
|
xpt2046_corr((uint16_t *)&last_x, (uint16_t *)&last_y); |
|
|
|
// SERIAL_ECHOLNPAIR("X: ", last_x, ", y: ", last_y);
|
|
|
|
data->point.x = last_x; |
|
|
|
data->point.y = last_y; |
|
|
|
|
|
|
|
last_x = 0; |
|
|
|
last_y = 0; |
|
|
|
last_x = last_y = 0; |
|
|
|
} |
|
|
|
else { |
|
|
|
else |
|
|
|
data->state = LV_INDEV_STATE_REL; |
|
|
|
} |
|
|
|
|
|
|
|
touch_time1 = tmpTime; |
|
|
|
} |
|
|
|
|
|
|
|
return false; /*Return `false` because we are not buffering and no more data to read*/ |
|
|
|
return false; // Return `false` since no data is buffering or left to read
|
|
|
|
} |
|
|
|
|
|
|
|
#endif // HAS_TFT_LVGL_UI
|
|
|
|