You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RawHardwareTest.ino 13KB

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