Browse Source

Multi-Volume. Select Media for LVGL (#21344)

Victor Oliveira 3 years ago
parent
commit
138340ee99
No account linked to committer's email address

+ 9
- 0
Marlin/Configuration_adv.h View File

@@ -1478,6 +1478,15 @@
1478 1478
   // Enable if SD detect is rendered useless (e.g., by using an SD extender)
1479 1479
   //#define NO_SD_DETECT
1480 1480
 
1481
+  // Multiple volume support - EXPERIMENTAL.
1482
+  //#define MULTI_VOLUME
1483
+  #if ENABLED(MULTI_VOLUME)
1484
+    #define VOLUME_SD_ONBOARD
1485
+    #define VOLUME_USB_FLASH_DRIVE
1486
+    #define DEFAULT_VOLUME SD_ONBOARD
1487
+    #define DEFAULT_SHARED_VOLUME USB_FLASH_DRIVE
1488
+  #endif
1489
+
1481 1490
 #endif // SDSUPPORT
1482 1491
 
1483 1492
 /**

+ 9
- 9
Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp View File

@@ -32,7 +32,7 @@ Ctrl_status sd_mmc_spi_test_unit_ready() {
32 32
 Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) {
33 33
   if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
34 34
     return CTRL_NO_PRESENT;
35
-  *nb_sector = card.getSd2Card().cardSize() - 1;
35
+  *nb_sector = card.diskIODriver()->cardSize() - 1;
36 36
   return CTRL_GOOD;
37 37
 }
38 38
 
@@ -74,24 +74,24 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
74 74
   #endif
75 75
 
76 76
   // Start reading
77
-  if (!card.getSd2Card().readStart(addr))
77
+  if (!card.diskIODriver()->readStart(addr))
78 78
     return CTRL_FAIL;
79 79
 
80 80
   // For each specified sector
81 81
   while (nb_sector--) {
82 82
 
83 83
     // Read a sector
84
-    card.getSd2Card().readData(sector_buf);
84
+    card.diskIODriver()->readData(sector_buf);
85 85
 
86 86
     // RAM -> USB
87 87
     if (!udi_msc_trans_block(true, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) {
88
-      card.getSd2Card().readStop();
88
+      card.diskIODriver()->readStop();
89 89
       return CTRL_FAIL;
90 90
     }
91 91
   }
92 92
 
93 93
   // Stop reading
94
-  card.getSd2Card().readStop();
94
+  card.diskIODriver()->readStop();
95 95
 
96 96
   // Done
97 97
   return CTRL_GOOD;
@@ -113,7 +113,7 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
113 113
   }
114 114
   #endif
115 115
 
116
-  if (!card.getSd2Card().writeStart(addr, nb_sector))
116
+  if (!card.diskIODriver()->writeStart(addr, nb_sector))
117 117
     return CTRL_FAIL;
118 118
 
119 119
   // For each specified sector
@@ -121,16 +121,16 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
121 121
 
122 122
     // USB -> RAM
123 123
     if (!udi_msc_trans_block(false, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) {
124
-      card.getSd2Card().writeStop();
124
+      card.diskIODriver()->writeStop();
125 125
       return CTRL_FAIL;
126 126
     }
127 127
 
128 128
     // Write a sector
129
-    card.getSd2Card().writeData(sector_buf);
129
+    card.diskIODriver()->writeData(sector_buf);
130 130
   }
131 131
 
132 132
   // Stop writing
133
-  card.getSd2Card().writeStop();
133
+  card.diskIODriver()->writeStop();
134 134
 
135 135
   // Done
136 136
   return CTRL_GOOD;

+ 25
- 13
Marlin/src/HAL/STM32/msc_sd.cpp View File

@@ -30,54 +30,66 @@
30 30
 
31 31
 class Sd2CardUSBMscHandler : public USBMscHandler {
32 32
 public:
33
+  DiskIODriver* diskIODriver() {
34
+    #if ENABLED(MULTI_VOLUME)
35
+      #if SHARED_VOLUME_IS(SD_ONBOARD)
36
+        return &card.media_sd_spi;
37
+      #elif SHARED_VOLUME_IS(USB_FLASH_DRIVE)
38
+        return &card.media_usbFlashDrive;
39
+      #endif
40
+    #else
41
+      return diskIODriver();
42
+    #endif
43
+  }
44
+
33 45
   bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize) {
34
-    *pBlockNum = card.getSd2Card().cardSize();
46
+    *pBlockNum = diskIODriver()->cardSize();
35 47
     *pBlockSize = BLOCK_SIZE;
36 48
     return true;
37 49
   }
38 50
 
39 51
   bool Write(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) {
40
-    auto sd2card = card.getSd2Card();
52
+    auto sd2card = diskIODriver();
41 53
     // single block
42 54
     if (blkLen == 1) {
43 55
       watchdog_refresh();
44
-      sd2card.writeBlock(blkAddr, pBuf);
56
+      sd2card->writeBlock(blkAddr, pBuf);
45 57
       return true;
46 58
     }
47 59
 
48 60
     // multi block optmization
49
-    sd2card.writeStart(blkAddr, blkLen);
61
+    sd2card->writeStart(blkAddr, blkLen);
50 62
     while (blkLen--) {
51 63
       watchdog_refresh();
52
-      sd2card.writeData(pBuf);
64
+      sd2card->writeData(pBuf);
53 65
       pBuf += BLOCK_SIZE;
54 66
     }
55
-    sd2card.writeStop();
67
+    sd2card->writeStop();
56 68
     return true;
57 69
   }
58 70
 
59 71
   bool Read(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) {
60
-    auto sd2card = card.getSd2Card();
72
+    auto sd2card = diskIODriver();
61 73
     // single block
62 74
     if (blkLen == 1) {
63 75
       watchdog_refresh();
64
-      sd2card.readBlock(blkAddr, pBuf);
76
+      sd2card->readBlock(blkAddr, pBuf);
65 77
       return true;
66 78
     }
67 79
 
68 80
     // multi block optmization
69
-    sd2card.readStart(blkAddr);
81
+    sd2card->readStart(blkAddr);
70 82
     while (blkLen--) {
71 83
       watchdog_refresh();
72
-      sd2card.readData(pBuf);
84
+      sd2card->readData(pBuf);
73 85
       pBuf += BLOCK_SIZE;
74 86
     }
75
-    sd2card.readStop();
87
+    sd2card->readStop();
76 88
     return true;
77 89
   }
78 90
 
79 91
   bool IsReady() {
80
-    return card.isMounted();
92
+    return diskIODriver()->isReady();
81 93
   }
82 94
 };
83 95
 
@@ -105,8 +117,8 @@ USBMscHandler *pSingleMscHandler = &usbMscHandler;
105 117
 void MSC_SD_init() {
106 118
   USBDevice.end();
107 119
   delay(200);
108
-  USBDevice.begin();
109 120
   USBDevice.registerMscHandlers(1, &pSingleMscHandler, Marlin_STORAGE_Inquirydata);
121
+  USBDevice.begin();
110 122
 }
111 123
 
112 124
 #endif // __STM32F1__ && HAS_SD_HOST_DRIVE

+ 1
- 1
Marlin/src/MarlinCore.cpp View File

@@ -757,7 +757,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
757 757
   TERN_(SDSUPPORT, card.manage_media());
758 758
 
759 759
   // Handle USB Flash Drive insert / remove
760
-  TERN_(USB_FLASH_DRIVE_SUPPORT, Sd2Card::idle());
760
+  TERN_(USB_FLASH_DRIVE_SUPPORT, card.diskIODriver()->idle());
761 761
 
762 762
   // Announce Host Keepalive state (if any)
763 763
   TERN_(HOST_KEEPALIVE_FEATURE, gcode.host_keepalive());

+ 1
- 1
Marlin/src/inc/Conditionals_adv.h View File

@@ -245,7 +245,7 @@
245 245
   #define _CUTTER_POWER_PERCENT 2
246 246
   #define _CUTTER_POWER_RPM     3
247 247
   #define _CUTTER_POWER(V)      _CAT(_CUTTER_POWER_, V)
248
-  #define CUTTER_UNIT_IS(V)    (_CUTTER_POWER(CUTTER_POWER_UNIT)    == _CUTTER_POWER(V))
248
+  #define CUTTER_UNIT_IS(V)    (_CUTTER_POWER(CUTTER_POWER_UNIT) == _CUTTER_POWER(V))
249 249
 #endif
250 250
 
251 251
 // Add features that need hardware PWM here

+ 9
- 0
Marlin/src/inc/Conditionals_post.h View File

@@ -356,6 +356,15 @@
356 356
       #define SD_DETECT_STATE LOW
357 357
     #endif
358 358
   #endif
359
+
360
+  #if DISABLED(USB_FLASH_DRIVE_SUPPORT) || BOTH(MULTI_VOLUME, VOLUME_SD_ONBOARD)
361
+    #if ENABLED(SDIO_SUPPORT)
362
+      #define NEED_SD2CARD_SDIO 1
363
+    #else
364
+      #define NEED_SD2CARD_SPI 1
365
+    #endif
366
+  #endif
367
+
359 368
 #endif
360 369
 
361 370
 #if ANY(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT) || !PIN_EXISTS(SD_DETECT)

+ 2
- 2
Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp View File

@@ -148,7 +148,7 @@ static void lv_kb_event_cb(lv_obj_t *kb, lv_event_t event) {
148 148
             public_buf_l[6] = 0x00;
149 149
             raw_send_to_wifi((uint8_t*)public_buf_l, 6);
150 150
 
151
-            last_disp_state = KEY_BOARD_UI;
151
+            last_disp_state = KEYBOARD_UI;
152 152
             lv_clear_keyboard();
153 153
             wifi_tips_type = TIPS_TYPE_JOINING;
154 154
             lv_draw_wifi_tips();
@@ -216,7 +216,7 @@ static void lv_kb_event_cb(lv_obj_t *kb, lv_event_t event) {
216 216
 }
217 217
 
218 218
 void lv_draw_keyboard() {
219
-  scr = lv_screen_create(KEY_BOARD_UI, "");
219
+  scr = lv_screen_create(KEYBOARD_UI, "");
220 220
 
221 221
   // Create styles for the keyboard
222 222
   static lv_style_t rel_style, pr_style;

+ 73
- 0
Marlin/src/lcd/extui/lib/mks_ui/draw_media_select.cpp View File

@@ -0,0 +1,73 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+#include "../../../../inc/MarlinConfigPre.h"
23
+
24
+#if BOTH(HAS_TFT_LVGL_UI, MULTI_VOLUME)
25
+
26
+#include "draw_ui.h"
27
+#include <lv_conf.h>
28
+
29
+#include "../../../../inc/MarlinConfig.h"
30
+#include "../../../../sd/cardreader.h"
31
+
32
+extern lv_group_t *g;
33
+static lv_obj_t *scr;
34
+
35
+enum {
36
+  ID_T_USB_DISK = 1,
37
+  ID_T_SD_DISK,
38
+  ID_T_RETURN
39
+};
40
+
41
+#if ENABLED(MKS_TEST)
42
+  extern uint8_t curent_disp_ui;
43
+#endif
44
+
45
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
46
+  if (event != LV_EVENT_RELEASED) return;
47
+  lv_clear_media_select();
48
+  switch (obj->mks_obj_id) {
49
+    case ID_T_USB_DISK: card.changeMedia(&card.media_usbFlashDrive); break;
50
+    case ID_T_SD_DISK:  card.changeMedia(&card.media_sd_spi); break;
51
+    case ID_T_RETURN:
52
+      TERN_(MKS_TEST, curent_disp_ui = 1);
53
+      lv_draw_ready_print();
54
+      return;
55
+  }
56
+  lv_draw_print_file();
57
+}
58
+
59
+void lv_draw_media_select() {
60
+  scr = lv_screen_create(MEDIA_SELECT_UI);
61
+  lv_big_button_create(scr, "F:/bmp_sd.bin", media_select_menu.sd_disk, INTERVAL_V, titleHeight, event_handler, ID_T_SD_DISK);
62
+  lv_big_button_create(scr, "F:/bmp_usb_disk.bin", media_select_menu.usb_disk, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_T_USB_DISK);
63
+  lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_T_RETURN);
64
+}
65
+
66
+void lv_clear_media_select() {
67
+  #if HAS_ROTARY_ENCODER
68
+    if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
69
+  #endif
70
+  lv_obj_del(scr);
71
+}
72
+
73
+#endif // HAS_TFT_LVGL_UI

+ 33
- 0
Marlin/src/lcd/extui/lib/mks_ui/draw_media_select.h View File

@@ -0,0 +1,33 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+#pragma once
23
+
24
+#ifdef __cplusplus
25
+  extern "C" { /* C-declarations for C++ */
26
+#endif
27
+
28
+extern void lv_draw_media_select();
29
+extern void lv_clear_media_select();
30
+
31
+#ifdef __cplusplus
32
+  } /* C-declarations for C++ */
33
+#endif

