BTT SKR-SE-BX (STM32H743IIT6 ARM Cortex M7) and BIQU_BX_TFT70 (#21536)
This commit is contained in:
@ -19,7 +19,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
|
||||
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) && !defined(STM32H7xx)
|
||||
|
||||
#include "MarlinSPI.h"
|
||||
|
||||
|
@ -52,6 +52,6 @@
|
||||
#error "SERIAL_STATS_DROPPED_RX is not supported on STM32."
|
||||
#endif
|
||||
|
||||
#if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32F4xx, STM32F1xx)
|
||||
#error "TFT_COLOR_UI, TFT_LVGL_UI and TFT_CLASSIC_UI are currently only supported on STM32F4 and STM32F1 hardware."
|
||||
#if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32H7xx, STM32F4xx, STM32F1xx)
|
||||
#error "TFT_COLOR_UI, TFT_LVGL_UI and TFT_CLASSIC_UI are currently only supported on STM32H7, STM32F4 and STM32F1 hardware."
|
||||
#endif
|
||||
|
390
Marlin/src/HAL/STM32/tft/tft_ltdc.cpp
Normal file
390
Marlin/src/HAL/STM32/tft/tft_ltdc.cpp
Normal file
@ -0,0 +1,390 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2021 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/>.
|
||||
*
|
||||
*/
|
||||
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_LTDC_TFT
|
||||
|
||||
#include "tft_ltdc.h"
|
||||
#include "pinconfig.h"
|
||||
|
||||
#define FRAME_BUFFER_ADDRESS 0XC0000000 // SDRAM address
|
||||
|
||||
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
|
||||
#define REFRESH_COUNT ((uint32_t)0x02A5) // SDRAM refresh counter
|
||||
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
|
||||
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
|
||||
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
|
||||
|
||||
|
||||
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command) {
|
||||
|
||||
__IO uint32_t tmpmrd =0;
|
||||
/* Step 1: Configure a clock configuration enable command */
|
||||
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
|
||||
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
|
||||
Command->AutoRefreshNumber = 1;
|
||||
Command->ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
|
||||
|
||||
/* Step 2: Insert 100 us minimum delay */
|
||||
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
|
||||
HAL_Delay(1);
|
||||
|
||||
/* Step 3: Configure a PALL (precharge all) command */
|
||||
Command->CommandMode = FMC_SDRAM_CMD_PALL;
|
||||
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
|
||||
Command->AutoRefreshNumber = 1;
|
||||
Command->ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
|
||||
|
||||
/* Step 4 : Configure a Auto-Refresh command */
|
||||
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
|
||||
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
|
||||
Command->AutoRefreshNumber = 8;
|
||||
Command->ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
|
||||
|
||||
/* Step 5: Program the external memory mode register */
|
||||
tmpmrd = (uint32_t)(SDRAM_MODEREG_BURST_LENGTH_1 |
|
||||
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
|
||||
SDRAM_MODEREG_CAS_LATENCY_2 |
|
||||
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
|
||||
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE);
|
||||
|
||||
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
|
||||
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
|
||||
Command->AutoRefreshNumber = 1;
|
||||
Command->ModeRegisterDefinition = tmpmrd;
|
||||
/* Send the command */
|
||||
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
|
||||
|
||||
/* Step 6: Set the refresh rate counter */
|
||||
/* Set the device refresh rate */
|
||||
HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);
|
||||
}
|
||||
|
||||
void SDRAM_Config() {
|
||||
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_FMC_CLK_ENABLE();
|
||||
|
||||
SDRAM_HandleTypeDef hsdram;
|
||||
FMC_SDRAM_TimingTypeDef SDRAM_Timing;
|
||||
FMC_SDRAM_CommandTypeDef command;
|
||||
|
||||
/* Configure the SDRAM device */
|
||||
hsdram.Instance = FMC_SDRAM_DEVICE;
|
||||
hsdram.Init.SDBank = FMC_SDRAM_BANK1;
|
||||
hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
|
||||
hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
|
||||
hsdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
|
||||
hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
|
||||
hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
|
||||
hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
|
||||
hsdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
|
||||
hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
|
||||
hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
|
||||
|
||||
/* Timing configuration for 100Mhz as SDRAM clock frequency (System clock is up to 200Mhz) */
|
||||
SDRAM_Timing.LoadToActiveDelay = 2;
|
||||
SDRAM_Timing.ExitSelfRefreshDelay = 8;
|
||||
SDRAM_Timing.SelfRefreshTime = 6;
|
||||
SDRAM_Timing.RowCycleDelay = 6;
|
||||
SDRAM_Timing.WriteRecoveryTime = 2;
|
||||
SDRAM_Timing.RPDelay = 2;
|
||||
SDRAM_Timing.RCDDelay = 2;
|
||||
|
||||
/* Initialize the SDRAM controller */
|
||||
if (HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK)
|
||||
{
|
||||
/* Initialization Error */
|
||||
}
|
||||
|
||||
/* Program the SDRAM external device */
|
||||
SDRAM_Initialization_Sequence(&hsdram, &command);
|
||||
}
|
||||
|
||||
void LTDC_Config() {
|
||||
|
||||
__HAL_RCC_LTDC_CLK_ENABLE();
|
||||
__HAL_RCC_DMA2D_CLK_ENABLE();
|
||||
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
|
||||
|
||||
/* The PLL3R is configured to provide the LTDC PCLK clock */
|
||||
/* PLL3_VCO Input = HSE_VALUE / PLL3M = 25Mhz / 5 = 5 Mhz */
|
||||
/* PLL3_VCO Output = PLL3_VCO Input * PLL3N = 5Mhz * 160 = 800 Mhz */
|
||||
/* PLLLCDCLK = PLL3_VCO Output/PLL3R = 800Mhz / 16 = 50Mhz */
|
||||
/* LTDC clock frequency = PLLLCDCLK = 50 Mhz */
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
||||
PeriphClkInitStruct.PLL3.PLL3M = 5;
|
||||
PeriphClkInitStruct.PLL3.PLL3N = 160;
|
||||
PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
|
||||
PeriphClkInitStruct.PLL3.PLL3P = 2;
|
||||
PeriphClkInitStruct.PLL3.PLL3Q = 2;
|
||||
PeriphClkInitStruct.PLL3.PLL3R = (800 / LTDC_LCD_CLK);
|
||||
PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;
|
||||
PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_2;
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
||||
|
||||
LTDC_HandleTypeDef hltdc_F;
|
||||
LTDC_LayerCfgTypeDef pLayerCfg;
|
||||
|
||||
/* LTDC Initialization -------------------------------------------------------*/
|
||||
|
||||
/* Polarity configuration */
|
||||
/* Initialize the horizontal synchronization polarity as active low */
|
||||
hltdc_F.Init.HSPolarity = LTDC_HSPOLARITY_AL;
|
||||
/* Initialize the vertical synchronization polarity as active low */
|
||||
hltdc_F.Init.VSPolarity = LTDC_VSPOLARITY_AL;
|
||||
/* Initialize the data enable polarity as active low */
|
||||
hltdc_F.Init.DEPolarity = LTDC_DEPOLARITY_AL;
|
||||
/* Initialize the pixel clock polarity as input pixel clock */
|
||||
hltdc_F.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
|
||||
|
||||
/* Timing configuration */
|
||||
hltdc_F.Init.HorizontalSync = (LTDC_LCD_HSYNC - 1);
|
||||
hltdc_F.Init.VerticalSync = (LTDC_LCD_VSYNC - 1);
|
||||
hltdc_F.Init.AccumulatedHBP = (LTDC_LCD_HSYNC + LTDC_LCD_HBP - 1);
|
||||
hltdc_F.Init.AccumulatedVBP = (LTDC_LCD_VSYNC + LTDC_LCD_VBP - 1);
|
||||
hltdc_F.Init.AccumulatedActiveH = (TFT_HEIGHT + LTDC_LCD_VSYNC + LTDC_LCD_VBP - 1);
|
||||
hltdc_F.Init.AccumulatedActiveW = (TFT_WIDTH + LTDC_LCD_HSYNC + LTDC_LCD_HBP - 1);
|
||||
hltdc_F.Init.TotalHeigh = (TFT_HEIGHT + LTDC_LCD_VSYNC + LTDC_LCD_VBP + LTDC_LCD_VFP - 1);
|
||||
hltdc_F.Init.TotalWidth = (TFT_WIDTH + LTDC_LCD_HSYNC + LTDC_LCD_HBP + LTDC_LCD_HFP - 1);
|
||||
|
||||
/* Configure R,G,B component values for LCD background color : all black background */
|
||||
hltdc_F.Init.Backcolor.Blue = 0;
|
||||
hltdc_F.Init.Backcolor.Green = 0;
|
||||
hltdc_F.Init.Backcolor.Red = 0;
|
||||
|
||||
hltdc_F.Instance = LTDC;
|
||||
|
||||
/* Layer0 Configuration ------------------------------------------------------*/
|
||||
|
||||
/* Windowing configuration */
|
||||
pLayerCfg.WindowX0 = 0;
|
||||
pLayerCfg.WindowX1 = TFT_WIDTH;
|
||||
pLayerCfg.WindowY0 = 0;
|
||||
pLayerCfg.WindowY1 = TFT_HEIGHT;
|
||||
|
||||
/* Pixel Format configuration*/
|
||||
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
|
||||
|
||||
/* Start Address configuration : frame buffer is located at SDRAM memory */
|
||||
pLayerCfg.FBStartAdress = (uint32_t)(FRAME_BUFFER_ADDRESS);
|
||||
|
||||
/* Alpha constant (255 == totally opaque) */
|
||||
pLayerCfg.Alpha = 255;
|
||||
|
||||
/* Default Color configuration (configure A,R,G,B component values) : no background color */
|
||||
pLayerCfg.Alpha0 = 0; /* fully transparent */
|
||||
pLayerCfg.Backcolor.Blue = 0;
|
||||
pLayerCfg.Backcolor.Green = 0;
|
||||
pLayerCfg.Backcolor.Red = 0;
|
||||
|
||||
/* Configure blending factors */
|
||||
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
|
||||
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
|
||||
|
||||
/* Configure the number of lines and number of pixels per line */
|
||||
pLayerCfg.ImageWidth = TFT_WIDTH;
|
||||
pLayerCfg.ImageHeight = TFT_HEIGHT;
|
||||
|
||||
/* Configure the LTDC */
|
||||
if (HAL_LTDC_Init(&hltdc_F) != HAL_OK)
|
||||
{
|
||||
/* Initialization Error */
|
||||
}
|
||||
|
||||
/* Configure the Layer*/
|
||||
if (HAL_LTDC_ConfigLayer(&hltdc_F, &pLayerCfg, 0) != HAL_OK)
|
||||
{
|
||||
/* Initialization Error */
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t TFT_LTDC::x_min = 0;
|
||||
uint16_t TFT_LTDC::x_max = 0;
|
||||
uint16_t TFT_LTDC::y_min = 0;
|
||||
uint16_t TFT_LTDC::y_max = 0;
|
||||
uint16_t TFT_LTDC::x_cur = 0;
|
||||
uint16_t TFT_LTDC::y_cur = 0;
|
||||
uint8_t TFT_LTDC::reg = 0;
|
||||
volatile uint16_t* TFT_LTDC::framebuffer = (volatile uint16_t* )FRAME_BUFFER_ADDRESS;
|
||||
|
||||
void TFT_LTDC::Init() {
|
||||
|
||||
// SDRAM pins init
|
||||
for (uint16_t i = 0; PinMap_SDRAM[i].pin != NC; i++)
|
||||
pinmap_pinout(PinMap_SDRAM[i].pin, PinMap_SDRAM);
|
||||
|
||||
// SDRAM peripheral config
|
||||
SDRAM_Config();
|
||||
|
||||
// LTDC pins init
|
||||
for (uint16_t i = 0; PinMap_LTDC[i].pin != NC; i++)
|
||||
pinmap_pinout(PinMap_LTDC[i].pin, PinMap_LTDC);
|
||||
|
||||
// LTDC peripheral config
|
||||
LTDC_Config();
|
||||
}
|
||||
|
||||
uint32_t TFT_LTDC::GetID() {
|
||||
return 0xABAB;
|
||||
}
|
||||
|
||||
uint32_t TFT_LTDC::ReadID(tft_data_t Reg) {
|
||||
return 0xABAB;
|
||||
}
|
||||
|
||||
bool TFT_LTDC::isBusy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t TFT_LTDC::ReadPoint(uint16_t x, uint16_t y) {
|
||||
return framebuffer[(TFT_WIDTH * y) + x];
|
||||
}
|
||||
|
||||
void TFT_LTDC::DrawPoint(uint16_t x, uint16_t y, uint16_t color) {
|
||||
framebuffer[(TFT_WIDTH * y) + x] = color;
|
||||
}
|
||||
|
||||
void TFT_LTDC::DrawRect(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color) {
|
||||
|
||||
if (sx == ex || sy == ey) return;
|
||||
|
||||
uint16_t offline = TFT_WIDTH - (ex - sx);
|
||||
uint32_t addr = (uint32_t)&framebuffer[(TFT_WIDTH * sy) + sx];
|
||||
|
||||
DMA2D->CR &= ~(1 << 0);
|
||||
DMA2D->CR = 3 << 16;
|
||||
DMA2D->OPFCCR = 0X02;
|
||||
DMA2D->OOR = offline;
|
||||
DMA2D->OMAR = addr;
|
||||
DMA2D->NLR = (ey - sy) | ((ex - sx) << 16);
|
||||
DMA2D->OCOLR = color;
|
||||
DMA2D->CR |= 1<<0;
|
||||
|
||||
uint32_t timeout = 0;
|
||||
while((DMA2D->ISR & (1<<1)) == 0)
|
||||
{
|
||||
timeout++;
|
||||
if(timeout>0X1FFFFF)break;
|
||||
}
|
||||
DMA2D->IFCR |= 1<<1;
|
||||
}
|
||||
|
||||
void TFT_LTDC::DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *colors) {
|
||||
|
||||
if (sx == ex || sy == ey) return;
|
||||
|
||||
uint16_t offline = TFT_WIDTH - (ex - sx);
|
||||
uint32_t addr = (uint32_t)&framebuffer[(TFT_WIDTH * sy) + sx];
|
||||
|
||||
DMA2D->CR &= ~(1 << 0);
|
||||
DMA2D->CR = 0 << 16;
|
||||
DMA2D->FGPFCCR = 0X02;
|
||||
DMA2D->FGOR = 0;
|
||||
DMA2D->OOR = offline;
|
||||
DMA2D->FGMAR = (uint32_t)colors;
|
||||
DMA2D->OMAR = addr;
|
||||
DMA2D->NLR = (ey - sy) | ((ex - sx) << 16);
|
||||
DMA2D->CR |= 1<<0;
|
||||
|
||||
uint32_t timeout = 0;
|
||||
while((DMA2D->ISR & (1<<1)) == 0)
|
||||
{
|
||||
timeout++;
|
||||
if(timeout>0X1FFFFF)break;
|
||||
}
|
||||
DMA2D->IFCR |= 1<<1;
|
||||
}
|
||||
|
||||
void TFT_LTDC::WriteData(uint16_t data) {
|
||||
switch (reg) {
|
||||
case 0x01: x_cur = x_min = data; return;
|
||||
case 0x02: x_max = data; return;
|
||||
case 0x03: y_cur = y_min = data; return;
|
||||
case 0x04: y_max = data; return;
|
||||
}
|
||||
Transmit(data);
|
||||
}
|
||||
|
||||
void TFT_LTDC::Transmit(tft_data_t Data) {
|
||||
DrawPoint(x_cur, y_cur, Data);
|
||||
x_cur++;
|
||||
if (x_cur > x_max) {
|
||||
x_cur = x_min;
|
||||
y_cur++;
|
||||
if (y_cur > y_max) y_cur = y_min;
|
||||
}
|
||||
}
|
||||
|
||||
void TFT_LTDC::WriteReg(uint16_t Reg) {
|
||||
reg = Reg;
|
||||
}
|
||||
|
||||
void TFT_LTDC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
|
||||
|
||||
while (x_cur != x_min && Count) {
|
||||
Transmit(*Data);
|
||||
if (MemoryIncrease == DMA_PINC_ENABLE) Data++;
|
||||
Count--;
|
||||
}
|
||||
|
||||
uint16_t width = x_max - x_min + 1;
|
||||
uint16_t height = Count / width;
|
||||
uint16_t x_end_cnt = Count - (width * height);
|
||||
|
||||
if (height) {
|
||||
if (MemoryIncrease == DMA_PINC_ENABLE) {
|
||||
DrawImage(x_min, y_cur, x_min + width, y_cur + height, Data);
|
||||
Data += width * height;
|
||||
} else {
|
||||
DrawRect(x_min, y_cur, x_min + width, y_cur + height, *Data);
|
||||
}
|
||||
y_cur += height;
|
||||
}
|
||||
|
||||
while (x_end_cnt) {
|
||||
Transmit(*Data);
|
||||
if (MemoryIncrease == DMA_PINC_ENABLE) Data++;
|
||||
x_end_cnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAS_LTDC_TFT
|
||||
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
|
155
Marlin/src/HAL/STM32/tft/tft_ltdc.h
Normal file
155
Marlin/src/HAL/STM32/tft/tft_ltdc.h
Normal file
@ -0,0 +1,155 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2021 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"
|
||||
|
||||
#ifdef STM32H7xx
|
||||
#include "stm32h7xx_hal.h"
|
||||
#else
|
||||
#error "LTDC TFT is currently only supported on STM32H7 hardware."
|
||||
#endif
|
||||
|
||||
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
|
||||
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
|
||||
#define TFT_IO_DRIVER TFT_LTDC
|
||||
|
||||
#define TFT_DATASIZE DATASIZE_16BIT
|
||||
typedef uint16_t tft_data_t;
|
||||
|
||||
class TFT_LTDC {
|
||||
private:
|
||||
static volatile uint16_t *framebuffer;
|
||||
static uint16_t x_min, x_max, y_min, y_max, x_cur, y_cur;
|
||||
static uint8_t reg;
|
||||
|
||||
static uint32_t ReadID(tft_data_t Reg);
|
||||
|
||||
static uint16_t ReadPoint(uint16_t x, uint16_t y);
|
||||
static void DrawPoint(uint16_t x, uint16_t y, uint16_t color);
|
||||
static void DrawRect(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color);
|
||||
static void DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *colors);
|
||||
static void Transmit(tft_data_t Data);
|
||||
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
|
||||
|
||||
public:
|
||||
static void Init();
|
||||
static uint32_t GetID();
|
||||
static bool isBusy();
|
||||
static void Abort() { /*__HAL_DMA_DISABLE(&DMAtx);*/ }
|
||||
|
||||
static void DataTransferBegin(uint16_t DataWidth = TFT_DATASIZE) {}
|
||||
static void DataTransferEnd() {};
|
||||
|
||||
static void WriteData(uint16_t Data);
|
||||
static void WriteReg(uint16_t Reg);
|
||||
|
||||
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); }
|
||||
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const PinMap PinMap_LTDC[] = {
|
||||
{PF_10, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_DE
|
||||
{PG_7, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_CLK
|
||||
{PI_9, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_VSYNC
|
||||
{PI_10, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_HSYNC
|
||||
|
||||
{PG_6, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R7
|
||||
{PH_12, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R6
|
||||
{PH_11, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R5
|
||||
{PH_10, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R4
|
||||
{PH_9, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R3
|
||||
|
||||
{PI_2, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G7
|
||||
{PI_1, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G6
|
||||
{PI_0, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G5
|
||||
{PH_15, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G4
|
||||
{PH_14, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G3
|
||||
{PH_13, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G2
|
||||
|
||||
{PI_7, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B7
|
||||
{PI_6, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B6
|
||||
{PI_5, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B5
|
||||
{PI_4, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B4
|
||||
{PG_11, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B3
|
||||
{NC, NP, 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_SDRAM[] = {
|
||||
{PC_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDNWE
|
||||
{PC_2, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDNE0
|
||||
{PC_3, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDCKE0
|
||||
{PE_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_NBL0
|
||||
{PE_1, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_NBL1
|
||||
{PF_11, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDNRAS
|
||||
{PG_8, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDCLK
|
||||
{PG_15, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDNCAS
|
||||
{PG_4, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_BA0
|
||||
{PG_5, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_BA1
|
||||
{PD_14, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D0
|
||||
{PD_15, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D1
|
||||
{PD_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D2
|
||||
{PD_1, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D3
|
||||
{PE_7, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D4
|
||||
{PE_8, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D5
|
||||
{PE_9, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D6
|
||||
{PE_10, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D7
|
||||
{PE_11, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D8
|
||||
{PE_12, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D9
|
||||
{PE_13, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D10
|
||||
{PE_14, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D11
|
||||
{PE_15, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D12
|
||||
{PD_8, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D13
|
||||
{PD_9, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D14
|
||||
{PD_10, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D15
|
||||
{PF_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A0
|
||||
{PF_1, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A1
|
||||
{PF_2, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A2
|
||||
{PF_3, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A3
|
||||
{PF_4, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A4
|
||||
{PF_5, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A5
|
||||
{PF_12, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A6
|
||||
{PF_13, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A7
|
||||
{PF_14, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A8
|
||||
{PF_15, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A9
|
||||
{PG_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A10
|
||||
{PG_1, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A11
|
||||
{PG_2, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A12
|
||||
{NC, NP, 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_QUADSPI[] = {
|
||||
{PB_2, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK
|
||||
{PB_10, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_NCS
|
||||
{PF_6, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3
|
||||
{PF_7, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2
|
||||
{PF_8, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
|
||||
{PF_9, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
|
||||
{NC, NP, 0}
|
||||
};
|
@ -74,7 +74,7 @@
|
||||
#elif defined(STM32F401xC) || defined(STM32F401xE)
|
||||
#define MCU_STEP_TIMER 9
|
||||
#define MCU_TEMP_TIMER 10
|
||||
#elif defined(STM32F4xx) || defined(STM32F7xx)
|
||||
#elif defined(STM32F4xx) || defined(STM32F7xx) || defined(STM32H7xx)
|
||||
#define MCU_STEP_TIMER 6 // STM32F401 has no TIM6, TIM7, or TIM8
|
||||
#define MCU_TEMP_TIMER 14 // TIM7 is consumed by Software Serial if used.
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user