Marlin Color UI for STM32F1 (SPI) (#18958)
This commit is contained in:
		| @@ -26,12 +26,8 @@ | ||||
|   #undef SD_CHECK_AND_RETRY | ||||
| #endif | ||||
|  | ||||
| #if HAS_SPI_TFT | ||||
|   #error "Sorry! SPI TFT displays are not available for HAL/STM32F1 (yet)." | ||||
| #endif | ||||
|  | ||||
| // This platform has 'touch/xpt2046', not 'tft/xpt2046' | ||||
| #if ENABLED(TOUCH_SCREEN) && !HAS_FSMC_TFT | ||||
| #if ENABLED(TOUCH_SCREEN) && !HAS_FSMC_TFT && !HAS_SPI_TFT | ||||
|   #undef TOUCH_SCREEN | ||||
|   #undef TOUCH_SCREEN_CALIBRATION | ||||
|   #define HAS_TOUCH_XPT2046 1 | ||||
|   | ||||
							
								
								
									
										144
									
								
								Marlin/src/HAL/STM32F1/tft/tft_spi.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								Marlin/src/HAL/STM32F1/tft/tft_spi.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "../../../inc/MarlinConfig.h" | ||||
|  | ||||
| #if HAS_SPI_TFT | ||||
|  | ||||
| #include "tft_spi.h" | ||||
|  | ||||
| // TFT_SPI tft; | ||||
|  | ||||
| SPIClass TFT_SPI::SPIx(1); | ||||
|  | ||||
| #define SPI_TFT_CS_H  OUT_WRITE(TFT_CS_PIN, HIGH) | ||||
| #define SPI_TFT_CS_L  OUT_WRITE(TFT_CS_PIN, LOW) | ||||
|  | ||||
| #define SPI_TFT_DC_H  OUT_WRITE(TFT_DC_PIN, HIGH) | ||||
| #define SPI_TFT_DC_L  OUT_WRITE(TFT_DC_PIN, LOW) | ||||
|  | ||||
| #define SPI_TFT_RST_H OUT_WRITE(TFT_RST_PIN, HIGH) | ||||
| #define SPI_TFT_RST_L OUT_WRITE(TFT_RST_PIN, LOW) | ||||
|  | ||||
| #define SPI_TFT_BLK_H OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH) | ||||
| #define SPI_TFT_BLK_L OUT_WRITE(TFT_BACKLIGHT_PIN, LOW) | ||||
|  | ||||
| void TFT_SPI::Init() { | ||||
|   #if PIN_EXISTS(TFT_RESET) | ||||
|     // OUT_WRITE(TFT_RESET_PIN, HIGH); | ||||
|     SPI_TFT_RST_H; | ||||
|     delay(100); | ||||
|   #endif | ||||
|  | ||||
|   #if PIN_EXISTS(TFT_BACKLIGHT) | ||||
|     // OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); | ||||
|     SPI_TFT_BLK_H; | ||||
|   #endif | ||||
|  | ||||
|   SPI_TFT_DC_H; | ||||
|   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 | ||||
|    */ | ||||
|   #if SPI_DEVICE == 1 | ||||
|     #define SPI_CLOCK_MAX SPI_CLOCK_DIV4 | ||||
|   #else | ||||
|     #define SPI_CLOCK_MAX SPI_CLOCK_DIV2 | ||||
|   #endif | ||||
|   uint8_t  clock; | ||||
|   uint8_t spiRate = SPI_FULL_SPEED; | ||||
|   switch (spiRate) { | ||||
|     case SPI_FULL_SPEED:    clock = SPI_CLOCK_MAX ;  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 | ||||
|   } | ||||
|   SPIx.setModule(1); | ||||
|   SPIx.setClockDivider(clock); | ||||
|   SPIx.setBitOrder(MSBFIRST); | ||||
|   SPIx.setDataMode(SPI_MODE0); | ||||
| } | ||||
|  | ||||
| void TFT_SPI::DataTransferBegin(uint16_t DataSize) { | ||||
|   SPIx.setDataSize(DataSize); | ||||
|   SPIx.begin(); | ||||
|   SPI_TFT_CS_L; | ||||
| } | ||||
|  | ||||
| uint32_t TFT_SPI::GetID() { | ||||
|   uint32_t id; | ||||
|   id = ReadID(LCD_READ_ID); | ||||
|  | ||||
|   if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) | ||||
|     id = ReadID(LCD_READ_ID4); | ||||
|   return id; | ||||
| } | ||||
|  | ||||
| uint32_t TFT_SPI::ReadID(uint16_t Reg) { | ||||
|   #if !PIN_EXISTS(TFT_MISO) | ||||
|     return 0; | ||||
|   #else | ||||
|     uint16_t d = 0; | ||||
|     DataTransferBegin(DATASIZE_8BIT); | ||||
|     WriteReg(Reg); | ||||
|  | ||||
|     SPI.read((uint8_t*)&d, 1); //dummy read | ||||
|     SPI.read((uint8_t*)&d, 1); | ||||
|  | ||||
|     DataTransferEnd(); | ||||
|  | ||||
|     return d >> 7; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| bool TFT_SPI::isBusy() { | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| void TFT_SPI::Abort() { | ||||
|   DataTransferEnd(); | ||||
| } | ||||
|  | ||||
| void TFT_SPI::Transmit(uint16_t Data) { | ||||
|   SPIx.send(Data); | ||||
| } | ||||
|  | ||||
| void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { | ||||
|   DataTransferBegin(); | ||||
|   SPI_TFT_DC_H; | ||||
|   if (MemoryIncrease == DMA_MINC_ENABLE) { | ||||
|     SPIx.dmaSend(Data, Count, true); | ||||
|   } | ||||
|   else { | ||||
|     SPIx.dmaSend(Data, Count, false); | ||||
|   } | ||||
|  | ||||
|   DataTransferEnd(); | ||||
| } | ||||
|  | ||||
| #endif // HAS_SPI_TFT | ||||
							
								
								
									
										65
									
								
								Marlin/src/HAL/STM32F1/tft/tft_spi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								Marlin/src/HAL/STM32F1/tft/tft_spi.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| #include "../../../inc/MarlinConfig.h" | ||||
|  | ||||
| #include <SPI.h> | ||||
|  | ||||
| #ifndef LCD_READ_ID | ||||
|   #define LCD_READ_ID 0x04   // Read display identification information (0xD3 on ILI9341) | ||||
| #endif | ||||
| #ifndef LCD_READ_ID4 | ||||
|   #define LCD_READ_ID4 0xD3   // Read display identification information (0xD3 on ILI9341) | ||||
| #endif | ||||
|  | ||||
| #define DATASIZE_8BIT    DATA_SIZE_8BIT | ||||
| #define DATASIZE_16BIT   DATA_SIZE_16BIT | ||||
| #define TFT_IO TFT_SPI | ||||
|  | ||||
| #define DMA_MINC_ENABLE 1 | ||||
| #define DMA_MINC_DISABLE 0 | ||||
|  | ||||
| class TFT_SPI { | ||||
| private: | ||||
|   static uint32_t ReadID(uint16_t Reg); | ||||
|   static void Transmit(uint16_t Data); | ||||
|   static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); | ||||
|  | ||||
| public: | ||||
|   static SPIClass SPIx; | ||||
|  | ||||
|   static void Init(); | ||||
|   static uint32_t GetID(); | ||||
|   static bool isBusy(); | ||||
|   static void Abort(); | ||||
|  | ||||
|   static void DataTransferBegin(uint16_t DataWidth = DATA_SIZE_16BIT); | ||||
|   static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); SPIx.end(); }; | ||||
|   static void DataTransferAbort(); | ||||
|  | ||||
|   static void WriteData(uint16_t Data) { Transmit(Data); } | ||||
|   static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); } | ||||
|  | ||||
|   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); } | ||||
| }; | ||||
| @@ -65,9 +65,7 @@ void XPT2046::Init() { | ||||
|     SET_INPUT(TOUCH_INT_PIN); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(TOUCH_BUTTONS_HW_SPI) | ||||
|     touch_spi_init(SPI_SPEED_6); | ||||
|   #endif | ||||
|   TERN_(TOUCH_BUTTONS_HW_SPI, touch_spi_init(SPI_SPEED_6)); | ||||
|  | ||||
|   // Read once to enable pendrive status pin | ||||
|   getRawData(XPT2046_X); | ||||
| @@ -95,12 +93,14 @@ uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { | ||||
|   uint16_t data[3]; | ||||
|  | ||||
|   DataTransferBegin(); | ||||
|   TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.begin()); | ||||
|  | ||||
|   for (uint16_t i = 0; i < 3 ; i++) { | ||||
|     IO(coordinate); | ||||
|     data[i] = (IO() << 4) | (IO() >> 4); | ||||
|   } | ||||
|  | ||||
|   TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.end()); | ||||
|   DataTransferEnd(); | ||||
|  | ||||
|   uint16_t delta01 = delta(data[0], data[1]), | ||||
| @@ -114,14 +114,12 @@ uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { | ||||
| } | ||||
|  | ||||
| uint16_t XPT2046::IO(uint16_t data) { | ||||
|   TERN(TOUCH_BUTTONS_HW_SPI, HardwareIO, SoftwareIO)(data); | ||||
|   return TERN(TOUCH_BUTTONS_HW_SPI, HardwareIO, SoftwareIO)(data); | ||||
| } | ||||
|  | ||||
| #if ENABLED(TOUCH_BUTTONS_HW_SPI) | ||||
|   uint16_t XPT2046::HardwareIO(uint16_t data) { | ||||
|     SPIx.begin(); | ||||
|     uint16_t result = SPIx.transfer(data); | ||||
|     SPIx.end(); | ||||
|     return result; | ||||
|   } | ||||
| #endif | ||||
|   | ||||
| @@ -39,7 +39,9 @@ | ||||
| #define ILI9488_ORIENTATION_DOWN  ILI9488_MADCTL_MX                                         // 320x480 ; Cable on the upper side | ||||
|  | ||||
| #define ILI9488_COLOR_BGR | ||||
| #define ILI9488_ORIENTATION       ILI9488_ORIENTATION_LEFT | ||||
| #ifndef ILI9488_ORIENTATION | ||||
|   #define ILI9488_ORIENTATION     ILI9488_ORIENTATION_LEFT | ||||
| #endif | ||||
| #define ILI9488_MADCTL_DATA       (ILI9488_ORIENTATION | TERN(ILI9488_COLOR_BGR, ILI9488_MADCTL_BGR, ILI9488_MADCTL_RGB)) | ||||
|  | ||||
| #define ILI9488_NOP               0x00 // No Operation | ||||
|   | ||||
| @@ -225,10 +225,10 @@ | ||||
|   #define FSMC_DMA_DEV                      DMA2 | ||||
|   #define FSMC_DMA_CHANNEL               DMA_CH5 | ||||
|  | ||||
|   #define XPT2046_X_CALIBRATION           -17181 | ||||
|   #define XPT2046_Y_CALIBRATION            11434 | ||||
|   #define XPT2046_X_OFFSET                   501 | ||||
|   #define XPT2046_Y_OFFSET                    -9 | ||||
|   #define XPT2046_X_CALIBRATION            17880 | ||||
|   #define XPT2046_Y_CALIBRATION           -12234 | ||||
|   #define XPT2046_X_OFFSET                   -45 | ||||
|   #define XPT2046_Y_OFFSET                   349 | ||||
|  | ||||
|   #define TOUCH_CS_PIN                      PA7   // SPI2_NSS | ||||
|   #define TOUCH_SCK_PIN                     PB13   // SPI2_SCK | ||||
| @@ -237,6 +237,7 @@ | ||||
|  | ||||
|   #define TFT_DRIVER                        ILI9488 | ||||
|   #define TFT_BUFFER_SIZE                   14400 | ||||
|   #define ILI9488_ORIENTATION               ILI9488_MADCTL_MX | ILI9488_MADCTL_MV | ||||
| #endif | ||||
|  | ||||
| #define SPI_FLASH | ||||
|   | ||||
| @@ -344,6 +344,37 @@ | ||||
|     #define MKS_LCD12864B | ||||
|     #undef SHOW_BOOTSCREEN | ||||
|  | ||||
|   #elif ENABLED(TFT_480x320_SPI) | ||||
|     #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 TFT_RESET_PIN                   PC6 | ||||
|     #define TFT_BACKLIGHT_PIN               PD13 | ||||
|  | ||||
|     #define XPT2046_X_CALIBRATION         -17253 | ||||
|     #define XPT2046_Y_CALIBRATION          11579 | ||||
|     #define XPT2046_X_OFFSET                 514 | ||||
|     #define XPT2046_Y_OFFSET                 -24 | ||||
|  | ||||
|     #define TOUCH_CS_PIN                    PE14  // SPI1_NSS | ||||
|     #define TOUCH_SCK_PIN                   PA5   // SPI1_SCK | ||||
|     #define TOUCH_MISO_PIN                  PA6   // SPI1_MISO | ||||
|     #define TOUCH_MOSI_PIN                  PA7   // SPI1_MOSI | ||||
|  | ||||
|     #define TFT_DRIVER                    ST7796 | ||||
|     #define TFT_BUFFER_SIZE                14400 | ||||
|  | ||||
|     #define LCD_READ_ID                     0xD3 | ||||
|     #define LCD_USE_DMA_SPI | ||||
|  | ||||
|     #define TOUCH_BUTTONS_HW_SPI | ||||
|     #define TOUCH_BUTTONS_HW_SPI_DEVICE        1 | ||||
|  | ||||
|   #else                                           // !MKS_MINI_12864 | ||||
|  | ||||
|     #define LCD_PINS_D4                     PE14 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user