Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

497 lines
13KB

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