|
@@ -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
|