Zuletzt aktiv 1 month ago

esp32-spidump.ino Originalformat
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(20000000, 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];
85uint8_t pattern[CHUNK];
86
87uint32_t flashSize = 512 * 1024;
88
89uint8_t readStatus() {
90 uint8_t status;
91 digitalWrite(CS, LOW);
92 vspi->beginTransaction(settings);
93 vspi->transfer(0x05);
94 status = vspi->transfer(0);
95 vspi->endTransaction();
96 digitalWrite(CS, HIGH);
97 return status;
98}
99
100void waitReady() {
101 uint8_t status = 1;
102// Serial.println("Waiting device not BUSY");
103 while (status) {
104 delay(1);
105 status = readStatus();
106 status &= 1; // Only first bit
107 }
108// Serial.println("Device is free!");
109}
110
111void sectorErase(uint32_t addr) {
112 uint8_t ad[3];
113 uint8_t out;
114 ad[0] = (addr & 0xFF0000) >> 16;
115 ad[1] = (addr & 0x00FF00) >> 8;
116 ad[2] = (addr & 0x0000FF) >> 0;
117
118 writeEnable();
119 digitalWrite(CS, LOW);
120 vspi->beginTransaction(settings);
121 vspi->transfer(0x20); // Read Data command
122 vspi->transfer(ad[0]);
123 vspi->transfer(ad[1]);
124 vspi->transfer(ad[2]);
125 vspi->endTransaction();
126 digitalWrite(CS, HIGH);
127 waitReady();
128}
129
130#define SRP (1 << 7)
131#define TB (1 << 5)
132#define BP2 (1 << 4)
133#define BP1 (1 << 3)
134#define BP0 (1 << 2)
135#define WEL (1 << 1)
136
137void unprotect() {
138 writeEnable();
139 uint8_t ok = 0;
140 while(!ok) {
141 uint8_t status = readStatus();
142 status &= ~(SRP | TB | BP2 | BP1 | BP0); // Reset protections
143 status &= ~(WEL); // Avoid checking Write Enable that is reseted after operation
144
145 digitalWrite(CS, HIGH);
146 delay(1);
147 digitalWrite(CS, LOW);
148 vspi->beginTransaction(settings);
149 vspi->transfer(0x01);
150 vspi->transfer(status);
151 vspi->endTransaction();
152 digitalWrite(CS, HIGH);
153 delay(1);
154 waitReady();
155
156 uint8_t status2 = readStatus();
157 if (status != status2) {
158 Serial.print("Error writting status! Expected ");
159 Serial.print(status, HEX);
160 Serial.print(" got ");
161 Serial.println(status2, HEX);
162 } else {
163 ok = 1;
164 }
165 }
166}
167
168void writeEnable() {
169// Serial.println("Write Enable");
170 digitalWrite(CS, LOW);
171 vspi->beginTransaction(settings);
172 vspi->transfer(0x06);
173 vspi->endTransaction();
174 digitalWrite(CS, HIGH);
175 delay(10);
176 uint8_t status = readStatus();
177 status &= 2;
178 if (status != 2) {
179 Serial.println("ERROR setting Write Enable!");
180 }
181 waitReady();
182}
183
184void chipErase() {
185 writeEnable();
186 Serial.println("Chip Erase");
187 digitalWrite(CS, LOW);
188 vspi->beginTransaction(settings);
189 vspi->transfer(0xC7);
190 vspi->endTransaction();
191 digitalWrite(CS, HIGH);
192 delay(10);
193 waitReady();
194}
195
196void programPage(uint32_t addr, uint8_t *data) {
197 uint8_t ad[3];
198 ad[0] = (addr & 0xFF0000) >> 16;
199 ad[1] = (addr & 0x00FF00) >> 8;
200 ad[2] = (addr & 0x0000FF) >> 0;
201
202 writeEnable();
203 digitalWrite(CS, LOW);
204 vspi->beginTransaction(settings);
205 vspi->transfer(0x02);
206 vspi->transfer(ad[0]);
207 vspi->transfer(ad[1]);
208 vspi->transfer(ad[2]);
209 for (int i = 0; i < 256; i++) {
210 vspi->transfer(data[i]);
211 }
212 vspi->endTransaction();
213 digitalWrite(CS, HIGH);
214 delay(1);
215 waitReady();
216}
217
218char *wololo = "ACNDEFHEJRHSUDIFKEMLOPEC";
219
220void TestChip() {
221 Serial.println("Unprotect");
222 unprotect();
223// Serial.println("Erasing chip");
224// chipErase();
225 Serial.println("Programming test buffer");
226 for (int i = 0; i < CHUNK; i++) {
227 pattern[i] = (i & 0xFF);
228 }
229 int numPages = flashSize / CHUNK;
230 for (int i = 0; i < numPages; i++) {
231 Serial.print("Testing page ");
232 Serial.println(i, HEX);
233 sectorErase(i*CHUNK);
234 programPage(i*CHUNK, pattern);
235 readBuffer(i * CHUNK, databuff, CHUNK);
236 int diff = compare(databuff, pattern, 256);
237 if (diff != -1) {
238 Serial.print("Expected at offset ");
239 printHexPad32(i * CHUNK);
240 Serial.println("");
241 printBuff(pattern, CHUNK, i * CHUNK);
242 Serial.println("");
243 Serial.println("Got: ");
244 printBuff(databuff, CHUNK, i * CHUNK);
245 break;
246 }
247 }
248 Serial.println("FINISH");
249}
250
251void setup() {
252 Serial.begin(115200);
253 Serial.setDebugOutput(true);
254 Serial.println("ON!!!");
255
256 pinMode(23, OUTPUT);
257 pinMode(19, INPUT);
258 pinMode(18,OUTPUT);
259 pinMode(CS, OUTPUT);
260 pinMode(13, OUTPUT);
261 pinMode(22, OUTPUT);
262 digitalWrite(CS, HIGH);
263 digitalWrite(13, HIGH);
264 digitalWrite(22, HIGH);
265
266 if(FORMAT) {
267 SPIFFS.format();
268 }
269
270 if(!SPIFFS.begin(true)){
271 Serial.println("SPIFFS Mount Failed");
272 return;
273 }
274
275 memcpy(databuff, wololo, 24);
276
277 vspi = new SPIClass(VSPI);
278 vspi->begin();
279 vspi->setDataMode(0);
280 vspi->setBitOrder(MSBFIRST);
281
282
283 delay(100);
284
285 uint32_t offset = 0;
286 Serial.println("Send anything to start.");
287 while(Serial.available() <= 0);
288
289 TestChip();
290// unprotect();
291// chipErase();
292// programPage(0, databuff);
293// PrintFlash();
294// DumpFlash();
295// WriteFlash();
296// VerifyFlash();
297}
298
299int compare(uint8_t *buff0, uint8_t *buff1, uint32_t len) {
300 for (uint32_t i = 0; i < len; i++) {
301 if (buff0[i] != buff1[i]) {
302 return i;
303 }
304 }
305
306 return -1;
307}
308
309void VerifyFlash() {
310 File file = SPIFFS.open("/FLSHSAVE.BIN", FILE_READ);
311
312 if (!file) {
313 Serial.println("Error opening file!");
314 while(true) {
315 delay(1000);
316 }
317 }
318
319 uint32_t addr = 0;
320 int diff = -1;
321 Serial.println("VERIFING");
322 while(addr < flashSize) {
323// printHexPad32(addr);
324// Serial.println("");
325 file.read(databuff, 256);
326 readBuffer(addr, databuff + 512, 256);
327 diff = compare(databuff, databuff + 512, 256);
328 if (diff != -1) {
329 Serial.print("\nCorrupted at index ");
330 Serial.print(addr + diff, HEX);
331 Serial.println("");
332 break;
333 }
334 addr += 256;
335 }
336
337 file.close();
338 Serial.println("DONE");
339}
340
341void WriteFlash() {
342 unprotect();
343 chipErase();
344
345 File file = SPIFFS.open("/FLSHSAVE.BIN", FILE_READ);
346
347 if (!file) {
348 Serial.println("Error opening file!");
349 while(true) {
350 delay(1000);
351 }
352 }
353
354 uint32_t addr = 0;
355 Serial.println("FLASHING");
356
357 while(addr < flashSize) {
358 printHexPad32(addr);
359 Serial.println("");
360 file.read(databuff, 256);
361 programPage(addr, databuff);
362 addr += 256;
363 }
364
365 file.close();
366 Serial.println("DONE");
367}
368
369
370void PrintFlash() {
371 uint32_t offset = 0;
372
373 Serial.println("READING FLASH");
374 while (offset < flashSize) {
375 readBuffer(offset, databuff, CHUNK);
376 printBuff(databuff, CHUNK, offset);
377 offset += CHUNK;
378 break;
379 }
380}
381
382void DumpFlash() {
383 File file = SPIFFS.open("/SAVE.BIN", FILE_WRITE);
384 if (!file) {
385 Serial.println("Error opening file!");
386 while(true) {
387 delay(1000);
388 }
389 }
390
391 uint32_t offset = 0;
392
393 Serial.println("READING FLASH");
394 while (offset < flashSize) {
395 readBuffer(offset, databuff, CHUNK);
396 file.write(databuff, CHUNK);
397 printHexPad32(offset);
398 printBuff(databuff, CHUNK, offset);
399 Serial.println("");
400 offset += CHUNK;
401 }
402 file.close();
403}
404
405void loop() {
406 delay(1000);
407}