瀏覽代碼

Fix sd_mmc_spi_mem capacity; clean up USB code (#12134)

- Fix an error in the return value of `sd_mmc_spi_read_capacity` which was causing the host OS to read beyond the last sector in the card.
- Clean up the USB flashdrive code and add better debugging.
Marcio Teixeira 6 年之前
父節點
當前提交
5b7dd553d3

+ 3
- 1
Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.cpp 查看文件

@@ -24,10 +24,12 @@ Ctrl_status sd_mmc_spi_test_unit_ready(void) {
24 24
   return CTRL_GOOD;
25 25
 }
26 26
 
27
+// NOTE: This function is defined as returning the address of the last block
28
+// in the card, which is cardSize() - 1
27 29
 Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) {
28 30
   if (!IS_SD_INSERTED || IS_SD_PRINTING || IS_SD_FILE_OPEN || !card.cardOK)
29 31
     return CTRL_NO_PRESENT;
30
-  *nb_sector = card.getSd2Card().cardSize();
32
+  *nb_sector = card.getSd2Card().cardSize() - 1;
31 33
   return CTRL_GOOD;
32 34
 }
33 35
 

+ 66
- 69
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp 查看文件

@@ -24,49 +24,22 @@
24 24
 
25 25
 #if ENABLED(USB_FLASH_DRIVE_SUPPORT)
26 26
 
27
+#include "../../core/serial.h"
28
+
27 29
 #include "lib/Usb.h"
28 30
 #include "lib/masstorage.h"
29 31
 
30 32
 #include "Sd2Card_FlashDrive.h"
31 33
 
32
-#include <SPI.h>
33
-
34
-#include "../../core/serial.h"
35
-
36 34
 USB usb;
37 35
 BulkOnly bulk(&usb);
38 36
 
39 37
 Sd2Card::state_t Sd2Card::state;
40
-uint32_t         Sd2Card::block;
41
-
42
-bool Sd2Card::usbHostReady() {
43
-  return state == USB_HOST_INITIALIZED;
44
-}
45
-
46
-bool Sd2Card::isInserted() {
47
-  return usb.getUsbTaskState() == USB_STATE_RUNNING;
48
-}
49
-
50
-// Marlin calls this whenever an SD card is detected, so this method
51
-// should not be used to initialize the USB host library
52
-bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
53
-  if (!usbHostReady()) return false;
54 38
 
55
-  if (!bulk.LUNIsGood(0)) {
56
-    SERIAL_ECHOLNPGM("LUN zero is not good\n");
57
-    return false;
58
-  }
59
-
60
-  SERIAL_ECHOLNPAIR("LUN Capacity: ",bulk.GetCapacity(0));
61
-
62
-  const uint32_t sectorSize = bulk.GetSectorSize(0);
63
-  if (sectorSize != 512) {
64
-    SERIAL_ECHOLNPAIR("Expecting sector size of 512, got: ",sectorSize);
65
-    return false;
66
-  }
67
-
68
-  return true;
69
-}
39
+// The USB library needs to be called periodically to detect USB thumbdrive
40
+// insertion and removals. Call this idle() function periodically to allow
41
+// the USB libary to monitor for such events. This function also takes care
42
+// of initializing the USB library for the first time.
70 43
 
71 44
 void Sd2Card::idle() {
72 45
   static uint32_t next_retry;
@@ -100,60 +73,84 @@ void Sd2Card::idle() {
100 73
 
101 74
       if (lastUsbTaskState == USB_STATE_RUNNING && newUsbTaskState != USB_STATE_RUNNING) {
102 75
         // the user pulled the flash drive. Make sure the bulk storage driver releases the address
103
-        SERIAL_ECHOLNPGM("Drive removed\n");
76
+        #ifdef USB_DEBUG
77
+          SERIAL_ECHOLNPGM("USB drive removed");
78
+        #endif
104 79
         //bulk.Release();
105 80
       }
106
-      if (lastUsbTaskState != USB_STATE_RUNNING && newUsbTaskState == USB_STATE_RUNNING)
107
-        SERIAL_ECHOLNPGM("Drive inserted\n");
81
+      if (lastUsbTaskState != USB_STATE_RUNNING && newUsbTaskState == USB_STATE_RUNNING) {
82
+        #ifdef USB_DEBUG
83
+          SERIAL_ECHOLNPGM("USB drive inserted");
84
+        #endif
85
+      }
108 86
       break;
109 87
   }
110 88
 }
111 89
 
112
-uint32_t Sd2Card::cardSize() {
113
-  if (!usbHostReady()) return 0;
114
-  return bulk.GetCapacity(0);
115
-}
116
-
117
-bool Sd2Card::readData(uint8_t* dst) {
118
-  return readBlock(block++, dst);
119
-}
90
+// Marlin calls this function to check whether an USB drive is inserted.
91
+// This is equivalent to polling the SD_DETECT when using SD cards.
92
+bool Sd2Card::isInserted() {
93
+  return usb.getUsbTaskState() == USB_STATE_RUNNING;
94
+};
120 95
 
121
-bool Sd2Card::readStart(uint32_t blockNumber) {
122
-  block = blockNumber;
123
-  return true;
124
-}
96
+// Marlin calls this to initialize an SD card once it is inserted.
97
+bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
98
+  if (!ready()) return false;
125 99
 
126
-bool Sd2Card::readStop() {
127
-  return usbHostReady();
128
-}
100
+  if (!bulk.LUNIsGood(0)) {
101
+    SERIAL_ECHOLNPGM("LUN zero is not good");
102
+    return false;
103
+  }
129 104
 
