Dernière activité 1 month ago

ESP32 Arduino VSPI SPI Flash Reader / Writer

esp32-spiflash.ino Brut
1#include <SPI.h>
2#include "FS.h"
3#include "SPIFFS.h"
4
5#define CS 5
6#define FORMAT false
7SPIClass * vspi = NULL;
8
9SPISettings settings(10000000, MSBFIRST, SPI_MODE0);
10//SPISettings settings(1000000, MSBFIRST, SPI_MODE0);
11
12byte jedec[3];
13
14void 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
35void 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
47void printHexPad8(uint8_t val) {
48 if (val < 0x10) {
49 Serial.print("0");
50 }
51 Serial.print(val, HEX);
52}
53
54void printASCII(uint8_t v) {
55 if (v >= 0x20 && v <= 0x7E) {
56 Serial.print((char)v);
57 } else {
58 Serial.print(".");
59 }
60}
61
62void 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
84uint8_t databuff[CHUNK];
85
86uint32_t flashSize = 512 * 1024;
87
88uint8_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
99void 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
110void 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
135void 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
166void 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
182void 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
194void 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
216char *wololo = "ACNDEFHEJRHSUDIFKEMLOPEC";
217
218void 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
263int 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
273void 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
305void 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
334void 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
346void 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
368void 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}