1 //=================================================================
5 // Simple tests for FLASH drivers
7 //=================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2004 Gary Thomas
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //=================================================================
42 //#####DESCRIPTIONBEGIN####
47 // Description: Simple test of FLASH I/O.
50 //####DESCRIPTIONEND####
52 // #define DEBUG_PRINTFS
54 #include <pkgconf/hal.h>
55 #include <pkgconf/io_flash.h>
56 #include CYGHWR_MEMORY_LAYOUT_H
58 #include <cyg/infra/diag.h>
59 #include <cyg/infra/testcase.h>
61 #include <cyg/io/flash.h>
62 #include <cyg/hal/hal_if.h>
69 CYG_ADDRWORD flash_start, flash_end;
70 void **flash_start_addr = (void *)&flash_start;
71 void **flash_end_addr = (void *)&flash_end;
72 void *flash_test_start, *flash_addr;
73 cyg_int32 flash_block_size, flash_num_blocks;
74 CYG_ADDRWORD test_buf1, test_buf2;
75 cyg_uint32 *lp1, *lp2;
82 diag_printf("Testing udelay: ");
83 for (i = 0; i < 30; i++) {
84 for (j = 0; j < 1000; j++) {
85 CYGACC_CALL_IF_DELAY_US(1000); // Should be 1 second
94 if ((stat = flash_init(diag_printf)) != 0) {
95 diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat));
96 CYG_TEST_FAIL_FINISH("FLASH driver init failed");
98 flash_get_limits((void *)0, flash_start_addr, flash_end_addr);
99 // Keep 'end' address as last valid location, to avoid wrap around problems
100 flash_end = flash_end - 1;
101 flash_get_block_info(&flash_block_size, &flash_num_blocks);
103 diag_printf("FLASH: 0x%x - 0x%x, %d blocks of 0x%x bytes each.\n",
104 flash_start, flash_end + 1, flash_num_blocks,
107 // Verify that the testing limits are within the bounds of the
108 // physical device. Also verify that the size matches with
109 // the erase block size on the device
110 if ((CYGNUM_IO_FLASH_TEST_OFFSET > (flash_end - flash_start)) ||
111 ((CYGNUM_IO_FLASH_TEST_OFFSET + CYGNUM_IO_FLASH_TEST_LENGTH) > (flash_end - flash_start))) {
112 CYG_TEST_FAIL_FINISH("FLASH test region outside physical limits");
114 if ((CYGNUM_IO_FLASH_TEST_LENGTH % flash_block_size) != 0) {
115 CYG_TEST_FAIL_FINISH("FLASH test region must be integral multiple of erase block size");
118 // Allocate two buffers large enough for the test
119 test_buf1 = (CYG_ADDRWORD)CYGMEM_SECTION_heap1;
120 test_buf2 = test_buf1 + CYGNUM_IO_FLASH_TEST_LENGTH;
121 if (CYGMEM_SECTION_heap1_SIZE < (CYGNUM_IO_FLASH_TEST_LENGTH * 2)) {
122 CYG_TEST_FAIL_FINISH("FLASH not enough heap space - reduce size of test region");
124 diag_printf("... Using test buffers at %p and %p\n", (void *)test_buf1, (void *)test_buf2);
125 flash_test_start = (void *)(flash_start + CYGNUM_IO_FLASH_TEST_OFFSET);
128 diag_printf("... Erase test\n");
130 if ((stat = flash_erase(flash_test_start,
131 CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != FLASH_ERR_OK) {
132 diag_printf("FLASH: erase failed: %s\n", flash_errmsg(stat));
135 if (ok && (stat = flash_read(flash_test_start, (void *)test_buf1,
136 CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != FLASH_ERR_OK) {
137 diag_printf("FLASH: read/verify after erase failed: %s\n", flash_errmsg(stat));
140 lp1 = (cyg_uint32 *)test_buf1;
141 for (i = 0; i < CYGNUM_IO_FLASH_TEST_LENGTH; i += sizeof(cyg_uint32)) {
142 if (*lp1++ != 0xFFFFFFFF) {
143 diag_printf("FLASH: non-erased data found at offset %x\n", (CYG_ADDRWORD)(lp1-1) - test_buf1);
144 diag_dump_buf((void *)(lp1-1), 32);
149 // Try reading in little pieces
150 len = CYGNUM_IO_FLASH_TEST_LENGTH;
151 flash_addr = flash_test_start;
153 if ((stat = flash_read(flash_addr, (void *)test_buf1, 0x200, &err_addr)) != FLASH_ERR_OK) {
154 diag_printf("FLASH: read[short]/verify after erase failed: %s\n", flash_errmsg(stat));
158 flash_addr = (cyg_uint8 *)flash_addr + 0x200;
160 lp1 = (cyg_uint32 *)test_buf1;
161 for (i = 0; i < 0x200; i += sizeof(cyg_uint32)) {
162 if (*lp1++ != 0xFFFFFFFF) {
163 diag_printf("FLASH: non-erased data found at offset %p\n",
164 (cyg_uint8 *)flash_addr + (CYG_ADDRWORD)((lp1-1) - test_buf1));
165 diag_dump_buf((void *)(lp1-1), 32);
174 CYG_TEST_INFO("FLASH erase failed");
178 // Simple write/verify test
179 diag_printf("... Write/verify test\n");
180 lp1 = (cyg_uint32 *)test_buf1;
181 for (i = 0; i < CYGNUM_IO_FLASH_TEST_LENGTH; i += sizeof(cyg_uint32)) {
182 *lp1 = (cyg_uint32)lp1;
186 if (ok && (stat = flash_program(flash_test_start, (void *)test_buf1,
187 CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != FLASH_ERR_OK) {
188 diag_printf("FLASH: write failed: %s\n", flash_errmsg(stat));
191 if (ok && (stat = flash_read(flash_test_start, (void *)test_buf2,
192 CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != FLASH_ERR_OK) {
193 diag_printf("FLASH: read/verify after write failed: %s\n", flash_errmsg(stat));
196 lp1 = (cyg_uint32 *)test_buf1;
197 lp2 = (cyg_uint32 *)test_buf2;
198 for (i = 0; i < CYGNUM_IO_FLASH_TEST_LENGTH; i += sizeof(cyg_uint32)) {
199 if (*lp2++ != *lp1++) {
200 diag_printf("FLASH: incorrect data found at offset %x\n", (CYG_ADDRWORD)(lp2-1) - test_buf2);
201 diag_dump_buf((void *)(lp2-1), 32);
206 // Try reading in little pieces
207 len = CYGNUM_IO_FLASH_TEST_LENGTH;
208 flash_addr = flash_test_start;
209 lp1 = (cyg_uint32 *)test_buf1;
210 lp2 = (cyg_uint32 *)test_buf2;
212 if ((stat = flash_read(flash_addr, lp2, 0x200, &err_addr)) != FLASH_ERR_OK) {
213 diag_printf("FLASH: read[short]/verify after erase failed: %s\n", flash_errmsg(stat));
217 flash_addr = (cyg_uint8 *)flash_addr + 0x200;
219 for (i = 0; i < 0x200; i += sizeof(cyg_uint32)) {
220 if (*lp2++ != *lp1++) {
221 diag_printf("FLASH: incorrect data found at offset %p\n",
222 (cyg_uint8 *)flash_addr + (CYG_ADDRWORD)((lp2-1) - test_buf2));
223 diag_dump_buf((void *)(lp2-1), 32);
232 CYG_TEST_INFO("FLASH write/verify failed");
236 CYG_TEST_PASS_FINISH("FLASH test1");
238 CYG_TEST_FAIL_FINISH("FLASH test1");