選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

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