Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

RawHardwareTest.ino 13KB

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. }