1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/flash.h>
9 #include <zephyr/logging/log_ctrl.h>
10 #include <zephyr/pm/device.h>
11
12 /* Set to 1 to test the chip erase functionality. Please be aware that this
13 * operation takes quite a while (it depends on the chip size, but can easily
14 * take tens of seconds).
15 * Note - erasing of the test region or whole chip is performed only when
16 * CONFIG_SPI_FLASH_AT45_USE_READ_MODIFY_WRITE is not enabled.
17 */
18 #define ERASE_WHOLE_CHIP 0
19
20 #define TEST_REGION_OFFSET 0xFE00
21 #define TEST_REGION_SIZE 0x400
22
23 static uint8_t write_buf[TEST_REGION_SIZE];
24 static uint8_t read_buf[TEST_REGION_SIZE];
25
main(void)26 int main(void)
27 {
28 printk("DataFlash sample on %s\n", CONFIG_BOARD);
29
30 const struct device *const flash_dev = DEVICE_DT_GET_ONE(atmel_at45);
31 int i;
32 int err;
33 uint8_t data;
34 #ifdef CONFIG_FLASH_PAGE_LAYOUT
35 struct flash_pages_info pages_info;
36 size_t page_count, chip_size;
37 #endif
38
39 if (!device_is_ready(flash_dev)) {
40 printk("%s: device not ready.\n", flash_dev->name);
41 return 0;
42 }
43
44 #ifdef CONFIG_FLASH_PAGE_LAYOUT
45 page_count = flash_get_page_count(flash_dev);
46 (void)flash_get_page_info_by_idx(flash_dev, 0, &pages_info);
47 chip_size = page_count * pages_info.size;
48 printk("Using %s, chip size: %u bytes (page: %u)\n",
49 flash_dev->name, chip_size, pages_info.size);
50 #endif
51
52 printk("Reading the first byte of the test region ... ");
53 err = flash_read(flash_dev, TEST_REGION_OFFSET, &data, 1);
54 if (err != 0) {
55 printk("FAILED\n");
56 return 0;
57 }
58
59 printk("OK\n");
60
61 ++data;
62 printk("Preparing test content starting with 0x%02X.\n", data);
63 for (i = 0; i < TEST_REGION_SIZE; ++i) {
64 write_buf[i] = (uint8_t)(data + i);
65 }
66
67 #ifndef CONFIG_SPI_FLASH_AT45_USE_READ_MODIFY_WRITE
68 if (ERASE_WHOLE_CHIP) {
69 #ifdef CONFIG_FLASH_PAGE_LAYOUT
70 printk("Erasing the whole chip... ");
71 err = flash_erase(flash_dev, 0, chip_size);
72 #else
73 #error To full chip erase you need enable flash page layout
74 #endif
75 } else {
76 printk("Erasing the test region... ");
77 err = flash_erase(flash_dev,
78 TEST_REGION_OFFSET, TEST_REGION_SIZE);
79 }
80
81 if (err != 0) {
82 printk("FAILED\n");
83 return 0;
84 }
85
86 printk("OK\n");
87
88 printk("Checking if the test region is erased... ");
89 err = flash_read(flash_dev, TEST_REGION_OFFSET,
90 read_buf, TEST_REGION_SIZE);
91 if (err != 0) {
92 printk("FAILED\n");
93 return 0;
94 }
95
96 for (i = 0; i < TEST_REGION_SIZE; ++i) {
97 if (read_buf[i] != 0xFF) {
98 printk("\nERROR at read_buf[%d]: "
99 "expected 0x%02X, got 0x%02X\n",
100 i, 0xFF, read_buf[i]);
101 return 0;
102 }
103 }
104
105 printk("OK\n");
106 #endif /* !CONFIG_SPI_FLASH_AT45_USE_READ_MODIFY_WRITE */
107
108 printk("Writing the first half of the test region... ");
109 err = flash_write(flash_dev, TEST_REGION_OFFSET,
110 write_buf, TEST_REGION_SIZE/2);
111 if (err != 0) {
112 printk("FAILED\n");
113 return 0;
114 }
115
116 printk("OK\n");
117
118 printk("Writing the second half of the test region... ");
119 err = flash_write(flash_dev, TEST_REGION_OFFSET + TEST_REGION_SIZE/2,
120 &write_buf[TEST_REGION_SIZE/2], TEST_REGION_SIZE/2);
121 if (err != 0) {
122 printk("FAILED\n");
123 return 0;
124 }
125
126 printk("OK\n");
127
128 printk("Reading the whole test region... ");
129 err = flash_read(flash_dev, TEST_REGION_OFFSET,
130 read_buf, TEST_REGION_SIZE);
131 if (err != 0) {
132 printk("FAILED\n");
133 return 0;
134 }
135
136 printk("OK\n");
137
138 printk("Checking the read content... ");
139 for (i = 0; i < TEST_REGION_SIZE; ++i) {
140 if (read_buf[i] != write_buf[i]) {
141 printk("\nERROR at read_buf[%d]: "
142 "expected 0x%02X, got 0x%02X\n",
143 i, write_buf[i], read_buf[i]);
144 return 0;
145 }
146 }
147
148 printk("OK\n");
149
150 #if defined(CONFIG_PM_DEVICE)
151 printk("Putting the flash device into suspended state... ");
152 err = pm_device_action_run(flash_dev, PM_DEVICE_ACTION_SUSPEND);
153 if (err != 0) {
154 printk("FAILED\n");
155 return 0;
156 }
157
158 printk("OK\n");
159 #endif
160
161 k_sleep(K_FOREVER);
162 return 0;
163 }
164