Browse Source

⚡️ SPI+DMA+interrupt method (STM32 / MKS UI) (#23464)

Sola 3 years ago
parent
commit
c79174e862

+ 24 - 0
Marlin/src/HAL/STM32/tft/tft_spi.cpp

@@ -242,5 +242,29 @@ void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Coun
   Abort();
 }
 
+#if ENABLED(USE_SPI_DMA_TC)
+
+  void TFT_SPI::TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
+
+    DMAtx.Init.MemInc = MemoryIncrease;
+    HAL_DMA_Init(&DMAtx);
+
+    if (TFT_MISO_PIN == TFT_MOSI_PIN)
+      SPI_1LINE_TX(&SPIx);
+
+    DataTransferBegin();
+
+    HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 5, 0);
+    HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
+    HAL_DMA_Start_IT(&DMAtx, (uint32_t)Data, (uint32_t)&(SPIx.Instance->DR), Count);
+    __HAL_SPI_ENABLE(&SPIx);
+
+    SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN);   // Enable Tx DMA Request
+  }
+
+  extern "C" void DMA2_Stream3_IRQHandler(void) { HAL_DMA_IRQHandler(&TFT_SPI::DMAtx); }
+
+#endif
+
 #endif // HAS_SPI_TFT
 #endif // HAL_STM32

+ 14 - 4
Marlin/src/HAL/STM32/tft/tft_spi.h

@@ -36,20 +36,25 @@
   #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_DRIVER TFT_SPI
+#define DATASIZE_8BIT  SPI_DATASIZE_8BIT
+#define DATASIZE_16BIT SPI_DATASIZE_16BIT
+#define TFT_IO_DRIVER  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);
+  #if ENABLED(USE_SPI_DMA_TC)
+    static void TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
+  #endif
 
 public:
+  static DMA_HandleTypeDef DMAtx;
+
   static void Init();
   static uint32_t GetID();
   static bool isBusy();
@@ -63,6 +68,11 @@ public:
   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); }
+
+  #if ENABLED(USE_SPI_DMA_TC)
+    static void WriteSequenceIT(uint16_t *Data, uint16_t Count) { TransmitDMA_IT(DMA_MINC_ENABLE, Data, Count); }
+  #endif
+
   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;

+ 3 - 2
Marlin/src/lcd/extui/mks_ui/draw_ui.cpp

@@ -1331,7 +1331,6 @@ void lv_screen_menu_item_onoff_update(lv_obj_t *btn, const bool curValue) {
   lv_label_set_text((lv_obj_t*)btn->child_ll.head, curValue ? machine_menu.enable : machine_menu.disable);
 }
 
