SPI Emulated DOGM (like FSMC_GRAPHICAL_TFT, but SPI) (#18817)
This commit is contained in:
committed by
Scott Lahteine
parent
0c1bf01cf7
commit
fc12ffcb30
@ -87,6 +87,11 @@
|
||||
#define U8G_COM_HAL_FSMC_FN u8g_com_stm32duino_fsmc_fn
|
||||
#endif
|
||||
|
||||
#if ENABLED(SPI_GRAPHICAL_TFT)
|
||||
uint8_t u8g_com_stm32duino_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
#define U8G_COM_HAL_FSMC_FN u8g_com_stm32duino_spi_fn
|
||||
#endif
|
||||
|
||||
#elif defined(TARGET_LPC1768)
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
|
@ -57,14 +57,21 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_GRAPHICAL_LCD && PIN_EXISTS(FSMC_CS)
|
||||
#if HAS_GRAPHICAL_LCD && (PIN_EXISTS(FSMC_CS) || ENABLED(SPI_GRAPHICAL_TFT))
|
||||
|
||||
#include "HAL_LCD_com_defines.h"
|
||||
#include "ultralcd_DOGM.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
#if EITHER(LCD_USE_DMA_FSMC, LCD_USE_DMA_SPI)
|
||||
#define HAS_LCD_IO 1
|
||||
#endif
|
||||
|
||||
#if HAS_LCD_IO
|
||||
extern void LCD_IO_Init(uint8_t cs, uint8_t rs);
|
||||
extern uint16_t LCD_IO_ReadData(uint16_t Reg);
|
||||
extern uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize);
|
||||
extern void LCD_IO_WriteReg(uint16_t Reg);
|
||||
extern void LCD_IO_WriteData(uint16_t RegValue);
|
||||
extern void LCD_IO_WriteSequence(uint16_t *data, uint16_t length);
|
||||
@ -148,46 +155,34 @@ static uint32_t lcd_id = 0;
|
||||
|
||||
|
||||
static void setWindow_ili9328(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
LCD_IO_WriteReg(ILI9328_HASTART);
|
||||
LCD_IO_WriteData(Ymin);
|
||||
LCD_IO_WriteReg(ILI9328_HAEND);
|
||||
LCD_IO_WriteData(Ymax);
|
||||
LCD_IO_WriteReg(ILI9328_VASTART);
|
||||
LCD_IO_WriteData(Xmin);
|
||||
LCD_IO_WriteReg(ILI9328_VAEND);
|
||||
LCD_IO_WriteData(Xmax);
|
||||
#if HAS_LCD_IO
|
||||
#define IO_REG_DATA(R,D) do { LCD_IO_WriteReg(R); LCD_IO_WriteData(D); }while(0)
|
||||
#else
|
||||
#define IO_REG_DATA(R,D) do { u8g_WriteByte(u8g, dev, R); u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&D); }while(0)
|
||||
#endif
|
||||
|
||||
LCD_IO_WriteReg(ILI9328_HASET);
|
||||
LCD_IO_WriteData(Ymin);
|
||||
LCD_IO_WriteReg(ILI9328_VASET);
|
||||
LCD_IO_WriteData(Xmin);
|
||||
#if NONE(LCD_USE_DMA_FSMC, LCD_USE_DMA_SPI)
|
||||
u8g_SetAddress(u8g, dev, 0);
|
||||
#endif
|
||||
|
||||
IO_REG_DATA(ILI9328_HASTART, Ymin);
|
||||
IO_REG_DATA(ILI9328_HAEND, Ymax);
|
||||
IO_REG_DATA(ILI9328_VASTART, Xmin);
|
||||
IO_REG_DATA(ILI9328_VAEND, Xmax);
|
||||
|
||||
IO_REG_DATA(ILI9328_HASET, Ymin);
|
||||
IO_REG_DATA(ILI9328_VASET, Xmin);
|
||||
|
||||
#if HAS_LCD_IO
|
||||
LCD_IO_WriteReg(ILI9328_WRITE_RAM);
|
||||
#else
|
||||
u8g_SetAddress(u8g, dev, 0);
|
||||
|
||||
u8g_WriteByte(u8g, dev, ILI9328_HASTART);
|
||||
u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin);
|
||||
u8g_WriteByte(u8g, dev, ILI9328_HAEND);
|
||||
u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymax);
|
||||
u8g_WriteByte(u8g, dev, ILI9328_VASTART);
|
||||
u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin);
|
||||
u8g_WriteByte(u8g, dev, ILI9328_VAEND);
|
||||
u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmax);
|
||||
|
||||
u8g_WriteByte(u8g, dev, ILI9328_HASET);
|
||||
u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin);
|
||||
u8g_WriteByte(u8g, dev, ILI9328_VASET);
|
||||
u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin);
|
||||
|
||||
u8g_WriteByte(u8g, dev, ILI9328_WRITE_RAM);
|
||||
u8g_SetAddress(u8g, dev, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void setWindow_st7789v(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
#if HAS_LCD_IO
|
||||
LCD_IO_WriteReg(ST7789V_CASET);
|
||||
LCD_IO_WriteData((Xmin >> 8) & 0xFF);
|
||||
LCD_IO_WriteData(Xmin & 0xFF);
|
||||
@ -227,7 +222,7 @@ void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint
|
||||
#define ESC_END 0xFFFF, 0x7FFF
|
||||
#define ESC_FFFF 0xFFFF, 0xFFFF
|
||||
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
#if HAS_LCD_IO
|
||||
void writeEscSequence(const uint16_t *sequence) {
|
||||
uint16_t data;
|
||||
for (;;) {
|
||||
@ -247,6 +242,7 @@ void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint
|
||||
}
|
||||
}
|
||||
}
|
||||
#define WRITE_ESC_SEQUENCE(V) writeEscSequence(V)
|
||||
#else
|
||||
void writeEscSequence8(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
|
||||
uint16_t data;
|
||||
@ -271,6 +267,8 @@ void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint
|
||||
}
|
||||
}
|
||||
|
||||
#define WRITE_ESC_SEQUENCE(V) writeEscSequence8(u8g, dev, V)
|
||||
|
||||
void writeEscSequence16(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
|
||||
uint16_t data;
|
||||
u8g_SetAddress(u8g, dev, 0);
|
||||
@ -381,6 +379,30 @@ static const uint16_t ili9341_init[] = {
|
||||
ESC_END
|
||||
};
|
||||
|
||||
static const uint16_t st9677_init[] = {
|
||||
ESC_REG(0x0010), ESC_DELAY(120),
|
||||
ESC_REG(0x0001), ESC_DELAY(120),
|
||||
ESC_REG(0x0011), ESC_DELAY(120),
|
||||
ESC_REG(0x00F0), 0x00C3,
|
||||
ESC_REG(0x00F0), 0x0096,
|
||||
ESC_REG(0x0036), TERN(GRAPHICAL_TFT_ROTATE_180, 0x00E8, 0x0028),
|
||||
ESC_REG(0x003A), 0x0055,
|
||||
ESC_REG(0x00B4), 0x0001,
|
||||
ESC_REG(0x00B7), 0x00C6,
|
||||
ESC_REG(0x00E8), 0x0040, 0x008A, 0x0000, 0x0000, 0x0029, 0x0019, 0x00A5, 0x0033,
|
||||
ESC_REG(0x00C1), 0x0006,
|
||||
ESC_REG(0x00C2), 0x00A7,
|
||||
ESC_REG(0x00C5), 0x0018,
|
||||
ESC_REG(0x00E0), 0x00F0, 0x0009, 0x000B, 0x0006, 0x0004, 0x0015, 0x002F, 0x0054, 0x0042, 0x003C, 0x0017, 0x0014, 0x0018, 0x001B,
|
||||
ESC_REG(0x00E1), 0x00F0, 0x0009, 0x000B, 0x0006, 0x0004, 0x0003, 0x002D, 0x0043, 0x0042, 0x003B, 0x0016, 0x0014, 0x0017, 0x001B,
|
||||
ESC_REG(0x00F0), 0x003C,
|
||||
ESC_REG(0x00F0), 0x0069, ESC_DELAY(120),
|
||||
ESC_REG(0x0029),
|
||||
ESC_REG(0x0011),
|
||||
ESC_DELAY(100),
|
||||
ESC_END
|
||||
};
|
||||
|
||||
#if ENABLED(TOUCH_BUTTONS)
|
||||
|
||||
static const uint8_t buttonD[] = {
|
||||
@ -560,7 +582,7 @@ static const uint16_t ili9341_init[] = {
|
||||
v = TFT_MARLINBG_COLOR;
|
||||
LOOP_L_N(n, FSMC_UPSCALE) buffer[k++] = v;
|
||||
}
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
#if HAS_LCD_IO
|
||||
LOOP_S_L_N(n, 1, FSMC_UPSCALE)
|
||||
for (uint16_t l = 0; l < length * (FSMC_UPSCALE); l++)
|
||||
buffer[l + (length * (FSMC_UPSCALE) * n)] = buffer[l];
|
||||
@ -586,41 +608,39 @@ static uint8_t page;
|
||||
|
||||
uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) {
|
||||
u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
|
||||
#if ENABLED(SPI_GRAPHICAL_TFT)
|
||||
LCD_IO_Init(-1, -1);
|
||||
#endif
|
||||
|
||||
#if HAS_LCD_IO
|
||||
static uint16_t bufferA[WIDTH * sq(FSMC_UPSCALE)], bufferB[WIDTH * sq(FSMC_UPSCALE)];
|
||||
uint16_t* buffer = &bufferA[0];
|
||||
bool allow_async = true;
|
||||
bool allow_async = DISABLED(SPI_GRAPHICAL_TFT);
|
||||
#else
|
||||
uint16_t buffer[WIDTH*2]; // 16-bit RGB 565 pixel line buffer
|
||||
#endif
|
||||
|
||||
switch (msg) {
|
||||
case U8G_DEV_MSG_INIT:
|
||||
dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, &lcd_id);
|
||||
|
||||
switch (lcd_id & 0xFFFF) {
|
||||
case 0x8552: // ST7789V
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
writeEscSequence(st7789v_init);
|
||||
#else
|
||||
writeEscSequence8(u8g, dev, st7789v_init);
|
||||
#endif
|
||||
WRITE_ESC_SEQUENCE(st7789v_init);
|
||||
setWindow = setWindow_st7789v;
|
||||
break;
|
||||
case 0x9328: // ILI9328
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
writeEscSequence(ili9328_init);
|
||||
#else
|
||||
writeEscSequence16(u8g, dev, ili9328_init);
|
||||
#endif
|
||||
WRITE_ESC_SEQUENCE(ili9328_init);
|
||||
setWindow = setWindow_ili9328;
|
||||
break;
|
||||
case 0x9341: // ILI9341
|
||||
case 0x8066: // Anycubic / TronXY TFTs (480x320)
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
writeEscSequence(ili9341_init);
|
||||
#else
|
||||
writeEscSequence8(u8g, dev, ili9341_init);
|
||||
#endif
|
||||
WRITE_ESC_SEQUENCE(ili9341_init);
|
||||
setWindow = setWindow_st7789v;
|
||||
break;
|
||||
case 0x7796:
|
||||
WRITE_ESC_SEQUENCE(TERN(HAS_LCD_IO, st9677_init, ili9341_init));
|
||||
setWindow = setWindow_st7789v;
|
||||
break;
|
||||
case 0x0404: // No connected display on FSMC
|
||||
@ -630,10 +650,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
|
||||
lcd_id = 0;
|
||||
return 0;
|
||||
default:
|
||||
if (lcd_id && 0xFF000000)
|
||||
setWindow = setWindow_st7789v;
|
||||
else
|
||||
setWindow = setWindow_ili9328;
|
||||
setWindow = (lcd_id & 0xFF000000) ? setWindow_st7789v : setWindow_ili9328;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -644,7 +661,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
|
||||
|
||||
// Clear Screen
|
||||
setWindow(u8g, dev, 0, 0, LCD_FULL_PIXEL_WIDTH - 1, LCD_FULL_PIXEL_HEIGHT - 1);
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
#if HAS_LCD_IO
|
||||
LCD_IO_WriteMultiple(TFT_MARLINBG_COLOR, LCD_FULL_PIXEL_WIDTH * LCD_FULL_PIXEL_HEIGHT);
|
||||
#else
|
||||
memset2(buffer, TFT_MARLINBG_COLOR, 160);
|
||||
@ -681,7 +698,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
|
||||
|
||||
LOOP_L_N(y, PAGE_HEIGHT) {
|
||||
uint32_t k = 0;
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
#if HAS_LCD_IO
|
||||
buffer = (y & 1) ? bufferB : bufferA;
|
||||
#endif
|
||||
for (uint16_t i = 0; i < (uint32_t)pb->width; i++) {
|
||||
@ -689,7 +706,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
|
||||
const uint16_t c = TEST(b, y) ? TFT_MARLINUI_COLOR : TFT_MARLINBG_COLOR;
|
||||
LOOP_L_N(n, FSMC_UPSCALE) buffer[k++] = c;
|
||||
}
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
#if HAS_LCD_IO
|
||||
LOOP_S_L_N(n, 1, FSMC_UPSCALE)
|
||||
for (uint16_t l = 0; l < WIDTH * (FSMC_UPSCALE); l++)
|
||||
buffer[l + WIDTH * (FSMC_UPSCALE) * n] = buffer[l];
|
||||
|
@ -182,12 +182,16 @@
|
||||
#define U8G_CLASS U8GLIB_SH1106_128X64
|
||||
#define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, LCD_PINS_DC, LCD_PINS_RS
|
||||
|
||||
#elif ENABLED(FSMC_GRAPHICAL_TFT)
|
||||
#elif TFT_SCALED_DOGLCD
|
||||
|
||||
// Unspecified 320x240 TFT pre-initialized by built-in bootloader
|
||||
|
||||
#define U8G_CLASS U8GLIB_TFT_320X240_UPSCALE_FROM_128X64
|
||||
#define U8G_PARAM FSMC_CS_PIN, FSMC_RS_PIN
|
||||
#if ENABLED(FSMC_GRAPHICAL_TFT)
|
||||
#define U8G_PARAM FSMC_CS_PIN, FSMC_RS_PIN
|
||||
#else
|
||||
#define U8G_PARAM -1, -1
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
@ -210,18 +214,18 @@
|
||||
|
||||
// LCD_FULL_PIXEL_WIDTH =
|
||||
// LCD_PIXEL_OFFSET_X + (LCD_PIXEL_WIDTH * 2) + LCD_PIXEL_OFFSET_X
|
||||
#if ENABLED(FSMC_GRAPHICAL_TFT)
|
||||
#if TFT_SCALED_DOGLCD
|
||||
#ifndef LCD_FULL_PIXEL_WIDTH
|
||||
#define LCD_FULL_PIXEL_WIDTH 320
|
||||
#endif
|
||||
#ifndef LCD_PIXEL_OFFSET_X
|
||||
#define LCD_PIXEL_OFFSET_X 32
|
||||
#define LCD_PIXEL_OFFSET_X 32
|
||||
#endif
|
||||
#ifndef LCD_FULL_PIXEL_HEIGHT
|
||||
#define LCD_FULL_PIXEL_HEIGHT 240
|
||||
#endif
|
||||
#ifndef LCD_PIXEL_OFFSET_Y
|
||||
#define LCD_PIXEL_OFFSET_Y 32
|
||||
#define LCD_PIXEL_OFFSET_Y 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user