Optimize LVGL with HAL TFT IO (SPI and FSMC) (#18974)
This commit is contained in:
		| @@ -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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user