Последняя активность 1 month ago

ESP32 Arduino VSPI SPI Flash Reader / Writer

racerxdl's Avatar Lucas Teske ревизий этого фрагмента 5 years ago. К ревизии

1 file changed, 394 insertions

esp32-spiflash.ino(файл создан)

@@ -0,0 +1,394 @@
1 + #include <SPI.h>
2 + #include "FS.h"
3 + #include "SPIFFS.h"
4 +
5 + #define CS 5
6 + #define FORMAT false
7 + SPIClass * vspi = NULL;
8 +
9 + SPISettings settings(10000000, MSBFIRST, SPI_MODE0);
10 + //SPISettings settings(1000000, MSBFIRST, SPI_MODE0);
11 +
12 + byte jedec[3];
13 +
14 + void readBuffer(uint32_t addr, uint8_t *buff, uint32_t len) {
15 + uint8_t ad[3];
16 + uint8_t out;
17 + ad[0] = (addr & 0xFF0000) >> 16;
18 + ad[1] = (addr & 0x00FF00) >> 8;
19 + ad[2] = (addr & 0x0000FF) >> 0;
20 +
21 + digitalWrite(CS, LOW);
22 + vspi->beginTransaction(settings);
23 + vspi->transfer(0x03); // Read Data command
24 + vspi->transfer(ad[0]);
25 + vspi->transfer(ad[1]);
26 + vspi->transfer(ad[2]);
27 + for (uint32_t i = 0; i < len; i++) {
28 + *buff = vspi->transfer(0x00);
29 + buff++;
30 + }
31 + vspi->endTransaction();
32 + digitalWrite(CS, HIGH);
33 + }
34 +
35 + void printHexPad32(uint32_t val) {
36 + for (int i = 7; i > 0; i--) {
37 + uint32_t v = (1 << (i * 4));
38 + if (val < v) {
39 + Serial.print("0");
40 + } else {
41 + break;
42 + }
43 + }
44 + Serial.print(val, HEX);
45 + }
46 +
47 + void printHexPad8(uint8_t val) {
48 + if (val < 0x10) {
49 + Serial.print("0");
50 + }
51 + Serial.print(val, HEX);
52 + }
53 +
54 + void printASCII(uint8_t v) {
55 + if (v >= 0x20 && v <= 0x7E) {
56 + Serial.print((char)v);
57 + } else {
58 + Serial.print(".");
59 + }
60 + }
61 +
62 + void printBuff(uint8_t *buff, uint32_t len, uint32_t mainoffset) {
63 + Serial.println("-----------------------------");
64 + for (uint32_t i = 0; i < len; i++) {
65 + if (i % 16 == 0) {
66 + printHexPad32(mainoffset + i);
67 + Serial.print(": ");
68 + }
69 + printHexPad8(buff[i]);
70 + Serial.print(" ");
71 + if (i % 16 == 15) {
72 + uint32_t off = (i / 16) * 16;
73 + for (uint32_t p = 0; p < 16; p++) {
74 + printASCII(buff[off+p]);
75 + }
76 + Serial.println("");
77 + }
78 + }
79 + Serial.println("-----------------------------");
80 + }
81 +
82 + #define CHUNK 256
83 +
84 + uint8_t databuff[CHUNK];
85 +
86 + uint32_t flashSize = 512 * 1024;
87 +
88 + uint8_t readStatus() {
89 + uint8_t status;
90 + digitalWrite(CS, LOW);
91 + vspi->beginTransaction(settings);
92 + vspi->transfer(0x05);
93 + status = vspi->transfer(0);
94 + vspi->endTransaction();
95 + digitalWrite(CS, HIGH);
96 + return status;
97 + }
98 +
99 + void waitReady() {
100 + uint8_t status = 1;
101 + // Serial.println("Waiting device not BUSY");
102 + while (status) {
103 + delay(1);
104 + status = readStatus();
105 + status &= 1; // Only first bit
106 + }
107 + // Serial.println("Device is free!");
108 + }
109 +
110 + void sectorErase(uint32_t addr) {
111 + uint8_t ad[3];
112 + uint8_t out;
113 + ad[0] = (addr & 0xFF0000) >> 16;
114 + ad[1] = (addr & 0x00FF00) >> 8;
115 + ad[2] = (addr & 0x0000FF) >> 0;
116 +
117 + digitalWrite(CS, LOW);
118 + vspi->beginTransaction(settings);
119 + vspi->transfer(0x20); // Read Data command
120 + vspi->transfer(ad[0]);
121 + vspi->transfer(ad[1]);
122 + vspi->transfer(ad[2]);
123 + vspi->endTransaction();
124 + digitalWrite(CS, HIGH);
125 + waitReady();
126 + }
127 +
128 + #define SRP (1 << 7)
129 + #define TB (1 << 5)
130 + #define BP2 (1 << 4)
131 + #define BP1 (1 << 3)
132 + #define BP0 (1 << 2)
133 + #define WEL (1 << 1)
134 +
135 + void unprotect() {
136 + writeEnable();
137 + uint8_t ok = 0;
138 + while(!ok) {
139 + uint8_t status = readStatus();
140 + status &= ~(SRP | TB | BP2 | BP1 | BP0); // Reset protections
141 + status &= ~(WEL); // Avoid checking Write Enable that is reseted after operation
142 +
143 + digitalWrite(CS, HIGH);
144 + delay(1);
145 + digitalWrite(CS, LOW);
146 + vspi->beginTransaction(settings);
147 + vspi->transfer(0x01);
148 + vspi->transfer(status);
149 + vspi->endTransaction();
150 + digitalWrite(CS, HIGH);
151 + delay(1);
152 + waitReady();
153 +
154 + uint8_t status2 = readStatus();
155 + if (status != status2) {
156 + Serial.print("Error writting status! Expected ");
157 + Serial.print(status, HEX);
158 + Serial.print(" got ");
159 + Serial.println(status2, HEX);
160 + } else {
161 + ok = 1;
162 + }
163 + }
164 + }
165 +
166 + void writeEnable() {
167 + // Serial.println("Write Enable");
168 + digitalWrite(CS, LOW);
169 + vspi->beginTransaction(settings);
170 + vspi->transfer(0x06);
171 + vspi->endTransaction();
172 + digitalWrite(CS, HIGH);
173 + delay(10);
174 + uint8_t status = readStatus();
175 + status &= 2;
176 + if (status != 2) {
177 + Serial.println("ERROR setting Write Enable!");
178 + }
179 + waitReady();
180 + }
181 +
182 + void chipErase() {
183 + writeEnable();
184 + Serial.println("Chip Erase");
185 + digitalWrite(CS, LOW);
186 + vspi->beginTransaction(settings);
187 + vspi->transfer(0xC7);
188 + vspi->endTransaction();
189 + digitalWrite(CS, HIGH);
190 + delay(10);
191 + waitReady();
192 + }
193 +
194 + void programPage(uint32_t addr, uint8_t *data) {
195 + uint8_t ad[3];
196 + ad[0] = (addr & 0xFF0000) >> 16;
197 + ad[1] = (addr & 0x00FF00) >> 8;
198 + ad[2] = (addr & 0x0000FF) >> 0;
199 +
200 + writeEnable();
201 + digitalWrite(CS, LOW);
202 + vspi->beginTransaction(settings);
203 + vspi->transfer(0x02);
204 + vspi->transfer(ad[0]);
205 + vspi->transfer(ad[1]);
206 + vspi->transfer(ad[2]);
207 + for (int i = 0; i < 256; i++) {
208 + vspi->transfer(data[i]);
209 + }
210 + vspi->endTransaction();
211 + digitalWrite(CS, HIGH);
212 + delay(1);
213 + waitReady();
214 + }
215 +
216 + char *wololo = "ACNDEFHEJRHSUDIFKEMLOPEC";
217 +
218 + void setup() {
219 + Serial.begin(115200);
220 + Serial.setDebugOutput(true);
221 + Serial.println("ON!!!");
222 +
223 + pinMode(23, OUTPUT);
224 + pinMode(19, INPUT);
225 + pinMode(18,OUTPUT);
226 + pinMode(CS, OUTPUT);
227 + pinMode(13, OUTPUT);
228 + pinMode(22, OUTPUT);
229 + digitalWrite(CS, HIGH);
230 + digitalWrite(13, HIGH);
231 + digitalWrite(22, HIGH);
232 +
233 + if(FORMAT) {
234 + SPIFFS.format();
235 + }
236 +
237 + if(!SPIFFS.begin(true)){
238 + Serial.println("SPIFFS Mount Failed");
239 + return;
240 + }
241 +
242 + // memcpy(databuff, wololo, 24);
243 +
244 + vspi = new SPIClass(VSPI);
245 + vspi->begin();
246 + vspi->setDataMode(0);
247 + vspi->setBitOrder(MSBFIRST);
248 +
249 +
250 + delay(100);
251 +
252 + uint32_t offset = 0;
253 + waitReady();
254 +
255 +
256 + // programPage(0, databuff);
257 +
258 + // DumpFlash();
259 + // WriteFlash();
260 + VerifyFlash();
261 + }
262 +
263 + int compare(uint8_t *buff0, uint8_t *buff1, uint32_t len) {
264 + for (uint32_t i = 0; i < len; i++) {
265 + if (buff0[i] != buff1[i]) {
266 + return i;
267 + }
268 + }
269 +
270 + return -1;
271 + }
272 +
273 + void VerifyFlash() {
274 + File file = SPIFFS.open("/FLSHSAVE.BIN", FILE_READ);
275 +
276 + if (!file) {
277 + Serial.println("Error opening file!");
278 + while(true) {
279 + delay(1000);
280 + }
281 + }
282 +
283 + uint32_t addr = 0;
284 + int diff = -1;
285 + Serial.println("VERIFING");
286 + while(addr < flashSize) {
287 + // printHexPad32(addr);
288 + // Serial.println("");
289 + file.read(databuff, 256);
290 + readBuffer(addr, databuff + 512, 256);
291 + diff = compare(databuff, databuff + 512, 256);
292 + if (diff != -1) {
293 + Serial.print("\nCorrupted at index ");
294 + Serial.print(addr + diff, HEX);
295 + Serial.println("");
296 + break;
297 + }
298 + addr += 256;
299 + }
300 +
301 + file.close();
302 + Serial.println("DONE");
303 + }
304 +
305 + void WriteFlash() {
306 + unprotect();
307 + chipErase();
308 +
309 + File file = SPIFFS.open("/FLSHSAVE.BIN", FILE_READ);
310 +
311 + if (!file) {
312 + Serial.println("Error opening file!");
313 + while(true) {
314 + delay(1000);
315 + }
316 + }
317 +
318 + uint32_t addr = 0;
319 + Serial.println("FLASHING");
320 +
321 + while(addr < flashSize) {
322 + printHexPad32(addr);
323 + Serial.println("");
324 + file.read(databuff, 256);
325 + programPage(addr, databuff);
326 + addr += 256;
327 + }
328 +
329 + file.close();
330 + Serial.println("DONE");
331 + }
332 +
333 +
334 + void PrintFlash() {
335 + uint32_t offset = 0;
336 +
337 + Serial.println("READING FLASH");
338 + while (offset < flashSize) {
339 + readBuffer(offset, databuff, CHUNK);
340 + printBuff(databuff, CHUNK, offset);
341 + offset += CHUNK;
342 + }
343 + }
344 +
345 +
346 + void DumpFlash() {
347 + File file = SPIFFS.open("/SAVE.BIN", FILE_WRITE);
348 + if (!file) {
349 + Serial.println("Error opening file!");
350 + while(true) {
351 + delay(1000);
352 + }
353 + }
354 +
355 + uint32_t offset = 0;
356 +
357 + Serial.println("READING FLASH");
358 + while (offset < flashSize) {
359 + readBuffer(offset, databuff, CHUNK);
360 + file.write(databuff, CHUNK);
361 + printHexPad32(offset);
362 + Serial.println("");
363 + offset += CHUNK;
364 + }
365 + file.close();
366 + }
367 +
368 + void loop() {
369 +
370 +
371 + // digitalWrite(CS, HIGH);
372 + // delay(10);
373 + // digitalWrite(CS, LOW);
374 + //// delay(10);
375 + // vspi->beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
376 + // vspi->transfer(0x90);
377 + // vspi->transfer(0);
378 + // vspi->transfer(0);
379 + // vspi->transfer(0);
380 + // jedec[0] = vspi->transfer(0); // manufacturer id
381 + // jedec[1] = vspi->transfer(0); // memory type
382 + //// jedec[2] = vspi->transfer(0); // capacity
383 + //
384 + // vspi->endTransaction();
385 + // digitalWrite(CS, HIGH);
386 + // Serial.print("Response: ");
387 + // Serial.print(jedec[0], HEX);
388 + // Serial.print(",");
389 + // Serial.print(jedec[1], HEX);
390 + // Serial.print(",");
391 + // Serial.println(jedec[2], HEX);
392 +
393 + delay(1000);
394 + }
Новее Позже