Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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