最后活跃于 1 month ago

racerxdl's Avatar Lucas Teske 修订了这个 Gist 5 years ago. 转到此修订

1 file changed, 407 insertions

esp32-spidump.ino(文件已创建)

@@ -0,0 +1,407 @@
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(20000000, 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 + uint8_t pattern[CHUNK];
86 +
87 + uint32_t flashSize = 512 * 1024;
88 +
89 + uint8_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 +
100 + void 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 +
111 + void 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 +
137 + void 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 +
168 + void 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 +
184 + void 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 +
196 + void 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 +
218 + char *wololo = "ACNDEFHEJRHSUDIFKEMLOPEC";
219 +
220 + void 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 +
251 + void 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 +
299 + int 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 +
309 + void 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 +
341 + void 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 +
370 + void 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 +
382 + void 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 +
405 + void loop() {
406 + delay(1000);
407 + }
上一页 下一页