main.c
上传用户:xukun0987
上传日期:2022-07-16
资源大小:216k
文件大小:22k
源码类别:

微处理器开发

开发平台:

C/C++

  1. /* ----------------------------------------------------------------------------
  2.  *         ATMEL Microcontroller Software Support 
  3.  * ----------------------------------------------------------------------------
  4.  * Copyright (c) 2008, Atmel Corporation
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions are met:
  10.  *
  11.  * - Redistributions of source code must retain the above copyright notice,
  12.  * this list of conditions and the disclaimer below.
  13.  *
  14.  * Atmel's name may not be used to endorse or promote products derived from
  15.  * this software without specific prior written permission.
  16.  *
  17.  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  20.  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  23.  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  24.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  25.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  26.  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  * ----------------------------------------------------------------------------
  28.  */
  29. //------------------------------------------------------------------------------
  30. /// dir "Basic-serialflash-project"
  31. ///
  32. /// !!!Purpose
  33. ///
  34. /// The Basic Serialflash project will help new users get familiar with SPI interface 
  35. /// on Atmel's AT91 family of microcontrollers. This project gives you an AT26 
  36. /// serial firmware dataflash programming code so that can help develop your own 
  37. /// SPI devices applications with maximum efficiency.
  38. ///
  39. /// You can find following information depends on your needs:
  40. /// - A Spi low level driver performs SPI device Initializes, data transfer and 
  41. /// receive. It can be used by upper SPI driver such as AT26 %dataflash.
  42. /// - A Dataflash driver is based on top of the corresponding Spi driver.
  43. /// It allow user to do operations with %dataflash in a unified way.
  44. ///
  45. /// !See also
  46. ///    - "spi-flash": Dataflash interface driver.
  47. ///
  48. /// !!!Requirements
  49. ///
  50. /// This package can be used with all Atmel evaluation kits that have SPI
  51. /// interface and on-board or external Dataflash connected. The package runs at 
  52. /// SRAM or SDRAM, so SDRAM device is needed if you want to run this package in SDRAM.
  53. ///
  54. ///
  55. /// !!!Description
  56. ///
  57. /// The demonstration program tests the dataflash present on the evaluation kit by 
  58. /// erasing and writing each one of its pages.
  59. ///
  60. /// !!!Usage
  61. ///
  62. /// -# Build the program and download it inside the evaluation board. Please
  63. ///    refer to the <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6224.pdf">SAM-BA User Guide</a>,
  64. ///    the <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6310.pdf">GNU-Based Software Development</a>
  65. ///    application note or to the <a href="ftp://ftp.iar.se/WWWfiles/arm/Guides/EWARM_UserGuide.ENU.pdf">IAR EWARM User Guide</a>,
  66. ///    depending on your chosen solution.
  67. /// -# On the computer, open and configure a terminal application
  68. ///    (e.g. HyperTerminal on Microsoft Windows) with these settings:
  69. ///   - 115200 bauds
  70. ///   - 8 bits of data
  71. ///   - No parity
  72. ///   - 1 stop bit
  73. ///   - No flow control
  74. /// -# Start the application.
  75. /// -# Upon startup, the application will output the following lines on the DBGU: 
  76. ///    code
  77. ///     -- Basic Serial Firmware Dataflash Project xxx --
  78. ///     -- AT91xxxxxx-xx
  79. ///     -- Compiled: xxx xx xxxx xx:xx:xx --
  80. ///     -I- SPI and At26 initialized 
  81. ///    endcode
  82. /// -# The program will connect to the serial firmware dataflash through the SPI 
  83. ///    and start sending commands to it. It will perform the following: 
  84. ///    - Read the JEDEC identifier of the device to autodetect it 
  85. ///      The next line should indicate if the serial dataflash has been 
  86. ///      correctly identified. For example, this is what appears when an 
  87. ///      AT26DF321 chip is recognized: 
  88. ///    code
  89. ///    -I- AT26DF321 Serial Flash detected 
  90. ///    endcode
  91. ///    - Erase the chip 
  92. ///    - Check that each page is blank 
  93. ///    - Write a "Walking one" pattern on each page: 
  94. ///    code
  95. ///    Byte 0 = 00000001
  96. ///    Byte 1 = 00000010
  97. ///    Byte 2 = 00000100
  98. ///    ........ 
  99. ///    endcode
  100. ///    - Verify that the pattern has been correctly applied on each page 
  101. //------------------------------------------------------------------------------
  102. //------------------------------------------------------------------------------
  103. /// unit
  104. ///
  105. /// !Purpose
  106. ///
  107. /// This file contains all the specific code for the basic-serialflash-project.
  108. /// It tests the serial firmware dataflash present on the evaluation kit by 
  109. /// erasing and writing each one of its pages.
  110. /// 
  111. /// !Contents
  112. /// The code can be roughly broken down as follows:
  113. ///    - AT26 Dataflash write data function.
  114. ///    - AT26 Dataflash read data function.
  115. ///    - AT26 Dataflash erase function.
  116. ///    - Other AT26 functions (such as AT26_GetStatus())
  117. ///    - The main() function, which implements the program behavior.
  118. ///       - Initializes an AT26 instance and configures SPI chip select pin.
  119. ///       - Config SPI Interrupt Service Routine.
  120. ///       - Identifier the AT26 device connected to the evaluation kit.
  121. ///       - Test the dataflash by erasing and writing each one of its pages.
  122. /// 
  123. /// !See also
  124. ///    - "spi-flash": SPI Dataflash interface driver.
  125. ///
  126. /// Please refer to the list of functions in the #Overview# tab of this unit
  127. /// for more detailed information.
  128. //------------------------------------------------------------------------------
  129. //------------------------------------------------------------------------------
  130. //         Headers
  131. //------------------------------------------------------------------------------
  132. #include <board.h>
  133. #include <dbgu/dbgu.h>
  134. #include <pio/pio.h>
  135. #include <aic/aic.h>
  136. #include <utility/assert.h>
  137. #include <utility/trace.h>
  138. #include <utility/math.h>
  139. #include <memories/spi-flash/at26.h>
  140. #include <string.h>
  141. //------------------------------------------------------------------------------
  142. //         Internal definitions
  143. //------------------------------------------------------------------------------
  144. /// Maximum device page size in bytes.
  145. #define MAXPAGESIZE     256
  146. #if defined(BOARD_AT45_A_SPI_BASE)
  147. /// Address of the SPI peripheral connected to the AT26.
  148. #define SPI_BASE        BOARD_AT45_A_SPI_BASE
  149. /// Peripheral identifier of the SPI connected to the AT26.
  150. #define SPI_ID          BOARD_AT45_A_SPI_ID
  151. /// Chip select value used to select the AT26 chip.
  152. #define SPI_CS          BOARD_AT45_A_NPCS
  153. /// SPI peripheral pins to configure to access the serial flash.
  154. #define SPI_PINS        BOARD_AT45_A_SPI_PINS, BOARD_AT45_A_NPCS_PIN
  155. #elif defined(AT91C_BASE_SPI0)
  156. /// Address of the SPI peripheral connected to the AT26.
  157. #define SPI_BASE        AT91C_BASE_SPI0
  158. /// Peripheral identifier of the SPI connected to the AT26.
  159. #define SPI_ID          AT91C_ID_SPI0
  160. /// Chip select value used to select the AT26 chip.
  161. #define SPI_CS          0
  162. /// SPI peripheral pins to configure to access the serial flash.
  163. #define SPI_PINS        PINS_SPI0, PIN_SPI0_NPCS0
  164. #else
  165. /// Address of the SPI peripheral connected to the AT26.
  166. #define SPI_BASE        AT91C_BASE_SPI
  167. /// Peripheral identifier of the SPI connected to the AT26.
  168. #define SPI_ID          AT91C_ID_SPI
  169. /// Chip select value used to select the AT26 chip.
  170. #define SPI_CS          0
  171. /// SPI peripheral pins to configure to access the serial flash.
  172. #define SPI_PINS        PINS_SPI, PIN_SPI_NPCS0
  173. #endif //#if defined(AT91C_BASE_SPI0)
  174. //------------------------------------------------------------------------------
  175. //         Internal variables
  176. //------------------------------------------------------------------------------
  177. /// SPI driver instance.
  178. static Spid spid;
  179. /// Serial flash driver instance.
  180. static At26 at26;
  181. /// Pins to configure for the application.
  182. static Pin pins[] = {SPI_PINS};
  183. //------------------------------------------------------------------------------
  184. //         Internal functions
  185. //------------------------------------------------------------------------------
  186. //------------------------------------------------------------------------------
  187. /// Interrupt service routine for the SPI peripheral. Forwards the interrupt
  188. /// to the SPI driver.
  189. //------------------------------------------------------------------------------
  190. static void ISR_Spi(void)
  191. {
  192.     SPID_Handler(&spid);
  193. }
  194. //------------------------------------------------------------------------------
  195. /// Reads and returns the status register of the serial flash.
  196. /// param pAt26  Pointer to an AT26 driver instance.
  197. //------------------------------------------------------------------------------
  198. static unsigned char AT26_ReadStatus(At26 *pAt26)
  199. {
  200.     unsigned char error, status;
  201.     SANITY_CHECK(pAt26);
  202.     // Issue a status read command
  203.     error = AT26_SendCommand(pAt26, AT26_READ_STATUS, 1, &status, 1, 0, 0, 0);
  204.     ASSERT(!error, "-F- AT26_GetStatus: Failed to issue command.nr");
  205.     // Wait for transfer to finish
  206.     while (AT26_IsBusy(pAt26));
  207.     return status;
  208. }
  209. //------------------------------------------------------------------------------
  210. /// Writes the given value in the status register of the serial flash device.
  211. /// param pAt26  Pointer to an AT26 driver instance.
  212. /// param status  Status to write.
  213. //------------------------------------------------------------------------------
  214. static void AT26_WriteStatus(At26 *pAt26, unsigned char status)
  215. {
  216.     unsigned char error;
  217.     SANITY_CHECK(pAt26);
  218.     // Issue a write status command
  219.     error = AT26_SendCommand(pAt26, AT26_WRITE_STATUS, 1, &status, 1, 0, 0, 0);
  220.     ASSERT(!error, "-F- AT26_WriteStatus: Failed to issue command.nr");
  221.     while (AT26_IsBusy(pAt26));
  222. }
  223. //------------------------------------------------------------------------------
  224. /// Waits for the serial flash device to become ready to accept new commands.
  225. /// param pAt26  Pointer to an AT26 driver instance.
  226. //------------------------------------------------------------------------------
  227. static void AT26_WaitReady(At26 *pAt26)
  228. {
  229.     unsigned char ready = 0;
  230.     SANITY_CHECK(pAt26);
  231.     // Read status register and check busy bit
  232.     while (!ready) {
  233.         ready = ((AT26_ReadStatus(pAt26) & AT26_STATUS_RDYBSY) == AT26_STATUS_RDYBSY_READY);
  234.     }
  235. }
  236. //------------------------------------------------------------------------------
  237. /// Reads and returns the serial flash device ID.
  238. /// param pAt26  Pointer to an AT26 driver instance.
  239. //------------------------------------------------------------------------------
  240. static unsigned int AT26_ReadJedecId(At26 *pAt26)
  241. {
  242.     unsigned char error;
  243.     unsigned int id = 0;
  244.     SANITY_CHECK(pAt26);
  245.  
  246.     // Issue a read ID command
  247.     error = AT26_SendCommand(pAt26, AT26_READ_JEDEC_ID, 1,
  248.                              (unsigned char *) &id, 3, 0, 0, 0);
  249.     ASSERT(!error, "-F- AT26_GetJedecId: Could not issue command.nr");
  250.      // Wait for transfer to finish
  251.     while (AT26_IsBusy(pAt26));
  252.     return id;
  253. }
  254. //------------------------------------------------------------------------------
  255. /// Enables critical writes operation on a serial flash device, such as sector
  256. /// protection, status register, etc.
  257. /// para pAt26  Pointer to an AT26 driver instance.
  258. //------------------------------------------------------------------------------
  259. static void AT26_EnableWrite(At26 *pAt26)
  260. {
  261.     unsigned char error;
  262.     SANITY_CHECK(pAt26);
  263.     // Issue a write enable command
  264.     error = AT26_SendCommand(pAt26, AT26_WRITE_ENABLE, 1, 0, 0, 0, 0, 0);
  265.     ASSERT(!error, "-F- AT26_EnableWrite: Could not issue command.nr");
  266.     // Wait for end of transfer
  267.     while (AT26_IsBusy(pAt26));
  268. }
  269. //------------------------------------------------------------------------------
  270. /// Unprotects the contents of the serial flash device.
  271. /// Returns 0 if the device has been unprotected; otherwise returns
  272. /// SF_PROTECTED.
  273. /// param pAt26  Pointer to an AT26 driver instance.
  274. //------------------------------------------------------------------------------
  275. static unsigned char AT26_Unprotect(At26 *pAt26)
  276. {
  277.     unsigned char status;
  278.     SANITY_CHECK(pAt26);
  279.     // Get the status register value to check the current protection
  280.     status = AT26_ReadStatus(pAt26);
  281.     if ((status & AT26_STATUS_SWP) == AT26_STATUS_SWP_PROTNONE) {
  282.         // Protection already disabled
  283.         return 0;
  284.     }
  285.     
  286.     // Check if sector protection registers are locked
  287.     if ((status & AT26_STATUS_SPRL) == AT26_STATUS_SPRL_LOCKED) {
  288.         // Unprotect sector protection registers by writing the status reg.
  289.         AT26_EnableWrite(pAt26);
  290.         AT26_WriteStatus(pAt26, 0);
  291.     }
  292.     
  293.     // Perform a global unprotect command
  294.       AT26_EnableWrite(pAt26);
  295.     AT26_WriteStatus(pAt26, 0);
  296.     
  297.     // Check the new status
  298.     if ((status & (AT26_STATUS_SPRL | AT26_STATUS_SWP)) != 0) {
  299.         return AT26_ERROR_PROTECTED;
  300.     }
  301.     else {
  302.         return 0;
  303.     }
  304. }
  305. //------------------------------------------------------------------------------
  306. /// Erases all the content of the memory chip.
  307. /// param pAt26  Pointer to an AT26 driver instance.
  308. //------------------------------------------------------------------------------
  309. static unsigned char AT26_EraseChip(At26 *pAt26)
  310. {
  311.     unsigned char status;
  312.     unsigned char error;
  313.     SANITY_CHECK(pAt26);
  314.     // Check that the flash is ready an unprotected
  315.     status = AT26_ReadStatus(pAt26);
  316.     if ((status & AT26_STATUS_SWP) != AT26_STATUS_SWP_PROTNONE) {
  317.         TRACE_WARNING("AT26_EraseBlock: Device is protected.nr");
  318.         return AT26_ERROR_PROTECTED;
  319.     }
  320.     
  321.     // Enable critical write operation
  322.       AT26_EnableWrite(pAt26);
  323.     
  324.     // Erase the chip
  325.     error = AT26_SendCommand(pAt26, AT26_CHIP_ERASE_2, 1, 0, 0, 0, 0, 0);
  326.     ASSERT(!error, "-F- AT26_ChipErase: Could not issue command.nr");
  327.      while (AT26_IsBusy(pAt26));    
  328.     AT26_WaitReady(pAt26);
  329.     return 0;
  330. }
  331. //------------------------------------------------------------------------------
  332. /// Erases the specified 4KB block of the serial firmware dataflash.
  333. /// Returns 0 if successful; otherwise returns AT26_ERROR_PROTECTED if the
  334. /// device is protected or AT26_ERROR_BUSY if it is busy executing a command.
  335. /// param pAt26  Pointer to an AT26 driver instance.
  336. /// param address  Address of the block to erase.
  337. //------------------------------------------------------------------------------
  338. static unsigned char AT26_EraseBlock(At26 *pAt26, unsigned int address)
  339. {
  340.     unsigned char status;
  341.     unsigned char error;
  342.     SANITY_CHECK(pAt26);
  343.  
  344.     // Check that the flash is ready an unprotected
  345.     status = AT26_ReadStatus(pAt26);
  346.     if ((status & AT26_STATUS_RDYBSY) != AT26_STATUS_RDYBSY_BUSY) {
  347.         TRACE_WARNING("AT26_EraseBlock: Device is not ready.nr");
  348.         return AT26_ERROR_BUSY;
  349.     }
  350.     else if ((status & AT26_STATUS_SWP) != AT26_STATUS_SWP_PROTNONE) {
  351.         TRACE_WARNING("AT26_EraseBlock: Device is protected.nr");
  352.         return AT26_ERROR_PROTECTED;
  353.     }
  354.     // Enable critical write operation
  355.       AT26_EnableWrite(pAt26);
  356.     // Start the block erase command
  357.     error = AT26_SendCommand(pAt26, AT26_BLOCK_ERASE_4K, 4, 0, 0, address, 0, 0);
  358.     ASSERT(!error, "-F- AT26_EraseBlock: Could not issue command.nr");
  359.     while (AT26_IsBusy(pAt26));
  360.     AT26_WaitReady(pAt26);
  361.     return 0;
  362. }
  363. //------------------------------------------------------------------------------
  364. /// Writes data at the specified address on the serial firmware dataflash. The
  365. /// page(s) to program must have been erased prior to writing. This function
  366. /// handles page boundary crossing automatically.
  367. /// Returns 0 if successful; otherwise, returns AT26_ERROR_PROGRAM is there has
  368. /// been an error during the data programming.
  369. /// param pAt26  Pointer to an AT26 driver instance.
  370. /// param pData  Data buffer.
  371. /// param size  Number of bytes in buffer.
  372. /// param address  Write address.
  373. //------------------------------------------------------------------------------
  374. static unsigned char AT26_Write(
  375.     At26 *pAt26,
  376.     unsigned char *pData,
  377.     unsigned int size,
  378.     unsigned int address)
  379. {
  380.     unsigned int pageSize;
  381.     unsigned int writeSize;
  382.     unsigned char error;
  383.     unsigned char status;
  384.     SANITY_CHECK(pAt26);
  385.     SANITY_CHECK(pData);
  386.     // Retrieve device page size
  387.     pageSize = AT26_PageSize(&at26);
  388.     // Program one page after the other
  389.     while (size > 0) {
  390.         // Compute number of bytes to program in page
  391.         writeSize = min(size, pageSize - (address % pageSize));
  392.                 
  393.         // Enable critical write operation
  394.         AT26_EnableWrite(pAt26);
  395.      
  396.          // Program page
  397.           error = AT26_SendCommand(pAt26, AT26_BYTE_PAGE_PROGRAM, 4,
  398.                            pData, writeSize, address, 0, 0);
  399.         ASSERT(!error, "-F- AT26_WritePage: Failed to issue command.nr");
  400.         while (AT26_IsBusy(pAt26));
  401.         AT26_WaitReady(pAt26);
  402.         // Make sure that write was without error
  403.         status = AT26_ReadStatus(pAt26);
  404.         if ((status & AT26_STATUS_EPE) == AT26_STATUS_EPE_ERROR) {
  405.             return AT26_ERROR_PROGRAM;
  406.         }
  407.         
  408.         size -= writeSize;
  409.         address += writeSize;
  410.     }
  411.     return 0;
  412. }
  413. //------------------------------------------------------------------------------
  414. /// Reads data from the specified address on the serial flash.
  415. /// param pAt26  Pointer to an AT26 driver instance.
  416. /// param pData  Data buffer.
  417. /// param size  Number of bytes to read.
  418. /// param address  Read address.
  419. //------------------------------------------------------------------------------
  420. static void AT26_Read(
  421.     At26 *pAt26,
  422.     unsigned char *pData,
  423.     unsigned int size,
  424.     unsigned int address)
  425. {
  426.     unsigned char error;
  427.     
  428.      // Start a read operation
  429.       error = AT26_SendCommand(pAt26, AT26_READ_ARRAY_LF, 4, pData, size, address, 0, 0);
  430.     ASSERT(!error, "-F- AT26_Read: Could not issue command.nr");
  431.     while (AT26_IsBusy(pAt26));
  432. }
  433. //------------------------------------------------------------------------------
  434. //         External functions
  435. //------------------------------------------------------------------------------
  436. //------------------------------------------------------------------------------
  437. /// Initializes the serial flash and performs several tests on it.
  438. //------------------------------------------------------------------------------
  439. int main(void)
  440. {
  441.     unsigned int jedecId;
  442.     unsigned int numPages;
  443.     unsigned int pageSize;
  444.     unsigned int i, j;
  445.     unsigned int address;
  446.     unsigned char pBuffer[MAXPAGESIZE];
  447.     // Configure the DBGU
  448.     TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
  449.     printf("-- Basic Serial Firmware Dataflash Project %s --nr", SOFTPACK_VERSION);
  450.     printf("-- %snr", BOARD_NAME);
  451.     printf("-- Compiled: %s %s --nr", __DATE__, __TIME__);
  452.     // Initialize the SPI and serial flash
  453.     PIO_Configure(pins, PIO_LISTSIZE(pins));
  454.     AIC_ConfigureIT(SPI_ID, 0, ISR_Spi);
  455.     SPID_Configure(&spid, SPI_BASE, SPI_ID);
  456.     AT26_Configure(&at26, &spid, SPI_CS);
  457.     AIC_EnableIT(SPI_ID);
  458.     TRACE_INFO("SPI and AT26 drivers initializednr");
  459.     
  460.     // Read the JEDEC ID of the device to identify it
  461.     jedecId = AT26_ReadJedecId(&at26);
  462.     if (AT26_FindDevice(&at26, jedecId)) {
  463.         TRACE_INFO("%s serial flash detectednr", AT26_Name(&at26));
  464.     }
  465.     else {
  466.         TRACE_ERROR("Failed to recognize the device (JEDEC ID is 0x%08X).nr", jedecId);
  467.         return 1;
  468.     }
  469.     ASSERT(MAXPAGESIZE >= AT26_PageSize(&at26), "-F- MAXPAGESIZE too smallnr");
  470.     // Get device parameters
  471.     numPages = AT26_PageNumber(&at26);
  472.     pageSize = AT26_PageSize(&at26);
  473.     // Unprotected the flash
  474.     AT26_Unprotect(&at26);
  475.     TRACE_INFO("Flash unprotectednr");
  476.     // Erase the chip
  477.     TRACE_INFO("Chip is being erased...nr");
  478.     AT26_EraseChip(&at26);
  479.     TRACE_INFO("Checking erase ...nr");
  480.     // Check that the chip has been erased correctly
  481.     address = 0;
  482.     for (i=0; i < numPages; i++) {
  483.         TRACE_INFO("Checking page #%ur", i);
  484.         AT26_Read(&at26, pBuffer, pageSize, address);
  485.         for (j=0; j < pageSize; j++) {
  486.             if (pBuffer[j] != 0xFF) {
  487.                 TRACE_ERROR("Failed erase on page%u:byte%unr", i, j);
  488.                 TRACE_ERROR(
  489.                           "-E- Expected 0xFF, read 0x%02Xnr",
  490.                           pBuffer[j]);
  491.                 return 2;
  492.             }
  493.         }
  494.         address += pageSize;
  495.     }
  496.     TRACE_INFO("Erase successful.nr");
  497.     // Program a "walking one" pattern on each page
  498.     TRACE_INFO("Programming a walking 1 on all pages ...nr");
  499.     address = 0;
  500.     for (i=0; i < numPages; i++) {
  501.         TRACE_INFO("Programming page #%ur", i);
  502.         // Fill buffer
  503.         for (j=0; j < pageSize; j++) {
  504.             pBuffer[j] = 1 << (j & 0x7);
  505.         }
  506.         // Write buffer
  507.         AT26_Write(&at26, pBuffer, pageSize, address);
  508.         // Read page back and check result
  509.         memset(pBuffer, 0, pageSize);
  510.         AT26_Read(&at26, pBuffer, pageSize, address);
  511.         for (j=0; j < pageSize; j++) {
  512.             if (pBuffer[j] != (1 << (j & 0x7))) {
  513.                 TRACE_ERROR("Failed program on page%u:byte%unr", i, j);
  514.                 TRACE_ERROR(
  515.                           "-E- Expected 0x%02X, read 0x%02Xnr",
  516.                           1 << (j & 0x7),
  517.                           pBuffer[j]);
  518.                 return 3;
  519.             }
  520.         }
  521.         address += pageSize;
  522.     }
  523.     TRACE_INFO("Walking 1 test successful.nr");
  524.     return 0;
  525. }