Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LVGL and Classic UI on STM32 #20552

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Marlin/src/HAL/STM32/HAL_SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ static SPISettings spiConfig;
SPI.setMISO(MISO_PIN);
SPI.setMOSI(MOSI_PIN);
SPI.setSCLK(SCK_PIN);
SPI.setSSEL(SS_PIN);
#endif

SPI.begin();
Expand Down
12 changes: 8 additions & 4 deletions Marlin/src/HAL/STM32/MarlinSPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
_dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
}
#ifdef STM32F4xx
_dmaHandle.Init.Channel = DMA_CHANNEL_3;
_dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
#endif

Expand All @@ -73,7 +72,8 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel3 : DMA1_Channel2;
#elif defined(STM32F4xx)
__HAL_RCC_DMA2_CLK_ENABLE();
_dmaHandle.Instance = DMA2_Stream3;
_dmaHandle.Init.Channel = DMA_CHANNEL_3;
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Stream3 : DMA2_Stream0;
#endif
}
#endif
Expand All @@ -83,7 +83,9 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel5 : DMA1_Channel4;
#elif defined(STM32F4xx)
//TODO: f4 dma config
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Init.Channel = DMA_CHANNEL_0;
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream4 : DMA1_Stream3;
#endif
}
#endif
Expand All @@ -93,7 +95,9 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
__HAL_RCC_DMA2_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Channel2 : DMA2_Channel1;
#elif defined(STM32F4xx)
//TODO: f4 dma config
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Init.Channel = DMA_CHANNEL_0;
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream5 : DMA1_Stream2;
#endif
}
#endif
Expand Down
30 changes: 14 additions & 16 deletions Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,29 +154,27 @@ uint32_t TFT_FSMC::ReadID(tft_data_t Reg) {
}

bool TFT_FSMC::isBusy() {
if (__IS_DMA_ENABLED(&DMAtx))
#if defined(STM32F1xx)
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
#elif defined(STM32F4xx)
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
#endif
if (dmaEnabled) {
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);
}
else
Abort();
return dmaEnabled;
}

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);
DataTransferBegin();
HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(LCD->RAM), Count);
HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
Abort();
}

#endif // HAS_FSMC_TFT
Expand Down
9 changes: 7 additions & 2 deletions Marlin/src/HAL/STM32/tft/tft_fsmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@

#ifdef STM32F1xx
#include "stm32f1xx_hal.h"
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#elif defined(STM32F4xx)
#include "stm32f4xx_hal.h"
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#else
#error "FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware."
#endif
Expand Down Expand Up @@ -77,6 +75,13 @@ class TFT_FSMC {

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;
}
}
};


Expand Down
10 changes: 8 additions & 2 deletions Marlin/src/HAL/STM32/tft/tft_spi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void TFT_SPI::Init() {
#elif defined(STM32F4xx)
__HAL_RCC_DMA1_CLK_ENABLE();
DMAtx.Instance = DMA1_Stream4;
DMAtx.Init.Channel = DMA_CHANNEL_4;
DMAtx.Init.Channel = DMA_CHANNEL_0;
#endif
}
#endif
Expand All @@ -101,7 +101,7 @@ void TFT_SPI::Init() {
#elif defined(STM32F4xx)
__HAL_RCC_DMA1_CLK_ENABLE();
DMAtx.Instance = DMA1_Stream5;
DMAtx.Init.Channel = DMA_CHANNEL_5;
DMAtx.Init.Channel = DMA_CHANNEL_0;
#endif
}
#endif
Expand Down Expand Up @@ -183,6 +183,9 @@ bool TFT_SPI::isBusy() {
}

void TFT_SPI::Abort() {
// Wait for any running spi
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
// First, abort any running dma
HAL_DMA_Abort(&DMAtx);
// DeInit objects
Expand Down Expand Up @@ -223,6 +226,9 @@ void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Coun
__HAL_SPI_ENABLE(&SPIx);

SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */

HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
Abort();
}

#endif // HAS_SPI_TFT
Expand Down
7 changes: 7 additions & 0 deletions Marlin/src/HAL/STM32/tft/tft_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,11 @@ class TFT_SPI {

static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
}
}
};
22 changes: 1 addition & 21 deletions Marlin/src/HAL/STM32/tft/xpt2046.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@

#include "../../../inc/MarlinConfig.h"

#if HAS_TFT_XPT2046
#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS

#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;
Expand Down Expand Up @@ -71,34 +70,16 @@ void XPT2046::Init() {
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
}
Expand All @@ -107,7 +88,6 @@ void XPT2046::Init() {
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);
Expand Down
5 changes: 1 addition & 4 deletions Marlin/src/HAL/STM32/tft/xpt2046.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@

#ifdef STM32F1xx
#include <stm32f1xx_hal.h>
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#elif defined(STM32F4xx)
#include <stm32f4xx_hal.h>
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#endif

