Skip to content

Commit

Permalink
LVGL and Classic UI for STM32 (#20552)
Browse files Browse the repository at this point in the history
  • Loading branch information
rhapsodyv authored and thinkyhead committed Apr 29, 2021
1 parent a5dd402 commit fadc8a1
Show file tree
Hide file tree
Showing 22 changed files with 113 additions and 133 deletions.
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 @@ -3242,7 +3242,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

0 comments on commit fadc8a1

Please sign in to comment.