Skip to content

Commit

Permalink
Optimize LVGL with HAL TFT IO (SPI and FSMC) (MarlinFirmware#18974)
Browse files Browse the repository at this point in the history
  • Loading branch information
rhapsodyv authored and Speaka committed Aug 28, 2020
1 parent 4e24056 commit 0831b9c
Show file tree
Hide file tree
Showing 16 changed files with 191 additions and 785 deletions.
18 changes: 10 additions & 8 deletions Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -224,13 +224,15 @@ void TFT_FSMC::Abort() {
}

void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
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);
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);
#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);
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);
#endif
}

#endif // HAS_FSMC_TFT
7 changes: 7 additions & 0 deletions Marlin/src/HAL/STM32F1/tft/tft_fsmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
};
15 changes: 10 additions & 5 deletions Marlin/src/HAL/STM32F1/tft/tft_spi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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
}

Expand Down
7 changes: 7 additions & 0 deletions Marlin/src/HAL/STM32F1/tft/tft_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,11 @@ class TFT_SPI {

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;
}
}
};
2 changes: 1 addition & 1 deletion Marlin/src/inc/Conditionals_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
186 changes: 23 additions & 163 deletions Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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() {
Expand All @@ -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);
Expand Down Expand Up @@ -251,88 +172,27 @@ 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;
delay(2000);
}

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;
}
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);
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);
}
}

#endif // HAS_TFT_LVGL_UI_SPI
20 changes: 7 additions & 13 deletions Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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();
};

Expand Down
2 changes: 2 additions & 0 deletions Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 0831b9c

Please sign in to comment.