+ 2
- 1
Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp View File

@@ -177,7 +177,7 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) {
177 177
     }
178 178
     else {
179 179
       lv_clear_print_file();
180
-      lv_draw_ready_print();
180
+      TERN(MULTI_VOLUME, lv_draw_media_select(), lv_draw_ready_print());
181 181
     }
182 182
   }
183 183
   else {
@@ -248,6 +248,7 @@ static char test_public_buf_l[40];
248 248
 void disp_gcode_icon(uint8_t file_num) {
249 249
   uint8_t i;
250 250
 
251
+  // TODO: set current media title?!
251 252
   scr = lv_screen_create(PRINT_FILE_UI, "");
252 253
 
253 254
   // Create image buttons

+ 1
- 1
Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp View File

@@ -73,7 +73,7 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) {
73 73
     case ID_INFO_EXT:  uiCfg.curTempType = 0; lv_draw_preHeat(); break;
74 74
     case ID_INFO_BED:  uiCfg.curTempType = 1; lv_draw_preHeat(); break;
75 75
     case ID_INFO_FAN:  lv_draw_fan(); break;
76
-    case ID_PRINT:  lv_draw_print_file(); break;
76
+    case ID_PRINT: TERN(MULTI_VOLUME, lv_draw_media_select(), lv_draw_print_file()); break;
77 77
   }
78 78
 }
79 79
 

+ 64
- 114
Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp View File

@@ -447,111 +447,63 @@ char *getDispText(int index) {
447 447
   ZERO(public_buf_l);
448 448
 
449 449
   switch (disp_state_stack._disp_state[index]) {
450
-    case PRINT_READY_UI:
451
-      strcpy(public_buf_l, main_menu.title);
452
-      break;
453
-    case PRINT_FILE_UI:
454
-      strcpy(public_buf_l, file_menu.title);
455
-      break;
450
+    case PRINT_READY_UI:      strcpy(public_buf_l, main_menu.title); break;
451
+    case PRINT_FILE_UI:       strcpy(public_buf_l, file_menu.title); break;
456 452
     case PRINTING_UI:
457
-      if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI
458
-        #ifndef TFT35
459
-          || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI
460
-          || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI
461
-        #endif
462
-      )    strcpy(public_buf_l, common_menu.print_special_title);
463
-      else strcpy(public_buf_l, printing_menu.title);
464
-      break;
465
-    case MOVE_MOTOR_UI:
466
-      strcpy(public_buf_l, move_menu.title);
453
+      switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) {
454
+        IF_DISABLED(TFT35, case OPERATE_UI: case PAUSE_UI:)
455
+        case PRINTING_UI:     strcpy(public_buf_l, common_menu.print_special_title); break;
456
+        default:              strcpy(public_buf_l, printing_menu.title); break;
457
+      }
467 458
       break;
459
+    case MOVE_MOTOR_UI:       strcpy(public_buf_l, move_menu.title); break;
468 460
     case OPERATE_UI:
469
-      if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI
470
-        #ifndef TFT35
471
-          || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI
472
-          || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI
473
-        #endif
474
-      )    strcpy(public_buf_l, common_menu.operate_special_title);
475
-      else strcpy(public_buf_l, operation_menu.title);
461
+      switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) {
462
+        IF_DISABLED(TFT35, case OPERATE_UI: case PAUSE_UI:)
463
+        case PRINTING_UI:     strcpy(public_buf_l, common_menu.operate_special_title); break;
464
+        default:              strcpy(public_buf_l, operation_menu.title); break;
465
+      }
476 466
       break;
477 467
 
478 468
     case PAUSE_UI:
479
-      if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI
480
-        || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI
481
-        || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI
482
-      )    strcpy(public_buf_l, common_menu.pause_special_title);
483
-      else strcpy(public_buf_l, pause_menu.title);
484
-      break;
485
-
486
-    case EXTRUSION_UI:
487
-      strcpy(public_buf_l, extrude_menu.title);
488
-      break;
489
-    case CHANGE_SPEED_UI:
490
-      strcpy(public_buf_l, speed_menu.title);
491
-      break;
492
-    case FAN_UI:
493
-      strcpy(public_buf_l, fan_menu.title);
469
+      switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) {
470
+        case OPERATE_UI:
471
+        case PAUSE_UI:
472
+        case PRINTING_UI:     strcpy(public_buf_l, common_menu.pause_special_title); break;
473
+        default:              strcpy(public_buf_l, pause_menu.title); break;
474
+      }
494 475
       break;
476
+    case EXTRUSION_UI:        strcpy(public_buf_l, extrude_menu.title); break;
477
+    case CHANGE_SPEED_UI:     strcpy(public_buf_l, speed_menu.title); break;
478
+    case FAN_UI:              strcpy(public_buf_l, fan_menu.title); break;
495 479
     case PRE_HEAT_UI:
496
-      if ((disp_state_stack._disp_state[disp_state_stack._disp_index - 1] == OPERATE_UI))
497
-           strcpy(public_buf_l, preheat_menu.adjust_title);
498
-      else strcpy(public_buf_l, preheat_menu.title);
499
-      break;
500
-    case SET_UI:
501
-      strcpy(public_buf_l, set_menu.title);
502
-      break;
503
-    case ZERO_UI:
504
-      strcpy(public_buf_l, home_menu.title);
505
-      break;
506
-    case SPRAYER_UI: break;
507
-    case MACHINE_UI: break;
508
-    case LANGUAGE_UI:
509
-      strcpy(public_buf_l, language_menu.title);
510
-      break;
511
-    case ABOUT_UI:
512
-      strcpy(public_buf_l, about_menu.title);
513
-      break;
514
-    case LOG_UI: break;
515
-    case DISK_UI:
516
-      strcpy(public_buf_l, filesys_menu.title);
517
-      break;
518
-    case DIALOG_UI:
519
-      strcpy(public_buf_l, common_menu.dialog_confirm_title);
520
-      break;
521
-    case WIFI_UI:
522
-      strcpy(public_buf_l, wifi_menu.title);
480
+      switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) {
481
+        case OPERATE_UI:      strcpy(public_buf_l, preheat_menu.adjust_title);
482
+        default:              strcpy(public_buf_l, preheat_menu.title); break;
483
+      }
523 484
       break;
