Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

RawHardwareTest.ino 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. // RawHardwareTest - Check if a SPI Flash chip is compatible
  2. // with SerialFlash by performing many read and write tests
  3. // to its memory.
  4. //
  5. // The chip should be fully erased before running this test.
  6. // Use the EraseEverything to do a (slow) full chip erase.
  7. //
  8. // Normally you should NOT access the flash memory directly,
  9. // as this test program does. You should create files and
  10. // read and write the files. File creation allocates space
  11. // with program & erase boundaries within the chip, to allow
  12. // reading from any other files while a file is busy writing
  13. // or erasing (if created as erasable).
  14. //
  15. // If you discover an incompatible chip, please report it here:
  16. // https://github.com/PaulStoffregen/SerialFlash/issues
  17. // You MUST post the complete output of this program, and
  18. // the exact part number and manufacturer of the chip.
  19. #include <SerialFlash.h>
  20. #include <SPI.h>
  21. const int FlashChipSelect = 6; // digital pin for flash chip CS pin
  22. SerialFlashFile file;
  23. const unsigned long testIncrement = 4096;
  24. void setup() {
  25. //uncomment these if using Teensy audio shield
  26. //SPI.setSCK(14); // Audio shield has SCK on pin 14
  27. //SPI.setMOSI(7); // Audio shield has MOSI on pin 7
  28. //uncomment these if you have other SPI chips connected
  29. //to keep them disabled while using only SerialFlash
  30. //pinMode(4, INPUT_PULLUP);
  31. //pinMode(10, INPUT_PULLUP);
  32. Serial.begin(9600);
  33. while (!Serial) ;
  34. delay(100);
  35. Serial.println("Raw SerialFlash Hardware Test");
  36. SerialFlash.begin(FlashChipSelect);
  37. if (test()) {
  38. Serial.println();
  39. Serial.println("All Tests Passed :-)");
  40. Serial.println();
  41. Serial.println("Test data was written to your chip. You must run");
  42. Serial.println("EraseEverything before using this chip for files.");
  43. } else {
  44. Serial.println();
  45. Serial.println("Tests Failed :{");
  46. Serial.println();
  47. Serial.println("The flash chip may be left in an improper state.");
  48. Serial.println("You might need to power cycle to return to normal.");
  49. }
  50. }
  51. bool test() {
  52. unsigned char buf[256], sig[256], buf2[8];
  53. unsigned long address, count, chipsize, blocksize;
  54. unsigned long usec;
  55. bool first;
  56. // Read the chip identification
  57. Serial.println();
  58. Serial.println("Read Chip Identification:");
  59. SerialFlash.readID(buf);
  60. Serial.print(" JEDEC ID: ");
  61. Serial.print(buf[0], HEX);
  62. Serial.print(" ");
  63. Serial.print(buf[1], HEX);
  64. Serial.print(" ");
  65. Serial.println(buf[2], HEX);
  66. Serial.print(" Part Nummber: ");
  67. Serial.println(id2chip(buf));
  68. Serial.print(" Memory Size: ");
  69. chipsize = SerialFlash.capacity(buf);
  70. Serial.print(chipsize);
  71. Serial.println(" bytes");
  72. if (chipsize == 0) return false;
  73. Serial.print(" Block Size: ");
  74. blocksize = SerialFlash.blockSize();
  75. Serial.print(blocksize);
  76. Serial.println(" bytes");
  77. // Read the entire chip. Every test location must be
  78. // erased, or have a previously tested signature
  79. Serial.println();
  80. Serial.println("Reading Chip...");
  81. memset(buf, 0, sizeof(buf));
  82. memset(sig, 0, sizeof(sig));
  83. memset(buf2, 0, sizeof(buf2));
  84. address = 0;
  85. count = 0;
  86. first = true;
  87. while (address < chipsize) {
  88. SerialFlash.read(address, buf, 8);
  89. //Serial.print(" addr = ");
  90. //Serial.print(address, HEX);
  91. //Serial.print(", data = ");
  92. //printbuf(buf, 8);
  93. create_signature(address, sig);
  94. if (is_erased(buf, 8) == false) {
  95. if (equal_signatures(buf, sig) == false) {
  96. Serial.print(" Previous data found at address ");
  97. Serial.println(address);
  98. Serial.println(" You must fully erase the chip before this test");
  99. Serial.print(" found this: ");
  100. printbuf(buf, 8);
  101. Serial.print(" correct: ");
  102. printbuf(sig, 8);
  103. return false;
  104. }
  105. } else {
  106. count = count + 1; // number of blank signatures
  107. }
  108. if (first) {
  109. address = address + (testIncrement - 8);
  110. first = false;
  111. } else {
  112. address = address + 8;
  113. first = true;
  114. }
  115. }
  116. // Write any signatures that were blank on the original check
  117. if (count > 0) {
  118. Serial.println();
  119. Serial.print("Writing ");
  120. Serial.print(count);
  121. Serial.println(" signatures");
  122. memset(buf, 0, sizeof(buf));
  123. memset(sig, 0, sizeof(sig));
  124. memset(buf2, 0, sizeof(buf2));
  125. address = 0;
  126. first = true;
  127. while (address < chipsize) {
  128. SerialFlash.read(address, buf, 8);
  129. if (is_erased(buf, 8)) {
  130. create_signature(address, sig);
  131. //Serial.printf("write %08X: data: ", address);
  132. //printbuf(sig, 8);
  133. SerialFlash.write(address, sig, 8);
  134. while (!SerialFlash.ready()) ; // wait
  135. SerialFlash.read(address, buf, 8);
  136. if (equal_signatures(buf, sig) == false) {
  137. Serial.print(" error writing signature at ");
  138. Serial.println(address);
  139. Serial.print(" Read this: ");
  140. printbuf(buf, 8);
  141. Serial.print(" Expected: ");
  142. printbuf(sig, 8);
  143. return false;
  144. }
  145. }
  146. if (first) {
  147. address = address + (testIncrement - 8);
  148. first = false;
  149. } else {
  150. address = address + 8;
  151. first = true;
  152. }
  153. }
  154. } else {
  155. Serial.println(" all signatures present from prior tests");
  156. }
  157. // Read all the signatures again, just to be sure
  158. // checks prior writing didn't corrupt any other data
  159. Serial.println();
  160. Serial.println("Double Checking All Signatures:");
  161. memset(buf, 0, sizeof(buf));
  162. memset(sig, 0, sizeof(sig));
  163. memset(buf2, 0, sizeof(buf2));
  164. count = 0;
  165. address = 0;
  166. first = true;
  167. while (address < chipsize) {
  168. SerialFlash.read(address, buf, 8);
  169. create_signature(address, sig);
  170. if (equal_signatures(buf, sig) == false) {
  171. Serial.print(" error in signature at ");
  172. Serial.println(address);
  173. Serial.print(" Read this: ");
  174. printbuf(buf, 8);
  175. Serial.print(" Expected: ");
  176. printbuf(sig, 8);
  177. return false;
  178. }
  179. count = count + 1;
  180. if (first) {
  181. address = address + (testIncrement - 8);
  182. first = false;
  183. } else {
  184. address = address + 8;
  185. first = true;
  186. }
  187. }
  188. Serial.print(" all ");
  189. Serial.print(count);
  190. Serial.println(" signatures read ok");
  191. // Read pairs of adjacent signatures
  192. // check read works across boundaries
  193. Serial.println();
  194. Serial.println("Checking Signature Pairs");
  195. memset(buf, 0, sizeof(buf));
  196. memset(sig, 0, sizeof(sig));
  197. memset(buf2, 0, sizeof(buf2));
  198. count = 0;
  199. address = testIncrement - 8;
  200. first = true;
  201. while (address < chipsize - 8) {
  202. SerialFlash.read(address, buf, 16);
  203. create_signature(address, sig);
  204. create_signature(address + 8, sig + 8);
  205. if (memcmp(buf, sig, 16) != 0) {
  206. Serial.print(" error in signature pair at ");
  207. Serial.println(address);
  208. Serial.print(" Read this: ");
  209. printbuf(buf, 16);
  210. Serial.print(" Expected: ");
  211. printbuf(sig, 16);
  212. return false;
  213. }
  214. count = count + 1;
  215. address = address + testIncrement;
  216. }
  217. Serial.print(" all ");
  218. Serial.print(count);
  219. Serial.println(" signature pairs read ok");
  220. // Write data and read while write in progress
  221. Serial.println();
  222. Serial.println("Checking Read-While-Write (Program Suspend)");
  223. address = 256;
  224. while (address < chipsize) { // find a blank space
  225. SerialFlash.read(address, buf, 256);
  226. if (is_erased(buf, 256)) break;
  227. address = address + 256;
  228. }
  229. if (address >= chipsize) {
  230. Serial.println(" error, unable to find any blank space!");
  231. return false;
  232. }
  233. for (int i=0; i < 256; i += 8) {
  234. create_signature(address + i, sig + i);
  235. }
  236. Serial.print(" write 256 bytes at ");
  237. Serial.println(address);
  238. Serial.flush();
  239. SerialFlash.write(address, sig, 256);
  240. usec = micros();
  241. if (SerialFlash.ready()) {
  242. Serial.println(" error, chip did not become busy after write");
  243. return false;
  244. }
  245. SerialFlash.read(0, buf2, 8); // read while busy writing
  246. while (!SerialFlash.ready()) ; // wait
  247. usec = micros() - usec;
  248. Serial.print(" write time was ");
  249. Serial.print(usec);
  250. Serial.println(" microseconds.");
  251. SerialFlash.read(address, buf, 256);
  252. if (memcmp(buf, sig, 256) != 0) {
  253. Serial.println(" error writing to flash");
  254. Serial.print(" Read this: ");
  255. printbuf(buf, 256);
  256. Serial.print(" Expected: ");
  257. printbuf(sig, 256);
  258. return false;
  259. }
  260. create_signature(0, sig);
  261. if (memcmp(buf2, sig, 8) != 0) {
  262. Serial.println(" error, incorrect read while writing");
  263. Serial.print(" Read this: ");
  264. printbuf(buf2, 256);
  265. Serial.print(" Expected: ");
  266. printbuf(sig, 256);
  267. return false;
  268. }
  269. Serial.print(" read-while-writing: ");
  270. printbuf(buf2, 8);
  271. Serial.println(" test passed, good read while writing");
  272. // Erase a block and read while erase in progress
  273. if (chipsize >= 262144 + blocksize + testIncrement) {
  274. Serial.println();
  275. Serial.println("Checking Read-While-Erase (Erase Suspend)");
  276. memset(buf, 0, sizeof(buf));
  277. memset(sig, 0, sizeof(sig));
  278. memset(buf2, 0, sizeof(buf2));
  279. SerialFlash.eraseBlock(262144);
  280. usec = micros();
  281. delayMicroseconds(50);
  282. if (SerialFlash.ready()) {
  283. Serial.println(" error, chip did not become busy after erase");
  284. return false;
  285. }
  286. SerialFlash.read(0, buf2, 8); // read while busy writing
  287. while (!SerialFlash.ready()) ; // wait
  288. usec = micros() - usec;
  289. Serial.print(" erase time was ");
  290. Serial.print(usec);
  291. Serial.println(" microseconds.");
  292. // read all signatures, check ones in this block got
  293. // erased, and all the others are still intact
  294. address = 0;
  295. first = true;
  296. while (address < chipsize) {
  297. SerialFlash.read(address, buf, 8);
  298. if (address >= 262144 && address < 262144 + blocksize) {
  299. if (is_erased(buf, 8) == false) {
  300. Serial.print(" error in erasing at ");
  301. Serial.println(address);
  302. Serial.print(" Read this: ");
  303. printbuf(buf, 8);
  304. return false;
  305. }
  306. } else {
  307. create_signature(address, sig);
  308. if (equal_signatures(buf, sig) == false) {
  309. Serial.print(" error in signature at ");
  310. Serial.println(address);
  311. Serial.print(" Read this: ");
  312. printbuf(buf, 8);
  313. Serial.print(" Expected: ");
  314. printbuf(sig, 8);
  315. return false;
  316. }
  317. }
  318. if (first) {
  319. address = address + (testIncrement - 8);
  320. first = false;
  321. } else {
  322. address = address + 8;
  323. first = true;
  324. }
  325. }
  326. Serial.print(" erase correctly erased ");
  327. Serial.print(blocksize);
  328. Serial.println(" bytes");
  329. // now check if the data we read during erase is good
  330. create_signature(0, sig);
  331. if (memcmp(buf2, sig, 8) != 0) {
  332. Serial.println(" error, incorrect read while erasing");
  333. Serial.print(" Read this: ");
  334. printbuf(buf2, 256);
  335. Serial.print(" Expected: ");
  336. printbuf(sig, 256);
  337. return false;
  338. }
  339. Serial.print(" read-while-erasing: ");
  340. printbuf(buf2, 8);
  341. Serial.println(" test passed, good read while erasing");
  342. } else {
  343. Serial.println("Skip Read-While-Erase, this chip is too small");
  344. }
  345. return true;
  346. }
  347. void loop() {
  348. // do nothing after the test
  349. }
  350. const char * id2chip(const unsigned char *id)
  351. {
  352. if (id[0] == 0xEF) {
  353. // Winbond
  354. if (id[1] == 0x40) {
  355. if (id[2] == 0x14) return "W25Q80BV";
  356. if (id[2] == 0x17) return "W25Q64FV";
  357. if (id[2] == 0x18) return "W25Q128FV";
  358. if (id[2] == 0x19) return "W25Q256FV";
  359. }
  360. }
  361. if (id[0] == 0x01) {
  362. // Spansion
  363. if (id[1] == 0x02) {
  364. if (id[2] == 0x16) return "S25FL064A";
  365. if (id[2] == 0x19) return "S25FL256S";
  366. if (id[2] == 0x20) return "S25FL512S";
  367. }
  368. if (id[1] == 0x20) {
  369. if (id[2] == 0x18) return "S25FL127S";
  370. }
  371. }
  372. if (id[0] == 0xC2) {
  373. // Macronix
  374. if (id[1] == 0x20) {
  375. if (id[2] == 0x18) return "MX25L12805D";
  376. }
  377. }
  378. if (id[0] == 0x20) {
  379. // Micron
  380. if (id[1] == 0xBA) {
  381. if (id[2] == 0x20) return "N25Q512A";
  382. if (id[2] == 0x21) return "N25Q00AA";
  383. }
  384. if (id[1] == 0xBB) {
  385. if (id[2] == 0x22) return "MT25QL02GC";
  386. }
  387. }
  388. if (id[0] == 0xBF) {
  389. // SST
  390. if (id[1] == 0x25) {
  391. if (id[2] == 0x02) return "SST25WF010";
  392. if (id[2] == 0x03) return "SST25WF020";
  393. if (id[2] == 0x04) return "SST25WF040";
  394. if (id[2] == 0x41) return "SST25VF016B";
  395. if (id[2] == 0x4A) return "SST25VF032";
  396. }
  397. if (id[1] == 0x25) {
  398. if (id[2] == 0x01) return "SST26VF016";
  399. if (id[2] == 0x02) return "SST26VF032";
  400. if (id[2] == 0x43) return "SST26VF064";
  401. }
  402. }
  403. return "(unknown chip)";
  404. }
  405. void print_signature(const unsigned char *data)
  406. {
  407. Serial.print("data=");
  408. for (unsigned char i=0; i < 8; i++) {
  409. Serial.print(data[i]);
  410. Serial.print(" ");
  411. }
  412. Serial.println();
  413. }
  414. void create_signature(unsigned long address, unsigned char *data)
  415. {
  416. data[0] = address >> 24;
  417. data[1] = address >> 16;
  418. data[2] = address >> 8;
  419. data[3] = address;
  420. unsigned long hash = 2166136261ul;
  421. for (unsigned char i=0; i < 4; i++) {
  422. hash ^= data[i];
  423. hash *= 16777619ul;
  424. }
  425. data[4] = hash;
  426. data[5] = hash >> 8;
  427. data[6] = hash >> 16;
  428. data[7] = hash >> 24;
  429. }
  430. bool equal_signatures(const unsigned char *data1, const unsigned char *data2)
  431. {
  432. for (unsigned char i=0; i < 8; i++) {
  433. if (data1[i] != data2[i]) return false;
  434. }
  435. return true;
  436. }
  437. bool is_erased(const unsigned char *data, unsigned int len)
  438. {
  439. while (len > 0) {
  440. if (*data++ != 255) return false;
  441. len = len - 1;
  442. }
  443. return true;
  444. }
  445. void printbuf(const void *buf, uint32_t len)
  446. {
  447. const uint8_t *p = (const uint8_t *)buf;
  448. do {
  449. unsigned char b = *p++;
  450. Serial.print(b >> 4, HEX);
  451. Serial.print(b & 15, HEX);
  452. //Serial.printf("%02X", *p++);
  453. Serial.print(" ");
  454. } while (--len > 0);
  455. Serial.println();
  456. }