130
-bool Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
131
-  if (!usbHostReady()) {
132
-    SERIAL_ECHOLNPGM("Read from uninitalized USB host");
105
+  const uint32_t sectorSize = bulk.GetSectorSize(0);
106
+  if (sectorSize != 512) {
107
+    SERIAL_ECHOLNPAIR("Expecting sector size of 512, got:", sectorSize);
133 108
     return false;
134 109
   }
135
-  return bulk.Read(0, block, 512, 1, dst) == 0;
136
-}
137 110
 
138
-bool Sd2Card::writeData(const uint8_t* src) {
139
-  return writeBlock(block++, src);
111
+  #ifdef USB_DEBUG
112
+    lun0_capacity = bulk.GetCapacity(0);
113
+    SERIAL_ECHOLNPAIR("LUN Capacity (in blocks): ", lun0_capacity);
114
+  #endif
115
+  return true;
140 116
 }
141 117
 
142
-bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
143
-  block = blockNumber;
144
-  return true;
118
+// Returns the capacity of the card in blocks.
119
+uint32_t Sd2Card::cardSize() {
120
+  if (!ready()) return 0;
121
+  #ifndef USB_DEBUG
122
+    const uint32_t
123
+  #endif
124
+  lun0_capacity = bulk.GetCapacity(0);
125
+  return lun0_capacity;
145 126
 }
146 127
 
147
-bool Sd2Card::writeStop() {
148
-  return usbHostReady();
128
+bool Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
129
+  if (!ready()) return false;
130
+  #ifdef USB_DEBUG
131
+    if (block >= lun0_capacity) {
132
+      SERIAL_ECHOLNPAIR("Attempt to read past end of LUN: ", block);
133
+      return false;
134
+    }
135
+    #if USB_DEBUG > 1
136
+      SERIAL_ECHOLNPAIR("Read block ", block);
137
+    #endif
138
+  #endif
139
+  return bulk.Read(0, block, 512, 1, dst) == 0;
149 140
 }
150 141
 
151
-bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
152
-  if (!usbHostReady()) {
153
-    SERIAL_ECHOLNPGM("Write to uninitalized USB host");
154
-    return false;
155
-  }
156
-  return bulk.Write(0, blockNumber, 512, 1, src) == 0;
142
+bool Sd2Card::writeBlock(uint32_t block, const uint8_t* src) {
143
+  if (!ready()) return false;
144
+  #ifdef USB_DEBUG
145
+    if (block >= lun0_capacity) {
146
+      SERIAL_ECHOLNPAIR("Attempt to write past end of LUN: ", block);
147
+      return false;
148
+    }
149
+    #if USB_DEBUG > 1
150
+      SERIAL_ECHOLNPAIR("Write block ", block);
151
+    #endif
152
+  #endif
153
+  return bulk.Write(0, block, 512, 1, src) == 0;
157 154
 }
158 155
 
159 156
 #endif // USB_FLASH_DRIVE_SUPPORT

+ 25
- 13
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h 查看文件

@@ -28,6 +28,13 @@
28 28
 #ifndef _SD2CARD_FLASHDRIVE_H_
29 29
 #define _SD2CARD_FLASHDRIVE_H_
30 30
 
31
+/* Uncomment USB_DEBUG to enable debugging.
32
+ *    1 - basic debugging and bounds checking
33
+ *    2 - print each block access
34
+ */
35
+//#define USB_DEBUG 1
36
+
37
+
31 38
 #include "../SdFatConfig.h"
32 39
 #include "../SdInfo.h"
33 40
 
@@ -63,29 +70,34 @@ class Sd2Card {
63 70
       USB_HOST_INITIALIZED
64 71
     } state_t;
65 72
 
66
-    static state_t  state;
67
-    static uint32_t block;
73
+    static state_t state;
74
+
75
+    uint32_t pos;
76
+    #ifdef USB_DEBUG
77
+      uint32_t lun0_capacity;
78
+    #endif
68 79
 
69
-    static bool usbHostReady();
80
+    static inline bool ready() {return state == USB_HOST_INITIALIZED;}
70 81
 
71 82
   public:
83
+    bool init(uint8_t sckRateID = 0, uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
84
+
72 85
     static void idle();
73 86
 
74
-    static bool isInserted();
87
+    bool readStart(uint32_t block)                       { pos = block; return ready(); }
88
+    bool readData(uint8_t* dst)                          { return readBlock(pos++, dst); }
89
+    bool readStop()                                      { return true; }
75 90
 
76
-    uint32_t cardSize();
91
+    bool writeStart(uint32_t block, uint32_t eraseCount) { pos = block; return ready(); }
92
+    bool writeData(uint8_t* src)                         { return writeBlock(pos++, src); }
93
+    bool writeStop()                                     { return true; }
77 94
 
78
-    bool init(uint8_t sckRateID = 0, uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
79 95
 
80
-    bool readData(uint8_t* dst);
81
-    bool readStart(uint32_t blockNumber);
82
-    bool readStop();
83 96
     bool readBlock(uint32_t block, uint8_t* dst);
84
-
85
-    bool writeData(const uint8_t* src);
86
-    bool writeStart(uint32_t blockNumber, uint32_t eraseCount);
87
-    bool writeStop();
88 97
     bool writeBlock(uint32_t blockNumber, const uint8_t* src);
98
+
99
+    uint32_t cardSize();
100
+    static bool isInserted();
89 101
 };
90 102
 
91 103
 #endif  // _SD2CARD_FLASHDRIVE_H_

Loading…
取消
儲存