Support for TFT & Touch Screens (#18130)
This commit is contained in:
committed by
GitHub
parent
bba157e5bd
commit
117df87d19
180
Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
Normal file
180
Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
/**
|
||||
* 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_FSMC_TFT
|
||||
|
||||
#include "tft_fsmc.h"
|
||||
#include "pinconfig.h"
|
||||
|
||||
SRAM_HandleTypeDef TFT_FSMC::SRAMx;
|
||||
DMA_HandleTypeDef TFT_FSMC::DMAtx;
|
||||
LCD_CONTROLLER_TypeDef *TFT_FSMC::LCD;
|
||||
|
||||
void TFT_FSMC::Init() {
|
||||
uint32_t controllerAddress;
|
||||
|
||||
#if PIN_EXISTS(TFT_RESET)
|
||||
OUT_WRITE(TFT_RESET_PIN, HIGH);
|
||||
HAL_Delay(100);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
FSMC_NORSRAM_TimingTypeDef Timing, ExtTiming;
|
||||
|
||||
uint32_t NSBank = (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS);
|
||||
|
||||
SRAMx.Instance = FSMC_NORSRAM_DEVICE;
|
||||
SRAMx.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
|
||||
/* SRAMx.Init */
|
||||
SRAMx.Init.NSBank = NSBank;
|
||||
SRAMx.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
|
||||
SRAMx.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
|
||||
SRAMx.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
|
||||
SRAMx.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
|
||||
SRAMx.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
|
||||
SRAMx.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
|
||||
SRAMx.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
|
||||
SRAMx.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
|
||||
SRAMx.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
|
||||
SRAMx.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE;
|
||||
SRAMx.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
|
||||
SRAMx.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
|
||||
#ifdef STM32F4xx
|
||||
SRAMx.Init.PageSize = FSMC_PAGE_SIZE_NONE;
|
||||
#endif
|
||||
/* Read Timing - relatively slow to ensure ID information is correctly read from TFT controller */
|
||||
/* Can be decreases from 15-15-24 to 4-4-8 with risk of stability loss */
|
||||
Timing.AddressSetupTime = 15;
|
||||
Timing.AddressHoldTime = 15;
|
||||
Timing.DataSetupTime = 24;
|
||||
Timing.BusTurnAroundDuration = 0;
|
||||
Timing.CLKDivision = 16;
|
||||
Timing.DataLatency = 17;
|
||||
Timing.AccessMode = FSMC_ACCESS_MODE_A;
|
||||
/* Write Timing */
|
||||
/* Can be decreases from 8-15-8 to 0-0-1 with risk of stability loss */
|
||||
ExtTiming.AddressSetupTime = 8;
|
||||
ExtTiming.AddressHoldTime = 15;
|
||||
ExtTiming.DataSetupTime = 8;
|
||||
ExtTiming.BusTurnAroundDuration = 0;
|
||||
ExtTiming.CLKDivision = 16;
|
||||
ExtTiming.DataLatency = 17;
|
||||
ExtTiming.AccessMode = FSMC_ACCESS_MODE_A;
|
||||
|
||||
__HAL_RCC_FSMC_CLK_ENABLE();
|
||||
|
||||
for(uint16_t i = 0; PinMap_FSMC[i].pin != NC; i++)
|
||||
pinmap_pinout(PinMap_FSMC[i].pin, PinMap_FSMC);
|
||||
pinmap_pinout(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS);
|
||||
pinmap_pinout(digitalPinToPinName(TFT_RS_PIN), PinMap_FSMC_RS);
|
||||
|
||||
controllerAddress = FSMC_BANK1_1;
|
||||
#ifdef PF0
|
||||
switch (NSBank) {
|
||||
case FSMC_NORSRAM_BANK2: controllerAddress = FSMC_BANK1_2 ; break;
|
||||
case FSMC_NORSRAM_BANK3: controllerAddress = FSMC_BANK1_3 ; break;
|
||||
case FSMC_NORSRAM_BANK4: controllerAddress = FSMC_BANK1_4 ; break;
|
||||
}
|
||||
#endif
|
||||
|
||||
controllerAddress |= (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_RS_PIN), PinMap_FSMC_RS);
|
||||
|
||||
HAL_SRAM_Init(&SRAMx, &Timing, &ExtTiming);
|
||||
|
||||
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||
|
||||
#ifdef STM32F1xx
|
||||
DMAtx.Instance = DMA2_Channel1;
|
||||
#elif defined(STM32F4xx)
|
||||
DMAtx.Instance = DMA2_Stream0;
|
||||
DMAtx.Init.Channel = DMA_CHANNEL_0;
|
||||
DMAtx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
||||
DMAtx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
DMAtx.Init.MemBurst = DMA_MBURST_SINGLE;
|
||||
DMAtx.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
||||
#endif
|
||||
|
||||
DMAtx.Init.Direction = DMA_MEMORY_TO_MEMORY;
|
||||
DMAtx.Init.MemInc = DMA_MINC_DISABLE;
|
||||
DMAtx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
DMAtx.Init.Mode = DMA_NORMAL;
|
||||
DMAtx.Init.Priority = DMA_PRIORITY_HIGH;
|
||||
|
||||
LCD = (LCD_CONTROLLER_TypeDef *)controllerAddress;
|
||||
}
|
||||
|
||||
uint32_t TFT_FSMC::GetID() {
|
||||
uint32_t id;
|
||||
WriteReg(0x0000);
|
||||
id = LCD->RAM;
|
||||
|
||||
if (id == 0)
|
||||
id = ReadID(LCD_READ_ID);
|
||||
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
|
||||
id = ReadID(LCD_READ_ID4);
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t TFT_FSMC::ReadID(uint16_t Reg) {
|
||||
uint32_t id;
|
||||
WriteReg(Reg);
|
||||
id = LCD->RAM; // dummy read
|
||||
id = Reg << 24;
|
||||
id |= (LCD->RAM & 0x00FF) << 16;
|
||||
id |= (LCD->RAM & 0x00FF) << 8;
|
||||
id |= LCD->RAM & 0x00FF;
|
||||
return id;
|
||||
}
|
||||
|
||||
bool TFT_FSMC::isBusy() {
|
||||
if (__IS_DMA_ENABLED(&DMAtx))
|
||||
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0)
|
||||
Abort();
|
||||
return __IS_DMA_ENABLED(&DMAtx);
|
||||
}
|
||||
|
||||
void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
|
||||
DMAtx.Init.PeriphInc = MemoryIncrease;
|
||||
HAL_DMA_Init(&DMAtx);
|
||||
|
||||
__HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx));
|
||||
__HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx));
|
||||
|
||||
#ifdef STM32F1xx
|
||||
DMAtx.Instance->CNDTR = Count;
|
||||
DMAtx.Instance->CPAR = (uint32_t)Data;
|
||||
DMAtx.Instance->CMAR = (uint32_t)&(LCD->RAM);
|
||||
#elif defined(STM32F4xx)
|
||||
DMAtx.Instance->NDTR = Count;
|
||||
DMAtx.Instance->PAR = (uint32_t)Data;
|
||||
DMAtx.Instance->M0AR = (uint32_t)&(LCD->RAM);
|
||||
#endif
|
||||
__HAL_DMA_ENABLE(&DMAtx);
|
||||
}
|
||||
|
||||
#endif // HAS_FSMC_TFT
|
160
Marlin/src/HAL/STM32/tft/tft_fsmc.h
Normal file
160
Marlin/src/HAL/STM32/tft/tft_fsmc.h
Normal file
@ -0,0 +1,160 @@
|
||||
/**
|
||||
* 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
|
||||
|
||||
#ifdef STM32F1xx
|
||||
#include "stm32f1xx_hal.h"
|
||||
#elif defined(STM32F4xx)
|
||||
#include "stm32f4xx_hal.h"
|
||||
#else
|
||||
#error FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware.
|
||||
#endif
|
||||
|
||||
#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 SPI_DATASIZE_8BIT
|
||||
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
|
||||
#define TFT_IO TFT_FSMC
|
||||
|
||||
#ifdef STM32F1xx
|
||||
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
|
||||
#elif defined(STM32F4xx)
|
||||
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
__IO uint16_t REG;
|
||||
__IO uint16_t RAM;
|
||||
} LCD_CONTROLLER_TypeDef;
|
||||
|
||||
class TFT_FSMC {
|
||||
private:
|
||||
static SRAM_HandleTypeDef SRAMx;
|
||||
static DMA_HandleTypeDef DMAtx;
|
||||
|
||||
static LCD_CONTROLLER_TypeDef *LCD;
|
||||
|
||||
static uint32_t ReadID(uint16_t Reg);
|
||||
static void Transmit(uint16_t Data) { LCD->RAM = Data; __DSB(); }
|
||||
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 = DATASIZE_16BIT) {}
|
||||
static void DataTransferEnd() {};
|
||||
|
||||
static void WriteData(uint16_t Data) { Transmit(Data); }
|
||||
static void WriteReg(uint16_t Reg) { LCD->REG = Reg; __DSB(); }
|
||||
|
||||
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); }
|
||||
};
|
||||
|
||||
|
||||
#ifdef STM32F1xx
|
||||
#define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)
|
||||
#elif defined(STM32F4xx)
|
||||
#define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FSMC)
|
||||
#define FSMC_BANK1_1 0x60000000U
|
||||
#define FSMC_BANK1_2 0x64000000U
|
||||
#define FSMC_BANK1_3 0x68000000U
|
||||
#define FSMC_BANK1_4 0x6C000000U
|
||||
#else
|
||||
#error No configuration for this MCU
|
||||
#endif
|
||||
|
||||
const PinMap PinMap_FSMC[] = {
|
||||
{PD_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D00
|
||||
{PD_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D01
|
||||
{PD_0, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D02
|
||||
{PD_1, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D03
|
||||
{PE_7, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D04
|
||||
{PE_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D05
|
||||
{PE_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D06
|
||||
{PE_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D07
|
||||
{PE_11, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D08
|
||||
{PE_12, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D09
|
||||
{PE_13, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D10
|
||||
{PE_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D11
|
||||
{PE_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D12
|
||||
{PD_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D13
|
||||
{PD_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D14
|
||||
{PD_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D15
|
||||
{PD_4, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NOE
|
||||
{PD_5, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NWE
|
||||
{NC, NP, 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_FSMC_CS[] = {
|
||||
{PD_7, (void *)FSMC_NORSRAM_BANK1, FSMC_PIN_DATA}, // FSMC_NE1
|
||||
#ifdef PF0
|
||||
{PG_9, (void *)FSMC_NORSRAM_BANK2, FSMC_PIN_DATA}, // FSMC_NE2
|
||||
{PG_10, (void *)FSMC_NORSRAM_BANK3, FSMC_PIN_DATA}, // FSMC_NE3
|
||||
{PG_12, (void *)FSMC_NORSRAM_BANK4, FSMC_PIN_DATA}, // FSMC_NE4
|
||||
#endif
|
||||
{NC, NP, 0}
|
||||
};
|
||||
|
||||
#define FSMC_RS(A) (void *)((2 << A) - 2)
|
||||
|
||||
const PinMap PinMap_FSMC_RS[] = {
|
||||
#ifdef PF0
|
||||
{PF_0, FSMC_RS( 0), FSMC_PIN_DATA}, // FSMC_A0
|
||||
{PF_1, FSMC_RS( 1), FSMC_PIN_DATA}, // FSMC_A1
|
||||
{PF_2, FSMC_RS( 2), FSMC_PIN_DATA}, // FSMC_A2
|
||||
{PF_3, FSMC_RS( 3), FSMC_PIN_DATA}, // FSMC_A3
|
||||
{PF_4, FSMC_RS( 4), FSMC_PIN_DATA}, // FSMC_A4
|
||||
{PF_5, FSMC_RS( 5), FSMC_PIN_DATA}, // FSMC_A5
|
||||
{PF_12, FSMC_RS( 6), FSMC_PIN_DATA}, // FSMC_A6
|
||||
{PF_13, FSMC_RS( 7), FSMC_PIN_DATA}, // FSMC_A7
|
||||
{PF_14, FSMC_RS( 8), FSMC_PIN_DATA}, // FSMC_A8
|
||||
{PF_15, FSMC_RS( 9), FSMC_PIN_DATA}, // FSMC_A9
|
||||
{PG_0, FSMC_RS(10), FSMC_PIN_DATA}, // FSMC_A10
|
||||
{PG_1, FSMC_RS(11), FSMC_PIN_DATA}, // FSMC_A11
|
||||
{PG_2, FSMC_RS(12), FSMC_PIN_DATA}, // FSMC_A12
|
||||
{PG_3, FSMC_RS(13), FSMC_PIN_DATA}, // FSMC_A13
|
||||
{PG_4, FSMC_RS(14), FSMC_PIN_DATA}, // FSMC_A14
|
||||
{PG_5, FSMC_RS(15), FSMC_PIN_DATA}, // FSMC_A15
|
||||
#endif
|
||||
{PD_11, FSMC_RS(16), FSMC_PIN_DATA}, // FSMC_A16
|
||||
{PD_12, FSMC_RS(17), FSMC_PIN_DATA}, // FSMC_A17
|
||||
{PD_13, FSMC_RS(18), FSMC_PIN_DATA}, // FSMC_A18
|
||||
{PE_3, FSMC_RS(19), FSMC_PIN_DATA}, // FSMC_A19
|
||||
{PE_4, FSMC_RS(20), FSMC_PIN_DATA}, // FSMC_A20
|
||||
{PE_5, FSMC_RS(21), FSMC_PIN_DATA}, // FSMC_A21
|
||||
{PE_6, FSMC_RS(22), FSMC_PIN_DATA}, // FSMC_A22
|
||||
{PE_2, FSMC_RS(23), FSMC_PIN_DATA}, // FSMC_A23
|
||||
#ifdef PF0
|
||||
{PG_13, FSMC_RS(24), FSMC_PIN_DATA}, // FSMC_A24
|
||||
{PG_14, FSMC_RS(25), FSMC_PIN_DATA}, // FSMC_A25
|
||||
#endif
|
||||
{NC, NP, 0}
|
||||
};
|
212
Marlin/src/HAL/STM32/tft/tft_spi.cpp
Normal file
212
Marlin/src/HAL/STM32/tft/tft_spi.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
/**
|
||||
* 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"
|
||||
#include "pinconfig.h"
|
||||
|
||||
SPI_HandleTypeDef TFT_SPI::SPIx;
|
||||
DMA_HandleTypeDef TFT_SPI::DMAtx;
|
||||
|
||||
void TFT_SPI::Init() {
|
||||
SPI_TypeDef *spiInstance;
|
||||
|
||||
#if PIN_EXISTS(TFT_RESET)
|
||||
OUT_WRITE(TFT_RESET_PIN, HIGH);
|
||||
HAL_Delay(100);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
OUT_WRITE(TFT_A0_PIN, HIGH);
|
||||
OUT_WRITE(TFT_CS_PIN, HIGH);
|
||||
|
||||
if ((spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK)) == NP) return;
|
||||
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI)) return;
|
||||
|
||||
#if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN)
|
||||
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO)) return;
|
||||
#endif
|
||||
|
||||
SPIx.Instance = spiInstance;
|
||||
SPIx.State = HAL_SPI_STATE_RESET;
|
||||
SPIx.Init.NSS = SPI_NSS_SOFT;
|
||||
SPIx.Init.Mode = SPI_MODE_MASTER;
|
||||
SPIx.Init.Direction =
|
||||
#if TFT_MISO_PIN == TFT_MOSI_PIN
|
||||
SPI_DIRECTION_1LINE;
|
||||
#else
|
||||
SPI_DIRECTION_2LINES;
|
||||
#endif
|
||||
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
SPIx.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
SPIx.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
SPIx.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
SPIx.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
SPIx.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
SPIx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
SPIx.Init.CRCPolynomial = 10;
|
||||
|
||||
pinmap_pinout(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK);
|
||||
pinmap_pinout(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI);
|
||||
#if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN)
|
||||
pinmap_pinout(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO);
|
||||
#endif
|
||||
pin_PullConfig(get_GPIO_Port(STM_PORT(digitalPinToPinName(TFT_SCK_PIN))), STM_LL_GPIO_PIN(digitalPinToPinName(TFT_SCK_PIN)), GPIO_PULLDOWN);
|
||||
|
||||
#ifdef SPI1_BASE
|
||||
if (SPIx.Instance == SPI1) {
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
|
||||
DMAtx.Instance = DMA1_Channel3;
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI2_BASE
|
||||
if (SPIx.Instance == SPI2) {
|
||||
__HAL_RCC_SPI2_CLK_ENABLE();
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
DMAtx.Instance = DMA1_Channel5;
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI3_BASE
|
||||
if (SPIx.Instance == SPI3) {
|
||||
__HAL_RCC_SPI3_CLK_ENABLE();
|
||||
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||
DMAtx.Instance = DMA2_Channel2;
|
||||
}
|
||||
#endif
|
||||
|
||||
HAL_SPI_Init(&SPIx);
|
||||
|
||||
DMAtx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
DMAtx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
DMAtx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
DMAtx.Init.Mode = DMA_NORMAL;
|
||||
DMAtx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
|
||||
SPIx.Init.DataSize = DataSize == DATASIZE_8BIT ? SPI_DATASIZE_8BIT : SPI_DATASIZE_16BIT;
|
||||
HAL_SPI_Init(&SPIx);
|
||||
WRITE(TFT_CS_PIN, LOW);
|
||||
}
|
||||
|
||||
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
|
||||
uint32_t BaudRatePrescaler = SPIx.Init.BaudRatePrescaler;
|
||||
uint32_t i, Data = 0;
|
||||
|
||||
SPIx.Init.BaudRatePrescaler = SPIx.Instance == SPI1 ? SPI_BAUDRATEPRESCALER_8 : SPI_BAUDRATEPRESCALER_4;
|
||||
DataTransferBegin(DATASIZE_8BIT);
|
||||
WriteReg(Reg);
|
||||
|
||||
if (SPIx.Init.Direction == SPI_DIRECTION_1LINE) SPI_1LINE_RX(&SPIx);
|
||||
__HAL_SPI_ENABLE(&SPIx);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
#if TFT_MISO_PIN != TFT_MOSI_PIN
|
||||
//if (hspi->Init.Direction == SPI_DIRECTION_2LINES) {
|
||||
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
|
||||
SPIx.Instance->DR = 0;
|
||||
//}
|
||||
#endif
|
||||
while ((SPIx.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
|
||||
Data = (Data << 8) | SPIx.Instance->DR;
|
||||
}
|
||||
|
||||
__HAL_SPI_DISABLE(&SPIx);
|
||||
DataTransferEnd();
|
||||
|
||||
SPIx.Init.BaudRatePrescaler = BaudRatePrescaler;
|
||||
|
||||
return Data >> 7;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool TFT_SPI::isBusy() {
|
||||
if (DMAtx.Instance->CCR & DMA_CCR_EN)
|
||||
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0)
|
||||
Abort();
|
||||
return DMAtx.Instance->CCR & DMA_CCR_EN;
|
||||
}
|
||||
|
||||
void TFT_SPI::Abort() {
|
||||
__HAL_DMA_DISABLE(&DMAtx);
|
||||
DataTransferEnd();
|
||||
}
|
||||
|
||||
void TFT_SPI::Transmit(uint16_t Data) {
|
||||
#if TFT_MISO_PIN == TFT_MOSI_PIN
|
||||
SPI_1LINE_TX(&SPIx);
|
||||
#endif
|
||||
|
||||
__HAL_SPI_ENABLE(&SPIx);
|
||||
|
||||
SPIx.Instance->DR = Data;
|
||||
|
||||
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
|
||||
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
|
||||
|
||||
#if TFT_MISO_PIN != TFT_MOSI_PIN
|
||||
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); /* Clear overrun flag in 2 Lines communication mode because received is not read */
|
||||
#endif
|
||||
}
|
||||
|
||||
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
|
||||
DMAtx.Init.MemInc = MemoryIncrease;
|
||||
HAL_DMA_Init(&DMAtx);
|
||||
|
||||
DataTransferBegin();
|
||||
|
||||
#if TFT_MISO_PIN == TFT_MOSI_PIN
|
||||
SPI_1LINE_TX(&SPIx);
|
||||
#endif
|
||||
|
||||
DMAtx.DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << DMAtx.ChannelIndex);
|
||||
DMAtx.Instance->CNDTR = Count;
|
||||
DMAtx.Instance->CPAR = (uint32_t)&(SPIx.Instance->DR);
|
||||
DMAtx.Instance->CMAR = (uint32_t)Data;
|
||||
__HAL_DMA_ENABLE(&DMAtx);
|
||||
__HAL_SPI_ENABLE(&SPIx);
|
||||
|
||||
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
|
||||
}
|
||||
|
||||
#endif // HAS_SPI_TFT
|
67
Marlin/src/HAL/STM32/tft/tft_spi.h
Normal file
67
Marlin/src/HAL/STM32/tft/tft_spi.h
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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
|
||||
|
||||
#ifdef STM32F1xx
|
||||
#include "stm32f1xx_hal.h"
|
||||
#elif defined(STM32F4xx)
|
||||
#include "stm32f4xx_hal.h"
|
||||
#else
|
||||
#error SPI TFT is currently only supported on STM32F1 and STM32F4 hardware.
|
||||
#endif
|
||||
|
||||
#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 SPI_DATASIZE_8BIT
|
||||
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
|
||||
#define TFT_IO TFT_SPI
|
||||
|
||||
class TFT_SPI {
|
||||
private:
|
||||
static SPI_HandleTypeDef SPIx;
|
||||
static DMA_HandleTypeDef DMAtx;
|
||||
|
||||
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 void Init();
|
||||
static uint32_t GetID();
|
||||
static bool isBusy();
|
||||
static void Abort();
|
||||
|
||||
static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT);
|
||||
static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); };
|
||||
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); }
|
||||
};
|
185
Marlin/src/HAL/STM32/tft/xpt2046.cpp
Normal file
185
Marlin/src/HAL/STM32/tft/xpt2046.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* 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_TFT_XPT2046
|
||||
|
||||
#include "xpt2046.h"
|
||||
#include "pinconfig.h"
|
||||
|
||||
uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; }
|
||||
|
||||
SPI_HandleTypeDef XPT2046::SPIx;
|
||||
DMA_HandleTypeDef XPT2046::DMAtx;
|
||||
|
||||
void XPT2046::Init() {
|
||||
SPI_TypeDef *spiInstance;
|
||||
|
||||
OUT_WRITE(TOUCH_CS_PIN, HIGH);
|
||||
|
||||
#if PIN_EXISTS(TOUCH_INT)
|
||||
// Optional Pendrive interrupt pin
|
||||
SET_INPUT(TOUCH_INT_PIN);
|
||||
#endif
|
||||
|
||||
spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_SCK_PIN), PinMap_SPI_SCLK);
|
||||
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_MOSI_PIN), PinMap_SPI_MOSI)) spiInstance = NP;
|
||||
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_MISO_PIN), PinMap_SPI_MISO)) spiInstance = NP;
|
||||
|
||||
SPIx.Instance = spiInstance;
|
||||
|
||||
if (SPIx.Instance) {
|
||||
SPIx.State = HAL_SPI_STATE_RESET;
|
||||
SPIx.Init.NSS = SPI_NSS_SOFT;
|
||||
SPIx.Init.Mode = SPI_MODE_MASTER;
|
||||
SPIx.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
|
||||
SPIx.Init.CLKPhase = SPI_PHASE_2EDGE;
|
||||
SPIx.Init.CLKPolarity = SPI_POLARITY_HIGH;
|
||||
SPIx.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
SPIx.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
SPIx.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
SPIx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
SPIx.Init.CRCPolynomial = 10;
|
||||
|
||||
pinmap_pinout(digitalPinToPinName(TOUCH_SCK_PIN), PinMap_SPI_SCLK);
|
||||
pinmap_pinout(digitalPinToPinName(TOUCH_MOSI_PIN), PinMap_SPI_MOSI);
|
||||
pinmap_pinout(digitalPinToPinName(TOUCH_MISO_PIN), PinMap_SPI_MISO);
|
||||
|
||||
#ifdef SPI1_BASE
|
||||
if (SPIx.Instance == SPI1) {
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
|
||||
#ifdef STM32F1xx
|
||||
DMAtx.Instance = DMA1_Channel3;
|
||||
#elif defined(STM32F4xx)
|
||||
DMAtx.Instance = DMA2_Stream3; // DMA2_Stream5
|
||||
#endif
|
||||
//SERIAL_ECHO_MSG(" Touch Screen on SPI1");
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI2_BASE
|
||||
if (SPIx.Instance == SPI2) {
|
||||
__HAL_RCC_SPI2_CLK_ENABLE();
|
||||
#ifdef STM32F1xx
|
||||
DMAtx.Instance = DMA1_Channel5;
|
||||
#elif defined(STM32F4xx)
|
||||
DMAtx.Instance = DMA1_Stream4;
|
||||
#endif
|
||||
//SERIAL_ECHO_MSG(" Touch Screen on SPI2");
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI3_BASE
|
||||
if (SPIx.Instance == SPI3) {
|
||||
__HAL_RCC_SPI3_CLK_ENABLE();
|
||||
#ifdef STM32F1xx
|
||||
DMAtx.Instance = DMA2_Channel2;
|
||||
#elif defined(STM32F4xx)
|
||||
DMAtx.Instance = DMA1_Stream5; // DMA1_Stream7
|
||||
#endif
|
||||
//SERIAL_ECHO_MSG(" Touch Screen on SPI3");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
SPIx.Instance = NULL;
|
||||
SET_INPUT(TOUCH_MISO_PIN);
|
||||
SET_OUTPUT(TOUCH_MOSI_PIN);
|
||||
SET_OUTPUT(TOUCH_SCK_PIN);
|
||||
//SERIAL_ECHO_MSG(" Touch Screen on Software SPI");
|
||||
}
|
||||
|
||||
getRawData(XPT2046_Z1);
|
||||
}
|
||||
|
||||
bool XPT2046::isTouched() {
|
||||
return isBusy() ? false : (
|
||||
#if PIN_EXISTS(TOUCH_INT)
|
||||
READ(TOUCH_INT_PIN) != HIGH
|
||||
#else
|
||||
getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
bool XPT2046::getRawPoint(int16_t *x, int16_t *y) {
|
||||
if (isBusy()) return false;
|
||||
if (!isTouched()) return false;
|
||||
*x = getRawData(XPT2046_X);
|
||||
*y = getRawData(XPT2046_Y);
|
||||
return isTouched();
|
||||
}
|
||||
|
||||
uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) {
|
||||
uint16_t data[3];
|
||||
|
||||
DataTransferBegin();
|
||||
|
||||
for (uint16_t i = 0; i < 3 ; i++) {
|
||||
IO(coordinate);
|
||||
data[i] = (IO() << 4) | (IO() >> 4);
|
||||
}
|
||||
|
||||
DataTransferEnd();
|
||||
|
||||
uint16_t delta01 = delta(data[0], data[1]);
|
||||
uint16_t delta02 = delta(data[0], data[2]);
|
||||
uint16_t delta12 = delta(data[1], data[2]);
|
||||
|
||||
if (delta01 > delta02 || delta01 > delta12) {
|
||||
if (delta02 > delta12)
|
||||
data[0] = data[2];
|
||||
else
|
||||
data[1] = data[2];
|
||||
}
|
||||
|
||||
return (data[0] + data[1]) >> 1;
|
||||
}
|
||||
|
||||
uint16_t XPT2046::HardwareIO(uint16_t data) {
|
||||
__HAL_SPI_ENABLE(&SPIx);
|
||||
while((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
|
||||
SPIx.Instance->DR = data;
|
||||
while((SPIx.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
|
||||
__HAL_SPI_DISABLE(&SPIx);
|
||||
|
||||
return SPIx.Instance->DR;
|
||||
}
|
||||
|
||||
uint16_t XPT2046::SoftwareIO(uint16_t data) {
|
||||
uint16_t result = 0;
|
||||
|
||||
for (uint8_t j = 0x80; j > 0; j >>= 1) {
|
||||
WRITE(TOUCH_SCK_PIN, LOW);
|
||||
__DSB();
|
||||
WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW);
|
||||
__DSB();
|
||||
if (READ(TOUCH_MISO_PIN)) result |= j;
|
||||
__DSB();
|
||||
WRITE(TOUCH_SCK_PIN, HIGH);
|
||||
__DSB();
|
||||
}
|
||||
WRITE(TOUCH_SCK_PIN, LOW);
|
||||
__DSB();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // HAS_TFT_XPT2046
|
86
Marlin/src/HAL/STM32/tft/xpt2046.h
Normal file
86
Marlin/src/HAL/STM32/tft/xpt2046.h
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* 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
|
||||
|
||||
#ifdef STM32F1xx
|
||||
#include <stm32f1xx_hal.h>
|
||||
#elif defined(STM32F4xx)
|
||||
#include <stm32f4xx_hal.h>
|
||||
#endif
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
// Not using regular SPI interface by default to avoid SPI mode conflicts with other SPI devices
|
||||
|
||||
#if !PIN_EXISTS(TOUCH_MISO)
|
||||
#error "TOUCH_MISO_PIN is not defined."
|
||||
#elif !PIN_EXISTS(TOUCH_MOSI)
|
||||
#error "TOUCH_MOSI_PIN is not defined."
|
||||
#elif !PIN_EXISTS(TOUCH_SCK)
|
||||
#error "TOUCH_SCK_PIN is not defined."
|
||||
#elif !PIN_EXISTS(TOUCH_CS)
|
||||
#error "TOUCH_CS_PIN is not defined."
|
||||
#endif
|
||||
|
||||
#ifndef TOUCH_INT_PIN
|
||||
#define TOUCH_INT_PIN -1
|
||||
#endif
|
||||
|
||||
#define XPT2046_DFR_MODE 0x00
|
||||
#define XPT2046_SER_MODE 0x04
|
||||
#define XPT2046_CONTROL 0x80
|
||||
|
||||
enum XPTCoordinate : uint8_t {
|
||||
XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE,
|
||||
XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE,
|
||||
XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE,
|
||||
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
|
||||
};
|
||||
|
||||
#if !defined(XPT2046_Z1_THRESHOLD)
|
||||
#define XPT2046_Z1_THRESHOLD 10
|
||||
#endif
|
||||
|
||||
#ifdef STM32F1xx
|
||||
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
|
||||
#elif defined(STM32F4xx)
|
||||
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
|
||||
#endif
|
||||
|
||||
|
||||
class XPT2046 {
|
||||
private:
|
||||
static SPI_HandleTypeDef SPIx;
|
||||
static DMA_HandleTypeDef DMAtx;
|
||||
|
||||
static bool isBusy() { return SPIx.Instance ? __IS_DMA_ENABLED(&DMAtx) : false; }
|
||||
|
||||
static uint16_t getRawData(const XPTCoordinate coordinate);
|
||||
static bool isTouched();
|
||||
|
||||
static inline void DataTransferBegin() { if (SPIx.Instance) { HAL_SPI_Init(&SPIx); } WRITE(TOUCH_CS_PIN, LOW); };
|
||||
static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
|
||||
static uint16_t HardwareIO(uint16_t data);
|
||||
static uint16_t SoftwareIO(uint16_t data);
|
||||
static uint16_t IO(uint16_t data = 0) { return SPIx.Instance ? HardwareIO(data) : SoftwareIO(data); }
|
||||
|
||||
public:
|
||||
static void Init();
|
||||
static bool getRawPoint(int16_t *x, int16_t *y);
|
||||
};
|
Reference in New Issue
Block a user