485
+    case SET_UI:              strcpy(public_buf_l, set_menu.title); break;
486
+    case ZERO_UI:             strcpy(public_buf_l, home_menu.title); break;
487
+    case SPRAYER_UI:          break;
488
+    case MACHINE_UI:          break;
489
+    case LANGUAGE_UI:         strcpy(public_buf_l, language_menu.title); break;
490
+    case ABOUT_UI:            strcpy(public_buf_l, about_menu.title); break;
491
+    case LOG_UI:              break;
492
+    case DISK_UI:             strcpy(public_buf_l, filesys_menu.title); break;
493
+    case DIALOG_UI:           strcpy(public_buf_l, common_menu.dialog_confirm_title); break;
494
+    case WIFI_UI:             strcpy(public_buf_l, wifi_menu.title); break;
524 495
     case MORE_UI:
525
-    case PRINT_MORE_UI:
526
-      strcpy(public_buf_l, more_menu.title);
527
-      break;
528
-    case FILAMENTCHANGE_UI:
529
-      strcpy(public_buf_l, filament_menu.title);
530
-      break;
496
+    case PRINT_MORE_UI:       strcpy(public_buf_l, more_menu.title); break;
497
+    case FILAMENTCHANGE_UI:   strcpy(public_buf_l, filament_menu.title); break;
531 498
     case LEVELING_UI:
532
-    case MESHLEVELING_UI:
533
-      strcpy(public_buf_l, leveling_menu.title);
534
-      break;
535
-    case BIND_UI:
536
-      strcpy(public_buf_l, cloud_menu.title);
537
-      break;
538
-    case TOOL_UI:
539
-      strcpy(public_buf_l, tool_menu.title);
540
-      break;
541
-    case WIFI_LIST_UI:
542
-      #if ENABLED(MKS_WIFI_MODULE)
543
-        strcpy(public_buf_l, list_menu.title);
544
-        break;
545
-      #endif
546
-    case MACHINE_PARA_UI:
547
-      strcpy(public_buf_l, MachinePara_menu.title);
548
-      break;
549
-    case BABY_STEP_UI:
550
-      strcpy(public_buf_l, operation_menu.babystep);
551
-      break;
552
-    case EEPROM_SETTINGS_UI:
553
-      strcpy(public_buf_l, eeprom_menu.title);
554
-      break;
499
+    case MESHLEVELING_UI:     strcpy(public_buf_l, leveling_menu.title); break;
500
+    case BIND_UI:             strcpy(public_buf_l, cloud_menu.title); break;
501
+    case TOOL_UI:             strcpy(public_buf_l, tool_menu.title); break;
502
+    case WIFI_LIST_UI:        TERN_(MKS_WIFI_MODULE, strcpy(public_buf_l, list_menu.title)); break;
503
+    case MACHINE_PARA_UI:     strcpy(public_buf_l, MachinePara_menu.title); break;
504
+    case BABY_STEP_UI:        strcpy(public_buf_l, operation_menu.babystep); break;
505
+    case EEPROM_SETTINGS_UI:  strcpy(public_buf_l, eeprom_menu.title); break;
506
+    case MEDIA_SELECT_UI:     strcpy(public_buf_l, media_select_menu.title); break;
555 507
     default: break;
556 508
   }
557 509
 
@@ -828,11 +780,9 @@ void GUI_RefreshPage() {
828 780
       }
829 781
       break;
830 782
 
831
-    case OPERATE_UI:
832
-      break;
783
+    case OPERATE_UI: break;
833 784
 
834
-    case PAUSE_UI:
835
-      break;
785
+    case PAUSE_UI: break;
836 786
 
837 787
     case FAN_UI:
