Sample SPI drivers for a number of the Adesto Technologies flash devices.
test.c
Go to the documentation of this file.
1 /*
2  * The Clear BSD License
3  * Copyright (c) 2018 Adesto Technologies Corporation, Inc
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted (subject to the limitations in the disclaimer below) provided
8  * that the following conditions are met:
9  *
10  * o Redistributions of source code must retain the above copyright notice, this list
11  * of conditions and the following disclaimer.
12  *
13  * o Redistributions in binary form must reproduce the above copyright notice, this
14  * list of conditions and the following disclaimer in the documentation and/or
15  * other materials provided with the distribution.
16  *
17  * o Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
26  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
42 #include "test.h"
43 
44 #if defined(MONETA_DEVICE)
45 
46 uint32_t defaultTest(){return monetaTest();};
47 
48 int monetaTest()
49 {
50  // Sets the various pins as inputs and output
52 
53  // Instantiate the arrays needed for testing purposes.
54  // dataWrite is used when sending data that will be flashed to the device.
55  uint8_t dataWrite[MAXIMUM_BUFFER_SIZE] = {0};
56  // dataRead is used as a buffer for received data. Read data will be stored here.
57  uint8_t dataRead[MAXIMUM_BUFFER_SIZE] = {0};
58  // dataTest is used as a buffer for comparisons. dataRead will be
59  // loaded with data and compared against this buffer for equality.
60  uint8_t dataTest[MAXIMUM_BUFFER_SIZE] = {0};
61  // Count the number of errors, this is output at the end of the testbench.
62  int errorCount = 0;
63 
64  // Store all Fs in the test buffer for later comparison
65  for(int i = 0; i < MAXIMUM_BUFFER_SIZE; i++)
66  {
67  dataTest[i] = 0xFF;
68  }
69 
70  // Store the manufacturing ID for later comparison
71  uint8_t MID[8] = {0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x43};
72 
73  // Load up dataWrite with a pattern that will be stored in flash memory.
74  for(uint32_t a = 0; a < 100; a++)
75  {
76  dataWrite[a] = (uint8_t) 0xA+a;
77  }
78 
79  /********************************************************************
80  * 1. Read manufacturing ID, test write enable, test write disable. *
81  ********************************************************************/
82 
83  printf("\n\nTesting Read MID, WEnable, and WDisable ----------\n\n");
84 
85  // Part A: Test that the MID can be read.
86  // Read the manufacturing ID and store the returned data in dataRead
87  monetaReadMID(dataRead);
88  // Compare the read data to the expected bytes stored in MID. Print
89  // the result of the test.
90  if(compareByteArrays(dataRead, MID, 8))
91  {
92  printf("ReadMID Success.\n");
93  }
94  else
95  {
96  printf("ReadMID fail.\n");
97  errorCount++;
98  }
99 
100  // Part B: Ensure that the device can be write enabled.
101  // The device is write enabled...
103  // ... the status register is then read ..
104  monetaReadSR(dataRead);
105  // ... and the write enable bit checked.
106  // WE should be 1 if the command and setup are operational.
107  if(!((dataRead[0] >> 1) & 1))
108  {
109  printf("Error with WE or Read SR\n");
110  errorCount++;
111  }
112  else
113  {
114  printf("WE success.\n");
115  }
116 
117  // Part C: Now attempt to disable write.
118  // The command is sent to disable write...
121 
122  /********************************************************************
123  * 2. Test read and write. *
124  ********************************************************************/
125 
126  printf("\n\nTesting read and write -----------------------------\n\n");
127 
128  // Part A: Program the device.
129  // Write enable the device since we'll be modifying data.
132  // Program the first 50 bytes.
133  monetaWriteArray(0, dataWrite, 50);
135 
136  // Part B: Check that the data is correct by reading and comparing to a known value.
137  monetaReadArray(0, dataRead, 100);
138  // Compare against known data.
139  if(compareByteArrays(dataRead, dataWrite, 50))
140  {
141  printf("Program and read operations successful.\n");
142  }
143  else
144  {
145  printf("Program and read operations fail.\n");
146  errorCount++;
147  }
148 
149  /********************************************************************
150  * 3. Test ultra deep power down mode and JEDEC reset. *
151  ********************************************************************/
152 
153  printf("\n\nTesting UDPD Mode and JEDEC Reset --------------------\n\n");
154 
155  // Part A: Enter UDPD mode and confirm that the device outputs Hi-Z.
156  // Set the device into ultra deep power down (UDPD) mode.
157  monetaUDPDMode1();
158  // Attempt to read from the device. Note, this should not work in DPD Mode.
159  monetaReadArray(0, dataRead, 100);
160  // Compare the data as stated above. There should me a data mismatch in DPD mode.
161  if(!compareByteArrays(dataRead, dataTest, 25))
162  {
163  printf("DEVICE IS IN UDPD MODE. DATA MISMATCH EXPECTED. TEST PASSED.\n");
164  }
165  else
166  {
167  printf("DEVICE FAILED UDPD TEST. The device is reading stored data when the line should be in Hi-Z state.\n");
168  errorCount++;
169  }
170 
171  // Part B: Test that the device can recover from UDPD mode.
172  // Exit UDPD mode by performing a hardware reset.
174  printf("JEDEC reset performed, device should be operational.\n");
175  // Perform a device read and compare against known data.
176  monetaReadArray(0, dataRead, 50);
177  if(compareByteArrays(dataRead, dataWrite, 50))
178  {
179  printf("JEDEC reset operation success.\n");
180  }
181  else
182  {
183  printf("JEDEC reset operation fail.\n");
184  errorCount++;
185  }
186 
187  // Test complete, exit and print messages.
188  printf("\n\n#############################################\n\n");
189  printf("Testing complete.\n");
190  printf("Total errors detected: %d\n", errorCount);
191  printf("Terminating testbench...\n");
192  printf("\n#############################################\n\n");
193  return errorCount;
194 }
195 
196 #elif defined(FUSION_DEVICE)
197 
198 uint32_t defaultTest(){return fusionTest();};
199 
200 uint32_t fusionTest()
201 {
202  // Sets the various pins as inputs and output
204 
205  // Instantiate the arrays needed for testing purposes.
206  // dataWrite is used when sending data that will be flashed to the device.
207  uint8_t dataWrite[MAXIMUM_BUFFER_SIZE] = {0};
208  // dataRead is used as a buffer for received data. Read data will be stored here.
209  uint8_t dataRead[MAXIMUM_BUFFER_SIZE] = {0};
210  // dataTest is used as a buffer for comparisons. dataRead will be
211  // loaded with data and compared against this buffer for equality.
212  uint8_t dataTest[MAXIMUM_BUFFER_SIZE] = {0};
213  // Count the number of errors, this is output at the end of the testbench.
214  uint32_t errorCount = 0;
215 
216  // Store all Fs in the test buffer for later comparison
217  for(int i = 0; i < MAXIMUM_BUFFER_SIZE; i++)
218  {
219  dataTest[i] = 0xFF;
220  }
221 #if PARTNO == AT25XE512C
222  // Store the manufacturing ID for later comparison
223  uint8_t MID[4] = {0x1F, 0x65, 0x01, 0x00};
224 #elif PARTNO == AT25XE011
225  // Store the manufacturing ID for later comparison
226  uint8_t MID[4] = {0x1F, 0x42, 0x00, 0x00};
227 #elif PARTNO == AT25XE021A
228  // Store the manufacturing ID for later comparison
229  uint8_t MID[4] = {0x1F, 0x43, 0x01, 0x00};
230 #elif PARTNO == AT25XE041B
231  // Store the manufacturing ID for later comparison
232  uint8_t MID[4] = {0x1F, 0x44, 0x02, 0x00};
233 #elif PARTNO == AT25DN256
234  // Store the manufacturing ID for later comparison
235  uint8_t MID[4] = {0x1F, 0x40, 0x00, 0x00};
236 #elif PARTNO == AT25DN512C
237  // Store the manufacturing ID for later comparison
238  uint8_t MID[4] = {0x1F, 0x65, 0x01, 0x00};
239 #elif PARTNO == AT25DN011
240  // Store the manufacturing ID for later comparison
241  uint8_t MID[4] = {0x1F, 0x42, 0x00, 0x00};
242 #elif PARTNO == AT25DF256
243  // Store the manufacturing ID for later comparison
244  uint8_t MID[4] = {0x1F, 0x40, 0x00, 0x00};
245 #elif PARTNO == AT25DF512C
246  // Store the manufacturing ID for later comparison
247  uint8_t MID[4] = {0x1F, 0x64, 0x01, 0x00};
248 #elif PARTNO == AT25DF011
249  // Store the manufacturing ID for later comparison
250  uint8_t MID[4] = {0x1F, 0x42, 0x00, 0x00};
251 #elif PARTNO == AT25DF021A
252  // Store the manufacturing ID for later comparison
253  uint8_t MID[4] = {0x1F, 0x43, 0x01, 0x00};
254 #elif PARTNO == AT25DF041B
255  // Store the manufacturing ID for later comparison
256  uint8_t MID[4] = {0x1F, 0x44, 0x02, 0x00};
257 #elif PARTNO == AT25XV021A
258  // Store the manufacturing ID for later comparison
259  uint8_t MID[4] = {0x1F, 0x43, 0x01, 0x00};
260 #elif PARTNO == AT25XV041B
261  // Store the manufacturing ID for later comparison
262  uint8_t MID[4] = {0x1F, 0x44, 0x02, 0x00};
263 #endif
264 
265  // Load up dataWrite with a pattern that will be stored in flash memory.
266  for(uint32_t a = 0; a < 100; a++)
267  {
268  dataWrite[a] = (uint8_t) 0xA+a;
269  }
270 
271  /********************************************************************
272  * 1. Read manufacturing ID, test write enable, test write disable. *
273  ********************************************************************/
274 
275  printf("\n\nTesting Read MID, WEnable, and WDisable ----------\n\n");
276 
277  // Part A: Test that the MID can be read.
278  // Read the manufacturing ID and store the returned data in dataRead
279  fusionReadMID(dataRead);
280  // Compare the read data to the expected bytes stored in MID. Print
281  // the result of the test.
282  if(compareByteArrays(dataRead, MID, 4))
283  {
284  printf("ReadMID Success.\n");
285  }
286  else
287  {
288  printf("ReadMID fail.\n");
289  errorCount++;
290  }
291 
292 
293  // Part B: Ensure that the device can be write enabled.
294  // The device is write enabled...
296  // ... the status register is then read ..
297  fusionReadSR(dataRead);
298  // ... and the write enable bit checked.
299  // WE should be 1 if the command and setup are operational.
300  if(!((dataRead[0] >> 1) & 1))
301  {
302  printf("Error with WE or Read SR");
303  errorCount++;
304  }
305  else
306  {
307  printf("WE success.\n");
308  }
309 
310 
311  // Part C: Now attempt to disable write.
312  // The command is sent to disable write...
314  // ... the status register is then read...
315  fusionReadSR(dataRead);
316  // ... and the write enable bit checked.
317  // WE should be 0 if the command and setup are operational.
318  if(((dataRead[0] >> 1) & 1))
319  {
320  printf("Error with WD or Read SR");
321  errorCount++;
322  }
323  else
324  {
325  printf("WD success.\n");
326  }
327 
328 #if (PARTNO == AT25XE021A) || \
329  (PARTNO == AT25XE041B) || \
330  (PARTNO == AT25DF021A) || \
331  (PARTNO == AT25DF041B) || \
332  (PARTNO == AT25XV021A) || \
333  (PARTNO == AT25XV041B) || \
334  (ALL == 1)
335  /********************************************************************
336  * 2. Test that sectors can be properly unprotected. *
337  ********************************************************************/
338 
339 
340  printf("\n\nTesting Un/protect Sector ------------------------\n\n");
341 
342  // Part A: Guarantee sector 0 is protected.
343  // To start with, ensure that sector 0 is protected. It should be if
344  // the test bench has been run before this and completed.
346  // The register should read 0xFF is protected.
347  if(dataRead[0] != 0xFF)
348  {
349  printf("Error with protection SR of sector 0");
350  errorCount++;
351  }
352  else
353  {
354  printf("Protect success.\n");
355  }
356 
357  // Part B: Unprotect sector 0.
358  // Write enable the device since we'll be writing to it...
360  // ... and unprotect sector 0.
362  // Follow up by reading the status register which should be 0x00
363  // if the sector was unprotected properly.
365  // Sector 0 should be unprotected (0x00)
366  if(dataRead[0] != 0x00)
367  {
368  printf("Error unprotecting sector 0");
369  errorCount++;
370  }
371  else
372  {
373  printf("Unprotect success.\n");
374  }
375 #endif
376  /********************************************************************
377  * 3. Test the page erase functionality. *
378  ********************************************************************/
379 
380  printf("\n\nTesting Erase ------------------------------------\n\n");
381 
382  // Test by erasing the device and confirming all bits are set.
383  // Write enable the device since we'll be issuing a command that will modify stored data.
385  // Issue a page erase command starting from address 0 (page 0).
386  fusionPageErase(0);
387  // Wait for the operation to complete.
389  // Now read the flash device. All bits should be set -> FF for each byte.
390  fusionReadArray(0, dataRead, 100);
391  // If any of the first 100 bytes are not 0xFF, print an error message.
392  if(compareByteArrays(dataRead, dataTest, 100))
393  {
394  printf("PageErase success.\n");
395  }
396  else
397  {
398  printf("PageErase fail.\n");
399  errorCount++;
400  }
401 
402 #if (PARTNO == AT25XE021A) || \
403  (PARTNO == AT25XE041B) || \
404  (PARTNO == AT25DF021A) || \
405  (PARTNO == AT25DF041B) || \
406  (PARTNO == AT25XV021A) || \
407  (PARTNO == AT25XV041B) || \
408  (ALL == 1)
409  /********************************************************************
410  * 4. Test the sequential/byte program mode. *
411  ********************************************************************/
412 
413  printf("\n\nTesting Sequential Program Mode -------------------\n\n");
414 
415  // Part A: Sequentially program the device to confirm sequential program works.
416  // Write enable the device since we'll be issuing a command that will modify stored data.
418  // Begin sequentially programming the device byte by byte from address 0.
419  // The first byte programmed is included in the initial program command.
421  // Set the first element of the comparison buffer to zero, the byte programmed above.
422  dataTest[0] = 0x00;
423  // Now program 48 other bytes, and store the values in the test buffer. Note the offset
424  // (j=1) since the first byte was already programmed.
425  for(int j = 1; j < 50; j++)
426  {
427  dataTest[j] = (uint8_t) j;
429  }
430 
431  // Part B: Leave sequential program mode.
432  // Exit sequential program mode by issuing a write disable command.
434 
435  // Part C: Test that the data was written properly.
436  // For the sake of testing that we can no longer write in sequential program mode, try
437  // writing one last byte. Since we erase this memory location in a prior operation, a
438  // 'failed' write in sequential mode means it should still be FF. FF is stored in the buffer
439  // for this element so an error will be printed if they do not match.
441  // Read the array, and compare against known data.
442  fusionReadArray(0, dataRead, 100);
443  if(compareByteArrays(dataRead, dataTest, 51))
444  {
445  printf("Sequential operation success.\n");
446  }
447  else
448  {
449  printf("Sequential operation fail.\n");
450  errorCount++;
451  }
452  // We checked the 'failed' sequential program mode above, but if indeed it still programmed,
453  // This will print out a directed message.
454  if(dataRead[0x50] != 0xFF)
455  {
456  printf("Error, data programmed when write disabled.");
457  errorCount++;
458  }
459 
460  /********************************************************************
461  * 5. Test dual read and write. *
462  ********************************************************************/
463 
464  printf("\n\nTesting Dual Read/Write Mode -------------------------\n\n");
465 
466  // Part A: Program the device in dual mode.
467  // Write enable the device since we'll be modifying data.
469  // Perform a block erase to setup the test.
471  // Wait for the block erase to finish.
473  // Reissue the write enable command since we'll be modifying the data a second time.
475  // Program the first 50 bytes in dual input program mode.
476  fusionDualInputProgram(0, dataWrite, 50);
477  // Wait for the operation to complete. (data is sent to a buffer and the write to flash occurs
478  // after CSb is deselected).
480 
481  // Part B: Confirm dual mode write worked.
482  // Now perform a standard read. This ensures that the data is readable in both formats
483  // and that there wasn't some sort of odd segmentation.
484  fusionReadArray(0, dataRead, 100);
485  // Compare against known data.
486  if(compareByteArrays(dataRead, dataWrite, 50))
487  {
488  printf("Dual input program operation success.\n");
489  }
490  else
491  {
492  printf("Dual input program operation fail.\n");
493  errorCount++;
494  }
495 
496  // Part C: Test that dual output read works.
497  // Now test dual output read...
498  fusionDualOutputRead(0, dataRead, 100);
499  // ... and compare against known data.
500  if(compareByteArrays(dataRead, dataWrite, 50))
501  {
502  printf("Dual output read operation success.\n");
503  }
504  else
505  {
506  printf("Dual output read operation fail.\n");
507  errorCount++;
508  }
509 #endif
510  /********************************************************************
511  * 6. Test deep power down mode *
512  ********************************************************************/
513 
514  printf("\n\nTesting Deep Power Down functionality -----------------\n\n");
515 
516  // Part A: Test that the device goes into DPD mode.
517  // Send the device into deep power down (DPD) mode. In DPD mode the MISO line is in a high impedance
518  // state and the data will be unpredictable. We test for this by reading the device and confirming
519  // that the output doesn't match the stored data. The probability that it will is infinitesimal.
520  // If any errors are output, the device is in DPD Mode and the test passes.
522  // Attempt to read from the device. Note, this should not work in DPD Mode.
523  fusionReadArray(0, dataRead, 100);
524  // Compare the data as stated above. There should me a data mismatch in DPD mode.
525  if(!compareByteArrays(dataRead, dataTest, 25))
526  {
527  printf("DEVICE IS IN DPD MODE. DATA MISMATCH EXPECTED. TEST PASSED.\n");
528  }
529  else
530  {
531  printf("DEVICE FAILED DPD TEST. The device is reading stored data when the line should be in Hi-Z state.\n");
532  errorCount++;
533  }
534 
535  // Part B: Test that the device can exit DPD mode.
536  printf("Resuming from Deep Power Down Mode...\n");
537 
538  // Now resume from DPD mode...
540  // ... and try to read from the device. It should function in its normal state.
541  fusionReadArray(0, dataRead, 50);
542  // A comparison of read data to expected data should pass.
543  if(compareByteArrays(dataRead, dataWrite, 50))
544  {
545  printf("Resume from DPD operation success.\n");
546  }
547  else
548  {
549  printf("Resume from DPD operation fail.\n");
550  errorCount++;
551  }
552 
553 #if (PARTNO == AT25XE021A) || \
554  (PARTNO == AT25XE041B) || \
555  (PARTNO == AT25DF021A) || \
556  (PARTNO == AT25DF041B) || \
557  (PARTNO == AT25XV021A) || \
558  (PARTNO == AT25XV041B) || \
559  (ALL == 1)
560  /********************************************************************
561  * 7. Test global protect and global unprotect. *
562  ********************************************************************/
563 
564  printf("\n\nTesting Global Un/Protect -----------------------------\n\n");
565 
566  // Part A: Confirm the cuttenr state of the protection registers.
567  // This is not a comprehensive test. We will examine sector zero protect and unprotect
568  // to determine that the protection register does indeed change based on the commands issued.
569  // From previous steps, sector zero was unprotected, so confirm that this is indeed the case
570  // first.
571  // Read sector 0's protection register
573  // An unprotected sector should read 0x00.
574  if(dataRead[0] != 0x00)
575  {
576  printf("Error with sector 0 protection");
577  errorCount++;
578  }
579 
580  // Part B: Protect the sectors.
581  // Now attempt to protect all sectors.
583  // Read the sector protection register for sector zero. It should read 0xFF for protected.
585  // Confirm that the sector is protected.
586  if(dataRead[0] != 0xFF)
587  {
588  printf("Error with global protect");
589  errorCount++;
590  }
591  else
592  {
593  printf("Global protect success.\n");
594  }
595 
596  // Part C: Unprotect the sectors.
597  // Now perform a global unprotect to confirm we can leave the protected state through
598  // this command.
600  // Read the SPR again and confirm sector 0 is unprotected.
602  if(dataRead[0] != 0x00)
603  {
604  printf("Error with global unprotect");
605  errorCount++;
606  }
607  else
608  {
609  printf("Global unprotect success.\n");
610  }
611 #endif
612  /********************************************************************
613  * 8. Test ultra deep power down mode and JEDEC reset. *
614  ********************************************************************/
615 
616  printf("\n\nTesting UDPD Mode and JEDEC Reset --------------------\n\n");
617 
618  // Part A: Enter UDPD mode and confirm that the device outputs Hi-Z.
619  // Set the device into ultra deep power down (UDPD) mode. The tests performed here
620  // are the same as the ones performed for the DPD mode, but the device is woken up
621  // with a JEDEC reset.
622  fusionUDPDMode();
623  // Attempt to read from the device. Note, this should not work in DPD Mode.
624  fusionReadArray(0, dataRead, 100);
625  // Compare the data as stated above. There should me a data mismatch in DPD mode.
626  if(!compareByteArrays(dataRead, dataTest, 25))
627  {
628  printf("DEVICE IS IN UDPD MODE. DATA MISMATCH EXPECTED. TEST PASSED.\n");
629  }
630  else
631  {
632  printf("DEVICE FAILED UDPD TEST. The device is reading stored data when the line should be in Hi-Z state.\n");
633  errorCount++;
634  }
635 
636  // Part B: Test that the device can recover from UDPD mode.
637  // Exit UDPD mode by performing a hardware reset.
639  printf("JEDEC reset performed, device should be operational.\n");
640  // Perform a device read and compare against known data.
641  fusionReadArray(0, dataRead, 50);
642  if(compareByteArrays(dataRead, dataWrite, 50))
643  {
644  printf("JEDEC reset operation success.\n");
645  }
646  else
647  {
648  printf("JEDEC reset operation fail.\n");
649  errorCount++;
650  }
651 
652  // Test complete, exit and print messages.
653  printf("\n\n#############################################\n\n");
654  printf("Testing complete.\n");
655  printf("Total errors detected: %d\n", errorCount);
656  printf("Terminating testbench...\n");
657  printf("\n#############################################\n\n");
658 
659  return errorCount;
660 }
661 
662 #elif defined(DATAFLASH_DEVICE)
663 
664 uint32_t defaultTest(){return dataflashTest();};
665 
666 uint32_t dataflashTest()
667 {
668  // Sets the various pins as inputs and output
670 
671  // Instantiate the arrays needed for testing purposes.
672  // dataWrite is used when sending data that will be flashed to the device.
673  uint8_t dataWrite[MAXIMUM_BUFFER_SIZE] = {0};
674  // dataRead is used as a buffer for received data. Read data will be stored here.
675  uint8_t dataRead[MAXIMUM_BUFFER_SIZE] = {0};
676  // dataTest is used as a buffer for comparisons. dataRead will be
677  // loaded with data and compared against this buffer for equality.
678  uint8_t dataTest[MAXIMUM_BUFFER_SIZE] = {0};
679  // Count the number of errors, this is output at the end of the testbench.
680  uint32_t errorCount = 0;
681 
682 #if PARTNO == AT45DB021E
683  // Store the manufacturing ID for later comparison
684  uint8_t MID[5] = {0x1F, 0x23, 0x00, 0x01, 0x00};
685 #elif PARTNO == AT45DB041E
686  // Store the manufacturing ID for later comparison
687  uint8_t MID[5] = {0x1F, 0x24, 0x00, 0x01, 0x00};
688 #elif PARTNO == AT45DB081E
689  // Store the manufacturing ID for later comparison
690  uint8_t MID[5] = {0x1F, 0x25, 0x00, 0x01, 0x00};
691 #elif PARTNO == AT45DB161E
692  // Store the manufacturing ID for later comparison
693  uint8_t MID[5] = {0x1F, 0x26, 0x00, 0x01, 0x00};
694 #elif PARTNO == AT45DB321E
695  // Store the manufacturing ID for later comparison
696  uint8_t MID[5] = {0x1F, 0x27, 0x01, 0x01, 0x00};
697 #elif PARTNO == AT45DB641E
698  // Store the manufacturing ID for later comparison
699  uint8_t MID[5] = {0x1F, 0x28, 0x00, 0x01, 0x00};
700 #elif PARTNO == AT45DQ161
701  // Store the manufacturing ID for later comparison
702  uint8_t MID[5] = {0x1F, 0x26, 0x00, 0x01, 0x00};
703 #elif PARTNO == AT45DQ321
704  // Store the manufacturing ID for later comparison
705  uint8_t MID[5] = {0x1F, 0x27, 0x01, 0x01, 0x00};
706 #elif PARTNO == AT25PE20
707  // Store the manufacturing ID for later comparison
708  uint8_t MID[5] = {0x1F, 0x23, 0x00, 0x01, 0x00};
709 #elif PARTNO == AT25PE40
710  // Store the manufacturing ID for later comparison
711  uint8_t MID[5] = {0x1F, 0x24, 0x00, 0x01, 0x00};
712 #elif PARTNO == AT25PE80
713  // Store the manufacturing ID for later comparison
714  uint8_t MID[5] = {0x1F, 0x25, 0x00, 0x01, 0x00};
715 #elif PARTNO == AT25PE16
716  // Store the manufacturing ID for later comparison
717  uint8_t MID[5] = {0x1F, 0x26, 0x00, 0x01, 0x00};
718 #endif
719 
720 
721  // Store all Fs in the test buffer for later comparison
722  fillArrayConst(dataTest, MAXIMUM_BUFFER_SIZE, 0xFF);
723  // Load up dataWrite with a pattern that will be used for testing.
724  fillArrayPattern(dataWrite, 100, 0x00);
725 
726 
727  /********************************************************************
728  * 1. Read manufacturing ID *
729  ********************************************************************/
730 
731  printf("\n\nTesting Read MID -----------------------------------\n\n");
732 
733  // Part A: Test that the MID can be read.
734  // Read the manufacturing ID and store the returned data in dataRead
735  dataflashReadMID(dataRead);
736  // Compare the read data to the expected bytes stored in MID. Print
737  // the result of the test.
738  if(compareByteArrays(dataRead, MID, 5))
739  {
740  printf("ReadMID Success.\n");
741  }
742  else
743  {
744  printf("ReadMID fail.\n");
745  errorCount++;
746  }
747 
748 
749  /********************************************************************
750  * 2. Test read and write functionality. *
751  ********************************************************************/
752  /*
753  * This test is comprised of 4 components:
754  * Part A: Test buffer read and buffer write.
755  * Part B: Test buffer to main memory.
756  * Part C: Test buffer to memory without erase.
757  * Part D: Test program through buffer without erase.
758  */
759 
760  printf("\n\nTesting Read and Write functionality ---------------\n\n");
761 
762  // Test buffer 1:
763  // Part A: Test that the buffers can be written to and read.
764  // Data will be written to the buffers then read back using both high and low frequency commands
765  fillArrayPattern(dataWrite, 100, 0x05);
766  dataflashBuffer1Write(0, dataWrite, 100);
767  dataflashBuffer1ReadLowFreq(0, dataRead, 100);
768  if(!compareByteArrays(dataRead, dataWrite, 100))
769  {
770  printf("Buffer 1 Write or ReadLF failure.\n");
771  errorCount++;
772  }
773  else
774  {
775  printf("Buffer 1 Write and ReadLF success.\n");
776  }
777  dataflashBuffer1ReadHighFreq(0, dataRead, 100);
778  if(!compareByteArrays(dataRead, dataWrite, 100))
779  {
780  printf("Buffer 1 Write or ReadHF failure.\n");
781  errorCount++;
782  }
783  else
784  {
785  printf("Buffer 1 Write and ReadHF success.\n");
786  }
787  // Test buffer 1:
788  // Part B: Test that data can be written to main memory.
789  // Data will be programmed to the device through the buffer, and then read back with different
790  // read commands. Each read command will be tested, and success/failure messages output to the
791  // console.
794  dataflashArrayReadLowFreq(0, dataRead, 100);
795  if(!compareByteArrays(dataRead, dataWrite, 100))
796  {
797  printf("Main memory through Buffer 1 r/w failure.\n");
798  errorCount++;
799  }
800  else
801  {
802  printf("Main memory through Buffer 1 r/w success.\n");
803  }
804 
805 #if (PARTNO == AT45DB021E) || \
806  (PARTNO == AT45DB041E) || \
807  (PARTNO == AT45DB081E) || \
808  (PARTNO == AT45DB161E) || \
809  (PARTNO == AT45DB321E) || \
810  (PARTNO == AT45DB641E) || \
811  (PARTNO == AT45DQ161) || \
812  (PARTNO == AT45DQ321) || \
813  (PARTNO == AT25PE40) || \
814  (PARTNO == AT25PE80) || \
815  (PARTNO == AT25PE16) || \
816  (ALL == 1)
817  // Test buffer 2:
818  // Part A: Test that the buffers can be written to and read.
819  // Data will be programmed to the device through the buffer, read back,
820  // and success/failure message output to the console.
821  fillArrayPattern(dataWrite, 100, 0x25);
822  dataflashBuffer2Write(0, dataWrite, 100);
823  dataflashBuffer2ReadLowFreq(0, dataRead, 100);
824  if(!compareByteArrays(dataRead, dataWrite, 100))
825  {
826  printf("Buffer 2 Write or ReadLF failure.\n");
827  errorCount++;
828  }
829  else
830  {
831  printf("Buffer 2 Write and ReadLF success.\n");
832  }
833  dataflashBuffer2ReadHighFreq(0, dataRead, 100);
834  if(!compareByteArrays(dataRead, dataWrite, 100))
835  {
836  printf("Buffer 2 Write or ReadHF failure.\n");
837  errorCount++;
838  }
839  else
840  {
841  printf("Buffer 2 Write and ReadHF success.\n");
842  }
843 
844  // Test buffer 2:
845  // Part B: Test that data can be written to main memory with erase.
846  // Data will be programmed to the device through the buffer, read back,
847  // and success/failure message output to the console.
848 
851  dataflashArrayReadLowPower(0, dataRead, 100);
852  if(!compareByteArrays(dataRead, dataWrite, 100))
853  {
854  printf("Main memory through Buffer 2 r/w failure.\n");
855  errorCount++;
856  }
857  else
858  {
859  printf("Main memory through Buffer 2 r/w success.\n");
860  }
861 #endif
862  // Part C: Test buffer to memory without erase.
863  // All 0s will be stored in the buffers and then the buffers will be written to main memory
864  // without erase. This should reset all bits.
865 
866  // Test buffer 1:
867  // Load zeroes into the array
868  fillArrayConst(dataWrite, 100, 0);
869  // Store the values in buffer 1
870  dataflashBuffer1Write(0, dataWrite, 100);
871  // Write the data to main memory from buffer 1 without erase
873  // Read back and compare
874  dataflashArrayReadLowFreq(0, dataRead, 100);
875  if(!compareByteArrays(dataRead, dataWrite, 100))
876  {
877  printf("Buffer 1 to main memory failure.\n");
878  errorCount++;
879  }
880  else
881  {
882  printf("Buffer 1 to main memory success.\n");
883  }
884 
885 #if (PARTNO == AT45DB021E) || \
886  (PARTNO == AT45DB041E) || \
887  (PARTNO == AT45DB081E) || \
888  (PARTNO == AT45DB161E) || \
889  (PARTNO == AT45DB321E) || \
890  (PARTNO == AT45DB641E) || \
891  (PARTNO == AT45DQ161) || \
892  (PARTNO == AT45DQ321) || \
893  (PARTNO == AT25PE40) || \
894  (PARTNO == AT25PE80) || \
895  (PARTNO == AT25PE16) || \
896  (ALL == 1)
897  // Test buffer 2:
898  // Load zeroes into the array
899  fillArrayConst(dataWrite, 100, 0);
900  // Store the values in buffer 1
901  dataflashBuffer2Write(100, dataWrite, 100);
902  // Write the data to main memory from buffer 1 without erase
904  // Read back and compare
905  dataflashArrayReadLowFreq(100, dataRead, 100);
906  if(!compareByteArrays(dataRead, dataWrite, 100))
907  {
908  printf("Buffer 2 to main memory failure.\n");
909  errorCount++;
910  }
911  else
912  {
913  printf("Buffer 2 to main memory success.\n");
914  }
915 #endif
916  // Part D: Test program through buffer with erase.
917  // Program through buffer 1 and compare the buffer to the input data.
918  fillArrayPattern(dataWrite, 100, 0x45);
921  dataflashBuffer1ReadHighFreq(0, dataRead, 100);
922  if(!compareByteArrays(dataRead, dataWrite, 100))
923  {
924  printf("Program through Buffer 1 failure.\n");
925  errorCount++;
926  }
927  else
928  {
929  printf("Program through Buffer 1 success.\n");
930  }
931 #if (PARTNO == AT45DB021E) || \
932  (PARTNO == AT45DB041E) || \
933  (PARTNO == AT45DB081E) || \
934  (PARTNO == AT45DB161E) || \
935  (PARTNO == AT45DB321E) || \
936  (PARTNO == AT45DB641E) || \
937  (PARTNO == AT45DQ161) || \
938  (PARTNO == AT45DQ321) || \
939  (PARTNO == AT25PE40) || \
940  (PARTNO == AT25PE80) || \
941  (PARTNO == AT25PE16) || \
942  (ALL == 1)
943  // Program through buffer 2 and compare the buffer to the input data.
944  fillArrayPattern(dataWrite, 100, 0x23);
947  dataflashBuffer2ReadHighFreq(0, dataRead, 100);
948  if(!compareByteArrays(dataRead, dataWrite, 100))
949  {
950  printf("Program through Buffer 2 failure.\n");
951  errorCount++;
952  }
953  else
954  {
955  printf("Program through Buffer 2 success.\n");
956  }
957 #endif
958  /********************************************************************
959  * 3. Test deep power down mode *
960  ********************************************************************/
961  /*
962  * This portion tests the deep power down mode of the flash device.
963  */
964 
965  printf("\n\nTesting Deep Power Down functionality ---------------\n\n");
966 
967  // Part A: Test that the device goes into DPD mode.
968  // Send the device into deep power down (DPD) mode. In DPD mode the MISO line is in a high impedance
969  // state and the data will be unpredictable. We test for this by reading the device and confirming
970  // that the output doesn't match the stored data. The probability that it will is infinitesimal.
971  // If any errors are output, the device is in DPD Mode and the test passes.
972 
973  // First, program some data to the device.
974  fillArrayPattern(dataWrite, 100, 0x90);
977 
978  // Send the device to deep power down mode.
979  dataflashDPD();
980  // Attempt to read from the device. Note, this should not work in DPD Mode.
981  dataflashArrayReadLowFreq(0, dataRead, 100);
982  // Compare the data as stated above. There should be a data mismatch in DPD mode.
983  if(!compareByteArrays(dataRead, dataWrite, 25))
984  {
985  printf("DEVICE IS IN DPD MODE. DATA MISMATCH EXPECTED. TEST PASSED.\n");
986  }
987  else
988  {
989  printf("DEVICE FAILED DPD TEST. The device is reading stored data when the line should be in Hi-Z state.\n");
990  errorCount++;
991  }
992 
993  // Part B: Test that the device can exit DPD mode.
994  printf("Resuming from Deep Power Down Mode...\n");
995 
996  // Now resume from DPD mode...
999  // ... and try to read from the device. It should function in its normal state.
1000  dataflashArrayReadHighFreq0(0, dataRead, 100);
1001  // A comparison of read data to expected data should pass.
1002  if(compareByteArrays(dataRead, dataWrite, 50))
1003  {
1004  printf("Resume from DPD operation success.\n");
1005  }
1006  else
1007  {
1008  printf("Resume from DPD operation fail.\n");
1009  errorCount++;
1010  }
1011 
1012 
1013  /********************************************************************
1014  * 4. Test ultra deep power down mode and JEDEC reset. *
1015  ********************************************************************/
1016  /*
1017  * This portion tests the ultra deep power down mode and JEDEC reset.
1018  */
1019  printf("\n\nTesting UDPD Mode and JEDEC Reset --------------------\n\n");
1020 
1021  // Part A: Enter UDPD mode and confirm that the device outputs Hi-Z.
1022  // Set the device into ultra deep power down (UDPD) mode. The tests performed here
1023  // are the same as the ones performed for the DPD mode, but the device is woken up
1024  // with a JEDEC reset.
1026  // Attempt to read from the device. Note, this should not work in DPD Mode.
1027  dataflashArrayReadLowFreq(0, dataRead, 100);
1028  // Compare the data as stated above. There should me a data mismatch in DPD mode.
1029  if(!compareByteArrays(dataRead, dataWrite, 25))
1030  {
1031  printf("DEVICE IS IN UDPD MODE. DATA MISMATCH EXPECTED. TEST PASSED.\n");
1032  }
1033  else
1034  {
1035  printf("DEVICE FAILED UDPD TEST. The device is reading stored data when the line should be in Hi-Z state.\n");
1036  errorCount++;
1037  }
1038 
1039  // Part B: Test that the device can recover from UDPD mode.
1040  // Exit UDPD mode by performing a hardware reset.
1042  printf("JEDEC reset performed, device should be operational.\n");
1043  // Perform a device read and compare against known data.
1044  dataflashArrayReadHighFreq1(0, dataRead, 100);
1045  if(compareByteArrays(dataRead, dataWrite, 50))
1046  {
1047  printf("JEDEC reset operation success.\n");
1048  }
1049  else
1050  {
1051  printf("JEDEC reset operation fail.\n");
1052  errorCount++;
1053  }
1054 
1055 
1056  /********************************************************************
1057  * 5. Test erase. *
1058  ********************************************************************/
1059 
1060  // This section tests all 4 erase commands available for the dataflash part.
1061  // A page erase will be performed, followed by block, sector, and chip erase.
1062  // In each test data is programmed to main memory, read back for confirmation,
1063  // then erased, at which point it's read back and tested against all F's.
1064 
1065  printf("\n\nTesting Erase Commands ------------------------------\n\n");
1066 
1067  // Part A: Test page erase.
1068  // Erase the page so that data can be written.
1069  dataflashPageErase(0);
1070  // Wait for the erase to finish.
1072  // Prep the data to be written and write it.
1073  fillArrayPattern(dataWrite, 100, 0x56);
1074  dataflashMemoryProgramThruBuffer1WithErase(0, dataWrite, 100);
1076  // Make sure the data was properly written
1077  dataflashArrayReadLowFreq(0, dataRead, 100);
1078  if(!compareByteArrays(dataRead, dataWrite, 25))
1079  {
1080  printf("Device r/w fail.\n");
1081  errorCount++;
1082  }
1083  // Erase the page
1084  dataflashPageErase(0);
1085  // ... and wait.
1087  // Read it back and test that the erase worked.
1088  dataflashArrayReadLegacy(0, dataRead, 100);
1089  if(!compareByteArrays(dataRead, dataTest, 25))
1090  {
1091  printf("Device page erase fail.\n");
1092  errorCount++;
1093  }
1094  else
1095  {
1096  printf("Page erase successful.\n");
1097  }
1098 
1099 
1100  // Part B: Repeat the above operation but perform a block erase instead.
1101  // Prep the device with some random sequence.
1102  fillArrayPattern(dataWrite, 100, 0x23);
1103  // Program the data to memory.
1104  dataflashMemoryProgramThruBuffer1WithErase(0, dataWrite, 100);
1105  // Wait for the operation to complete.
1107  // Read the data back for confirmation.
1108  dataflashArrayReadLowFreq(0, dataRead, 100);
1109  if(!compareByteArrays(dataRead, dataWrite, 25))
1110  {
1111  printf("Device r/w fail.\n");
1112  errorCount++;
1113  }
1114  // Block erase.
1116  // Wait for the erase to complete.
1118  // Confirm the data was erased.
1119  dataflashArrayReadLowFreq(0, dataRead, 100);
1120  if(!compareByteArrays(dataRead, dataTest, 25))
1121  {
1122  printf("Device block erase fail.\n");
1123  errorCount++;
1124  }
1125  else
1126  {
1127  printf("Block erase successful.\n");
1128  }
1129 
1130  // Part C: Repeat the above operation but perform a sector erase instead.
1131  fillArrayPattern(dataWrite, 100, 0x89);
1132  dataflashMemoryProgramThruBuffer1WithErase(0, dataWrite, 100);
1134  dataflashArrayReadLowFreq(0, dataRead, 100);
1135  if(!compareByteArrays(dataRead, dataWrite, 25))
1136  {
1137  printf("Device r/w fail.\n");
1138  errorCount++;
1139  }
1140  // Sector erase.
1143  dataflashArrayReadLowFreq(0, dataRead, 100);
1144  if(!compareByteArrays(dataRead, dataTest, 25))
1145  {
1146  printf("Device sector erase fail.\n");
1147  errorCount++;
1148  }
1149  else
1150  {
1151  printf("Sector erase successful.\n");
1152  }
1153 
1154  // Part D: Repeat the above operation but perform a chip erase instead.
1155  fillArrayPattern(dataWrite, 100, 0x76);
1156  dataflashMemoryProgramThruBuffer1WithErase(0, dataWrite, 100);
1158  dataflashArrayReadLowFreq(0, dataRead, 100);
1159  if(!compareByteArrays(dataRead, dataWrite, 25))
1160  {
1161  printf("Device r/w fail.\n");
1162  errorCount++;
1163  }
1164  // Chip erase.
1165 // dataflashChipErase(0);
1166 // dataflashWaitOnReady();
1167 // dataflashArrayReadLowPower(0, dataRead, 100);
1168 // if(!compareByteArrays(dataRead, dataTest, 25))
1169 // {
1170 // printf("Device chip erase fail.\n");
1171 // errorCount++;
1172 // }
1173 // else
1174 // {
1175 // printf("Chip erase successful.\n");
1176 // }
1177 
1178  /********************************************************************
1179  * 6. Test memory to buffer commands *
1180  ********************************************************************/
1181  // This section tests 2 memory/buffer transactions; memory to buffer transfer
1182  // and memory to buffer compare. Data is written to memory through buffer 1 and
1183  // then the memory to buffer commands store data from memory to buffers 1 and 2.
1184  // The memory to buffer command opcode is then sent over and the status register
1185  // read. Bit 6 is checked, and a success/fail message printed to the console.
1186  printf("\n\nTesting Memory to Buffer Commands -------------------\n\n");
1187 
1188  // Fill the txBuffer with a pattern
1189  fillArrayPattern(dataWrite, 100, 0x88);
1190  // Program the data through buffer 1
1191  dataflashMemoryProgramThruBuffer1WithErase(0, dataWrite, 100);
1192  // Wait for the operation to complete.
1194  // Read data to buffer 1
1197 #if (PARTNO == AT45DB021E) || \
1198  (PARTNO == AT45DB041E) || \
1199  (PARTNO == AT45DB081E) || \
1200  (PARTNO == AT45DB161E) || \
1201  (PARTNO == AT45DB321E) || \
1202  (PARTNO == AT45DB641E) || \
1203  (PARTNO == AT45DQ161) || \
1204  (PARTNO == AT45DQ321) || \
1205  (PARTNO == AT25PE40) || \
1206  (PARTNO == AT25PE80) || \
1207  (PARTNO == AT25PE16) || \
1208  (ALL == 1)
1209  // and read data to buffer 2
1212 #endif
1213  // Finally, run the compare and read the status register to confirm that the
1214  // operations were successful.
1217  dataflashReadSR(dataRead);
1218  if(dataRead[0] & (1<<6))
1219  {
1220  printf("Error with ReadSR, Buffer 1 to Memory Compare, or Memory Program.\n");
1221  errorCount++;
1222  }
1223  else
1224  {
1225  printf("Memory to Buffer 1 commands successful.\n");
1226  }
1227 #if (PARTNO == AT45DB021E) || \
1228  (PARTNO == AT45DB041E) || \
1229  (PARTNO == AT45DB081E) || \
1230  (PARTNO == AT45DB161E) || \
1231  (PARTNO == AT45DB321E) || \
1232  (PARTNO == AT45DB641E) || \
1233  (PARTNO == AT45DQ161) || \
1234  (PARTNO == AT45DQ321) || \
1235  (PARTNO == AT25PE40) || \
1236  (PARTNO == AT25PE80) || \
1237  (PARTNO == AT25PE16) || \
1238  (ALL == 1)
1239  // Run the comparison on buffer 2
1242  dataflashReadSR(dataRead);
1243  if(dataRead[0] & (1<<6))
1244  {
1245  printf("Error with ReadSR, Buffer 2 to Memory Compare, or Memory Program.\n");
1246  errorCount++;
1247  }
1248  else
1249  {
1250  printf("Memory to Buffer 2 commands successful.\n");
1251  }
1252 #endif
1253 
1254  /********************************************************************
1255  * 7. Test Read - Modify - Write capabilities. *
1256  ********************************************************************/
1257  // This portion tests the RMW capabilities of the flash device by modifying a single byte
1258  // and storing it in main main memory.
1259 
1260  printf("\n\nTesting RMW Commands --------------------------------\n\n");
1261  // Write data to main memory with erase
1262  fillArrayPattern(dataWrite, 100, 0x12);
1263  dataflashMemoryProgramThruBuffer1WithErase(0, dataWrite, 100);
1265  // Load a new value to dataWrite byte 5.
1266  if(dataWrite[4] != 0xAA)
1267  {
1268  dataWrite[4] = 0xAA;
1269  }
1270  else
1271  {
1272  dataWrite[4] = 0x55;
1273  }
1274  // Store the new byte in main memory.
1275  dataflashRMWThruBuffer1(4, &dataWrite[4], 1);
1277  // Read back the data and make sure the command worked properly.
1278  dataflashArrayReadLowPower(0, dataRead, 100);
1279  if(!compareByteArrays(dataWrite, dataRead, 100))
1280  {
1281  printf("Error with RMW through Buffer 1 command.\n");
1282  errorCount++;
1283  }
1284  else
1285  {
1286  printf("RMW through Buffer 1 command successful.\n");
1287  }
1288 #if (PARTNO == AT45DB021E) || \
1289  (PARTNO == AT45DB041E) || \
1290  (PARTNO == AT45DB081E) || \
1291  (PARTNO == AT45DB161E) || \
1292  (PARTNO == AT45DB321E) || \
1293  (PARTNO == AT45DB641E) || \
1294  (PARTNO == AT45DQ161) || \
1295  (PARTNO == AT45DQ321) || \
1296  (PARTNO == AT25PE40) || \
1297  (PARTNO == AT25PE80) || \
1298  (PARTNO == AT25PE16) || \
1299  (ALL == 1)
1300  // Repeat the process using buffer 2, and write 2 bytes.
1301  fillArrayPattern(dataWrite, 100, 0x21);
1302  dataflashMemoryProgramThruBuffer2WithErase(0, dataWrite, 100);
1304  // Load a new value to dataWrite byte 5, and byte 6.
1305  if(dataWrite[5] != 0xAA)
1306  {
1307  dataWrite[5] = 0xAA;
1308  dataWrite[6] = 0xAB;
1309  }
1310  else
1311  {
1312  dataWrite[5] = 0x55;
1313  dataWrite[6] = 0x56;
1314  }
1315  // Program it in.
1316  dataflashRMWThruBuffer1(5, &dataWrite[5], 2);
1318  // Test the data.
1319  dataflashArrayReadLowPower(0, dataRead, 100);
1320  if(!compareByteArrays(dataWrite, dataRead, 100))
1321  {
1322  printf("Error with RMW through Buffer 2 command.\n");
1323  errorCount++;
1324  }
1325  else
1326  {
1327  printf("RMW through Buffer 2 command successful.\n");
1328  }
1329 #endif
1330 
1331 #if (PARTNO == AT45DQ161) || \
1332  (PARTNO == AT45DQ321) || \
1333  (ALL == 1)
1336  // Read data on 4 IO lines
1337  dataflashQuadOutputRead(0, dataRead, 100);
1338  if(!compareByteArrays(dataWrite, dataRead, 100))
1339  {
1340  printf("Error with Quad Output Read command.\n");
1341  errorCount++;
1342  }
1343  else
1344  {
1345  printf("Quad Output Read command successful.\n");
1346  }
1349 #endif
1350  // Test complete. Print messages and exit.
1351  printf("\n\n#############################################\n\n");
1352  printf("Testing complete.\n");
1353  printf("Total errors detected: %d\n", errorCount);
1354  printf("Terminating testbench.\n");
1355  printf("\n#############################################\n\n");
1356 
1357  return errorCount;
1358 }
1359 
1360 #elif defined(STANDARDFLASH_DEVICE)
1361 
1362 uint32_t defaultTest(){return standardflashTest();};
1363 
1364 uint32_t standardflashTest()
1365 {
1366 #if PARTNO == AT25SF641
1367  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1368  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1369  uint8_t modeByteValue = 0xA0;
1370  // Store the manufacturer ID for later comparison
1371  uint8_t MID[3] = {0x1F, 0x32, 0x17};
1372 #elif PARTNO == AT25SF321
1373  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1374  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1375  uint8_t modeByteValue = 0x20;
1376  // Store the manufacturer ID for later comparison
1377  uint8_t MID[3] = {0x1F, 0x87, 0x01};
1378 #elif PARTNO == AT25SF161
1379  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1380  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1381  uint8_t modeByteValue = 0x20;
1382  // Store the manufacturer ID for later comparison
1383  uint8_t MID[3] = {0x1F, 0x86, 0x01};
1384 #elif PARTNO == AT25SF081
1385  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1386  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1387  uint8_t modeByteValue = 0x20;
1388  // Store the manufacturer ID for later comparison
1389  uint8_t MID[3] = {0x1F, 0x85, 0x01};
1390 #elif PARTNO == AT25SF041
1391  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1392  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1393  uint8_t modeByteValue = 0x20;
1394  // Store the manufacturer ID for later comparison
1395  uint8_t MID[3] = {0x1F, 0x84, 0x01};
1396 #elif PARTNO == AT25SL321
1397  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1398  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1399  uint8_t modeByteValue = 0xA0;
1400  // Store the manufacturer ID for later comparison
1401  uint8_t MID[3] = {0x1F, 0x42, 0x16};
1402 #elif PARTNO == AT25SL641
1403  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1404  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1405  uint8_t modeByteValue = 0xA0;
1406  // Store the manufacturer ID for later comparison
1407  uint8_t MID[3] = {0x1F, 0x43, 0x17};
1408 #elif PARTNO == AT25SL128A
1409  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1410  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1411  uint8_t modeByteValue = 0xA0;
1412  // Store the manufacturer ID for later comparison
1413  uint8_t MID[3] = {0x1F, 0x42, 0x18};
1414 #elif PARTNO == AT25DL081
1415  // Store the manufacturer ID for later comparison
1416  uint8_t MID[3] = {0x1F, 0x45, 0x02};
1417 #elif PARTNO == AT25DL161
1418  // Store the manufacturer ID for later comparison
1419  uint8_t MID[3] = {0x1F, 0x46, 0x03};
1420 #elif PARTNO == AT25DF081A
1421  // Store the manufacturer ID for later comparison
1422  uint8_t MID[3] = {0x1F, 0x45, 0x01};
1423 #elif PARTNO == AT25DF321A
1424  // Store the manufacturer ID for later comparison
1425  uint8_t MID[3] = {0x1F, 0x47, 0x01};
1426 #elif PARTNO == AT25DF641A
1427  // Store the manufacturer ID for later comparison
1428  uint8_t MID[3] = {0x1F, 0x48, 0x00};
1429 #elif PARTNO == AT25QL321
1430  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1431  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1432  uint8_t modeByteValue = 0xA0;
1433  // Store the manufacturer ID for later comparison
1434  uint8_t MID[3] = {0x1F, 0x42, 0x16};
1435 #elif PARTNO == AT25QL641
1436  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1437  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1438  uint8_t modeByteValue = 0xA0;
1439  // Store the manufacturer ID for later comparison
1440  uint8_t MID[3] = {0x1F, 0x43, 0x17};
1441 #elif PARTNO == AT25QL128A
1442  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1443  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1444  uint8_t modeByteValue = 0xA0;
1445  // Store the manufacturer ID for later comparison
1446  uint8_t MID[3] = {0x1F, 0x42, 0x18};
1447 #elif PARTNO == AT25QF641
1448  // Sets the modeByteValue used for instruction standardflashQuadIORead(). Set once then forget.
1449  // The hex value is determined by the datasheet. Certain bits in the byte need to be set/cleared.
1450  uint8_t modeByteValue = 0xA0;
1451  // Store the manufacturer ID for later comparison
1452  uint8_t MID[3] = {0x1F, 0x32, 0x17};
1453 #endif
1454 
1455  // Sets the various pins as inputs and output
1457 
1458  // Instantiate the arrays needed for testing purposes.
1459  // dataWrite is used when sending data that will be flashed to the device.
1460  uint8_t dataWrite[MAXIMUM_BUFFER_SIZE] = {0};
1461  // dataRead is used as a buffer for received data. Read data will be stored here.
1462  uint8_t dataRead[MAXIMUM_BUFFER_SIZE] = {0};
1463  // dataTest is used as a buffer for comparisons. dataRead will be
1464  // loaded with data and compared against this buffer for equality.
1465  uint8_t dataTest[MAXIMUM_BUFFER_SIZE] = {0};
1466  // Count the number of errors, this is output at the end of the testbench.
1467  uint32_t errorCount = 0;
1468 
1469  // Store all Fs in the test buffer for later comparison
1470  fillArrayConst(dataTest, MAXIMUM_BUFFER_SIZE, 0xFF);
1471 
1472  // Load up dataWrite with a pattern that will be used for testing.
1473  fillArrayPattern(dataWrite, 100, 0x05);
1474 
1475 
1476  /********************************************************************
1477  * 1. Read manufacturing ID *
1478  ********************************************************************/
1479 
1480  printf("\n\nTesting Read MID -----------------------------------\n\n");
1481 
1482  // Part A: Test that the MID can be read.
1483  // Read the manufacturing ID and store the returned data in dataRead.
1484  standardflashReadMID(dataRead);
1485  // Compare the read data to the expected bytes stored in MID. Print
1486  // the result of the test.
1487  if(compareByteArrays(dataRead, MID, 3))
1488  {
1489  printf("ReadMID Success.\n");
1490  }
1491  else
1492  {
1493  printf("ReadMID fail.\n");
1494  errorCount++;
1495  }
1496 
1497  /********************************************************************
1498  * 2. Write and read commands *
1499  ********************************************************************/
1500  /*
1501  * This test performs a 4K erase followed by 2 array programs at different addresses.
1502  * Data is read back using the both high and low frequency reads, and compared against
1503  * the expected values.
1504  */
1505 
1506  printf("\n\nTesting Standard Write and Read Commands -----------\n\n");
1507  // Part A: Test read.
1508  // Get data to be programmed.
1509  fillArrayPattern(dataWrite, 100, 0x10);
1510 #if (PARTNO == AT25DL081) || \
1511  (PARTNO == AT25DL161) || \
1512  (PARTNO == AT25DF081A) || \
1513  (PARTNO == AT25DF321A) || \
1514  (PARTNO == AT25DF641A) || \
1515  (ALL == 1)
1516  // Write enable the device and un-protect the first sector.
1519 #endif
1520  // Write enable the device then erase the first 4K block.
1524  // Program the device from address 0-100.
1526  standardflashBytePageProgram(0, dataWrite, 100);
1528  // Now read back the data in order to confirm that erase/program/read all work.
1529  standardflashReadArrayLowFreq(0, dataRead, 100);
1530  if(!compareByteArrays(dataRead, dataWrite, 100))
1531  {
1532  printf("Write or ReadLF failure.\n");
1533  errorCount++;
1534  }
1535  else
1536  {
1537  printf("Write and ReadLF success.\n");
1538  }
1539  // Part B: Test high frequency read.
1540  // Get data to be programmed.
1541  fillArrayPattern(dataWrite, 100, 0x15);
1542  // Program the device from address 100-200.
1544  standardflashBytePageProgram(100, dataWrite, 100);
1546  // Read back and test the programmed data to confirm proper functionality.
1547  standardflashReadArrayHighFreq(100, dataRead, 100);
1548  if(!compareByteArrays(dataRead, dataWrite, 100))
1549  {
1550  printf("Write or ReadHF failure.\n");
1551  errorCount++;
1552  }
1553  else
1554  {
1555  printf("Write and ReadHF success.\n");
1556  }
1557 #if (PARTNO == AT25SF641) || \
1558  (PARTNO == AT25SF321) || \
1559  (PARTNO == AT25SF161) || \
1560  (PARTNO == AT25SF081) || \
1561  (PARTNO == AT25SF041) || \
1562  (PARTNO == AT25SL128A) || \
1563  (PARTNO == AT25SL641) || \
1564  (PARTNO == AT25SL321) || \
1565  (PARTNO == AT25QL128A) || \
1566  (PARTNO == AT25QL641) || \
1567  (PARTNO == AT25QL321) || \
1568  (PARTNO == AT25QF641) || \
1569  (ALL == 1)
1570 
1571  /********************************************************************
1572  * 3. Dual read commands *
1573  ********************************************************************/
1574  /*
1575  * This test reads data from the device in dual read mode. Data is first read in
1576  * dual output mode, then read in dual IO mode. 2 ways to terminate the dual
1577  * continuous read mode are demonstrated.
1578  * The components of the test are broken down as follows:
1579  * Part A: Read data with dual output read.
1580  * Part B: Read data with dual IO read and terminate using dual IO read.
1581  * Part C: Read data with dual IO read and terminate using dual mode reset.
1582  */
1583  // Get data to be programmed.
1584  fillArrayPattern(dataWrite, 100, 0x20);
1585  // Write the new data to the device.
1590  standardflashBytePageProgram(0, dataWrite, 200);
1592 
1593  // Part A: Read data with dual output read and test it.
1594  standardflashDualOutputRead(0, dataRead, 200);
1595  if(!compareByteArrays(dataRead, dataWrite, 200))
1596  {
1597  printf("Write or Dual Output Read failure.\n");
1598  errorCount++;
1599  }
1600  else
1601  {
1602  printf("Write and Dual Output Read success.\n");
1603  }
1604 
1605  // Part B: Read and terminate with dual IO read command.
1606  standardflashDualIORead(0, dataRead, 10, 0, modeByteValue);
1607  standardflashDualIORead(10, &(dataRead[10]), 10, 1, modeByteValue);
1608  standardflashDualIORead(20, &(dataRead[20]), 10, 2, modeByteValue);
1609  standardflashDualIORead(30, &(dataRead[30]), 10, 2, modeByteValue);
1610  standardflashDualIORead(40, &(dataRead[40]), 10, 3, modeByteValue);
1611  if(!compareByteArrays(dataRead, dataWrite, 50))
1612  {
1613  printf("Write or Dual IO Read failure.\n");
1614  errorCount++;
1615  }
1616  else
1617  {
1618  printf("Write and Dual IO Read success.\n");
1619  }
1620 
1621  // Part C: Read and terminate with dual reset command.
1622  standardflashDualIORead(0, dataRead, 10, 0, modeByteValue);
1623  standardflashDualIORead(10, &(dataRead[10]), 10, 1, modeByteValue);
1624  standardflashDualIORead(20, &(dataRead[20]), 10, 2, modeByteValue);
1625  standardflashDualIORead(30, &(dataRead[30]), 10, 2, modeByteValue);
1626  standardflashDualIORead(40, &(dataRead[40]), 10, 2, modeByteValue);
1628 
1629  /********************************************************************
1630  * 4. Quad read commands *
1631  ********************************************************************/
1632  /*
1633  * This test reads data from the device in quad read mode. Data is first read in
1634  * quad output mode, then read in quad IO mode. 2 ways to terminate the quad
1635  * continuous read mode are demonstrated.
1636  * The components of the test are broken down as follows:
1637  * Part A: Read data with quad output read.
1638  * Part B: Read data with quad IO read and terminate using quad IO read.
1639  * Part C: Read data with quad IO read and terminate using quad mode reset.
1640  *
1641  * Note: The QE bit in status register byte 2 must be set in order to enable quad
1642  * commands. See standardflashSetQEBit().
1643  */
1644  // Get data to be programmed.
1645  fillArrayPattern(dataWrite, 100, 0x25);
1646  // Write the new data to the device.
1651  standardflashBytePageProgram(0, dataWrite, 200);
1655  // Part A: Read data with quad output read and test it.
1656  standardflashQuadOutputRead(0, dataRead, 200);
1657  if(!compareByteArrays(dataRead, dataWrite, 200))
1658  {
1659  printf("Write or Quad Output Read failure.\n");
1660  errorCount++;
1661  }
1662  else
1663  {
1664  printf("Write and Quad Output Read success.\n");
1665  }
1666 
1667  // Part B: Read and terminate with quad IO read command.
1668  standardflashQuadIORead(0, dataRead, 10, 0, modeByteValue);
1669  standardflashQuadIORead(10, &(dataRead[10]), 10, 1, modeByteValue);
1670  standardflashQuadIORead(20, &(dataRead[20]), 10, 2, modeByteValue);
1671  standardflashQuadIORead(30, &(dataRead[30]), 10, 2, modeByteValue);
1672  standardflashQuadIORead(40, &(dataRead[40]), 10, 3, modeByteValue);
1673  if(!compareByteArrays(dataRead, dataWrite, 50))
1674  {
1675  printf("Write or Quad IO Read failure.\n");
1676  errorCount++;
1677  }
1678  else
1679  {
1680  printf("Write and Quad IO Read success.\n");
1681  }
1682 
1683  // Part C: Read and terminate with quad reset command.
1684  standardflashQuadIORead(0, dataRead, 10, 0, modeByteValue);
1685  standardflashQuadIORead(10, &(dataRead[10]), 10, 1, modeByteValue);
1686  standardflashQuadIORead(20, &(dataRead[20]), 10, 2, modeByteValue);
1687  standardflashQuadIORead(30, &(dataRead[30]), 10, 2, modeByteValue);
1688  standardflashQuadIORead(40, &(dataRead[40]), 10, 2, modeByteValue);
1690 
1692 
1694 
1695  // Ensure that the device is no longer in quad mode.
1696  standardflashReadArrayHighFreq(0, dataRead, 100);
1697  if(!compareByteArrays(dataRead, dataWrite, 100))
1698  {
1699  printf("Leave Quad IO failure.\n");
1700  errorCount++;
1701  }
1702  else
1703  {
1704  printf("Leave Quad IO success.\n");
1705  }
1706 #endif
1707 
1708  /********************************************************************
1709  * 5. Test deep power down mode *
1710  ********************************************************************/
1711  /*
1712  * This portion tests the deep power down mode of the flash device.
1713  */
1714 
1715  printf("\n\nTesting Deep Power Down functionality ---------------\n\n");
1716 
1717  // Part A: Test that the device goes into DPD mode.
1718  // Send the device into deep power down (DPD) mode. In DPD mode the MISO line is in a high impedance
1719  // state and the data will be unpredictable. We test for this by reading the device and confirming
1720  // that the output doesn't match the stored data. The probability that it will is infinitesimal.
1721  // If any errors are output, the device is in DPD Mode and the test passes.
1722 
1723  // First, program some data to the device.
1724  fillArrayPattern(dataWrite, 100, 0x30);
1729  standardflashBytePageProgram(0, dataWrite, 100);
1731 
1732  // Send the device to deep power down mode.
1733  standardflashDPD();
1734  // Attempt to read from the device. Note, this should not work in DPD Mode.
1735  standardflashReadArrayLowFreq(0, dataRead, 100);
1736  // Compare the data as stated above. There should be a data mismatch in DPD mode.
1737  if(!compareByteArrays(dataRead, dataWrite, 25))
1738  {
1739  printf("DEVICE IS IN DPD MODE. DATA MISMATCH EXPECTED. TEST PASSED.\n");
1740  }
1741  else
1742  {
1743  printf("DEVICE FAILED DPD TEST. The device is reading stored data when the line should be in Hi-Z state.\n");
1744  errorCount++;
1745  }
1746 
1747  // Part B: Test that the device can exit DPD mode.
1748  printf("Resuming from Deep Power Down Mode...\n");
1749 
1750  // Now resume from DPD mode...
1753  // ... and try to read from the device. It should function in its normal state.
1754  standardflashReadArrayHighFreq(0, dataRead, 100);
1755  // A comparison of read data to expected data should pass.
1756  if(compareByteArrays(dataRead, dataWrite, 50))
1757  {
1758  printf("Resume from DPD operation success.\n");
1759  }
1760  else
1761  {
1762  printf("Resume from DPD operation fail.\n");
1763  errorCount++;
1764  }
1765 
1766 
1767 
1768 #if (PARTNO == AT25SF641) || \
1769  (PARTNO == AT25SL128A) || \
1770  (PARTNO == AT25SL641) || \
1771  (PARTNO == AT25SL321) || \
1772  (PARTNO == AT25QL128A) || \
1773  (PARTNO == AT25QL641) || \
1774  (PARTNO == AT25QL321) || \
1775  (PARTNO == AT25QF641) || \
1776  (ALL == 1)
1777 
1778  printf("\n\nThis device has Quad IO Capabilities.\n");
1779 
1780  printf("\n\nTesting Read MID Quad IO ----------------------------\n\n");
1781 
1782  /********************************************************************
1783  * 1. Read manufacturing ID *
1784  ********************************************************************/
1785 
1791  // Part A: Test that the MID can be read.
1792  // Read the manufacturing ID and store the returned data in dataRead.
1793  standardflashReadMID(dataRead);
1794  // Compare the read data to the expected bytes stored in MID. Print
1795  // the result of the test.
1796  if(compareByteArrays(dataRead, MID, 3))
1797  {
1798  printf("ReadMID in Quad IO Success.\n");
1799  }
1800  else
1801  {
1802  printf("ReadMID Quad IO fail.\n");
1803  errorCount++;
1804  }
1805 
1811 
1812  standardflashReadMID(dataRead);
1813  // Compare the read data to the expected bytes stored in MID. Print
1814  // the result of the test.
1815  if(compareByteArrays(dataRead, MID, 3))
1816  {
1817  printf("ReadMID Success.\nLeft Quad IO successfully.\n");
1818  }
1819  else
1820  {
1821  printf("ReadMID fail.\nFailed to Leave Quad IO.\n");
1822  errorCount++;
1823  }
1824 
1825  /********************************************************************
1826  * 2. Write and read commands *
1827  ********************************************************************/
1828  /*
1829  * This test performs a 4K erase followed by 2 array programs at different addresses.
1830  * Data is read back using the both high and low frequency reads, and compared against
1831  * the expected values.
1832  */
1838 
1839  printf("\n\nTesting Write and Read Quad IO Commands --------------\n\n");
1840 
1841  // Part A: Test low frequency read.
1842  // Get data to be programmed.
1843  fillArrayPattern(dataWrite, 100, 0x30);
1844  // Write enable the device then erase the first 4K block.
1848  // Program the device from address 0-100.
1850  standardflashBytePageProgram(0, dataWrite, 100);
1852  // Now read back the data in order to confirm that erase/program/read all work.
1853  standardflashReadArrayHighFreq(0, dataRead, 100);
1854  if(!compareByteArrays(dataRead, dataWrite, 100))
1855  {
1856  printf("Write or ReadHF failure.\n");
1857  errorCount++;
1858  }
1859  else
1860  {
1861  printf("Write and ReadHF success.\n");
1862  }
1863  // Part B: Test high frequency read.
1864  // Get data to be programmed.
1865  fillArrayPattern(dataWrite, 100, 0x35);
1866  // Program the device from address 100-200.
1868  standardflashBytePageProgram(100, dataWrite, 100);
1870  // Read back and test the programmed data to confirm proper functionality.
1871  standardflashReadArrayHighFreq(100, dataRead, 100);
1872  if(!compareByteArrays(dataRead, dataWrite, 100))
1873  {
1874  printf("Write or ReadHF failure.\n");
1875  errorCount++;
1876  }
1877  else
1878  {
1879  printf("Write and ReadHF success.\n");
1880  }
1881 
1882 
1883 
1884  /********************************************************************
1885  * 3. Quad read commands *
1886  ********************************************************************/
1887  /*
1888  * This test reads data from the device in quad read mode.
1889  * The components of the test are broken down as follows:
1890  * Part A: Read data with quad output read.
1891  * Part B: Read data with quad IO read and terminate using quad IO read.
1892  */
1893  // Get data to be programmed.
1894  fillArrayPattern(dataWrite, 100, 0x40);
1895  // Write the new data to the device.
1900  standardflashBytePageProgram(0, dataWrite, 200);
1902  // Part A: Read data with quad output read and test it.
1903  standardflashReadArrayHighFreq(0, dataRead, 200);
1904  if(!compareByteArrays(dataRead, dataWrite, 200))
1905  {
1906  printf("Write or Quad Output Read failure.\n");
1907  errorCount++;
1908  }
1909  else
1910  {
1911  printf("Write and Quad Output Read success.\n");
1912  }
1913 
1914  // Part B: Read and terminate with quad IO read command.
1915  standardflashQuadIORead(0, dataRead, 10, 0, modeByteValue);
1916  standardflashQuadIORead(10, &(dataRead[10]), 10, 1, modeByteValue);
1917  standardflashQuadIORead(20, &(dataRead[20]), 10, 2, modeByteValue);
1918  standardflashQuadIORead(30, &(dataRead[30]), 10, 2, modeByteValue);
1919  // Device won't be in QPI mode after this command.
1920  standardflashQuadIORead(40, &(dataRead[40]), 10, 3, modeByteValue);
1921  // For the purpose of this test, return the flash device to QPI mode.
1922  // If one wishes to continue in SPI, call standardflashDisableQPI() to return
1923  // the MCU_SPI_MODE variable (part of the driver) to 0.
1925  if(!compareByteArrays(dataRead, dataWrite, 50))
1926  {
1927  printf("Write or Quad IO Read failure.\n");
1928  errorCount++;
1929  }
1930  else
1931  {
1932  printf("Write and Quad IO Read success.\n");
1933  }
1934 
1940 
1941 #endif
1942 
1943 #if (PARTNO == AT25DL081) || \
1944  (PARTNO == AT25DL161) || \
1945  (PARTNO == AT25DF081A) || \
1946  (PARTNO == AT25DF321A) || \
1947  (PARTNO == AT25DF641A) || \
1948  (ALL == 1)
1949 
1950  /********************************************************************
1951  * 4. Dual-Input Program *
1952  ********************************************************************/
1953 
1954  printf("\nThis device has the ability to program using 2 IOs.\n");
1955  fillArrayPattern(dataWrite, 100, 0x26);
1956  // Write enable the device for an erase and erase.
1960  // Write enable for a program and then program starting at address 0x0.
1962  standardflashDualInputBytePageProgram(0, dataWrite, 100);
1964  // Read it back and confirm the program worked.
1965  standardflashReadArrayHighFreq(0, dataRead, 100);
1966  if(!compareByteArrays(dataRead, dataWrite, 100))
1967  {
1968  printf("Dual Write or HF Read failure.\n");
1969  errorCount++;
1970  }
1971  else
1972  {
1973  printf("Dual Write and HF Read success.\n");
1974  }
1975 
1976 #endif
1977 
1978  // Test complete. Print messages and exit.
1979  printf("\n\n#############################################\n\n");
1980  printf("Testing complete.\n");
1981  printf("Total errors detected: %d\n", errorCount);
1982  printf("Terminating testbench.\n");
1983  printf("\n#############################################\n\n");
1984 
1985  return errorCount;
1986 }
1987 
1988 #endif
void monetaWaitOnReady()
: Wait while Read/Busy Status bit in SRB is 1 (device is busy).
Definition: moneta.c:53
void dataflashArrayReadLowPower(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x01 Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: dataflash.c:106
void fusionUDPDMode()
OPCODE: 0x79 Sends the device into Ultra Deep Power Down Mode. Exit UDPD Mode by toggling CS with c...
Definition: fusion.c:260
void dataflashMemoryProgramThruBuffer1WithErase(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0x82 Programs main memory through buffer 1 starting at the address indicated by &#39;address&#39; w...
Definition: dataflash.c:213
void dataflashBuffer2Write(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0x87 Programs &#39;txNumBytes&#39; bytes of data to buffer 2 starting at the address indicated by a...
Definition: dataflash.c:767
void dataflashBlockErase(uint32_t address)
OPCODE: 0x50 Erases a block of data (8 pages) starting from page address &#39;address.&#39;.
Definition: dataflash.c:257
void fusionWriteEnable()
OPCODE: 0x06 Sends opcode to enable writing.
Definition: fusion.c:167
void fusionReadSectorProtectionRegisters(uint32_t address, uint8_t *rxBuffer)
OPCODE: 0x3C Reads the sector protection register at address &#39;address.&#39; 0x00 -> Sector is unprotect...
Definition: fusion.c:326
void standardflashResumeFromDPD()
OPCODE: 0xAB Wake the device from deep power down mode. See dataflashDPD().
void standardflashEnableQPI()
OPCODE: 0x38 Switches the device from SPI mode to QPI mode, and sets a variable to quad mode...
void dataflashDPD()
OPCODE: 0xB9 Put the device into deep power down mode. Call dataflashResumeFromDPD() to wake up...
Definition: dataflash.c:415
void fusionReadMID(uint8_t *rxBuffer)
OPCODE: 0x9F Reads the manufacturer ID and stores the data in rxBuffer.
Definition: fusion.c:230
void monetaReadArray(uint16_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x03 Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: moneta.c:121
void dataflashArrayReadHighFreq0(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x0B Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: dataflash.c:126
void fusionResumeFromDeepPowerDown()
OPCODE: 0xAB Wakes the device up from Deep Power Down mode (fusionDeepPowerDown()).
Definition: fusion.c:250
void dataflashBuffer2ReadLowFreq(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0xD3 Reads rxNumBytes starting from location &#39;address&#39; in buffer 2 and stores the data in t...
Definition: dataflash.c:747
void standardflashContinuousReadModeDualReset()
OPCODE: 0xFFFF Resets the dual continuous read mode that was entered with standardflashDualIORead()...
void monetaHardwareReset()
Exits Ultra Deep Power Down mode using the hardware reset option.
Definition: moneta.c:177
void fusionHardwareReset()
Performs a hardware (JEDEC) reset on the device.
Definition: fusion.c:348
void dataflashMemtoBuffer1Compare(uint32_t address)
OPCODE: 0x60 Compare the contents of a page in main memory to the contents of buffer 1...
Definition: dataflash.c:395
void dataflashBuffer1ToMainMemoryWithoutErase(uint32_t address)
OPCODE: 0x88 Programs the entire buffer 1 page to main memory starting at the address indicated by ...
Definition: dataflash.c:203
void standardflashDPD()
OPCODE: 0xB9 Put the device into deep power down mode. Call dataflashResumeFromDPD() to wake up...
bool compareByteArrays(uint8_t *arr1, uint8_t *arr2, uint32_t arrLength)
Helper function to compare 2 byte arrays and print an error message if they do not match...
void standardflashQuadIORead(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes, uint8_t readMode, uint8_t modeByteValue)
OPCODE: 0xEB Reads &#39;txNumBytes&#39; bytes of data in Quad IO Mode starting at &#39;address&#39; using SI...
void standardflashDualIORead(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes, uint8_t readMode, uint8_t modeByteValue)
OPCODE: 0xBB Reads &#39;txNumBytes&#39; bytes of data in Dual IO Mode starting at &#39;address&#39; using both SI a...
Test layer declarations exist here.
void dataflashBuffer2ToMainMemoryWithoutErase(uint32_t address)
OPCODE: 0x89 Programs the entire buffer 2 page to main memory starting at the address indicated by ...
Definition: dataflash.c:794
void standardflashReadArrayLowFreq(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x03 Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
void dataflashUDPDMode()
OPCODE: 0x79 Put the device into ultra deep power down mode. Wake the device with dataflashHardware...
Definition: dataflash.c:425
void dataflashArrayReadLegacy(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0xE8 Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: dataflash.c:146
void dataflashRMWThruBuffer1(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0x58 Reads main memory to buffer 1, modifies it, then writes the data back to main memory w...
Definition: dataflash.c:290
void dataflashQuadEnable()
OPCODE: 0x3D2A8166 Programs the NV-QE bit to a logical 1 to enable the Quad I/O commands...
Definition: dataflash.c:621
void standardflashSetQEBit()
: Sets the QE bit in status register byte 2. Does not modify any other bits. This is accomplished by ...
Definition: standardflash.c:99
void fusionDeepPowerDown()
OPCODE: 0xB9 Enters the device into Deep Power Down mode. fusionResumeFromDeepPowerDown() will wake...
Definition: fusion.c:240
void dataflashHardwareReset()
Perform a JEDEC reset on the flash device.
Definition: dataflash.c:435
void dataflashBuffer2ToMainMemoryWithErase(uint32_t address)
OPCODE: 0x86 Programs the entire buffer 2 page to main memory starting at the address indicated by ...
Definition: dataflash.c:784
void fusionGlobalUnprotect()
Unprotects all sectors by issuing a WE, then write of 0x00 to status register byte 1...
Definition: fusion.c:84
void standardflashDualInputBytePageProgram(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0xA2 Programs &#39;txNumBytes&#39; bytes of data starting at the address indicated by address using...
void dataflashBuffer1ReadLowFreq(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0xD1 Reads rxNumBytes starting from location &#39;address&#39; in buffer 1 and stores the data in t...
Definition: dataflash.c:156
void dataflashReadSR(uint8_t *rxBuffer)
OPCODE: 0xD7 Reads the value in the device status register (bytes 1 and 2).
Definition: dataflash.c:86
void standardflashUnprotectSector(uint32_t address)
OPCODE: 0x39 Un-protects a sector containing the address address.
void fusionWaitOnReady()
: Wait while Read/Busy Status bit in SRB is 1 (device is busy).
Definition: fusion.c:67
void monetaWriteDisable()
OPCODE: 0x04 Sends opcode to disable writing.
Definition: moneta.c:75
void standardflashContinuousReadModeQuadReset()
OPCODE: 0xFF Resets the quad continuous read mode that was entered with standardflashQuadIORead() w...
void standardflashReadMID(uint8_t *rxBuffer)
OPCODE: 0x9F Reads the manufacturer ID and stores the data in rxBuffer.
void fusionWriteDisable()
OPCODE: 0x04 Sends opcode to disable writing.
Definition: fusion.c:177
void dataflashArrayReadLowFreq(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x03 Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: dataflash.c:116
void dataflashReadMID(uint8_t *rxBuffer)
OPCODE: 0x9F Reads the manufacturer ID and stores the data in rxBuffer.
Definition: dataflash.c:76
void fusionBlockErase4K(uint32_t address)
OPCODE: 0x20 Erases a block of data (4 KBytes) starting from page address &#39;address.&#39;.
Definition: fusion.c:130
void standardflashClearQEBit()
: Clears the QE bit in status register byte 2. Does not modify any other bits. This is accomplished b...
void dataflashPageErase(uint32_t address)
OPCODE: 0x81 Erases a page of data (256/264 Bytes) starting from page address &#39;address.&#39;.
Definition: dataflash.c:247
void dataflashBuffer1ReadHighFreq(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0xD4
Definition: dataflash.c:166
void fillArrayPattern(uint8_t *byteArray, uint32_t numBytes, int seedNumber)
Helper function to display fill a byte array/buffer with a pattern based on a seedNumber. The seed will be incremented by the index of the array.
void standardflashQuadOutputRead(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x6B Reads &#39;txNumBytes&#39; bytes of data in Quad Output Mode starting at &#39;address&#39; using SI...
void fusionDualInputProgram(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0xA2 Programs &#39;txNumBytes&#39; bytes of data in Dual Input Mode starting at &#39;address&#39; using bot...
Definition: fusion.c:289
void monetaReadMID(uint8_t *rxBuffer)
OPCODE: 0x9F Reads the manufacturer ID and stores the data in rxBuffer.
Definition: moneta.c:157
void dataflashSectorErase(uint32_t address)
OPCODE: 0x7C
Definition: dataflash.c:267
void standardflashReadArrayHighFreq(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x0B Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
void fusionGlobalProtect()
Protects all sectors by issuing a WE, then write of 0x7F to status register byte 1. These 2 write are accomplished with fusionWriteEnable() and fusionWriteSRB1().
Definition: fusion.c:78
void standardflashWaitOnReady()
: Wait while Read/Busy Status bit in SRB is 1 (device is busy). This is accomplished by reading the f...
Definition: standardflash.c:77
void dataflashBuffer1Write(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0x84 Programs &#39;txNumBytes&#39; bytes of data to buffer 1 starting at the address indicated by a...
Definition: dataflash.c:176
void dataflashBuffer1ToMainMemoryWithErase(uint32_t address)
OPCODE: 0x83 Programs the entire buffer 1 page to main memory starting at the address indicated by ...
Definition: dataflash.c:193
void standardflashWriteEnable()
OPCODE: 0x06 Sends opcode to enable writing.
void dataflashResumeFromDPD()
OPCODE: 0xAB Wake the device from deep power down mode. See dataflashDPD().
Definition: dataflash.c:440
void fusionSequentialProgramMode(uint8_t txBuffer)
OPCODE: 0xAD Sends the byte in txBuffer to the flash device for programming. This command should on...
Definition: fusion.c:278
#define MAXIMUM_BUFFER_SIZE
Definition: cmd_defs.h:48
void monetaWriteEnable()
OPCODE: 0x06 Sends opcode to enable writing.
Definition: moneta.c:64
void dataflashWaitOnReady()
: Wait while Read/Busy Status bit in SRB is 1 (device is busy).
Definition: dataflash.c:65
void dataflashQuadOutputRead(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x6B Reads &#39;txNumBytes&#39; bytes of data in Quad Output Mode starting at &#39;address&#39; using SI...
Definition: dataflash.c:541
void monetaReadSR(uint8_t *rxBuffer)
OPCODE: 0x05 Reads the value in the status registers.
Definition: moneta.c:86
uint32_t defaultTest()
The default test function can be called by the user to perform the default test prepared for each dev...
void dataflashMemtoBuffer2Compare(uint32_t address)
OPCODE: 0x61 Compare the contents of a page in main memory to the contents of buffer 2...
Definition: dataflash.c:848
void fusionReadArray(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x0B Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: fusion.c:90
void dataflashBuffer2ReadHighFreq(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0xD6 Reads rxNumBytes starting from location &#39;address&#39; in buffer 2 and stores the data in t...
Definition: dataflash.c:757
void fusionDualOutputRead(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x3B Reads &#39;txNumBytes&#39; bytes of data in Dual Output Mode starting at &#39;address&#39; using both ...
Definition: fusion.c:110
void fusionPageErase(uint32_t address)
OPCODE: 0x81 Erases a page of data (256 Bytes) starting from page address &#39;address.&#39;.
Definition: fusion.c:120
void dataflashMemtoBuffer1Transfer(uint32_t address)
OPCODE: 0x53 Transfer the contents of a page in main memory at the address indicated by &#39;address&#39; t...
Definition: dataflash.c:385
void standardflashDualOutputRead(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x3B Reads &#39;txNumBytes&#39; bytes of data in Dual Output Mode starting at &#39;address&#39; using both ...
void fillArrayConst(uint8_t *byteArray, uint32_t numBytes, int constantNum)
Helper function to display fill a byte array/buffer with a constant number.
void fusionSequentialProgramModeEnable(uint32_t address, uint8_t txBuffer)
OPCODE: 0xAD Enables sequential program mode and loads the starting address into the device...
Definition: fusion.c:336
void standardflashBlockErase4K(uint32_t address)
OPCODE: 0x20 Erases a block of data (4 KBytes) starting from page address &#39;address.&#39;.
void fusionUnprotectSector(uint32_t address)
OPCODE: 0x39 Sends opcode to enable writing.
Definition: fusion.c:316
void fusionReadSR(uint8_t *rxBuffer)
OPCODE: 0x05 Reads the value in the status register (bytes 1 and 2).
Definition: fusion.c:187
void standardflashBytePageProgram(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0x02 Programs &#39;txNumBytes&#39; bytes of data starting at the address indicated by address...
void dataflashMemtoBuffer2Transfer(uint32_t address)
OPCODE: 0x55
Definition: dataflash.c:838
void dataflashArrayReadHighFreq1(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x1B Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: dataflash.c:136
void standardflashDisableQPI()
OPCODE: 0xFF Switches the device from QPI mode to SPI mode, and sets a variable to spi mode...
void monetaWriteArray(uint16_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0x02 Writes txNumBytes bytes of data starting at the address indicated by address...
Definition: moneta.c:134
void monetaUDPDMode1()
OPCODE: 0x79 Sends the device into Ultra Deep Power Down Mode 1. Exit UDPD Mode 1 by power cycling ...
Definition: moneta.c:167
void SPI_ConfigureSingleSPIIOs()
Configure the IOs for SPI bit banging usage. 4 pins are needed: CSb, SCK, MOSI, MISO.
Definition: spi_driver.c:61
void dataflashQuadDisable()
OPCODE: 0x3D2A8167 Programs the NV-QE bit to a logical 0 to disable the Quad I/O commands...
Definition: dataflash.c:634
void dataflashMemoryProgramThruBuffer2WithErase(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0x85 Programs main memory through buffer 2 starting at the address indicated by &#39;address&#39; w...
Definition: dataflash.c:804