1 /*
2 * Copyright (c) 2016 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/flash.h>
9 #include <zephyr/device.h>
10 #include <zephyr/devicetree.h>
11 #include <stdio.h>
12 #include <string.h>
13
14 #if defined(CONFIG_BOARD_ADAFRUIT_FEATHER_STM32F405)
15 #define SPI_FLASH_TEST_REGION_OFFSET 0xf000
16 #elif defined(CONFIG_BOARD_ARTY_A7_DESIGNSTART_FPGA_CORTEX_M1) || \
17 defined(CONFIG_BOARD_ARTY_A7_DESIGNSTART_FPGA_CORTEX_M3)
18 /* The FPGA bitstream is stored in the lower 536 sectors of the flash. */
19 #define SPI_FLASH_TEST_REGION_OFFSET \
20 DT_REG_SIZE(DT_NODE_BY_FIXED_PARTITION_LABEL(fpga_bitstream))
21 #elif defined(CONFIG_BOARD_NPCX9M6F_EVB) || \
22 defined(CONFIG_BOARD_NPCX7M6FB_EVB)
23 #define SPI_FLASH_TEST_REGION_OFFSET 0x7F000
24 #elif defined(CONFIG_BOARD_EK_RA8M1) || defined(CONFIG_BOARD_EK_RA8D1)
25 #define SPI_FLASH_TEST_REGION_OFFSET 0x40000
26 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_qspi_nor) && DT_PROP(DT_NODELABEL(quadspi), dual_flash)
27 #define SPI_FLASH_TEST_REGION_OFFSET 0xfe000
28 #else
29 #define SPI_FLASH_TEST_REGION_OFFSET 0xff000
30 #endif
31 #if defined(CONFIG_BOARD_EK_RA8M1) || defined(CONFIG_BOARD_EK_RA8D1)
32 #define SPI_FLASH_SECTOR_SIZE 262144
33 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_qspi_nor) && DT_PROP(DT_NODELABEL(quadspi), dual_flash)
34 #define SPI_FLASH_SECTOR_SIZE 8192
35 #else
36 #define SPI_FLASH_SECTOR_SIZE 4096
37 #endif
38
39 #if defined(CONFIG_FLASH_STM32_OSPI) || defined(CONFIG_FLASH_STM32_QSPI) || \
40 defined(CONFIG_FLASH_STM32_XSPI) || defined(CONFIG_FLASH_RENESAS_RA_OSPI_B)
41
42 #define SPI_FLASH_MULTI_SECTOR_TEST
43 #endif
44
45 #if DT_HAS_COMPAT_STATUS_OKAY(jedec_spi_nor)
46 #define SPI_FLASH_COMPAT jedec_spi_nor
47 #elif DT_HAS_COMPAT_STATUS_OKAY(jedec_mspi_nor)
48 #define SPI_FLASH_COMPAT jedec_mspi_nor
49 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_qspi_nor)
50 #define SPI_FLASH_COMPAT st_stm32_qspi_nor
51 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_ospi_nor)
52 #define SPI_FLASH_COMPAT st_stm32_ospi_nor
53 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_xspi_nor)
54 #define SPI_FLASH_COMPAT st_stm32_xspi_nor
55 #elif DT_HAS_COMPAT_STATUS_OKAY(nordic_qspi_nor)
56 #define SPI_FLASH_COMPAT nordic_qspi_nor
57 #elif DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_ospi_b_nor)
58 #define SPI_FLASH_COMPAT renesas_ra_ospi_b_nor
59 #else
60 #define SPI_FLASH_COMPAT invalid
61 #endif
62
63 #if defined(CONFIG_FLASH_RENESAS_RA_OSPI_B)
64 const uint8_t erased[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
65 #else
66 const uint8_t erased[] = { 0xff, 0xff, 0xff, 0xff };
67 #endif
68
single_sector_test(const struct device * flash_dev)69 void single_sector_test(const struct device *flash_dev)
70 {
71 #if defined(CONFIG_FLASH_RENESAS_RA_OSPI_B)
72 const uint8_t expected[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
73 #else
74 const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 };
75 #endif
76 const size_t len = sizeof(expected);
77 uint8_t buf[sizeof(expected)];
78 int rc;
79
80 printf("\nPerform test on single sector");
81 /* Write protection needs to be disabled before each write or
82 * erase, since the flash component turns on write protection
83 * automatically after completion of write and erase
84 * operations.
85 */
86 printf("\nTest 1: Flash erase\n");
87
88 /* Full flash erase if SPI_FLASH_TEST_REGION_OFFSET = 0 and
89 * SPI_FLASH_SECTOR_SIZE = flash size
90 */
91 rc = flash_erase(flash_dev, SPI_FLASH_TEST_REGION_OFFSET,
92 SPI_FLASH_SECTOR_SIZE);
93 if (rc != 0) {
94 printf("Flash erase failed! %d\n", rc);
95 } else {
96 /* Check erased pattern */
97 memset(buf, 0, len);
98 rc = flash_read(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, buf, len);
99 if (rc != 0) {
100 printf("Flash read failed! %d\n", rc);
101 return;
102 }
103 if (memcmp(erased, buf, len) != 0) {
104 printf("Flash erase failed at offset 0x%x got 0x%x\n",
105 SPI_FLASH_TEST_REGION_OFFSET, *(uint32_t *)buf);
106 return;
107 }
108 printf("Flash erase succeeded!\n");
109 }
110 printf("\nTest 2: Flash write\n");
111
112 printf("Attempting to write %zu bytes\n", len);
113 rc = flash_write(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, expected, len);
114 if (rc != 0) {
115 printf("Flash write failed! %d\n", rc);
116 return;
117 }
118
119 memset(buf, 0, len);
120 rc = flash_read(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, buf, len);
121 if (rc != 0) {
122 printf("Flash read failed! %d\n", rc);
123 return;
124 }
125
126 if (memcmp(expected, buf, len) == 0) {
127 printf("Data read matches data written. Good!!\n");
128 } else {
129 const uint8_t *wp = expected;
130 const uint8_t *rp = buf;
131 const uint8_t *rpe = rp + len;
132
133 printf("Data read does not match data written!!\n");
134 while (rp < rpe) {
135 printf("%08x wrote %02x read %02x %s\n",
136 (uint32_t)(SPI_FLASH_TEST_REGION_OFFSET + (rp - buf)),
137 *wp, *rp, (*rp == *wp) ? "match" : "MISMATCH");
138 ++rp;
139 ++wp;
140 }
141 }
142 }
143
144 #if defined SPI_FLASH_MULTI_SECTOR_TEST
multi_sector_test(const struct device * flash_dev)145 void multi_sector_test(const struct device *flash_dev)
146 {
147 #if defined(CONFIG_FLASH_RENESAS_RA_OSPI_B)
148 const uint8_t expected[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
149 #else
150 const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 };
151 #endif
152 const size_t len = sizeof(expected);
153 uint8_t buf[sizeof(expected)];
154 int rc;
155
156 printf("\nPerform test on multiple consecutive sectors");
157
158 /* Write protection needs to be disabled before each write or
159 * erase, since the flash component turns on write protection
160 * automatically after completion of write and erase
161 * operations.
162 */
163 printf("\nTest 1: Flash erase\n");
164
165 /* Full flash erase if SPI_FLASH_TEST_REGION_OFFSET = 0 and
166 * SPI_FLASH_SECTOR_SIZE = flash size
167 * Erase 2 sectors for check for erase of consequtive sectors
168 */
169 rc = flash_erase(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, SPI_FLASH_SECTOR_SIZE * 2);
170 if (rc != 0) {
171 printf("Flash erase failed! %d\n", rc);
172 } else {
173 /* Read the content and check for erased */
174 memset(buf, 0, len);
175 size_t offs = SPI_FLASH_TEST_REGION_OFFSET;
176
177 while (offs < SPI_FLASH_TEST_REGION_OFFSET + 2 * SPI_FLASH_SECTOR_SIZE) {
178 rc = flash_read(flash_dev, offs, buf, len);
179 if (rc != 0) {
180 printf("Flash read failed! %d\n", rc);
181 return;
182 }
183 if (memcmp(erased, buf, len) != 0) {
184 printf("Flash erase failed at offset 0x%x got 0x%x\n",
185 offs, *(uint32_t *)buf);
186 return;
187 }
188 offs += SPI_FLASH_SECTOR_SIZE;
189 }
190 printf("Flash erase succeeded!\n");
191 }
192
193 printf("\nTest 2: Flash write\n");
194
195 size_t offs = SPI_FLASH_TEST_REGION_OFFSET;
196
197 while (offs < SPI_FLASH_TEST_REGION_OFFSET + 2 * SPI_FLASH_SECTOR_SIZE) {
198 printf("Attempting to write %zu bytes at offset 0x%x\n", len, offs);
199 rc = flash_write(flash_dev, offs, expected, len);
200 if (rc != 0) {
201 printf("Flash write failed! %d\n", rc);
202 return;
203 }
204
205 memset(buf, 0, len);
206 rc = flash_read(flash_dev, offs, buf, len);
207 if (rc != 0) {
208 printf("Flash read failed! %d\n", rc);
209 return;
210 }
211
212 if (memcmp(expected, buf, len) == 0) {
213 printf("Data read matches data written. Good!!\n");
214 } else {
215 const uint8_t *wp = expected;
216 const uint8_t *rp = buf;
217 const uint8_t *rpe = rp + len;
218
219 printf("Data read does not match data written!!\n");
220 while (rp < rpe) {
221 printf("%08x wrote %02x read %02x %s\n",
222 (uint32_t)(offs + (rp - buf)),
223 *wp, *rp, (*rp == *wp) ? "match" : "MISMATCH");
224 ++rp;
225 ++wp;
226 }
227 }
228 offs += SPI_FLASH_SECTOR_SIZE;
229 }
230 }
231 #endif
232
main(void)233 int main(void)
234 {
235 const struct device *flash_dev = DEVICE_DT_GET_ONE(SPI_FLASH_COMPAT);
236
237 if (!device_is_ready(flash_dev)) {
238 printk("%s: device not ready.\n", flash_dev->name);
239 return 0;
240 }
241
242 printf("\n%s SPI flash testing\n", flash_dev->name);
243 printf("==========================\n");
244
245 single_sector_test(flash_dev);
246 #if defined SPI_FLASH_MULTI_SECTOR_TEST
247 multi_sector_test(flash_dev);
248 #endif
249 return 0;
250 }
251