mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2024-11-27 13:56:24 +00:00
Optimize LVGL with HAL TFT IO (SPI and FSMC) (#18974)
This commit is contained in:
parent
3b9e0c3dde
commit
ff5c8d3570
@ -22,7 +22,7 @@
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_FSMC_TFT
|
||||
#if HAS_FSMC_TFT || ENABLED(TFT_LVGL_UI_FSMC)
|
||||
|
||||
#include "tft_fsmc.h"
|
||||
#include <libmaple/fsmc.h>
|
||||
@ -224,6 +224,7 @@ void TFT_FSMC::Abort() {
|
||||
}
|
||||
|
||||
void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
|
||||
#if defined(FSMC_DMA_DEV) && defined(FSMC_DMA_CHANNEL)
|
||||
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | MemoryIncrease);
|
||||
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Count);
|
||||
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
@ -231,6 +232,7 @@ void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Cou
|
||||
|
||||
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {};
|
||||
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // HAS_FSMC_TFT
|
||||
|
@ -61,4 +61,11 @@ class TFT_FSMC {
|
||||
|
||||
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_MODE, Data, Count); }
|
||||
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_CIRC_MODE, &Data, Count); }
|
||||
static void WriteMultiple(uint16_t Color, uint32_t Count) {
|
||||
static uint16_t Data; Data = Color;
|
||||
while (Count > 0) {
|
||||
TransmitDMA(DMA_CIRC_MODE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
|
||||
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_SPI_TFT
|
||||
#if HAS_SPI_TFT || ENABLED(TFT_LVGL_UI_SPI)
|
||||
|
||||
#include "tft_spi.h"
|
||||
|
||||
@ -103,16 +103,21 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
|
||||
#if !PIN_EXISTS(TFT_MISO)
|
||||
return 0;
|
||||
#else
|
||||
uint16_t d = 0;
|
||||
uint8_t d = 0;
|
||||
uint32_t data = 0;
|
||||
SPIx.setClockDivider(SPI_CLOCK_DIV16);
|
||||
DataTransferBegin(DATASIZE_8BIT);
|
||||
WriteReg(Reg);
|
||||
|
||||
SPI.read((uint8_t*)&d, 1); //dummy read
|
||||
SPI.read((uint8_t*)&d, 1);
|
||||
LOOP_L_N(i, 4) {
|
||||
SPIx.read((uint8_t*)&d, 1);
|
||||
data = (data << 8) | d;
|
||||
}
|
||||
|
||||
DataTransferEnd();
|
||||
SPIx.setClockDivider(SPI_CLOCK_MAX);
|
||||
|
||||
return d >> 7;
|
||||
return data >> 7;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -62,4 +62,11 @@ public:
|
||||
|
||||
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
|
||||
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
|
||||
static void WriteMultiple(uint16_t Color, uint32_t Count) {
|
||||
static uint16_t Data; Data = Color;
|
||||
while (Count > 0) {
|
||||
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
|
||||
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -252,7 +252,7 @@
|
||||
#endif
|
||||
|
||||
// Full Touch Screen needs 'tft/xpt2046'
|
||||
#if ENABLED(TOUCH_SCREEN)
|
||||
#if EITHER(TOUCH_SCREEN, HAS_TFT_LVGL_UI)
|
||||
#define HAS_TFT_XPT2046 1
|
||||
#endif
|
||||
|
||||
|
@ -54,112 +54,27 @@ TFT SPI_TFT;
|
||||
|
||||
// use SPI1 for the spi tft.
|
||||
void TFT::spi_init(uint8_t spiRate) {
|
||||
|
||||
SPI_TFT_CS_H;
|
||||
|
||||
/**
|
||||
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
|
||||
* STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
|
||||
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
|
||||
*/
|
||||
uint8_t clock;
|
||||
switch (spiRate) {
|
||||
case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV4; break;
|
||||
case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4; break;
|
||||
case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8; break;
|
||||
case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
|
||||
case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
|
||||
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
|
||||
default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
|
||||
}
|
||||
SPI.setModule(1);
|
||||
SPI.begin();
|
||||
SPI.setClockDivider(clock);
|
||||
SPI.setBitOrder(MSBFIRST);
|
||||
SPI.setDataMode(SPI_MODE0);
|
||||
}
|
||||
|
||||
uint8_t TFT::spi_Rec() {
|
||||
uint8_t returnByte = SPI.transfer(ff);
|
||||
return returnByte;
|
||||
}
|
||||
|
||||
uint8_t TFT::spi_read_write_byte(uint8_t data) {
|
||||
uint8_t returnByte = SPI.transfer(data);
|
||||
return returnByte;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a number of bytes from the SPI port to a buffer
|
||||
*
|
||||
* @param buf Pointer to starting address of buffer to write to.
|
||||
* @param nbyte Number of bytes to receive.
|
||||
* @return Nothing
|
||||
*
|
||||
* @details Uses DMA
|
||||
*/
|
||||
void TFT::spi_Read(uint8_t* buf, uint16_t nbyte) {SPI.dmaTransfer(0, const_cast<uint8_t*>(buf), nbyte);}
|
||||
|
||||
/**
|
||||
* @brief Send a single byte on SPI port
|
||||
*
|
||||
* @param b Byte to send
|
||||
*
|
||||
* @details
|
||||
*/
|
||||
void TFT::spi_Send(uint8_t b) {SPI.send(b);}
|
||||
|
||||
/**
|
||||
* @brief Write token and then write from 512 byte buffer to SPI (for SD card)
|
||||
*
|
||||
* @param buf Pointer with buffer start address
|
||||
* @return Nothing
|
||||
*
|
||||
* @details Use DMA
|
||||
*/
|
||||
void TFT::spi_SendBlock(uint8_t token, const uint8_t* buf) {
|
||||
SPI.send(token);
|
||||
SPI.dmaSend(const_cast<uint8_t*>(buf), 512);
|
||||
tftio.Init();
|
||||
}
|
||||
|
||||
void TFT::LCD_WR_REG(uint8_t cmd) {
|
||||
SPI_TFT_CS_L;
|
||||
SPI_TFT_DC_L;
|
||||
spi_Send(cmd);
|
||||
SPI_TFT_CS_H;
|
||||
tftio.WriteReg(cmd);
|
||||
}
|
||||
void TFT::LCD_WR_DATA(uint8_t data) {
|
||||
SPI_TFT_CS_L;
|
||||
SPI_TFT_DC_H;
|
||||
spi_Send(data);
|
||||
SPI_TFT_CS_H;
|
||||
}
|
||||
void TFT::LCD_WriteRAM_Prepare() {LCD_WR_REG(0X2C);}
|
||||
void TFT::SetCursor(uint16_t x, uint16_t y) {
|
||||
LCD_WR_REG(0x2A);
|
||||
LCD_WR_DATA(x >> 8);
|
||||
LCD_WR_DATA(x);
|
||||
LCD_WR_DATA(x >> 8);
|
||||
LCD_WR_DATA(x);
|
||||
|
||||
LCD_WR_REG(0x2B);
|
||||
LCD_WR_DATA(y >> 8);
|
||||
LCD_WR_DATA(y);
|
||||
LCD_WR_DATA(y >> 8);
|
||||
LCD_WR_DATA(y);
|
||||
void TFT::LCD_WR_DATA(uint8_t data) {
|
||||
tftio.WriteData(data);
|
||||
}
|
||||
|
||||
void TFT::SetPoint(uint16_t x, uint16_t y, uint16_t point) {
|
||||
if ((x > 480) || (y > 320)) return;
|
||||
|
||||
SetCursor(x, y);
|
||||
|
||||
LCD_WriteRAM_Prepare();
|
||||
LCD_WR_DATA((uint8_t)(point >> 8));
|
||||
LCD_WR_DATA((uint8_t)point);
|
||||
SetWindows(x, y, 1, 1);
|
||||
tftio.WriteMultiple(point, (uint16_t)1);
|
||||
}
|
||||
|
||||
void TFT::SetWindows(uint16_t x, uint16_t y, uint16_t with, uint16_t height) {
|
||||
tftio.DataTransferBegin(DATASIZE_8BIT);
|
||||
|
||||
LCD_WR_REG(0x2A);
|
||||
LCD_WR_DATA(x >> 8);
|
||||
LCD_WR_DATA(x);
|
||||
@ -171,6 +86,10 @@ void TFT::SetWindows(uint16_t x, uint16_t y, uint16_t with, uint16_t height) {
|
||||
LCD_WR_DATA(y);
|
||||
LCD_WR_DATA((y + height - 1) >> 8);
|
||||
LCD_WR_DATA(y + height - 1);
|
||||
|
||||
LCD_WR_REG(0X2C);
|
||||
|
||||
tftio.DataTransferEnd();
|
||||
}
|
||||
|
||||
void TFT::LCD_init() {
|
||||
@ -180,6 +99,8 @@ void TFT::LCD_init() {
|
||||
delay(150);
|
||||
SPI_TFT_RST_H;
|
||||
|
||||
tftio.DataTransferBegin(DATASIZE_8BIT);
|
||||
|
||||
delay(120);
|
||||
LCD_WR_REG(0x11);
|
||||
delay(120);
|
||||
@ -251,6 +172,8 @@ void TFT::LCD_init() {
|
||||
delay(120); // Delay 120ms
|
||||
LCD_WR_REG(0x29); // Display ON
|
||||
|
||||
tftio.DataTransferEnd();
|
||||
|
||||
LCD_clear(0x0000); //
|
||||
LCD_Draw_Logo();
|
||||
SPI_TFT_BLK_H;
|
||||
@ -258,81 +181,18 @@ void TFT::LCD_init() {
|
||||
}
|
||||
|
||||
void TFT::LCD_clear(uint16_t color) {
|
||||
unsigned int i;
|
||||
uint8_t tbuf[960];
|
||||
|
||||
SetCursor(0, 0);
|
||||
SetWindows(0, 0, 480 - 1, 320 - 1);
|
||||
LCD_WriteRAM_Prepare();
|
||||
SPI_TFT_CS_L;
|
||||
SPI_TFT_DC_H;
|
||||
for (i = 0; i < 960;) {
|
||||
tbuf[i] = color >> 8;
|
||||
tbuf[i + 1] = color;
|
||||
i += 2;
|
||||
}
|
||||
for (i = 0; i < 320; i++) {
|
||||
// for (m=0;m<480;m++)
|
||||
// {
|
||||
// LCD_WR_DATA(color>>8);
|
||||
// LCD_WR_DATA(color);
|
||||
SPI.dmaSend(tbuf, 960, true);
|
||||
// SPI_TFT_CS_H;
|
||||
// }
|
||||
}
|
||||
SPI_TFT_CS_H;
|
||||
SetWindows(0, 0, (LCD_FULL_PIXEL_WIDTH) - 1, (LCD_FULL_PIXEL_HEIGHT) - 1);
|
||||
tftio.WriteMultiple(color, (uint32_t)(LCD_FULL_PIXEL_WIDTH) * (LCD_FULL_PIXEL_HEIGHT));
|
||||
}
|
||||
|
||||
extern unsigned char bmp_public_buf[17 * 1024];
|
||||
|
||||
void TFT::LCD_Draw_Logo() {
|
||||
uint16_t i,y_off = 0;
|
||||
uint16_t *p_index;
|
||||
uint16_t Color;
|
||||
|
||||
#if 1
|
||||
for (y_off = 0; y_off < 320; y_off ++) {
|
||||
Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, 960);
|
||||
|
||||
SPI_TFT.spi_init(SPI_FULL_SPEED);
|
||||
SetWindows(0, y_off, 480, 1);
|
||||
LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */
|
||||
for (i = 0; i < 960;) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
Color = (*p_index >> 8);
|
||||
*p_index = Color | ((*p_index & 0xFF) << 8);
|
||||
i+=2;
|
||||
SetWindows(0, 0, LCD_FULL_PIXEL_WIDTH, LCD_FULL_PIXEL_HEIGHT);
|
||||
for (uint16_t i = 0; i < (LCD_FULL_PIXEL_HEIGHT); i ++) {
|
||||
Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, (LCD_FULL_PIXEL_WIDTH) * 2);
|
||||
tftio.WriteSequence((uint16_t *)bmp_public_buf, LCD_FULL_PIXEL_WIDTH);
|
||||
}
|
||||
SPI_TFT_CS_L;
|
||||
SPI_TFT_DC_H;
|
||||
SPI.dmaSend(bmp_public_buf,960,true);
|
||||
SPI_TFT_CS_H;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for (index = 0; index < 40; index ++) {
|
||||
Pic_Logo_Read((uint8_t *)"", bmp_public_buf, 480*8*2);
|
||||
i = 0;
|
||||
SetCursor(0,0);
|
||||
SetWindows(0, y_off * 8, 480, 8);
|
||||
LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */
|
||||
for (i = 0; i < 480 * 8 * 2;) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
Color = (*p_index >> 8);
|
||||
*p_index = Color | ((*p_index & 0xFF) << 8);
|
||||
i += 2;
|
||||
}
|
||||
SPI_TFT_CS_L;
|
||||
SPI_TFT_DC_H;
|
||||
SPI.dmaSend(bmp_public_buf,480*8*2,true);
|
||||
SPI_TFT_CS_H;
|
||||
|
||||
y_off++;
|
||||
}
|
||||
#endif
|
||||
|
||||
SetWindows(0, 0, 479, 319);
|
||||
}
|
||||
|
||||
#endif // HAS_TFT_LVGL_UI_SPI
|
||||
|
@ -21,13 +21,13 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#define SPI_TFT_CS_H OUT_WRITE(SPI_TFT_CS_PIN, HIGH)
|
||||
#define SPI_TFT_CS_L OUT_WRITE(SPI_TFT_CS_PIN, LOW)
|
||||
|
||||
#define SPI_TFT_DC_H OUT_WRITE(SPI_TFT_DC_PIN, HIGH)
|
||||
#define SPI_TFT_DC_L OUT_WRITE(SPI_TFT_DC_PIN, LOW)
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
#include HAL_PATH(../../HAL, tft/tft_spi.h)
|
||||
#elif ENABLED(TFT_LVGL_UI_FSMC)
|
||||
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
|
||||
#endif
|
||||
|
||||
#define SPI_TFT_RST_H OUT_WRITE(SPI_TFT_RST_PIN, HIGH)
|
||||
#define SPI_TFT_RST_L OUT_WRITE(SPI_TFT_RST_PIN, LOW)
|
||||
@ -37,20 +37,14 @@
|
||||
|
||||
class TFT {
|
||||
public:
|
||||
TFT_IO tftio;
|
||||
void spi_init(uint8_t spiRate);
|
||||
uint8_t spi_Rec();
|
||||
uint8_t spi_read_write_byte(uint8_t data);
|
||||
void spi_Read(uint8_t* buf, uint16_t nbyte);
|
||||
void spi_Send(uint8_t b);
|
||||
void spi_SendBlock(uint8_t token, const uint8_t* buf);
|
||||
void LCD_WR_REG(uint8_t cmd);
|
||||
void LCD_WR_DATA(uint8_t data);
|
||||
void SetCursor(uint16_t x, uint16_t y);
|
||||
void SetPoint(uint16_t x, uint16_t y, uint16_t point);
|
||||
void SetWindows(uint16_t x, uint16_t y, uint16_t with, uint16_t height);
|
||||
void LCD_init();
|
||||
void LCD_clear(uint16_t color);
|
||||
void LCD_WriteRAM_Prepare();
|
||||
void LCD_Draw_Logo();
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,8 @@
|
||||
#endif
|
||||
#include "../../../../gcode/gcode.h"
|
||||
|
||||
#include "pic_manager.h"
|
||||
|
||||
static lv_obj_t * scr;
|
||||
extern uint8_t sel_id;
|
||||
extern uint8_t once_flag;
|
||||
|
@ -500,14 +500,9 @@ char *creat_title_text() {
|
||||
}
|
||||
}
|
||||
|
||||
//SERIAL_ECHOLNPAIR("gPicturePreviewStart: ", gPicturePreviewStart, " PREVIEW_LITTLE_PIC_SIZE: ", PREVIEW_LITTLE_PIC_SIZE);
|
||||
|
||||
card.setIndex((gPicturePreviewStart + To_pre_view) + size * row + 8);
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
SPI_TFT.spi_init(SPI_FULL_SPEED);
|
||||
//SPI_TFT.SetCursor(0,0);
|
||||
SPI_TFT.SetWindows(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
SPI_TFT.LCD_WriteRAM_Prepare();
|
||||
#else
|
||||
ili9320_SetWindows(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
LCD_WriteRAM_Prepare();
|
||||
@ -525,19 +520,11 @@ char *creat_title_text() {
|
||||
if (j >= 400) break;
|
||||
}
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
uint16_t Color, SpiColor;
|
||||
SpiColor = (LV_COLOR_BACKGROUND.full >> 8) | ((LV_COLOR_BACKGROUND.full & 0xFF) << 8);
|
||||
for (i = 0; i < 400;) {
|
||||
for (i = 0; i < 400; i += 2) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
Color = (*p_index >> 8);
|
||||
*p_index = Color | ((*p_index & 0xFF) << 8);
|
||||
i += 2;
|
||||
if (*p_index == 0x0000) *p_index = SpiColor;
|
||||
if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full;
|
||||
}
|
||||
SPI_TFT_CS_L;
|
||||
SPI_TFT_DC_H;
|
||||
SPI.dmaSend(bmp_public_buf, 400, true);
|
||||
SPI_TFT_CS_H;
|
||||
SPI_TFT.tftio.WriteSequence((uint16_t*)bmp_public_buf, 200);
|
||||
#else
|
||||
for (i = 0; i < 400;) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
@ -627,10 +614,7 @@ char *creat_title_text() {
|
||||
|
||||
card.setIndex((PREVIEW_LITTLE_PIC_SIZE + To_pre_view) + size * row + 8);
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
SPI_TFT.spi_init(SPI_FULL_SPEED);
|
||||
//SPI_TFT.SetCursor(0,0);
|
||||
SPI_TFT.SetWindows(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
SPI_TFT.LCD_WriteRAM_Prepare();
|
||||
#else
|
||||
ili9320_SetWindows(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
LCD_WriteRAM_Prepare();
|
||||
@ -750,9 +734,6 @@ char *creat_title_text() {
|
||||
void Draw_default_preview(int xpos_pixel, int ypos_pixel, uint8_t sel) {
|
||||
int index;
|
||||
int y_off = 0;
|
||||
int _y;
|
||||
uint16_t *p_index;
|
||||
int i;
|
||||
|
||||
for (index = 0; index < 10; index++) { // 200*200
|
||||
#if HAS_BAK_VIEW_IN_FLASH
|
||||
@ -761,58 +742,24 @@ char *creat_title_text() {
|
||||
}
|
||||
else {
|
||||
default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 20k
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
uint16_t Color;
|
||||
for (i = 0; i < (DEFAULT_VIEW_MAX_SIZE / 10);) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
Color = (*p_index >> 8);
|
||||
*p_index = Color | ((*p_index & 0xff) << 8);
|
||||
i += 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 20k
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
for (i = 0; i < (DEFAULT_VIEW_MAX_SIZE / 10);) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
Color = (*p_index >> 8);
|
||||
*p_index = Color | ((*p_index & 0xff) << 8);
|
||||
i += 2;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
i = 0;
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
|
||||
//SPI_TFT.spi_init(SPI_FULL_SPEED);
|
||||
//SPI_TFT.SetWindows(xpos_pixel, y_off * 20+ypos_pixel, 200,20); //200*200
|
||||
//SPI_TFT.LCD_WriteRAM_Prepare();
|
||||
int j = 0;
|
||||
for (_y = y_off * 20; _y < (y_off + 1) * 20; _y++) {
|
||||
SPI_TFT.spi_init(SPI_FULL_SPEED);
|
||||
SPI_TFT.SetWindows(xpos_pixel, y_off * 20 + ypos_pixel + j, 200, 1); // 200*200
|
||||
SPI_TFT.LCD_WriteRAM_Prepare();
|
||||
|
||||
j++;
|
||||
//memcpy(public_buf,&bmp_public_buf[i],400);
|
||||
SPI_TFT_CS_L;
|
||||
SPI_TFT_DC_H;
|
||||
SPI.dmaSend(&bmp_public_buf[i], 400, true);
|
||||
SPI_TFT_CS_H;
|
||||
|
||||
i += 400;
|
||||
if (i >= 8000) break;
|
||||
}
|
||||
SPI_TFT.SetWindows(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200
|
||||
SPI_TFT.tftio.WriteSequence((uint16_t*)(bmp_public_buf), DEFAULT_VIEW_MAX_SIZE / 20);
|
||||
#else
|
||||
int x_off = 0;
|
||||
uint16_t temp_p;
|
||||
int i = 0;
|
||||
uint16_t *p_index;
|
||||
ili9320_SetWindows(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200
|
||||
|
||||
LCD_WriteRAM_Prepare();
|
||||
|
||||
for (_y = y_off * 20; _y < (y_off + 1) * 20; _y++) {
|
||||
for (int _y = y_off * 20; _y < (y_off + 1) * 20; _y++) {
|
||||
for (x_off = 0; x_off < 200; x_off++) {
|
||||
if (sel == 1) {
|
||||
temp_p = (uint16_t)(bmp_public_buf[i] | bmp_public_buf[i + 1] << 8);
|
||||
|
@ -590,8 +590,6 @@ void disp_char_1624(uint16_t x, uint16_t y, uint8_t c, uint16_t charColor, uint1
|
||||
}
|
||||
|
||||
void disp_string(uint16_t x, uint16_t y, const char * string, uint16_t charColor, uint16_t bkColor) {
|
||||
// Select TFT SPI so it can receive data
|
||||
TERN_(TFT_LVGL_UI_SPI, SPI_TFT.spi_init(SPI_FULL_SPEED));
|
||||
while (*string != '\0') {
|
||||
disp_char_1624(x, y, *string, charColor, bkColor);
|
||||
string++;
|
||||
|
@ -22,249 +22,39 @@
|
||||
|
||||
#include "../../../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_TFT_LVGL_UI
|
||||
#if ENABLED(TFT_LVGL_UI_FSMC)
|
||||
|
||||
#if defined(ARDUINO_ARCH_STM32F1) && PIN_EXISTS(FSMC_CS) // FSMC on 100/144 pins SoCs
|
||||
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
|
||||
TFT_IO tftio;
|
||||
|
||||
#include <libmaple/fsmc.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/dma.h>
|
||||
#include <boards.h>
|
||||
|
||||
/* Timing configuration */
|
||||
#define FSMC_ADDRESS_SETUP_TIME 15// AddressSetupTime
|
||||
#define FSMC_DATA_SETUP_TIME 15// DataSetupTime
|
||||
|
||||
void LCD_IO_Init(uint8_t cs, uint8_t rs);
|
||||
void LCD_IO_WriteData(uint16_t RegValue);
|
||||
void LCD_IO_WriteReg(uint16_t Reg);
|
||||
uint16_t LCD_IO_ReadData(uint16_t RegValue);
|
||||
uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize);
|
||||
uint16_t ILI9488_ReadRAM();
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
void LCD_IO_Init(uint8_t cs, uint8_t rs);
|
||||
void LCD_IO_WriteData(uint16_t RegValue);
|
||||
void LCD_IO_WriteReg(uint16_t Reg);
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
void LCD_IO_WriteMultiple(uint16_t data, uint32_t count);
|
||||
void LCD_IO_WriteSequence(uint16_t *data, uint16_t length);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* FSMC LCD IO
|
||||
*/
|
||||
#define __ASM __asm
|
||||
#define __STATIC_INLINE static inline
|
||||
void LCD_IO_Init(uint8_t cs, uint8_t rs) {
|
||||
tftio.Init();
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __DSB() {__ASM volatile ("dsb 0xF" ::: "memory");}
|
||||
void LCD_IO_WriteData(uint16_t RegValue) {
|
||||
tftio.WriteData(RegValue);
|
||||
}
|
||||
|
||||
#define FSMC_CS_NE1 PD7
|
||||
|
||||
#if ENABLED(STM32_XL_DENSITY)
|
||||
#define FSMC_CS_NE2 PG9
|
||||
#define FSMC_CS_NE3 PG10
|
||||
#define FSMC_CS_NE4 PG12
|
||||
|
||||
#define FSMC_RS_A0 PF0
|
||||
#define FSMC_RS_A1 PF1
|
||||
#define FSMC_RS_A2 PF2
|
||||
#define FSMC_RS_A3 PF3
|
||||
#define FSMC_RS_A4 PF4
|
||||
#define FSMC_RS_A5 PF5
|
||||
#define FSMC_RS_A6 PF12
|
||||
#define FSMC_RS_A7 PF13
|
||||
#define FSMC_RS_A8 PF14
|
||||
#define FSMC_RS_A9 PF15
|
||||
#define FSMC_RS_A10 PG0
|
||||
#define FSMC_RS_A11 PG1
|
||||
#define FSMC_RS_A12 PG2
|
||||
#define FSMC_RS_A13 PG3
|
||||
#define FSMC_RS_A14 PG4
|
||||
#define FSMC_RS_A15 PG5
|
||||
#endif
|
||||
|
||||
#define FSMC_RS_A16 PD11
|
||||
#define FSMC_RS_A17 PD12
|
||||
#define FSMC_RS_A18 PD13
|
||||
#define FSMC_RS_A19 PE3
|
||||
#define FSMC_RS_A20 PE4
|
||||
#define FSMC_RS_A21 PE5
|
||||
#define FSMC_RS_A22 PE6
|
||||
#define FSMC_RS_A23 PE2
|
||||
|
||||
#if ENABLED(STM32_XL_DENSITY)
|
||||
#define FSMC_RS_A24 PG13
|
||||
#define FSMC_RS_A25 PG14
|
||||
#endif
|
||||
|
||||
static uint8_t fsmcInit = 0;
|
||||
|
||||
typedef struct {
|
||||
__IO uint16_t REG;
|
||||
__IO uint16_t RAM;
|
||||
} LCD_CONTROLLER_TypeDef;
|
||||
|
||||
LCD_CONTROLLER_TypeDef *LCD;
|
||||
|
||||
void LCD_IO_Init(uint8_t cs, uint8_t rs) {
|
||||
uint32_t controllerAddress;
|
||||
struct fsmc_nor_psram_reg_map* fsmcPsramRegion;
|
||||
|
||||
if (fsmcInit) return;
|
||||
fsmcInit = 1;
|
||||
|
||||
switch (cs) {
|
||||
case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; fsmcPsramRegion = FSMC_NOR_PSRAM1_BASE; break;
|
||||
#if ENABLED(STM32_XL_DENSITY)
|
||||
case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; fsmcPsramRegion = FSMC_NOR_PSRAM2_BASE; break;
|
||||
case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; fsmcPsramRegion = FSMC_NOR_PSRAM3_BASE; break;
|
||||
case FSMC_CS_NE4: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION4; fsmcPsramRegion = FSMC_NOR_PSRAM4_BASE; break;
|
||||
#endif
|
||||
default: return;
|
||||
}
|
||||
|
||||
#define _ORADDR(N) controllerAddress |= (_BV32(N) - 2)
|
||||
|
||||
switch (rs) {
|
||||
#if ENABLED(STM32_XL_DENSITY)
|
||||
case FSMC_RS_A0: _ORADDR( 1); break;
|
||||
case FSMC_RS_A1: _ORADDR( 2); break;
|
||||
case FSMC_RS_A2: _ORADDR( 3); break;
|
||||
case FSMC_RS_A3: _ORADDR( 4); break;
|
||||
case FSMC_RS_A4: _ORADDR( 5); break;
|
||||
case FSMC_RS_A5: _ORADDR( 6); break;
|
||||
case FSMC_RS_A6: _ORADDR( 7); break;
|
||||
case FSMC_RS_A7: _ORADDR( 8); break;
|
||||
case FSMC_RS_A8: _ORADDR( 9); break;
|
||||
case FSMC_RS_A9: _ORADDR(10); break;
|
||||
case FSMC_RS_A10: _ORADDR(11); break;
|
||||
case FSMC_RS_A11: _ORADDR(12); break;
|
||||
case FSMC_RS_A12: _ORADDR(13); break;
|
||||
case FSMC_RS_A13: _ORADDR(14); break;
|
||||
case FSMC_RS_A14: _ORADDR(15); break;
|
||||
case FSMC_RS_A15: _ORADDR(16); break;
|
||||
#endif
|
||||
case FSMC_RS_A16: _ORADDR(17); break;
|
||||
case FSMC_RS_A17: _ORADDR(18); break;
|
||||
case FSMC_RS_A18: _ORADDR(19); break;
|
||||
case FSMC_RS_A19: _ORADDR(20); break;
|
||||
case FSMC_RS_A20: _ORADDR(21); break;
|
||||
case FSMC_RS_A21: _ORADDR(22); break;
|
||||
case FSMC_RS_A22: _ORADDR(23); break;
|
||||
case FSMC_RS_A23: _ORADDR(24); break;
|
||||
#if ENABLED(STM32_XL_DENSITY)
|
||||
case FSMC_RS_A24: _ORADDR(25); break;
|
||||
case FSMC_RS_A25: _ORADDR(26); break;
|
||||
#endif
|
||||
default: return;
|
||||
}
|
||||
|
||||
rcc_clk_enable(RCC_FSMC);
|
||||
|
||||
gpio_set_mode(GPIOD, 14, GPIO_AF_OUTPUT_PP); // FSMC_D00
|
||||
gpio_set_mode(GPIOD, 15, GPIO_AF_OUTPUT_PP); // FSMC_D01
|
||||
gpio_set_mode(GPIOD, 0, GPIO_AF_OUTPUT_PP);// FSMC_D02
|
||||
gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP);// FSMC_D03
|
||||
gpio_set_mode(GPIOE, 7, GPIO_AF_OUTPUT_PP);// FSMC_D04
|
||||
gpio_set_mode(GPIOE, 8, GPIO_AF_OUTPUT_PP);// FSMC_D05
|
||||
gpio_set_mode(GPIOE, 9, GPIO_AF_OUTPUT_PP);// FSMC_D06
|
||||
gpio_set_mode(GPIOE, 10, GPIO_AF_OUTPUT_PP); // FSMC_D07
|
||||
gpio_set_mode(GPIOE, 11, GPIO_AF_OUTPUT_PP); // FSMC_D08
|
||||
gpio_set_mode(GPIOE, 12, GPIO_AF_OUTPUT_PP); // FSMC_D09
|
||||
gpio_set_mode(GPIOE, 13, GPIO_AF_OUTPUT_PP); // FSMC_D10
|
||||
gpio_set_mode(GPIOE, 14, GPIO_AF_OUTPUT_PP); // FSMC_D11
|
||||
gpio_set_mode(GPIOE, 15, GPIO_AF_OUTPUT_PP); // FSMC_D12
|
||||
gpio_set_mode(GPIOD, 8, GPIO_AF_OUTPUT_PP);// FSMC_D13
|
||||
gpio_set_mode(GPIOD, 9, GPIO_AF_OUTPUT_PP);// FSMC_D14
|
||||
gpio_set_mode(GPIOD, 10, GPIO_AF_OUTPUT_PP); // FSMC_D15
|
||||
|
||||
gpio_set_mode(GPIOD, 4, GPIO_AF_OUTPUT_PP);// FSMC_NOE
|
||||
gpio_set_mode(GPIOD, 5, GPIO_AF_OUTPUT_PP);// FSMC_NWE
|
||||
|
||||
gpio_set_mode(PIN_MAP[cs].gpio_device, PIN_MAP[cs].gpio_bit, GPIO_AF_OUTPUT_PP); //FSMC_CS_NEx
|
||||
gpio_set_mode(PIN_MAP[rs].gpio_device, PIN_MAP[rs].gpio_bit, GPIO_AF_OUTPUT_PP); //FSMC_RS_Ax
|
||||
|
||||
fsmcPsramRegion->BCR = FSMC_BCR_WREN | FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_MBKEN;
|
||||
fsmcPsramRegion->BTR = (FSMC_DATA_SETUP_TIME << 8) | FSMC_ADDRESS_SETUP_TIME;
|
||||
|
||||
afio_remap(AFIO_REMAP_FSMC_NADV);
|
||||
|
||||
LCD = (LCD_CONTROLLER_TypeDef*)controllerAddress;
|
||||
}
|
||||
|
||||
void LCD_IO_WriteData(uint16_t RegValue) {
|
||||
LCD->RAM = RegValue;
|
||||
__DSB();
|
||||
}
|
||||
|
||||
void LCD_IO_WriteReg(uint16_t Reg) {
|
||||
LCD->REG = Reg;
|
||||
__DSB();
|
||||
}
|
||||
|
||||
uint16_t LCD_IO_ReadData(uint16_t RegValue) {
|
||||
LCD->REG = RegValue;
|
||||
__DSB();
|
||||
|
||||
return LCD->RAM;
|
||||
}
|
||||
|
||||
uint16_t ILI9488_ReadRAM() {
|
||||
uint16_t data;
|
||||
data = LCD->RAM;
|
||||
return data;
|
||||
}
|
||||
|
||||
uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize) {
|
||||
volatile uint32_t data;
|
||||
LCD->REG = RegValue;
|
||||
__DSB();
|
||||
|
||||
data = LCD->RAM; // dummy read
|
||||
data = LCD->RAM & 0x00FF;
|
||||
|
||||
while (--ReadSize) {
|
||||
data <<= 8;
|
||||
data |= (LCD->RAM & 0x00FF);
|
||||
}
|
||||
return uint32_t(data);
|
||||
}
|
||||
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
void LCD_IO_WriteReg(uint16_t Reg) {
|
||||
tftio.WriteReg(Reg);
|
||||
}
|
||||
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
void LCD_IO_WriteMultiple(uint16_t color, uint32_t count) {
|
||||
while (count > 0) {
|
||||
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, &color, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM);
|
||||
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, count > 65535 ? 65535 : count);
|
||||
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
|
||||
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}
|
||||
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
|
||||
count = count > 65535 ? count - 65535 : 0;
|
||||
}
|
||||
tftio.WriteMultiple(color, count);
|
||||
}
|
||||
|
||||
void LCD_IO_WriteSequence(uint16_t *data, uint16_t length) {
|
||||
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | DMA_PINC_MODE);
|
||||
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, length);
|
||||
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
|
||||
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}
|
||||
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
tftio.WriteSequence(data, length);
|
||||
}
|
||||
#endif // LCD_USE_DMA_FSMC
|
||||
|
||||
void LCD_IO_WriteSequence_Async(uint16_t *data, uint16_t length) {
|
||||
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | DMA_PINC_MODE);
|
||||
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, length);
|
||||
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
}
|
||||
|
||||
void LCD_IO_WaitSequence_Async() {
|
||||
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}
|
||||
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
}
|
||||
|
||||
#endif // LCD_USE_DMA_FSMC
|
||||
|
||||
#endif // ARDUINO_ARCH_STM32F1 && FSMC_CS_PIN
|
||||
#endif // HAS_TFT_LVGL_UI
|
||||
|
@ -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,13 +120,13 @@ void tft_set_cursor(uint16_t x, uint16_t y) {
|
||||
|
||||
void LCD_WriteRAM_Prepare(void) {
|
||||
#if 0
|
||||
if ((DeviceCode == 0x9325) || (DeviceCode == 0x9328) || (DeviceCode == 0x8989)) {
|
||||
switch (DeviceCode) {
|
||||
case 0x9325: case 0x9328: case 0x8989: {
|
||||
ClrCs
|
||||
LCD->LCD_REG = R34;
|
||||
SetCs
|
||||
}
|
||||
else {
|
||||
LCD_WrtReg(0x002C);
|
||||
} break;
|
||||
default: LCD_WrtReg(0x002C);
|
||||
}
|
||||
#else
|
||||
LCD_IO_WriteReg(0x002C);
|
||||
@ -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.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);
|
||||
}
|
||||
SPI_TFT_CS_L;
|
||||
SPI_TFT_DC_H;
|
||||
SPI.dmaSend(tbuf, width * 2, true);
|
||||
SPI_TFT_CS_H;
|
||||
}
|
||||
|
||||
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)
|
||||
static bool get_point(int16_t *x, int16_t *y) {
|
||||
bool is_touched = touch.getRawPoint(x, y);
|
||||
|
||||
#ifndef USE_XPT2046
|
||||
#define USE_XPT2046 1
|
||||
#define XPT2046_XY_SWAP 1
|
||||
#define XPT2046_X_INV 1
|
||||
#define XPT2046_Y_INV 0
|
||||
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;
|
||||
}
|
||||
|
||||
#if ENABLED(GRAPHICAL_TFT_ROTATE_180)
|
||||
x = (LCD_FULL_PIXEL_WIDTH) - x;
|
||||
y = (LCD_FULL_PIXEL_HEIGHT) - y;
|
||||
#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
|
||||
return is_touched;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
*Y_Addata = (y_addata[times / 2 - 1] + y_addata[times / 2]) / 2;
|
||||
}
|
||||
|
||||
#define ADC_VALID_OFFSET 10
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -164,7 +164,6 @@
|
||||
#define HAS_LANG_SELECT_SCREEN 1
|
||||
#define HAS_BAK_VIEW_IN_FLASH 0
|
||||
#define HAS_LOGO_IN_FLASH 0
|
||||
#define HAS_TOUCH_XPT2046 1
|
||||
|
||||
#define TOUCH_CS_PIN PB7 // SPI1_NSS
|
||||
#define TOUCH_SCK_PIN PA5 // SPI1_SCK
|
||||
@ -183,6 +182,8 @@
|
||||
|
||||
#define LCD_RESET_PIN PF11
|
||||
#define LCD_BACKLIGHT_PIN PD13
|
||||
#define TFT_RESET_PIN PF11
|
||||
#define TFT_BACKLIGHT_PIN PD13
|
||||
|
||||
#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT
|
||||
#define FSMC_CS_PIN PD7
|
||||
@ -197,24 +198,10 @@
|
||||
#define LCD_PIXEL_OFFSET_X 48
|
||||
#define LCD_PIXEL_OFFSET_Y 48
|
||||
|
||||
#define XPT2046_X_CALIBRATION -12316
|
||||
#define XPT2046_Y_CALIBRATION 8981
|
||||
#define XPT2046_X_OFFSET 340
|
||||
#define XPT2046_Y_OFFSET -20
|
||||
|
||||
#define USE_XPT2046 1
|
||||
#define XPT2046_XY_SWAP 0
|
||||
#define XPT2046_X_INV 1
|
||||
#define XPT2046_Y_INV 0
|
||||
|
||||
#define XPT2046_HOR_RES 480
|
||||
#define XPT2046_VER_RES 320
|
||||
#define XPT2046_X_MIN 140
|
||||
#define XPT2046_Y_MIN 200
|
||||
#define XPT2046_X_MAX 1900
|
||||
#define XPT2046_Y_MAX 1900
|
||||
#define XPT2046_AVG 4
|
||||
#define XPT2046_INV 0
|
||||
#define XPT2046_X_CALIBRATION -17181
|
||||
#define XPT2046_Y_CALIBRATION 11434
|
||||
#define XPT2046_X_OFFSET 501
|
||||
#define XPT2046_Y_OFFSET -9
|
||||
|
||||
#elif ENABLED(TFT_480x320)
|
||||
#define TFT_RESET_PIN PF11
|
||||
|
@ -198,7 +198,6 @@
|
||||
#define HAS_LANG_SELECT_SCREEN 0
|
||||
#define HAS_BAK_VIEW_IN_FLASH 0
|
||||
#define HAS_LOGO_IN_FLASH 0
|
||||
#define HAS_TOUCH_XPT2046 1
|
||||
|
||||
#define TOUCH_CS_PIN PB7 // SPI1_NSS
|
||||
#define TOUCH_SCK_PIN PA5 // SPI1_SCK
|
||||
@ -217,6 +216,8 @@
|
||||
|
||||
#define LCD_RESET_PIN PF11
|
||||
#define LCD_BACKLIGHT_PIN PD13
|
||||
#define TFT_RESET_PIN PF11
|
||||
#define TFT_BACKLIGHT_PIN PD13
|
||||
|
||||
#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT
|
||||
#define FSMC_CS_PIN PD7
|
||||
@ -231,24 +232,10 @@
|
||||
#define LCD_PIXEL_OFFSET_X 48
|
||||
#define LCD_PIXEL_OFFSET_Y 48
|
||||
|
||||
#define XPT2046_X_CALIBRATION -12316
|
||||
#define XPT2046_Y_CALIBRATION 8981
|
||||
#define XPT2046_X_OFFSET 340
|
||||
#define XPT2046_Y_OFFSET -20
|
||||
|
||||
#define USE_XPT2046 1
|
||||
#define XPT2046_XY_SWAP 0
|
||||
#define XPT2046_X_INV 1
|
||||
#define XPT2046_Y_INV 0
|
||||
|
||||
#define XPT2046_HOR_RES 480
|
||||
#define XPT2046_VER_RES 320
|
||||
#define XPT2046_X_MIN 140
|
||||
#define XPT2046_Y_MIN 200
|
||||
#define XPT2046_X_MAX 1900
|
||||
#define XPT2046_Y_MAX 1900
|
||||
#define XPT2046_AVG 4
|
||||
#define XPT2046_INV 0
|
||||
#define XPT2046_X_CALIBRATION -17181
|
||||
#define XPT2046_Y_CALIBRATION 11434
|
||||
#define XPT2046_X_OFFSET 501
|
||||
#define XPT2046_Y_OFFSET -9
|
||||
#endif
|
||||
|
||||
// SPI1(PA7)=LCD & SPI3(PB5)=STUFF, are not available
|
||||
|
@ -177,6 +177,17 @@
|
||||
|
||||
#define LCD_BACKLIGHT_PIN PD13
|
||||
|
||||
#define XPT2046_X_CALIBRATION 17880
|
||||
#define XPT2046_Y_CALIBRATION -12234
|
||||
#define XPT2046_X_OFFSET -45
|
||||
#define XPT2046_Y_OFFSET 349
|
||||
|
||||
#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT
|
||||
#define FSMC_CS_PIN PD7
|
||||
#define FSMC_RS_PIN PD11
|
||||
#define FSMC_DMA_DEV DMA2
|
||||
#define FSMC_DMA_CHANNEL DMA_CH5
|
||||
|
||||
#elif ENABLED(FSMC_GRAPHICAL_TFT)
|
||||
|
||||
#define DOGLCD_MOSI -1 // prevent redefine Conditionals_post.h
|
||||
|
@ -261,17 +261,30 @@
|
||||
#define BTN_EN2 PE11
|
||||
#define BTN_ENC PE13
|
||||
|
||||
#elif ENABLED(TFT_LITTLE_VGL_UI)
|
||||
#define TFT_CS_PIN PD11
|
||||
#define TFT_SCK_PIN PA5
|
||||
#define TFT_MISO_PIN PA6
|
||||
#define TFT_MOSI_PIN PA7
|
||||
#define TFT_DC_PIN PD10
|
||||
#define TFT_RST_PIN PC6
|
||||
#define TFT_A0_PIN TFT_DC_PIN
|
||||
|
||||
#define FSMC_CS_PIN PD7 // NE4
|
||||
#define FSMC_RS_PIN PD11 // A0
|
||||
#define TFT_RESET_PIN PC6
|
||||
#define TFT_BACKLIGHT_PIN PD13
|
||||
|
||||
#define TOUCH_CS_PIN PA7 // SPI2_NSS
|
||||
#define TOUCH_SCK_PIN PB13 // SPI2_SCK
|
||||
#define TOUCH_MISO_PIN PB14 // SPI2_MISO
|
||||
#define TOUCH_MOSI_PIN PB15 // SPI2_MOSI
|
||||
#define XPT2046_X_CALIBRATION -17253
|
||||
#define XPT2046_Y_CALIBRATION 11579
|
||||
#define XPT2046_X_OFFSET 514
|
||||
#define XPT2046_Y_OFFSET -24
|
||||
#define TOUCH_BUTTONS_HW_SPI
|
||||
#define TOUCH_BUTTONS_HW_SPI_DEVICE 1
|
||||
|
||||
#define LCD_BACKLIGHT_PIN PD13
|
||||
#ifndef LCD_FULL_PIXEL_WIDTH
|
||||
#define LCD_FULL_PIXEL_WIDTH 480
|
||||
#endif
|
||||
#ifndef LCD_FULL_PIXEL_HEIGHT
|
||||
#define LCD_FULL_PIXEL_HEIGHT 320
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user