#include "../../../inc/MarlinConfig.h"
Expand Down Expand Up @@ -65,9 +63,8 @@ enum XPTCoordinate : uint8_t {
class XPT2046 {
private:
static SPI_HandleTypeDef SPIx;
static DMA_HandleTypeDef DMAtx;

static bool isBusy() { return SPIx.Instance ? __IS_DMA_ENABLED(&DMAtx) : false; }
static bool isBusy() { return false; }

static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/gcode/calibrate/G34.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void GcodeSuite::G34() {
if (!all_axes_trusted()) home_all_axes();

TERN_(HAS_LEVELING, TEMPORARY_BED_LEVELING_STATE(false));

SET_SOFT_ENDSTOP_LOOSE(true);
TemporaryGlobalEndstopsState unlock_z(false);

Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/inc/Conditionals_LCD.h
Original file line number Diff line number Diff line change
Expand Up @@ -1187,7 +1187,7 @@
// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT
#undef TOUCH_SCREEN
#if !HAS_TFT_LVGL_UI
#if ENABLED(TFT_CLASSIC_UI)
#define HAS_TOUCH_BUTTONS 1
#endif
#endif
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -3244,7 +3244,7 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
/**
* Touch Buttons
*/
#if ENABLED(TOUCH_SCREEN)
#if ENABLED(TOUCH_SCREEN) && DISABLED(TOUCH_SCREEN_CALIBRATION)
#ifndef TOUCH_CALIBRATION_X
#error "TOUCH_CALIBRATION_X must be defined with TOUCH_SCREEN."
#endif
Expand Down
17 changes: 8 additions & 9 deletions Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ static uint8_t page;
}
#endif // HAS_TOUCH_BUTTONS

static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT

uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) {
u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);

Expand All @@ -352,19 +354,21 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
switch (msg) {
case U8G_DEV_MSG_INIT:
dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, nullptr);
tftio.Init();
tftio.InitTFT();
TERN_(TOUCH_SCREEN_CALIBRATION, touch_calibration.calibration_reset());

if (preinit) {
preinit = false;
return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg);
}

if (msgInitCount) return -1;
tftio.Init();
tftio.InitTFT();
TERN_(TOUCH_SCREEN_CALIBRATION, touch_calibration.calibration_reset());

// Clear Screen
setWindow(u8g, dev, 0, 0, (TFT_WIDTH) - 1, (TFT_HEIGHT) - 1);
#if HAS_LCD_IO
tftio.WriteMultiple(TFT_MARLINBG_COLOR, uint32_t(TFT_WIDTH) * (TFT_HEIGHT));
tftio.WriteMultiple(TFT_MARLINBG_COLOR, (TFT_WIDTH) * (TFT_HEIGHT));
#else
memset2(buffer, TFT_MARLINBG_COLOR, (TFT_WIDTH) / 2);
for (uint16_t i = 0; i < (TFT_HEIGHT) * sq(GRAPHICAL_TFT_UPSCALE); i++)
Expand Down Expand Up @@ -420,8 +424,6 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg);
}

static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT

uint8_t u8g_com_hal_tft_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
if (msgInitCount) {
if (msg == U8G_COM_MSG_INIT) msgInitCount--;
Expand All @@ -433,8 +435,6 @@ uint8_t u8g_com_hal_tft_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_p
switch (msg) {
case U8G_COM_MSG_STOP: break;
case U8G_COM_MSG_INIT:
u8g_SetPIOutput(u8g, U8G_PI_RESET);
u8g_Delay(50);
isCommand = 0;
break;

Expand All @@ -443,7 +443,6 @@ uint8_t u8g_com_hal_tft_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_p
break;

case U8G_COM_MSG_RESET:
u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
break;

case U8G_COM_MSG_WRITE_BYTE:
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/lcd/tft/tft.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#include "../../inc/MarlinConfig.h"

#if TFT_INTERFACE_FSMC_8BIT
#if ENABLED(TFT_INTERFACE_FSMC_8BIT)
// When we have a 8 bit interface, we need to invert the bytes of the color
#define ENDIAN_COLOR(C) (((C) >> 8) | ((C) << 8))
#else
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/lcd/tft_io/tft_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class TFT_IO {
static void write_esc_sequence(const uint16_t *Sequence);

// Deletaged methods
inline static void Init() { io.Init(); };
inline static void Init() { io.Init(); io.Abort(); };
inline static bool isBusy() { return io.isBusy(); };
inline static void Abort() { io.Abort(); };
inline static uint32_t GetID() { return io.GetID(); };
Expand Down
4 changes: 3 additions & 1 deletion Marlin/src/lcd/touch/touch_buttons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ XPT2046 touchIO;
#endif

#include "../marlinui.h" // For EN_C bit mask
#include "../tft_io/tft_io.h"

#define DOGM_AREA_LEFT TFT_PIXEL_OFFSET_X
#define DOGM_AREA_TOP TFT_PIXEL_OFFSET_Y
Expand All @@ -49,7 +50,8 @@ uint8_t TouchButtons::read_buttons() {
#ifdef HAS_WIRED_LCD
int16_t x, y;

if (!touchIO.getRawPoint(&x, &y)) return 0;
const bool is_touched = (TERN(TOUCH_SCREEN_CALIBRATION, touch_calibration.calibration.orientation, TOUCH_ORIENTATION) == TOUCH_PORTRAIT ? touchIO.getRawPoint(&y, &x) : touchIO.getRawPoint(&x, &y));
if (!is_touched) return 0;

#if ENABLED(TOUCH_SCREEN_CALIBRATION)
const calibrationState state = touch_calibration.get_calibration_state();
Expand Down
6 changes: 5 additions & 1 deletion Marlin/src/pins/stm32f4/pins_ANET_ET4.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,15 @@
#define TFT_RS_PIN PD13
#define TFT_INTERFACE_FSMC_8BIT

#define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT
#define FSMC_CS_PIN TFT_CS_PIN
#define FSMC_RS_PIN TFT_RS_PIN

//
// Touch Screen
// https://ldm-systems.ru/f/doc/catalog/HY-TFT-2,8/XPT2046.pdf
//
#if ENABLED(TOUCH_SCREEN)
#if NEED_TOUCH_PINS
#define TOUCH_CS_PIN PB2
#define TOUCH_SCK_PIN PB0
#define TOUCH_MOSI_PIN PE5
Expand Down
Loading