PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

508 linhas
14KB

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