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