838 788
       if (temps_update_flag) {
@@ -841,8 +791,7 @@ void GUI_RefreshPage() {
841 791
       }
842 792
       break;
843 793
 
844
-    case MOVE_MOTOR_UI:
845
-      break;
794
+    case MOVE_MOTOR_UI: break;
846 795
 
847 796
     #if ENABLED(MKS_WIFI_MODULE)
848 797
       case WIFI_UI:
@@ -852,10 +801,9 @@ void GUI_RefreshPage() {
852 801
         }
853 802
         break;
854 803
 
855
-      case BIND_UI:
856
-        refresh_bind_ui();
857
-        break;
804
+      case BIND_UI: refresh_bind_ui(); break;
858 805
     #endif
806
+
859 807
     case FILAMENTCHANGE_UI:
860 808
       if (temps_update_flag) {
861 809
         temps_update_flag = false;
@@ -866,10 +814,8 @@ void GUI_RefreshPage() {
866 814
       filament_dialog_handle();
867 815
       TERN_(MKS_WIFI_MODULE, wifi_scan_handle());
868 816
       break;
869
-    case MESHLEVELING_UI:
870
-      break;
871
-    case HARDWARE_TEST_UI:
872
-      break;
817
+    case MESHLEVELING_UI: break;
818
+    case HARDWARE_TEST_UI: break;
873 819
     case WIFI_LIST_UI:
874 820
       #if ENABLED(MKS_WIFI_MODULE)
875 821
         if (printing_rate_update_flag) {
@@ -878,8 +824,8 @@ void GUI_RefreshPage() {
878 824
         }
879 825
       #endif
880 826
       break;
881
-    case KEY_BOARD_UI:
882
-      break;
827
+    case KEYBOARD_UI: break;
828
+
883 829
     #if ENABLED(MKS_WIFI_MODULE)
884 830
       case WIFI_TIPS_UI:
885 831
         switch (wifi_tips_type) {
@@ -932,6 +878,7 @@ void GUI_RefreshPage() {
932 878
         disp_z_offset_value();
933 879
       }
934 880
       break;
881
+
935 882
     default: break;
936 883
   }
937 884
 
@@ -982,7 +929,7 @@ void clear_cur_ui() {
982 929
     #if ENABLED(MKS_WIFI_MODULE)
983 930
       case WIFI_LIST_UI:              lv_clear_wifi_list(); break;
984 931
     #endif
985
-    case KEY_BOARD_UI:                lv_clear_keyboard(); break;
932
+    case KEYBOARD_UI:                 lv_clear_keyboard(); break;
986 933
     #if ENABLED(MKS_WIFI_MODULE)
987 934
       case WIFI_TIPS_UI:              lv_clear_wifi_tips(); break;
988 935
     #endif
@@ -1013,9 +960,9 @@ void clear_cur_ui() {
1013 960
     case NUMBER_KEY_UI:               lv_clear_number_key(); break;
1014 961
     case BABY_STEP_UI:                lv_clear_baby_stepping(); break;
1015 962
     case PAUSE_POS_UI:                lv_clear_pause_position(); break;
1016
-      #if HAS_TRINAMIC_CONFIG
1017
-        case TMC_CURRENT_UI:          lv_clear_tmc_current_settings(); break;
1018
-      #endif
963
+    #if HAS_TRINAMIC_CONFIG
964
+      case TMC_CURRENT_UI:            lv_clear_tmc_current_settings(); break;
965
+    #endif
1019 966
     case EEPROM_SETTINGS_UI:          lv_clear_eeprom_settings(); break;
1020 967
     #if HAS_STEALTHCHOP
1021 968
       case TMC_MODE_UI:               lv_clear_tmc_step_mode_settings(); break;
@@ -1032,6 +979,9 @@ void clear_cur_ui() {
1032 979
     #if ENABLED(TOUCH_SCREEN_CALIBRATION)
1033 980
       case TOUCH_CALIBRATION_UI:      lv_clear_touch_calibration_screen(); break;
1034 981
     #endif
982
+    #if ENABLED(MULTI_VOLUME)
983
+      case MEDIA_SELECT_UI:           lv_clear_media_select(); break;
984
+    #endif
1035 985
     default: break;
1036 986
   }
1037 987
 }
@@ -1087,7 +1037,7 @@ void draw_return_ui() {
1087 1037
       #if ENABLED(MKS_WIFI_MODULE)
1088 1038
         case WIFI_LIST_UI:              lv_draw_wifi_list(); break;
1089 1039
       #endif
1090
-      case KEY_BOARD_UI:                lv_draw_keyboard(); break;
1040
+      case KEYBOARD_UI:                 lv_draw_keyboard(); break;
1091 1041
       #if ENABLED(MKS_WIFI_MODULE)
1092 1042
         case WIFI_TIPS_UI:              lv_draw_wifi_tips(); break;
1093 1043
       #endif

+ 3
- 1
Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h View File

@@ -76,6 +76,7 @@
76 76
 #include "draw_homing_sensitivity_settings.h"
77 77
 #include "draw_baby_stepping.h"
78 78
 #include "draw_keyboard.h"
79
+#include "draw_media_select.h"
79 80
 #include "draw_encoder_settings.h"
80 81
 
81 82
 #include "../../../../inc/MarlinConfigPre.h"
@@ -289,7 +290,7 @@ typedef enum {
289 290
   TOOL_UI,
290 291
   HARDWARE_TEST_UI,
291 292
   WIFI_LIST_UI,
292
-  KEY_BOARD_UI,
293
+  KEYBOARD_UI,
293 294
   WIFI_TIPS_UI,
294 295
   MACHINE_PARA_UI,
295 296
   MACHINE_SETTINGS_UI,
@@ -327,6 +328,7 @@ typedef enum {
327 328
   ENCODER_SETTINGS_UI,
328 329
   TOUCH_CALIBRATION_UI,
329 330
   GCODE_UI,
331
+  MEDIA_SELECT_UI,
330 332
 } DISP_STATE;
331 333
 
332 334
 typedef struct {

+ 7
- 0
Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp View File

@@ -197,6 +197,13 @@ static const char assets[][LONG_FILENAME_LENGTH] = {
197 197
     "bmp_cloud.bin",
198 198
   #endif
199 199
 
200
+  #if ENABLED(MULTI_VOLUME)
201
+    "bmp_usb_disk.bin",
202
+    // "bmp_usb_disk_sel.bin",
203
+    "bmp_sd.bin",
204
+    // "bmp_sd_sel.bin",
205
+  #endif
206
+
200 207
   // Babystep screen
201 208
   "bmp_baby_move0_01.bin",
202 209
   "bmp_baby_move0_05.bin",

+ 1
- 0
Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h View File

@@ -540,6 +540,7 @@
540 540
 #define USB_DRIVE_BACK_EN                 "< Back"
541 541
 #define FILE_PAGES_EN                     "%d/%d"
542 542
 #define FILE_NEXT_PAGE_EN                 "Next Page"
543
+#define MEDIA_SELECT_TITLE_EN             "Select Media"
543 544
 
544 545
 //BUILD PLATE
545 546
 #define PLATE_TITLE_EN                    "Build Plate"

+ 5
- 0
Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp View File

@@ -56,6 +56,7 @@ tool_menu_def                tool_menu;
56 56
 MachinePara_menu_def         MachinePara_menu;
57 57
 pause_msg_def                pause_msg_menu;
58 58
 eeprom_def                   eeprom_menu;
59
+media_select_menu_def        media_select_menu;
59 60
 
60 61
 machine_common_def machine_menu;
61 62
 void machine_setting_disp() {
@@ -821,6 +822,10 @@ void disp_language_init() {
821 822
 
822 823
   filament_menu.stat_temp = TEXT_VALUE;
823 824
 
825
+  media_select_menu.title    = MEDIA_SELECT_TITLE_EN;
826
+  media_select_menu.sd_disk  = SD_CARD_TITLE_EN;
827
+  media_select_menu.usb_disk = USB_DRIVE_TITLE_EN;
828
+
824 829
   machine_menu.key_0     = KEYBOARD_KEY0_EN;
825 830
   machine_menu.key_1     = KEYBOARD_KEY1_EN;
826 831
   machine_menu.key_2     = KEYBOARD_KEY2_EN;

+ 8
- 0
Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h View File

@@ -706,6 +706,14 @@ typedef struct tool_menu_disp {
706 706
 
707 707
 extern tool_menu_def tool_menu;
708 708
 
709
+typedef struct media_select_menu_disp {
710
+  const char *title;
711
+  const char *sd_disk;
712
+  const char *usb_disk;
713
+} media_select_menu_def;
714
+
715
+extern media_select_menu_def media_select_menu;
716
+
709 717
 typedef struct MachinePara_menu_disp {
710 718
   const char *title;
711 719
   const char *MachineSetting;

+ 1
- 1
Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp View File

@@ -1142,7 +1142,7 @@ static void wifi_list_msg_handle(uint8_t * msg, uint16_t msgLen) {
1142 1142
   int8_t valid_name_num;
1143 1143
 
1144 1144
   if (msgLen <= 0) return;
1145
-  if (disp_state == KEY_BOARD_UI) return;
1145
+  if (disp_state == KEYBOARD_UI) return;
1146 1146
 
1147 1147
   wifi_list.getNameNum = msg[0];
1148 1148
 

+ 26
- 22
Marlin/src/sd/Sd2Card.cpp View File

@@ -30,7 +30,7 @@
30 30
 
31 31
 #include "../inc/MarlinConfig.h"
32 32
 
33
-#if ENABLED(SDSUPPORT) && NONE(USB_FLASH_DRIVE_SUPPORT, SDIO_SUPPORT)
33
+#if NEED_SD2CARD_SPI
34 34
 
35 35
 /* Enable FAST CRC computations - You can trade speed for FLASH space if
36 36
  * needed by disabling the following define */
@@ -88,7 +88,7 @@
88 88
 #endif
89 89
 
90 90
 // Send command and return error code. Return zero for OK
91
-uint8_t Sd2Card::cardCommand(const uint8_t cmd, const uint32_t arg) {
91
+uint8_t DiskIODriver_SPI_SD::cardCommand(const uint8_t cmd, const uint32_t arg) {
92 92
   // Select card
93 93
   chipSelect();
94 94
 
@@ -133,7 +133,7 @@ uint8_t Sd2Card::cardCommand(const uint8_t cmd, const uint32_t arg) {
133 133
  * \return The number of 512 byte data blocks in the card
134 134
  *         or zero if an error occurs.
135 135
  */
136
-uint32_t Sd2Card::cardSize() {
136
+uint32_t DiskIODriver_SPI_SD::cardSize() {
137 137
   csd_t csd;
138 138
   if (!readCSD(&csd)) return 0;
139 139
   if (csd.v1.csd_ver == 0) {
@@ -155,12 +155,12 @@ uint32_t Sd2Card::cardSize() {
155 155
   }
156 156
 }
157 157
 
158
-void Sd2Card::chipDeselect() {
158
+void DiskIODriver_SPI_SD::chipDeselect() {
159 159
   extDigitalWrite(chipSelectPin_, HIGH);
160 160
   spiSend(0xFF); // Ensure MISO goes high impedance
161 161
 }
162 162
 
163
-void Sd2Card::chipSelect() {
163
+void DiskIODriver_SPI_SD::chipSelect() {
164 164
   spiInit(spiRate_);
165 165
   extDigitalWrite(chipSelectPin_, LOW);
166 166
 }
@@ -178,7 +178,7 @@ void Sd2Card::chipSelect() {
178 178
  *
179 179
  * \return true for success, false for failure.
180 180
  */
181
-bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
181
+bool DiskIODriver_SPI_SD::erase(uint32_t firstBlock, uint32_t lastBlock) {
182 182
   if (ENABLED(SDCARD_READONLY)) return false;
183 183
 
184 184
   csd_t csd;
@@ -216,7 +216,7 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
216 216
  * \return true if single block erase is supported.
217 217
  *         false if single block erase is not supported.
218 218
  */
219
-bool Sd2Card::eraseSingleBlockEnable() {
219
+bool DiskIODriver_SPI_SD::eraseSingleBlockEnable() {
220 220
   csd_t csd;
221 221
   return readCSD(&csd) ? csd.v1.erase_blk_en : false;
222 222
 }
@@ -230,7 +230,7 @@ bool Sd2Card::eraseSingleBlockEnable() {
230 230
  * \return true for success, false for failure.
231 231
  * The reason for failure can be determined by calling errorCode() and errorData().
232 232
  */
233
-bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
233
+bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
234 234
   #if IS_TEENSY_35_36 || IS_TEENSY_40_41
235 235
     chipSelectPin_ = BUILTIN_SDCARD;
236 236
     const uint8_t ret = SDHC_CardInit();
@@ -324,10 +324,12 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
324 324
   }
325 325
   chipDeselect();
326 326
 
327
+  ready = true;
327 328
   return setSckRate(sckRateID);
328 329
 
329 330
   FAIL:
330 331
   chipDeselect();
332
+  ready = false;
331 333
   return false;
332 334
 }
333 335
 
@@ -338,7 +340,7 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
338 340
  * \param[out] dst Pointer to the location that will receive the data.
339 341
  * \return true for success, false for failure.
340 342
  */
341
-bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t *dst) {
343
+bool DiskIODriver_SPI_SD::readBlock(uint32_t blockNumber, uint8_t *dst) {
342 344
   #if IS_TEENSY_35_36 || IS_TEENSY_40_41
343 345
     return 0 == SDHC_CardReadBlock(dst, blockNumber);
344 346
   #endif
@@ -378,7 +380,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t *dst) {
378 380
  *
379 381
  * \return true for success, false for failure.
380 382
  */
381
-bool Sd2Card::readData(uint8_t *dst) {
383
+bool DiskIODriver_SPI_SD::readData(uint8_t *dst) {
382 384
   chipSelect();
383 385
   return readData(dst, 512);
384 386
 }
@@ -445,7 +447,7 @@ bool Sd2Card::readData(uint8_t *dst) {
445 447
   #endif
446 448
 #endif // SD_CHECK_AND_RETRY
447 449
 
448
-bool Sd2Card::readData(uint8_t *dst, const uint16_t count) {
450
+bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) {
449 451
   bool success = false;
450 452
 
451 453
   const millis_t read_timeout = millis() + SD_READ_TIMEOUT;
@@ -477,7 +479,7 @@ bool Sd2Card::readData(uint8_t *dst, const uint16_t count) {
477 479
 }
478 480
 
479 481
 /** read CID or CSR register */
480
-bool Sd2Card::readRegister(const uint8_t cmd, void *buf) {
482
+bool DiskIODriver_SPI_SD::readRegister(const uint8_t cmd, void *buf) {
481 483
   uint8_t *dst = reinterpret_cast<uint8_t*>(buf);
482 484
   if (cardCommand(cmd, 0)) {
483 485
     error(SD_CARD_ERROR_READ_REG);
@@ -497,7 +499,7 @@ bool Sd2Card::readRegister(const uint8_t cmd, void *buf) {
497 499
  *
498 500
  * \return true for success, false for failure.
499 501
  */
500
-bool Sd2Card::readStart(uint32_t blockNumber) {
502
+bool DiskIODriver_SPI_SD::readStart(uint32_t blockNumber) {
501 503
   if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
502 504
 
503 505
   const bool success = !cardCommand(CMD18, blockNumber);
@@ -511,7 +513,7 @@ bool Sd2Card::readStart(uint32_t blockNumber) {
511 513
  *
512 514
  * \return true for success, false for failure.
513 515
  */
514
-bool Sd2Card::readStop() {
516
+bool DiskIODriver_SPI_SD::readStop() {
515 517
   chipSelect();
516 518
   const bool success = !cardCommand(CMD12, 0);
517 519
   if (!success) error(SD_CARD_ERROR_CMD12);
@@ -531,7 +533,7 @@ bool Sd2Card::readStop() {
531 533
  * \return The value one, true, is returned for success and the value zero,
532 534
  * false, is returned for an invalid value of \a sckRateID.
533 535
  */
534
-bool Sd2Card::setSckRate(const uint8_t sckRateID) {
536
+bool DiskIODriver_SPI_SD::setSckRate(const uint8_t sckRateID) {
535 537
   const bool success = (sckRateID <= 6);
536 538
   if (success) spiRate_ = sckRateID; else error(SD_CARD_ERROR_SCK_RATE);
537 539
   return success;
@@ -542,12 +544,14 @@ bool Sd2Card::setSckRate(const uint8_t sckRateID) {
542 544
  * \param[in] timeout_ms Timeout to abort.
543 545
  * \return true for success, false for timeout.
544 546
  */
545
-bool Sd2Card::waitNotBusy(const millis_t timeout_ms) {
547
+bool DiskIODriver_SPI_SD::waitNotBusy(const millis_t timeout_ms) {
546 548
   const millis_t wait_timeout = millis() + timeout_ms;
547 549
   while (spiRec() != 0xFF) if (ELAPSED(millis(), wait_timeout)) return false;
548 550
   return true;
549 551
 }
550 552
 
553
+void DiskIODriver_SPI_SD::error(const uint8_t code) { errorCode_ = code; }
554
+
551 555
 /**
552 556
  * Write a 512 byte block to an SD card.
553 557
  *
@@ -555,7 +559,7 @@ bool Sd2Card::waitNotBusy(const millis_t timeout_ms) {
555 559
  * \param[in] src Pointer to the location of the data to be written.
556 560
  * \return true for success, false for failure.
557 561
  */
558
-bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t *src) {
562
+bool DiskIODriver_SPI_SD::writeBlock(uint32_t blockNumber, const uint8_t *src) {
559 563
   if (ENABLED(SDCARD_READONLY)) return false;
560 564
 
561 565
   #if IS_TEENSY_35_36 || IS_TEENSY_40_41
@@ -586,7 +590,7 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t *src) {
586 590
  * \param[in] src Pointer to the location of the data to be written.
587 591
  * \return true for success, false for failure.
588 592
  */
589
-bool Sd2Card::writeData(const uint8_t *src) {
593
+bool DiskIODriver_SPI_SD::writeData(const uint8_t *src) {
590 594
   if (ENABLED(SDCARD_READONLY)) return false;
591 595
 
592 596
   bool success = true;
@@ -601,7 +605,7 @@ bool Sd2Card::writeData(const uint8_t *src) {
601 605
 }
602 606
 
603 607
 // Send one block of data for write block or write multiple blocks
604
-bool Sd2Card::writeData(const uint8_t token, const uint8_t *src) {
608
+bool DiskIODriver_SPI_SD::writeData(const uint8_t token, const uint8_t *src) {
605 609
   if (ENABLED(SDCARD_READONLY)) return false;
606 610
 
607 611
   const uint16_t crc = TERN(SD_CHECK_AND_RETRY, CRC_CCITT(src, 512), 0xFFFF);
@@ -629,7 +633,7 @@ bool Sd2Card::writeData(const uint8_t token, const uint8_t *src) {
629 633
  *
630 634
  * \return true for success, false for failure.
631 635
  */
632
-bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
636
+bool DiskIODriver_SPI_SD::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
633 637
   if (ENABLED(SDCARD_READONLY)) return false;
634 638
 
635 639
   bool success = false;
@@ -650,7 +654,7 @@ bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
650 654
  *
651 655
  * \return true for success, false for failure.
652 656
  */
653
-bool Sd2Card::writeStop() {
657
+bool DiskIODriver_SPI_SD::writeStop() {
654 658
   if (ENABLED(SDCARD_READONLY)) return false;
655 659
 
656 660
   bool success = false;
@@ -666,4 +670,4 @@ bool Sd2Card::writeStop() {
666 670
   return success;
667 671
 }
668 672
 
669
-#endif // SDSUPPORT
673
+#endif // NEED_SD2CARD_SPI

+ 65
- 54
Marlin/src/sd/Sd2Card.h View File

@@ -35,47 +35,50 @@
35 35
 
36 36
 #include "SdFatConfig.h"
37 37
 #include "SdInfo.h"
38
+#include "disk_io_driver.h"
38 39
 
39 40
 #include <stdint.h>
40 41
 
41
-uint16_t const SD_INIT_TIMEOUT = 2000,    // init timeout ms
42
-               SD_ERASE_TIMEOUT = 10000,  // erase timeout ms
43
-               SD_READ_TIMEOUT = 300,     // read timeout ms
44
-               SD_WRITE_TIMEOUT = 600;    // write time out ms
42
+uint16_t const SD_INIT_TIMEOUT  = 2000,  // (ms) Init timeout
43
+               SD_ERASE_TIMEOUT = 10000, // (ms) Erase timeout
44
+               SD_READ_TIMEOUT  = 300,   // (ms) Read timeout
45
+               SD_WRITE_TIMEOUT = 600;   // (ms) Write timeout
45 46
 
46 47
 // SD card errors
47
-uint8_t const SD_CARD_ERROR_CMD0 = 0x01,                // timeout error for command CMD0 (initialize card in SPI mode)
48
-              SD_CARD_ERROR_CMD8 = 0x02,                // CMD8 was not accepted - not a valid SD card
49
-              SD_CARD_ERROR_CMD12 = 0x03,               // card returned an error response for CMD12 (write stop)
50
-              SD_CARD_ERROR_CMD17 = 0x04,               // card returned an error response for CMD17 (read block)
51
-              SD_CARD_ERROR_CMD18 = 0x05,               // card returned an error response for CMD18 (read multiple block)
52
-              SD_CARD_ERROR_CMD24 = 0x06,               // card returned an error response for CMD24 (write block)
53
-              SD_CARD_ERROR_CMD25 = 0x07,               // WRITE_MULTIPLE_BLOCKS command failed
54
-              SD_CARD_ERROR_CMD58 = 0x08,               // card returned an error response for CMD58 (read OCR)
55
-              SD_CARD_ERROR_ACMD23 = 0x09,              // SET_WR_BLK_ERASE_COUNT failed
56
-              SD_CARD_ERROR_ACMD41 = 0x0A,              // ACMD41 initialization process timeout
57
-              SD_CARD_ERROR_BAD_CSD = 0x0B,             // card returned a bad CSR version field
58
-              SD_CARD_ERROR_ERASE = 0x0C,               // erase block group command failed
59
-              SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0x0D,  // card not capable of single block erase
60
-              SD_CARD_ERROR_ERASE_TIMEOUT = 0x0E,       // Erase sequence timed out
61
-              SD_CARD_ERROR_READ = 0x0F,                // card returned an error token instead of read data
62
-              SD_CARD_ERROR_READ_REG = 0x10,            // read CID or CSD failed
63
-              SD_CARD_ERROR_READ_TIMEOUT = 0x11,        // timeout while waiting for start of read data
64
-              SD_CARD_ERROR_STOP_TRAN = 0x12,           // card did not accept STOP_TRAN_TOKEN
65
-              SD_CARD_ERROR_WRITE = 0x13,               // card returned an error token as a response to a write operation
66
-              SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14,    // REMOVE - not used ... attempt to write protected block zero
67
-              SD_CARD_ERROR_WRITE_MULTIPLE = 0x15,      // card did not go ready for a multiple block write
68
-              SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16,   // card returned an error to a CMD13 status check after a write
69
-              SD_CARD_ERROR_WRITE_TIMEOUT = 0x17,       // timeout occurred during write programming
70
-              SD_CARD_ERROR_SCK_RATE = 0x18,            // incorrect rate selected
71
-              SD_CARD_ERROR_INIT_NOT_CALLED = 0x19,     // init() not called
72
-              // 0x1A is unused now, it was: card returned an error for CMD59 (CRC_ON_OFF)
73
-              SD_CARD_ERROR_READ_CRC = 0x1B;            // invalid read CRC
48
+typedef enum : uint8_t {
49
+  SD_CARD_ERROR_CMD0               = 0x01, // Timeout error for command CMD0 (initialize card in SPI mode)
50
+  SD_CARD_ERROR_CMD8               = 0x02, // CMD8 was not accepted - not a valid SD card
51
+  SD_CARD_ERROR_CMD12              = 0x03, // Card returned an error response for CMD12 (write stop)
52
+  SD_CARD_ERROR_CMD17              = 0x04, // Card returned an error response for CMD17 (read block)
53
+  SD_CARD_ERROR_CMD18              = 0x05, // Card returned an error response for CMD18 (read multiple block)
54
+  SD_CARD_ERROR_CMD24              = 0x06, // Card returned an error response for CMD24 (write block)
55
+  SD_CARD_ERROR_CMD25              = 0x07, // WRITE_MULTIPLE_BLOCKS command failed
56
+  SD_CARD_ERROR_CMD58              = 0x08, // Card returned an error response for CMD58 (read OCR)
57
+  SD_CARD_ERROR_ACMD23             = 0x09, // SET_WR_BLK_ERASE_COUNT failed
58
+  SD_CARD_ERROR_ACMD41             = 0x0A, // ACMD41 initialization process timeout
59
+  SD_CARD_ERROR_BAD_CSD            = 0x0B, // Card returned a bad CSR version field
60
+  SD_CARD_ERROR_ERASE              = 0x0C, // Erase block group command failed
61
+  SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0x0D, // Card not capable of single block erase
62
+  SD_CARD_ERROR_ERASE_TIMEOUT      = 0x0E, // Erase sequence timed out
63
+  SD_CARD_ERROR_READ               = 0x0F, // Card returned an error token instead of read data
64
+  SD_CARD_ERROR_READ_REG           = 0x10, // Read CID or CSD failed
65
+  SD_CARD_ERROR_READ_TIMEOUT       = 0x11, // Timeout while waiting for start of read data
66
+  SD_CARD_ERROR_STOP_TRAN          = 0x12, // Card did not accept STOP_TRAN_TOKEN
67
+  SD_CARD_ERROR_WRITE              = 0x13, // Card returned an error token as a response to a write operation
68
+  SD_CARD_ERROR_WRITE_BLOCK_ZERO   = 0x14, // REMOVE - not used ... attempt to write protected block zero
69
+  SD_CARD_ERROR_WRITE_MULTIPLE     = 0x15, // Card did not go ready for a multiple block write
70
+  SD_CARD_ERROR_WRITE_PROGRAMMING  = 0x16, // Card returned an error to a CMD13 status check after a write
71
+  SD_CARD_ERROR_WRITE_TIMEOUT      = 0x17, // Timeout occurred during write programming
72
+  SD_CARD_ERROR_SCK_RATE           = 0x18, // Incorrect rate selected
73
+  SD_CARD_ERROR_INIT_NOT_CALLED    = 0x19, // Init() not called
74
+  // 0x1A is unused now, it was: card returned an error for CMD59 (CRC_ON_OFF)
75
+  SD_CARD_ERROR_READ_CRC = 0x1B             // Invalid read CRC
76
+} sd_error_code_t;
74 77
 
75 78
 // card types
76
-uint8_t const SD_CARD_TYPE_SD1  = 1,                    // Standard capacity V1 SD card
77
-              SD_CARD_TYPE_SD2  = 2,                    // Standard capacity V2 SD card
78
-              SD_CARD_TYPE_SDHC = 3;                    // High Capacity SD card
79
+uint8_t const SD_CARD_TYPE_SD1  = 1,        // Standard capacity V1 SD card
80
+              SD_CARD_TYPE_SD2  = 2,        // Standard capacity V2 SD card
81
+              SD_CARD_TYPE_SDHC = 3;        // High Capacity SD card
79 82
 
80 83
 /**
81 84
  * Define SOFTWARE_SPI to use bit-bang SPI
@@ -93,12 +96,11 @@ uint8_t const SD_CARD_TYPE_SD1  = 1,                    // Standard capacity V1
93 96
  * \class Sd2Card
94 97
  * \brief Raw access to SD and SDHC flash memory cards.
95 98
  */
96
-class Sd2Card {
99
+class DiskIODriver_SPI_SD : public DiskIODriver {
97 100
 public:
98 101
 
99
-  Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {}
102
+  DiskIODriver_SPI_SD() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {}
100 103
 
101
-  uint32_t cardSize();
102 104
   bool erase(uint32_t firstBlock, uint32_t lastBlock);
103 105
   bool eraseSingleBlockEnable();
104 106
 
@@ -106,7 +108,7 @@ public:
106 108
    *  Set SD error code.
107 109
    *  \param[in] code value for error code.
108 110
    */
109
-  inline void error(const uint8_t code) { errorCode_ = code; }
111
+  void error(const uint8_t code);
110 112
 
111 113
   /**
112 114
    * \return error code for last error. See Sd2Card.h for a list of error codes.
@@ -122,9 +124,15 @@ public:
122 124
    *
123 125
    * \return true for success or false for failure.
124 126
    */
125
-  bool init(const uint8_t sckRateID, const pin_t chipSelectPin);
127
+  bool init(const uint8_t sckRateID, const pin_t chipSelectPin) override;
126 128
 
127
-  bool readBlock(uint32_t block, uint8_t *dst);
129
+  bool setSckRate(const uint8_t sckRateID);
130
+
131
+  /**
132
+   * Return the card type: SD V1, SD V2 or SDHC
133
+   * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
134
+   */
135
+  int type() const { return type_; }
128 136
 
129 137
   /**
130 138
    * Read a card's CID register. The CID contains card identification
@@ -145,24 +153,27 @@ public:
145 153
    *
146 154
    * \return true for success or false for failure.
147 155
    */
148
-  inline bool readCSD(csd_t *csd) { return readRegister(CMD9, csd); }
156
+  inline bool readCSD(csd_t *csd) override { return readRegister(CMD9, csd); }
149 157
 
150
-  bool readData(uint8_t *dst);
151
-  bool readStart(uint32_t blockNumber);
152
-  bool readStop();
153
-  bool setSckRate(const uint8_t sckRateID);
158
+  bool readData(uint8_t *dst) override;
159
+  bool readStart(uint32_t blockNumber) override;
160
+  bool readStop() override;
154 161
 
155
-  /**
156
-   * Return the card type: SD V1, SD V2 or SDHC
157
-   * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
158
-   */
159
-  int type() const {return type_;}
160
-  bool writeBlock(uint32_t blockNumber, const uint8_t *src);
161
-  bool writeData(const uint8_t *src);
162
-  bool writeStart(uint32_t blockNumber, const uint32_t eraseCount);
163
-  bool writeStop();
162
+  bool writeData(const uint8_t *src) override;
163
+  bool writeStart(const uint32_t blockNumber, const uint32_t eraseCount) override;
164
+  bool writeStop() override;
165
+
166
+  bool readBlock(uint32_t block, uint8_t *dst) override;
167
+  bool writeBlock(uint32_t blockNumber, const uint8_t *src) override;
168
+
169
+  uint32_t cardSize() override;
170
+
171
+  bool isReady() override { return ready; };
172
+
173
+  void idle() override {}
164 174
 
165 175
 private:
176
+  bool ready = false;
166 177
   uint8_t chipSelectPin_,
167 178
           errorCode_,
168 179
           spiRate_,

+ 23
- 7
Marlin/src/sd/Sd2Card_sdio.h View File

@@ -23,17 +23,33 @@
23 23
 
24 24
 #include "../inc/MarlinConfig.h"
25 25
 
26
-#if ENABLED(SDIO_SUPPORT)
26
+#include "SdInfo.h"
27
+#include "disk_io_driver.h"
27 28
 
28 29
 bool SDIO_Init();
29 30
 bool SDIO_ReadBlock(uint32_t block, uint8_t *dst);
30 31
 bool SDIO_WriteBlock(uint32_t block, const uint8_t *src);
31 32
 
32
-class Sd2Card {
33
+class DiskIODriver_SDIO : public DiskIODriver {
33 34
   public:
34
-    bool init(uint8_t sckRateID = 0, uint8_t chipSelectPin = 0) { return SDIO_Init(); }
35
-    bool readBlock(uint32_t block, uint8_t *dst) { return SDIO_ReadBlock(block, dst); }
36
-    bool writeBlock(uint32_t block, const uint8_t *src) { return SDIO_WriteBlock(block, src); }
37
-};
35
+    bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=0) override { return SDIO_Init(); }
36
+
37
+    bool readCSD(csd_t *csd)                              override { return false; }
38
+
39
+    bool readStart(const uint32_t block)                  override { return false; }
40
+    bool readData(uint8_t *dst)                           override { return false; }
41
+    bool readStop()                                       override { return false; }
42
+
43
+    bool writeStart(const uint32_t block, const uint32_t) override { return false; }
44
+    bool writeData(const uint8_t *src)                    override { return false; }
45
+    bool writeStop()                                      override { return false; }
38 46
 
39
-#endif // SDIO_SUPPORT
47
+    bool readBlock(uint32_t block, uint8_t *dst)          override { return SDIO_ReadBlock(block, dst); }
48
+    bool writeBlock(uint32_t block, const uint8_t *src)   override { return SDIO_WriteBlock(block, src); }
49
+
50
+    uint32_t cardSize()                                   override { return 0; }
51
+
52
+    bool isReady()                                        override { return true; }
53
+
54
+    void idle()                                           override {}
55
+};

+ 1
- 1
Marlin/src/sd/SdFatConfig.h View File

@@ -39,7 +39,7 @@
39 39
  *
40 40
  * Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
41 41
  */
42
-#define USE_MULTIPLE_CARDS 0
42
+#define USE_MULTIPLE_CARDS 0 //TODO? ENABLED(MULTI_VOLUME)
43 43
 
44 44
 /**
45 45
  * Call flush for endl if ENDL_CALLS_FLUSH is nonzero

+ 3
- 3
Marlin/src/sd/SdVolume.cpp View File

@@ -41,10 +41,10 @@
41 41
   // raw block cache
42 42
   uint32_t SdVolume::cacheBlockNumber_;  // current block number
43 43
   cache_t  SdVolume::cacheBuffer_;       // 512 byte cache for Sd2Card
44
-  Sd2Card* SdVolume::sdCard_;            // pointer to SD card object
44
+  DiskIODriver *SdVolume::sdCard_;       // pointer to SD card object
45 45
   bool     SdVolume::cacheDirty_;        // cacheFlush() will write block if true
46 46
   uint32_t SdVolume::cacheMirrorBlock_;  // mirror  block for second FAT
47
-#endif  // USE_MULTIPLE_CARDS
47
+#endif
48 48
 
49 49
 // find a contiguous group of clusters
50 50
 bool SdVolume::allocContiguous(uint32_t count, uint32_t *curCluster) {
@@ -326,7 +326,7 @@ int32_t SdVolume::freeClusterCount() {
326 326
  * Reasons for failure include not finding a valid partition, not finding a valid
327 327
  * FAT file system in the specified partition or an I/O error.
328 328
  */
329
-bool SdVolume::init(Sd2Card* dev, uint8_t part) {
329
+bool SdVolume::init(DiskIODriver* dev, uint8_t part) {
330 330
   uint32_t totalBlocks, volumeStartBlock = 0;
331 331
   fat32_boot_t *fbs;
332 332
 

+ 13
- 10
Marlin/src/sd/SdVolume.h View File

@@ -36,9 +36,11 @@
36 36
 
37 37
 #if ENABLED(USB_FLASH_DRIVE_SUPPORT)
38 38
   #include "usb_flashdrive/Sd2Card_FlashDrive.h"
39
-#elif ENABLED(SDIO_SUPPORT)
39
+#endif
40
+
41
+#if NEED_SD2CARD_SDIO
40 42
   #include "Sd2Card_sdio.h"
41
-#else
43
+#elif NEED_SD2CARD_SPI
42 44
   #include "Sd2Card.h"
43 45
 #endif
44 46
 
@@ -47,6 +49,7 @@
47 49
 
48 50
 //==============================================================================
49 51
 // SdVolume class
52
+
50 53
 /**
51 54
  * \brief Cache for an SD data block
52 55
  */
@@ -84,14 +87,14 @@ class SdVolume {
84 87
    * Initialize a FAT volume.  Try partition one first then try super
85 88
    * floppy format.
86 89
    *
87
-   * \param[in] dev The Sd2Card where the volume is located.
90
+   * \param[in] dev The DiskIODriver where the volume is located.
88 91
    *
89 92
    * \return true for success, false for failure.
90 93
    * Reasons for failure include not finding a valid partition, not finding
91 94
    * a valid FAT file system or an I/O error.
92 95
    */
93
-  bool init(Sd2Card *dev) { return init(dev, 1) ? true : init(dev, 0); }
94
-  bool init(Sd2Card *dev, uint8_t part);
96
+  bool init(DiskIODriver *dev) { return init(dev, 1) || init(dev, 0); }
97
+  bool init(DiskIODriver *dev, uint8_t part);
95 98
 
96 99
   // inline functions that return volume info
97 100
   uint8_t blocksPerCluster() const { return blocksPerCluster_; } //> \return The volume's cluster size in blocks.
@@ -112,10 +115,10 @@ class SdVolume {
112 115
   uint32_t rootDirStart() const { return rootDirStart_; }
113 116
 
114 117
   /**
115
-   * Sd2Card object for this volume
116
-   * \return pointer to Sd2Card object.
118
+   * DiskIODriver object for this volume
119
+   * \return pointer to DiskIODriver object.
117 120
    */
118
-  Sd2Card* sdCard() { return sdCard_; }
121
+  DiskIODriver* sdCard() { return sdCard_; }
119 122
 
120 123
   /**
121 124
    * Debug access to FAT table
@@ -138,13 +141,13 @@ class SdVolume {
138 141
   #if USE_MULTIPLE_CARDS
139 142
     cache_t cacheBuffer_;        // 512 byte cache for device blocks
140 143
     uint32_t cacheBlockNumber_;  // Logical number of block in the cache
141
-    Sd2Card *sdCard_;            // Sd2Card object for cache
144
+    DiskIODriver *sdCard_;       // DiskIODriver object for cache
142 145
     bool cacheDirty_;            // cacheFlush() will write block if true
143 146
     uint32_t cacheMirrorBlock_;  // block number for mirror FAT
144 147
   #else
145 148
     static cache_t cacheBuffer_;        // 512 byte cache for device blocks
146 149
     static uint32_t cacheBlockNumber_;  // Logical number of block in the cache
147
-    static Sd2Card *sdCard_;            // Sd2Card object for cache
150
+    static DiskIODriver *sdCard_;       // DiskIODriver object for cache
148 151
     static bool cacheDirty_;            // cacheFlush() will write block if true
149 152
     static uint32_t cacheMirrorBlock_;  // block number for mirror FAT
150 153
   #endif

+ 23
- 4
Marlin/src/sd/cardreader.cpp View File

@@ -120,7 +120,16 @@ uint8_t CardReader::workDirDepth;
120 120
 
121 121
 #endif // SDCARD_SORT_ALPHA
122 122
 
123
-Sd2Card CardReader::sd2card;
123
+#if SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT)
124
+  DiskIODriver_USBFlash CardReader::media_usbFlashDrive;
125
+#endif
126
+#if NEED_SD2CARD_SDIO
127
+  DiskIODriver_SDIO CardReader::media_sdio;
128
+#elif NEED_SD2CARD_SPI
129
+  DiskIODriver_SPI_SD CardReader::media_sd_spi;
130
+#endif
131
+
132
+DiskIODriver* CardReader::driver = nullptr;
124 133
 SdVolume CardReader::volume;
125 134
 SdFile CardReader::file;
126 135
 
@@ -133,6 +142,16 @@ SdFile CardReader::file;
133 142
 uint32_t CardReader::filesize, CardReader::sdpos;
134 143
 
135 144
 CardReader::CardReader() {
145
+  changeMedia(&
146
+    #if SHARED_VOLUME_IS(SD_ONBOARD)
147
+      media_sd_spi
148
+    #elif SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT)
149
+      media_usbFlashDrive
150
+    #else
151
+      TERN(SDIO_SUPPORT, media_sdio, media_sd_spi)
152
+    #endif
153
+  );
154
+
136 155
   #if ENABLED(SDCARD_SORT_ALPHA)
137 156
     sort_count = 0;
138 157
     #if ENABLED(SDSORT_GCODE)
@@ -383,12 +402,12 @@ void CardReader::mount() {
383 402
   flag.mounted = false;
384 403
   if (root.isOpen()) root.close();
385 404
 
386
-  if (!sd2card.init(SD_SPI_SPEED, SDSS)
405
+  if (!driver->init(SD_SPI_SPEED, SDSS)
387 406
     #if defined(LCD_SDSS) && (LCD_SDSS != SDSS)
388
-      && !sd2card.init(SD_SPI_SPEED, LCD_SDSS)
407
+      && !driver->init(SD_SPI_SPEED, LCD_SDSS)
389 408
     #endif
390 409
   ) SERIAL_ECHO_MSG(STR_SD_INIT_FAIL);
391
-  else if (!volume.init(&sd2card))
410
+  else if (!volume.init(driver))
392 411
     SERIAL_ERROR_MSG(STR_SD_VOL_INIT_FAIL);
393 412
   else if (!root.openRoot(&volume))
394 413
     SERIAL_ERROR_MSG(STR_SD_OPENROOT_FAIL);

+ 39
- 4
Marlin/src/sd/cardreader.h View File

@@ -42,6 +42,29 @@ extern const char M23_STR[], M24_STR[];
42 42
 #define MAXPATHNAMELENGTH  (1 + (MAXDIRNAMELENGTH + 1) * (MAX_DIR_DEPTH) + 1 + FILENAME_LENGTH) // "/" + N * ("ADIRNAME/") + "filename.ext"
43 43
 
44 44
 #include "SdFile.h"
45
+#include "disk_io_driver.h"
46
+
47
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
48
+  #include "usb_flashdrive/Sd2Card_FlashDrive.h"
49
+#endif
50
+
51
+#if NEED_SD2CARD_SDIO
52
+  #include "Sd2Card_sdio.h"
53
+#elif NEED_SD2CARD_SPI
54
+  #include "Sd2Card.h"
55
+#endif
56
+
57
+#if ENABLED(MULTI_VOLUME)
58
+  #define SV_SD_ONBOARD      1
59
+  #define SV_USB_FLASH_DRIVE 2
60
+  #define _VOLUME_ID(N) _CAT(SV_, N)
61
+  #define SHARED_VOLUME_IS(N) (DEFAULT_SHARED_VOLUME == _VOLUME_ID(N))
62
+  #if !SHARED_VOLUME_IS(SD_ONBOARD) && !SHARED_VOLUME_IS(USB_FLASH_DRIVE)
63
+    #error "DEFAULT_SHARED_VOLUME must be either SD_ONBOARD or USB_FLASH_DRIVE."
64
+  #endif
65
+#else
66
+  #define SHARED_VOLUME_IS(...) 0
67
+#endif
45 68
 
46 69
 typedef struct {
47 70
   bool saving:1,
@@ -80,6 +103,8 @@ public:
80 103
 
81 104
   CardReader();
82 105
 
106
+  static void changeMedia(DiskIODriver *_driver) { driver = _driver; }
107
+
83 108
   static SdFile getroot() { return root; }
84 109
 
85 110
   static void mount();
@@ -171,7 +196,8 @@ public:
171 196
   static inline int16_t read(void *buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; }
172 197
   static inline int16_t write(void *buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; }
173 198
 
174
-  static Sd2Card& getSd2Card() { return sd2card; }
199
+  // TODO: rename to diskIODriver()
200
+  static DiskIODriver* diskIODriver() { return driver; }
175 201
 
176 202
   #if ENABLED(AUTO_REPORT_SD_STATUS)
177 203
     //
@@ -181,6 +207,15 @@ public:
181 207
     static AutoReporter<AutoReportSD> auto_reporter;
182 208
   #endif
183 209
 
210
+  #if SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT)
211
+    static DiskIODriver_USBFlash media_usbFlashDrive;
212
+  #endif
213
+  #if NEED_SD2CARD_SDIO
214
+    static DiskIODriver_SDIO media_sdio;
215
+  #elif NEED_SD2CARD_SPI
216
+    static DiskIODriver_SPI_SD media_sd_spi;
217
+  #endif
218
+
184 219
 private:
185 220
   //
186 221
   // Working directory and parents
@@ -236,7 +271,7 @@ private:
236 271
         #if ENABLED(SDSORT_DYNAMIC_RAM)
237 272
           static uint8_t *isDir;
238 273
         #elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK)
239
-          static uint8_t isDir[(SDSORT_LIMIT+7)>>3];
274
+          static uint8_t isDir[(SDSORT_LIMIT + 7) >> 3];
240 275
         #endif
241 276
       #endif
242 277
 
@@ -244,7 +279,7 @@ private:
244 279
 
245 280
   #endif // SDCARD_SORT_ALPHA
246 281
 
247
-  static Sd2Card sd2card;
282
+  static DiskIODriver *driver;
248 283
   static SdVolume volume;
249 284
   static SdFile file;
250 285
 
@@ -275,7 +310,7 @@ private:
275 310
 };
276 311
 
277 312
 #if ENABLED(USB_FLASH_DRIVE_SUPPORT)
278
-  #define IS_SD_INSERTED() Sd2Card::isInserted()
313
+  #define IS_SD_INSERTED() DiskIODriver_USBFlash::isInserted()
279 314
 #elif PIN_EXISTS(SD_DETECT)
280 315
   #define IS_SD_INSERTED() (READ(SD_DETECT_PIN) == SD_DETECT_STATE)
281 316
 #else

+ 67
- 0
Marlin/src/sd/disk_io_driver.h View File

@@ -0,0 +1,67 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+#pragma once
23
+
24
+#include <stdint.h>
25
+
26
+/**
27
+ * DiskIO Interace
28
+ *
29
+ * Interface for low level disk io
30
+ */
31
+class DiskIODriver {
32
+public:
33
+  /**
34
+   * Initialize an SD flash memory card with default clock rate and chip
35
+   * select pin.  See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
36
+   *
37
+   * \return true for success or false for failure.
38
+   */
39
+  virtual bool init(const uint8_t sckRateID, const pin_t chipSelectPin) = 0; //TODO: only for SPI
40
+
41
+  /**
42
+   * Read a card's CSD register. The CSD contains Card-Specific Data that
43
+   * provides information regarding access to the card's contents.
44
+   *
45
+   * \param[out] csd pointer to area for returned data.
46
+   *
47
+   * \return true for success or false for failure.
48
+   */
49
+  virtual bool readCSD(csd_t* csd) = 0;
50
+
51
+  virtual bool readStart(const uint32_t block) = 0;
52
+  virtual bool readData(uint8_t* dst) = 0;
53
+  virtual bool readStop() = 0;
54
+
55
+  virtual bool writeStart(const uint32_t block, const uint32_t) = 0;
56
+  virtual bool writeData(const uint8_t* src) = 0;
57
+  virtual bool writeStop() = 0;
58
+
59
+  virtual bool readBlock(uint32_t block, uint8_t* dst) = 0;
60
+  virtual bool writeBlock(uint32_t blockNumber, const uint8_t* src) = 0;
61
+
62
+  virtual uint32_t cardSize() = 0;
63
+
64
+  virtual bool isReady() = 0;
65
+
66
+  virtual void idle() = 0;
67
+};

+ 9
- 9
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp View File

@@ -121,7 +121,7 @@ static enum {
121 121
   uint32_t lun0_capacity;
122 122
 #endif
123 123
 
124
-bool Sd2Card::usbStartup() {
124
+bool DiskIODriver_USBFlash::usbStartup() {
125 125
   if (state <= DO_STARTUP) {
126 126
     SERIAL_ECHOPGM("Starting USB host...");
127 127
     if (!UHS_START) {
@@ -147,7 +147,7 @@ bool Sd2Card::usbStartup() {
147 147
 // the USB library to monitor for such events. This function also takes care
148 148
 // of initializing the USB library for the first time.
149 149
 
150
-void Sd2Card::idle() {
150
+void DiskIODriver_USBFlash::idle() {
151 151
   usb.Task();
152 152
 
153 153
   const uint8_t task_state = usb.getUsbTaskState();
@@ -258,16 +258,16 @@ void Sd2Card::idle() {
258 258
 
259 259
 // Marlin calls this function to check whether an USB drive is inserted.
260 260
 // This is equivalent to polling the SD_DETECT when using SD cards.
261
-bool Sd2Card::isInserted() {
261
+bool DiskIODriver_USBFlash::isInserted() {
262 262
   return state == MEDIA_READY;
263 263
 }
264 264
 
265
-bool Sd2Card::isReady() {
266
-  return state > DO_STARTUP;
265
+bool DiskIODriver_USBFlash::isReady() {
266
+  return state > DO_STARTUP && usb.getUsbTaskState() == UHS_STATE(RUNNING);
267 267
 }
268 268
 
269 269
 // Marlin calls this to initialize an SD card once it is inserted.
270
-bool Sd2Card::init(const uint8_t, const pin_t) {
270
+bool DiskIODriver_USBFlash::init(const uint8_t, const pin_t) {
271 271
   if (!isInserted()) return false;
272 272
 
273 273
   #if USB_DEBUG >= 1
@@ -286,7 +286,7 @@ bool Sd2Card::init(const uint8_t, const pin_t) {
286 286
 }
287 287
 
288 288
 // Returns the capacity of the card in blocks.
289
-uint32_t Sd2Card::cardSize() {
289
+uint32_t DiskIODriver_USBFlash::cardSize() {
290 290
   if (!isInserted()) return false;
291 291
   #if USB_DEBUG < 3
292 292
     const uint32_t
@@ -295,7 +295,7 @@ uint32_t Sd2Card::cardSize() {
295 295
   return lun0_capacity;
296 296
 }
297 297
 
298
-bool Sd2Card::readBlock(uint32_t block, uint8_t *dst) {
298
+bool DiskIODriver_USBFlash::readBlock(uint32_t block, uint8_t *dst) {
299 299
   if (!isInserted()) return false;
300 300
   #if USB_DEBUG >= 3
301 301
     if (block >= lun0_capacity) {
@@ -309,7 +309,7 @@ bool Sd2Card::readBlock(uint32_t block, uint8_t *dst) {
309 309
   return bulk.Read(0, block, 512, 1, dst) == 0;
310 310
 }
311 311
 
312
-bool Sd2Card::writeBlock(uint32_t block, const uint8_t *src) {
312
+bool DiskIODriver_USBFlash::writeBlock(uint32_t block, const uint8_t *src) {
313 313
   if (!isInserted()) return false;
314 314
   #if USB_DEBUG >= 3
315 315
     if (block >= lun0_capacity) {

+ 17
- 15
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h View File

@@ -27,6 +27,7 @@
27 27
  */
28 28
 #include "../SdFatConfig.h"
29 29
 #include "../SdInfo.h"
30
+#include "../disk_io_driver.h"
30 31
 
31 32
 #if DISABLED(USE_OTG_USB_HOST)
32 33
   /**
@@ -46,7 +47,7 @@
46 47
   #endif
47 48
 #endif
48 49
 
49
-class Sd2Card {
50
+class DiskIODriver_USBFlash : public DiskIODriver {
50 51
   private:
51 52
     uint32_t pos;
52 53
 
@@ -54,25 +55,26 @@ class Sd2Card {
54 55
 
55 56
   public:
56 57
     static bool usbStartup();
58
+    static bool isInserted();
57 59
 
58
-    bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=TERN(USE_OTG_USB_HOST, 0, SD_CHIP_SELECT_PIN));
60
+    bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=TERN(USE_OTG_USB_HOST, 0, SD_CHIP_SELECT_PIN)) override;
59 61
 
60
-    static void idle();
62
+    inline bool readCSD(csd_t*)                                  override { return true; }
61 63
 
62
-    inline bool readStart(const uint32_t block)                  { pos = block; return isReady(); }
63
-    inline bool readData(uint8_t *dst)                           { return readBlock(pos++, dst); }
64
-    inline bool readStop() const                                 { return true; }
64
+    inline bool readStart(const uint32_t block)                  override { pos = block; return isReady(); }
65
+    inline bool readData(uint8_t *dst)                           override { return readBlock(pos++, dst); }
66
+    inline bool readStop()                                       override { return true; }
65 67
 
66
-    inline bool writeStart(const uint32_t block, const uint32_t) { pos = block; return isReady(); }
67
-    inline bool writeData(uint8_t *src)                          { return writeBlock(pos++, src); }
68
-    inline bool writeStop() const                                { return true; }
68
+    inline bool writeStart(const uint32_t block, const uint32_t) override { pos = block; return isReady(); }
69
+    inline bool writeData(const uint8_t *src)                    override { return writeBlock(pos++, src); }
70
+    inline bool writeStop()                                      override { return true; }
69 71
 
70
-    bool readBlock(uint32_t block, uint8_t *dst);
71
-    bool writeBlock(uint32_t blockNumber, const uint8_t *src);
72
+    bool readBlock(uint32_t block, uint8_t *dst) override;
73
+    bool writeBlock(uint32_t blockNumber, const uint8_t *src) override;
72 74
 
73
-    bool readCSD(csd_t*)                                         { return true; }
75
+    uint32_t cardSize() override;
74 76
 
75
-    uint32_t cardSize();
76
-    static bool isInserted();
77
-    bool isReady();
77
+    bool isReady() override;
78
+
79
+    void idle() override;
78 80
 };

Loading…
Cancel
Save