-
 #if ENABLED(SDSUPPORT)
 
   void sd_detection() {
@@ -1360,7 +1359,9 @@ void print_time_count() {
 }
 
 void LV_TASK_HANDLER() {
-  lv_task_handler();
+
+  if (TERN1(USE_SPI_DMA_TC, !get_lcd_dma_lock()))
+    lv_task_handler();
 
   #if BOTH(MKS_TEST, SDSUPPORT)
     if (mks_test_flag == 0x1E) mks_hardware_test();

+ 49 - 3
Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp

@@ -133,6 +133,27 @@ void tft_lvgl_init() {
 
   watchdog_refresh();     // LVGL init takes time
 
+  #if ENABLED(USB_FLASH_DRIVE_SUPPORT)
+    uint16_t usb_flash_loop = 1000;
+    #if ENABLED(MULTI_VOLUME) && !HAS_SD_HOST_DRIVE
+      SET_INPUT_PULLUP(SD_DETECT_PIN);
+      if (READ(SD_DETECT_PIN) == LOW) card.changeMedia(&card.media_driver_sdcard);
+      else card.changeMedia(&card.media_driver_usbFlash);
+    #endif
+    do {
+      card.media_driver_usbFlash.idle();
+      watchdog_refresh();
+      delay(2);
+    } while (!card.media_driver_usbFlash.isInserted() && usb_flash_loop--);
+    card.mount();
+  #elif HAS_LOGO_IN_FLASH
+    delay(1000);
+    watchdog_refresh();
+    delay(1000);
+  #endif
+
+  watchdog_refresh();     // LVGL init takes time
+
   #if ENABLED(SDSUPPORT)
     UpdateAssets();
     watchdog_refresh();   // LVGL init takes time
@@ -231,19 +252,44 @@ void tft_lvgl_init() {
   #endif
 }
 
+static lv_disp_drv_t* disp_drv_p;
+
+#if ENABLED(USE_SPI_DMA_TC)
+  bool lcd_dma_trans_lock = false;
+#endif
+
+void dmc_tc_handler(struct __DMA_HandleTypeDef * hdma) {
+  #if ENABLED(USE_SPI_DMA_TC)
+    lv_disp_flush_ready(disp_drv_p);
+    lcd_dma_trans_lock = false;
+    TFT_SPI::Abort();
+  #endif
+}
+
 void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) {
   uint16_t width = area->x2 - area->x1 + 1,
           height = area->y2 - area->y1 + 1;
 
-  SPI_TFT.setWindow((uint16_t)area->x1, (uint16_t)area->y1, width, height);
+  TERN_(USE_SPI_DMA_TC, disp_drv_p = disp);
 
-  SPI_TFT.tftio.WriteSequence((uint16_t*)color_p, width * height);
+  SPI_TFT.setWindow((uint16_t)area->x1, (uint16_t)area->y1, width, height);
 
-  lv_disp_flush_ready(disp); // Indicate you are ready with the flushing
+  #if ENABLED(USE_SPI_DMA_TC)
+    lcd_dma_trans_lock = true;
+    SPI_TFT.tftio.WriteSequenceIT((uint16_t*)color_p, width * height);
+    TFT_SPI::DMAtx.XferCpltCallback = dmc_tc_handler;
+  #else
+    SPI_TFT.tftio.WriteSequence((uint16_t*)color_p, width * height);
+    lv_disp_flush_ready(disp_drv_p); // Indicate you are ready with the flushing
+  #endif
 
   W25QXX.init(SPI_QUARTER_SPEED);
 }
 
+#if ENABLED(USE_SPI_DMA_TC)
+  bool get_lcd_dma_lock() { return lcd_dma_trans_lock; }
+#endif
+
 void lv_fill_rect(lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2, lv_color_t bk_color) {
   uint16_t width, height;
   width = x2 - x1 + 1;

+ 2 - 0
Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.h

@@ -64,6 +64,8 @@ lv_fs_res_t sd_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
 
 void lv_fill_rect(lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2, lv_color_t bk_color);
 
+bool get_lcd_dma_lock();
+
 #ifdef __cplusplus
   } /* C-declarations for C++ */
 #endif

+ 5 - 0
Marlin/src/lcd/tft_io/tft_io.h

@@ -121,6 +121,11 @@ public:
   inline static void WriteReg(uint16_t Reg) { io.WriteReg(Reg); };
 
   inline static void WriteSequence(uint16_t *Data, uint16_t Count) { io.WriteSequence(Data, Count); };
+
+  #if ENABLED(USE_SPI_DMA_TC)
+    inline static void WriteSequenceIT(uint16_t *Data, uint16_t Count) { io.WriteSequenceIT(Data, Count); };
+  #endif
+
   // static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
   inline static void WriteMultiple(uint16_t Color, uint32_t Count) { io.WriteMultiple(Color, Count); };
 

+ 4 - 0
Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h

@@ -44,6 +44,10 @@
 
 //#define LED_PIN                           PB2
 
+#if HAS_TFT_LVGL_UI
+  #define BOARD_INIT OUT_WRITE(PB0, LOW)
+#endif
+
 #include "pins_MKS_ROBIN_NANO_common.h"
 
 #if HAS_TFT_LVGL_UI && FAN1_PIN != PB0 && HEATER_1_PIN != PB0

+ 9 - 3
Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3_common.h

@@ -366,9 +366,15 @@
 
 #endif // HAS_WIRED_LCD
 
+#if HAS_TFT_LVGL_UI
+  #define USE_SPI_DMA_TC
+#endif
+
 #if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI, HAS_WIRED_LCD)
   #define BEEPER_PIN                 EXP1_10_PIN
-  #define BTN_EN1                    EXP2_08_PIN
-  #define BTN_EN2                    EXP2_06_PIN
-  #define BTN_ENC                    EXP1_09_PIN
+  #if DISABLED(USE_SPI_DMA_TC)
+    #define BTN_EN1                  EXP2_08_PIN
+    #define BTN_EN2                  EXP2_06_PIN
+    #define BTN_ENC                  EXP1_09_PIN
+  #endif
 #endif