1 /*
2  * Copyright (c) 2022 Microchip Technology Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <soc.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/device.h>
13 #include <zephyr/drivers/spi.h>
14 
15 #define W25Q128_JEDEC_ID				0x001840efU
16 #define W25Q128JV_JEDEC_ID				0x001870efU
17 #define SST26VF016B_JEDEC_ID				0x004126bfU
18 #define SPI_FLASH_JEDEC_ID_MSK				0x00ffffffu
19 
20 #define SPI_FLASH_READ_JEDEC_ID_OPCODE			0x9fu
21 
22 #define SPI_FLASH_READ_STATUS1_OPCODE			0x05u
23 #define SPI_FLASH_READ_STATUS2_OPCODE			0x35u
24 #define SPI_FLASH_READ_STATUS3_OPCODE			0x15u
25 
26 #define SPI_FLASH_WRITE_STATUS1_OPCODE			0x01u
27 #define SPI_FLASH_WRITE_STATUS2_OPCODE			0x31u
28 #define SPI_FLASH_WRITE_STATUS3_OPCODE			0x11u
29 
30 #define SPI_FLASH_WRITE_ENABLE_OPCODE			0x06u
31 #define SPI_FLASH_WRITE_DISABLE_OPCODE			0x04u
32 #define SPI_FLASH_WRITE_ENABLE_VOLATILE_STS_OPCODE	0x50u
33 
34 #define SPI_FLASH_READ_SFDP_CMD				0x5au
35 
36 #define SPI_FLASH_READ_SLOW_OPCODE			0x03u
37 #define SPI_FLASH_READ_FAST_OPCODE			0x0bu
38 #define SPI_FLASH_READ_DUAL_OPCODE			0x3bu
39 #define SPI_FLASH_READ_QUAD_OPCODE			0x6bu
40 
41 #define SPI_FLASH_ERASE_SECTOR_OPCODE			0x20u
42 #define SPI_FLASH_ERASE_BLOCK1_OPCODE			0x52u
43 #define SPI_FLASH_ERASE_BLOCK2_OPCODE			0xd8u
44 #define SPI_FLASH_ERASE_CHIP_OPCODE			0xc7u
45 
46 #define SPI_FLASH_PAGE_PROG_OPCODE			0x02u
47 
48 #define SPI_FLASH_PAGE_SIZE		256
49 #define SPI_FLASH_SECTOR_SIZE		4096
50 #define SPI_FLASH_BLOCK1_SIZE		(32 * 1024)
51 #define SPI_FLASH_BLOCK2_SIZE		(64 * 1024)
52 
53 #define SPI_FLASH_STATUS1_BUSY_POS	0
54 #define SPI_FLASH_STATUS1_WEL_POS	1
55 
56 #define SPI_FLASH_STATUS2_SRL_POS	0
57 #define SPI_FLASH_STATUS2_QE_POS	1
58 #define SPI_FLASH_STATUS2_SUS_STS_POS	7
59 
60 #define SPI0_NODE			DT_NODELABEL(spi0)
61 
62 struct spi_address {
63 	uint32_t addr;
64 	uint8_t byte_len;
65 };
66 
67 enum spi_flash_read_cmd {
68 	CMD_SPI_FLASH_READ_SLOW = 0,
69 	CMD_SPI_FLASH_READ_FAST,
70 	CMD_SPI_FLASH_READ_DUAL,
71 	CMD_SPI_FLASH_READ_QUAD,
72 	CMD_SPI_FLASH_READ_MAX
73 };
74 
75 static const struct device *spi_dev = DEVICE_DT_GET(SPI0_NODE);
76 
77 static struct spi_config spi_cfg;
78 #ifdef CONFIG_SPI_EXTENDED_MODES
79 static struct spi_config spi_cfg_dual;
80 static struct spi_config spi_cfg_quad;
81 #endif
82 
83 static uint32_t jedec_id;
84 
85 #define SPI_TEST_BUF1_SIZE 256
86 
87 static uint8_t buf1[SPI_TEST_BUF1_SIZE];
88 
89 #define SPI_TEST_ADDR1 0xc10000u
90 
91 #define SPI_FILL_VAL 0x69u
92 #define SPI_TEST_BUFFER_SIZE (36 * 1024)
93 
94 struct test_buf {
95 	union {
96 		uint32_t w[(SPI_TEST_BUFFER_SIZE) / 4];
97 		uint16_t h[(SPI_TEST_BUFFER_SIZE) / 2];
98 		uint8_t b[(SPI_TEST_BUFFER_SIZE)];
99 	};
100 };
101 
102 static struct test_buf tb1;
103 
is_data_buf_filled_with(uint8_t * data,size_t datasz,uint8_t val)104 static bool is_data_buf_filled_with(uint8_t *data, size_t datasz, uint8_t val)
105 {
106 	if (!data || !datasz) {
107 		return false;
108 	}
109 
110 	for (size_t i = 0; i < datasz; i++) {
111 		if (data[i] != val) {
112 			return false;
113 		}
114 	}
115 
116 	return true;
117 }
118 
spi_flash_format_addr(uint32_t spi_addr,size_t addrsz,uint8_t * buf,size_t bufsz)119 static int spi_flash_format_addr(uint32_t spi_addr, size_t addrsz, uint8_t *buf, size_t bufsz)
120 {
121 	if (!buf || (addrsz > 4) || (bufsz < addrsz)) {
122 		return -EINVAL;
123 	}
124 
125 	for (size_t i = 0; i < addrsz; i++) {
126 		buf[i] = spi_addr >> ((addrsz - i - 1u) * 8);
127 	}
128 
129 	return 0;
130 }
131 
spi_flash_read_status(const struct device * dev,struct spi_config * spi_cfg,uint8_t read_status_opcode,uint8_t * status)132 static int spi_flash_read_status(const struct device *dev, struct spi_config *spi_cfg,
133 				 uint8_t read_status_opcode, uint8_t *status)
134 {
135 	struct spi_buf spi_buffers[2];
136 	uint32_t cmdbuf;
137 	int err;
138 
139 	if (!dev || !spi_cfg || !status) {
140 		return -EINVAL;
141 	}
142 
143 	cmdbuf = read_status_opcode;
144 	spi_buffers[0].buf = &cmdbuf;
145 	spi_buffers[0].len = 1;
146 	spi_buffers[1].buf = status;
147 	spi_buffers[1].len = 1;
148 
149 	const struct spi_buf_set tx_bufs = {
150 		.buffers = spi_buffers,
151 		.count = 2,
152 	};
153 
154 	const struct spi_buf_set rx_bufs = {
155 		.buffers = spi_buffers,
156 		.count = 2,
157 	};
158 
159 	err = spi_transceive(dev, spi_cfg, &tx_bufs, &rx_bufs);
160 
161 	return err;
162 }
163 
spi_poll_busy(const struct device * dev,struct spi_config * spi_cfg,uint32_t timeout_ms)164 static int spi_poll_busy(const struct device *dev, struct spi_config *spi_cfg, uint32_t timeout_ms)
165 {
166 	int err = 0;
167 	uint32_t ms = 0;
168 	uint8_t spi_status = 0;
169 
170 	if (!dev || !spi_cfg) {
171 		return -EINVAL;
172 	}
173 
174 	spi_status = 0xffu;
175 	while (timeout_ms) {
176 		k_busy_wait(2);
177 		ms += 2u;
178 		spi_status = 0xffu;
179 		err = spi_flash_read_status(spi_dev, spi_cfg, SPI_FLASH_READ_STATUS1_OPCODE,
180 					    &spi_status);
181 		if (err) {
182 			return err;
183 		}
184 
185 		if ((spi_status & BIT(SPI_FLASH_STATUS1_BUSY_POS)) == 0) {
186 			return 0;
187 		}
188 		if (ms > 1000) {
189 			timeout_ms--;
190 		}
191 	}
192 
193 	return -ETIMEDOUT;
194 }
195 
196 /* SPI flash full-duplex write of command opcode, optional command parameters, and optional data */
spi_flash_fd_wr_cpd(const struct device * dev,struct spi_config * spi_cfg,uint8_t cmd,uint8_t * cmdparams,size_t cmdparamsz,uint8_t * data,size_t datasz)197 static int spi_flash_fd_wr_cpd(const struct device *dev, struct spi_config *spi_cfg, uint8_t cmd,
198 			       uint8_t *cmdparams, size_t cmdparamsz, uint8_t *data, size_t datasz)
199 {
200 	struct spi_buf tx_spi_buffers[3];
201 	int bufidx = 0, err = 0;
202 	uint8_t spicmd;
203 
204 	if (!dev || !spi_cfg || (!cmdparams && cmdparamsz) || (!data && datasz)) {
205 		return -EINVAL;
206 	}
207 
208 	spicmd = cmd;
209 	tx_spi_buffers[bufidx].buf = &spicmd;
210 	tx_spi_buffers[bufidx++].len = 1;
211 	if (cmdparams && cmdparamsz) {
212 		tx_spi_buffers[bufidx].buf = cmdparams;
213 		tx_spi_buffers[bufidx++].len = cmdparamsz;
214 	}
215 	if (data && datasz) {
216 		tx_spi_buffers[bufidx].buf = data;
217 		tx_spi_buffers[bufidx++].len = datasz;
218 	}
219 
220 	const struct spi_buf_set tx_bufs = {
221 		.buffers = tx_spi_buffers,
222 		.count = bufidx,
223 	};
224 
225 	err = spi_transceive(dev, spi_cfg, &tx_bufs, NULL);
226 
227 	return err;
228 }
229 
spi_flash_read_fd_sync(const struct device * dev,struct spi_config * spi_cfg,struct spi_address * spi_addr,uint8_t * data,size_t datasz,uint8_t opcode)230 static int spi_flash_read_fd_sync(const struct device *dev, struct spi_config *spi_cfg,
231 				  struct spi_address *spi_addr, uint8_t *data, size_t datasz,
232 				  uint8_t opcode)
233 {
234 	uint8_t txdata[8] = {0};
235 	struct spi_buf spi_bufs[3] = {0};
236 	int cnt = 0, err = 0;
237 	size_t param_len = 0;
238 
239 	if (!dev || !spi_cfg || !data || !datasz) {
240 		return -EINVAL;
241 	}
242 
243 	txdata[0] = opcode;
244 	if (spi_addr) {
245 		if (spi_addr->byte_len > 4) {
246 			return -EINVAL;
247 		}
248 		err = spi_flash_format_addr(spi_addr->addr, spi_addr->byte_len,
249 					    &txdata[1], sizeof(txdata)-1);
250 		if (err) {
251 			return err;
252 		}
253 		param_len += spi_addr->byte_len;
254 	}
255 
256 	spi_bufs[cnt].buf = txdata;
257 	spi_bufs[cnt++].len = param_len + 1;
258 
259 	if (opcode == SPI_FLASH_READ_FAST_OPCODE) {
260 		spi_bufs[cnt].buf = NULL; /* 8 clocks with output tri-stated */
261 		spi_bufs[cnt++].len = 1;
262 	}
263 
264 	spi_bufs[cnt].buf = data;
265 	spi_bufs[cnt++].len = datasz;
266 
267 	const struct spi_buf_set txset = {
268 		.buffers = &spi_bufs[0],
269 		.count = cnt,
270 	};
271 	const struct spi_buf_set rxset = {
272 		.buffers = &spi_bufs[0],
273 		.count = cnt,
274 	};
275 
276 	err = spi_transceive(dev, spi_cfg, &txset, &rxset);
277 	if (err) {
278 		return err;
279 	}
280 
281 	return 0;
282 }
283 
284 /* Dual or Quad read */
spi_flash_read_hd_sync(const struct device * dev,struct spi_config * spi_cfg_cmd,struct spi_config * spi_cfg_data,struct spi_address * spi_addr,uint8_t * data,size_t datasz,uint8_t opcode)285 static int spi_flash_read_hd_sync(const struct device *dev, struct spi_config *spi_cfg_cmd,
286 				  struct spi_config *spi_cfg_data, struct spi_address *spi_addr,
287 				  uint8_t *data, size_t datasz, uint8_t opcode)
288 {
289 	uint8_t txdata[8] = {0};
290 	struct spi_buf spi_bufs[3] = {0};
291 	int err = 0;
292 
293 	if (!dev || !spi_cfg_cmd || !spi_cfg_data || !data || !datasz
294 	    || !spi_addr || (spi_addr->byte_len > 4)) {
295 		return -EINVAL;
296 	}
297 
298 	txdata[0] = opcode;
299 	err = spi_flash_format_addr(spi_addr->addr, spi_addr->byte_len,
300 				    &txdata[1], sizeof(txdata)-1);
301 	if (err) {
302 		return err;
303 	}
304 
305 	spi_bufs[0].buf = txdata;
306 	spi_bufs[0].len = spi_addr->byte_len + 1;
307 	spi_bufs[1].buf = NULL;
308 	spi_bufs[1].len = 1u;
309 	spi_bufs[2].buf = data;
310 	spi_bufs[2].len = datasz;
311 
312 	const struct spi_buf_set txset = {
313 		.buffers = &spi_bufs[0],
314 		.count = 2,
315 	};
316 	const struct spi_buf_set rxset = {
317 		.buffers = &spi_bufs[2],
318 		.count = 1,
319 	};
320 
321 	spi_cfg_cmd->operation |= SPI_HOLD_ON_CS;
322 	err = spi_transceive(dev, spi_cfg_cmd, &txset, NULL);
323 	spi_cfg_cmd->operation &= ~SPI_HOLD_ON_CS;
324 	if (err) {
325 		return err;
326 	}
327 
328 	err = spi_transceive(dev, spi_cfg_data, NULL, &rxset);
329 
330 	return err;
331 }
332 
spi_flash_erase_region(const struct device * dev,struct spi_config * spi_cfg,uint8_t erase_opcode,struct spi_address * spi_addr,int timeout_ms)333 static int spi_flash_erase_region(const struct device *dev, struct spi_config *spi_cfg,
334 				  uint8_t erase_opcode, struct spi_address *spi_addr,
335 				  int timeout_ms)
336 {
337 	int err = 0;
338 	uint8_t cmdparams[4] = {0};
339 
340 	if (!dev || !spi_cfg || !spi_addr) {
341 		return -EINVAL;
342 	}
343 
344 	err = spi_flash_format_addr(spi_addr->addr, spi_addr->byte_len,
345 				    cmdparams, sizeof(cmdparams));
346 	if (err) {
347 		return err;
348 	}
349 
350 	err = spi_flash_fd_wr_cpd(dev, spi_cfg, erase_opcode, cmdparams,
351 				  spi_addr->byte_len, NULL, 0);
352 	if (err) {
353 		return err;
354 	}
355 
356 	err = spi_poll_busy(dev, spi_cfg, timeout_ms);
357 
358 	return err;
359 }
360 
361 #ifdef CONFIG_SPI_ASYNC
362 #define NUM_ASYNC_SPI_BUFS 8
363 
364 static volatile int spi_async_done;
365 static volatile int spi_async_status;
366 static volatile void *spi_async_userdata;
367 
368 static struct spi_buf_set txbs;
369 static struct spi_buf_set rxbs;
370 static struct spi_buf sb[NUM_ASYNC_SPI_BUFS];
371 static uint8_t spi_async_txbuf[8];
372 
spi_cb(const struct device * dev,int status,void * userdata)373 static void spi_cb(const struct device *dev, int status, void *userdata)
374 {
375 	spi_async_status = status;
376 	spi_async_userdata = userdata;
377 	spi_async_done = 1;
378 }
379 
spi_flash_read_fd_async(const struct device * dev,struct spi_config * spi_cfg,struct spi_address * spi_addr,uint8_t * data,size_t datasz,uint8_t opcode,spi_callback_t cb,void * userdata)380 static int spi_flash_read_fd_async(const struct device *dev, struct spi_config *spi_cfg,
381 				   struct spi_address *spi_addr, uint8_t *data, size_t datasz,
382 				   uint8_t opcode, spi_callback_t cb, void *userdata)
383 {
384 	int cnt = 0, err = 0;
385 	size_t param_len = 0;
386 
387 	if (!dev || !spi_cfg || !data || !datasz) {
388 		return -EINVAL;
389 	}
390 
391 	spi_async_txbuf[0] = opcode;
392 	if (spi_addr) {
393 		if (spi_addr->byte_len > 4) {
394 			return -EINVAL;
395 		}
396 		err = spi_flash_format_addr(spi_addr->addr, spi_addr->byte_len,
397 					    &spi_async_txbuf[1], sizeof(spi_async_txbuf)-1);
398 		if (err) {
399 			return err;
400 		}
401 		param_len += spi_addr->byte_len;
402 	}
403 
404 	sb[cnt].buf = spi_async_txbuf;
405 	sb[cnt++].len = param_len + 1;
406 
407 	if (opcode == SPI_FLASH_READ_FAST_OPCODE) {
408 		sb[cnt].buf = NULL; /* 8 clocks with output tri-stated */
409 		sb[cnt++].len = 1;
410 	}
411 
412 	sb[cnt].buf = data;
413 	sb[cnt++].len = datasz;
414 
415 	txbs.buffers = &sb[0];
416 	txbs.count = cnt;
417 
418 	rxbs.buffers = &sb[0];
419 	rxbs.count = cnt;
420 
421 	/* these parameters cannot be stack local to his function */
422 	err = spi_transceive_cb(dev, spi_cfg, &txbs, &rxbs, cb, userdata);
423 	if (err) {
424 		return err;
425 	}
426 
427 	return 0;
428 }
429 #endif
430 
main(void)431 int main(void)
432 {
433 	int err;
434 	uint32_t wait_count;
435 	size_t spi_len;
436 	struct spi_address spi_addr;
437 	uint8_t spi_status1, spi_status2;
438 	bool quad_enabled = false;
439 
440 	spi_cfg.frequency = MHZ(24);
441 	spi_cfg.operation = SPI_WORD_SET(8) | SPI_LINES_SINGLE;
442 #ifdef CONFIG_SPI_EXTENDED_MODES
443 	spi_cfg_dual.frequency = spi_cfg.frequency;
444 	spi_cfg_dual.operation = SPI_WORD_SET(8) | SPI_LINES_DUAL;
445 	spi_cfg_quad.frequency = spi_cfg.frequency;
446 	spi_cfg_quad.operation = SPI_WORD_SET(8) | SPI_LINES_QUAD;
447 #endif
448 	if (!device_is_ready(spi_dev)) {
449 		printf("SPI 0 device not ready!\n");
450 		return -1;
451 	}
452 
453 	memset(sb, 0, sizeof(sb));
454 	memset(buf1, 0, sizeof(buf1));
455 	memset((void *)&tb1, 0x55, sizeof(tb1));
456 
457 	jedec_id = 0;
458 	err = spi_flash_read_fd_sync(spi_dev, &spi_cfg, NULL, (uint8_t *)&jedec_id, 3u,
459 				     SPI_FLASH_READ_JEDEC_ID_OPCODE);
460 	if (err) {
461 		printf("Read JEDEC_ID error %d\n", err);
462 		return err;
463 	}
464 
465 	printf("JEDEC ID = 0x%08x\n", jedec_id);
466 	if (jedec_id == W25Q128_JEDEC_ID) {
467 		printf("W25Q128 16Mbyte SPI flash\n");
468 	} else if (jedec_id == W25Q128JV_JEDEC_ID) {
469 		printf("W25Q128JV 16Mbyte SPI flash\n");
470 	} else if (jedec_id == SST26VF016B_JEDEC_ID) {
471 		printf("SST26VF016B 16MByte SPI flash\n");
472 	} else {
473 		printf("Unknown SPI flash device\n");
474 		return -EIO;
475 	}
476 
477 	spi_status1 = 0xffu;
478 	err = spi_flash_read_status(spi_dev, &spi_cfg, SPI_FLASH_READ_STATUS1_OPCODE,
479 				    &spi_status1);
480 	if (err) {
481 		printf("Read SPI flash Status1 error: %d\n", err);
482 		return err;
483 	}
484 
485 	printf("SPI Flash Status1 = 0x%02x\n", spi_status1);
486 
487 	spi_status2 = 0xffu;
488 	err = spi_flash_read_status(spi_dev, &spi_cfg, SPI_FLASH_READ_STATUS2_OPCODE,
489 				    &spi_status2);
490 	if (err) {
491 		printf("Read SPI flash STATUS2 error: %d\n", err);
492 		return err;
493 	}
494 
495 	printf("SPI Flash Status2 = 0x%02x\n", spi_status2);
496 	if (spi_status2 & BIT(SPI_FLASH_STATUS2_QE_POS)) {
497 		quad_enabled = true;
498 		printf("Quad-Enable bit is set. WP# and HOLD# are IO[2] and IO[3]\n");
499 	}
500 	if (spi_status2 & BIT(SPI_FLASH_STATUS2_SRL_POS)) {
501 		printf("SPI Flash Status registers are locked!\n");
502 	}
503 	if (spi_status2 & BIT(SPI_FLASH_STATUS2_SUS_STS_POS)) {
504 		printf("SPI Flash is in Suspend state\n");
505 	}
506 
507 	spi_addr.addr = SPI_TEST_ADDR1;
508 	spi_addr.byte_len = 3u;
509 
510 	int num_sectors = 1u;
511 
512 	if (SPI_TEST_BUFFER_SIZE > SPI_FLASH_SECTOR_SIZE) {
513 		num_sectors = SPI_TEST_BUFFER_SIZE / SPI_FLASH_SECTOR_SIZE;
514 	}
515 
516 	for (int i = 0; i < num_sectors; i++) {
517 		printf("Transmit SPI flash Write-Enable\n");
518 		err = spi_flash_fd_wr_cpd(spi_dev, &spi_cfg, SPI_FLASH_WRITE_ENABLE_OPCODE,
519 					  NULL, 0, NULL, 0);
520 		if (err) {
521 			printf("ERROR: transmit SPI flash Write-Enable: error %d\n", err);
522 			return err;
523 		}
524 
525 		printf("Transmit Erase-Sector at 0x%08x\n", spi_addr.addr);
526 		err = spi_flash_erase_region(spi_dev, &spi_cfg, SPI_FLASH_ERASE_SECTOR_OPCODE,
527 					     &spi_addr, 1000u);
528 		if (err) {
529 			printf("SPI flash erase sector error %d\n", err);
530 			return err;
531 		}
532 
533 		spi_addr.addr += SPI_FLASH_SECTOR_SIZE;
534 	}
535 
536 	printf("\nRead and check erased sectors using Read 1-1-1-0\n");
537 
538 	spi_addr.addr = SPI_TEST_ADDR1;
539 	spi_addr.byte_len = 3u;
540 
541 	for (int i = 0; i < num_sectors; i++) {
542 		memset(&tb1.b[0], 0x55, SPI_FLASH_SECTOR_SIZE);
543 		err = spi_flash_read_fd_sync(spi_dev, &spi_cfg, &spi_addr, &tb1.b[0],
544 					     SPI_FLASH_SECTOR_SIZE, SPI_FLASH_READ_SLOW_OPCODE);
545 		if (err) {
546 			printf("Read slow error %d\n", err);
547 			return err;
548 		}
549 
550 		if (is_data_buf_filled_with(&tb1.b[0], SPI_FLASH_SECTOR_SIZE, 0xffu)) {
551 			printf("Sector at 0x%08x is erased\n", spi_addr.addr);
552 		} else {
553 			printf("FAIL: sector at 0x%08x is not erased\n", spi_addr.addr);
554 			return -1;
555 		}
556 
557 		spi_addr.addr += SPI_FLASH_SECTOR_SIZE;
558 	}
559 
560 
561 	printf("Fill buffers for %d sectors and program flash region\n", num_sectors);
562 
563 	for (int i = 0; i < SPI_TEST_BUFFER_SIZE; i++) {
564 		tb1.b[i] = SPI_FILL_VAL;
565 	}
566 
567 	printf("\nProgram erased sectors\n");
568 
569 	int num_pages = SPI_TEST_BUFFER_SIZE / SPI_FLASH_PAGE_SIZE;
570 	int offset = 0;
571 
572 	spi_addr.addr = SPI_TEST_ADDR1;
573 	spi_addr.byte_len = 3u;
574 
575 	for (int i = 0; i < num_pages; i++) {
576 		err = spi_flash_format_addr(spi_addr.addr, spi_addr.byte_len, buf1, sizeof(buf1));
577 		if (err) {
578 			printf("ERROR: format SPI address: %d\n", err);
579 			return err;
580 		}
581 
582 		printf("Page at 0x%08x: Transmit SPI flash Write-Enable, "
583 			"Page-Program, and poll status\n", spi_addr.addr);
584 		err = spi_flash_fd_wr_cpd(spi_dev, &spi_cfg, SPI_FLASH_WRITE_ENABLE_OPCODE,
585 					  NULL, 0, NULL, 0);
586 		if (err) {
587 			printf("ERROR: transmit SPI flash Write-Enable: %d\n", err);
588 			return err;
589 		}
590 
591 		err = spi_flash_fd_wr_cpd(spi_dev, &spi_cfg, SPI_FLASH_PAGE_PROG_OPCODE,
592 					  buf1, spi_addr.byte_len, &tb1.b[offset],
593 					  SPI_FLASH_PAGE_SIZE);
594 		if (err) {
595 			printf("ERROR: transmit SPI Page-Program: %d\n", err);
596 			return err;
597 		}
598 
599 		err = spi_poll_busy(spi_dev, &spi_cfg, 100);
600 		if (err) {
601 			printf("ERROR: Poll SPI busy status: %d\n", err);
602 			return err;
603 		}
604 
605 		spi_addr.addr += SPI_FLASH_PAGE_SIZE;
606 		offset += SPI_FLASH_PAGE_SIZE;
607 	}
608 
609 	/* Read and check if programmed */
610 	spi_addr.addr = SPI_TEST_ADDR1;
611 	spi_addr.byte_len = 3u;
612 	spi_len = num_pages * SPI_FLASH_PAGE_SIZE;
613 
614 	memset(&tb1.b[0], 0, sizeof(tb1));
615 	printf("Read %u bytes from 0x%08x using SPI Read 1-1-1-0\n", spi_len, spi_addr.addr);
616 	err = spi_flash_read_fd_sync(spi_dev, &spi_cfg, &spi_addr, &tb1.b[0], spi_len,
617 				     SPI_FLASH_READ_SLOW_OPCODE);
618 	if (err) {
619 		printf("Read slow error %d\n", err);
620 		return err;
621 	}
622 
623 	if (is_data_buf_filled_with(&tb1.b[0], spi_len, SPI_FILL_VAL)) {
624 		printf("Data matches\n");
625 	} else {
626 		printf("FAIL: data mismatch\n");
627 		return -1;
628 	}
629 
630 	memset(&tb1.b[0], 0, sizeof(tb1));
631 	printf("Read %u bytes from 0x%08x using SPI Read 1-1-1-8\n", spi_len, spi_addr.addr);
632 	err = spi_flash_read_fd_sync(spi_dev, &spi_cfg, &spi_addr, &tb1.b[0], spi_len,
633 				     SPI_FLASH_READ_FAST_OPCODE);
634 	if (err) {
635 		printf("Read fast error %d\n", err);
636 		return err;
637 	}
638 
639 	if (is_data_buf_filled_with(&tb1.b[0], spi_len, SPI_FILL_VAL)) {
640 		printf("Data matches\n");
641 	} else {
642 		printf("FAIL: data mismatch\n");
643 		return -1;
644 	}
645 
646 	memset(&tb1.b[0], 0, sizeof(tb1));
647 	printf("Read %u bytes from 0x%08x using SPI Read 1-1-2-8\n", spi_len, spi_addr.addr);
648 	err = spi_flash_read_hd_sync(spi_dev, &spi_cfg, &spi_cfg_dual, &spi_addr, &tb1.b[0],
649 				     spi_len, SPI_FLASH_READ_DUAL_OPCODE);
650 	if (err) {
651 		printf("Read dual error %d\n", err);
652 		return err;
653 	}
654 
655 	if (is_data_buf_filled_with(&tb1.b[0], spi_len, SPI_FILL_VAL)) {
656 		printf("Data matches\n");
657 	} else {
658 		printf("FAIL: data mismatch\n");
659 		return -1;
660 	}
661 
662 	memset(&tb1.b[0], 0, sizeof(tb1));
663 	printf("Read %u bytes from 0x%08x using SPI Read 1-1-4-8\n", spi_len, spi_addr.addr);
664 	err = spi_flash_read_hd_sync(spi_dev, &spi_cfg, &spi_cfg_quad, &spi_addr, &tb1.b[0],
665 				     spi_len, SPI_FLASH_READ_QUAD_OPCODE);
666 	if (err) {
667 		printf("Read quad error %d\n", err);
668 		return err;
669 	}
670 
671 	if (is_data_buf_filled_with(&tb1.b[0], spi_len, SPI_FILL_VAL)) {
672 		printf("Data matches\n");
673 	} else {
674 		printf("FAIL: data mismatch\n");
675 		return -1;
676 	}
677 
678 #ifdef CONFIG_SPI_ASYNC
679 	memset(&tb1.b[0], 0, sizeof(tb1));
680 
681 	spi_async_status = 0;
682 	spi_async_userdata = 0;
683 	spi_async_done = 0;
684 	wait_count = 0;
685 
686 	err = spi_flash_read_fd_async(spi_dev, &spi_cfg, &spi_addr, &tb1.b[0], spi_len,
687 				      SPI_FLASH_READ_FAST_OPCODE, spi_cb,
688 				      (void *)spi_async_userdata);
689 	if (err) {
690 		printf("ERROR: SPI async full-duplex error: %d\n", err);
691 		return err;
692 	}
693 
694 	while (spi_async_done == 0) {
695 		wait_count++;
696 	}
697 
698 	printf("SPI Async read done: wait count = %u\n", wait_count);
699 	printf("SPI Async done = %d\n", spi_async_done);
700 	printf("SPI Async status = %d\n", spi_async_status);
701 	printf("SPI Async userdata = %p\n", spi_async_userdata);
702 
703 	if (is_data_buf_filled_with(&tb1.b[0], spi_len, SPI_FILL_VAL)) {
704 		printf("Data matches\n");
705 	} else {
706 		printf("FAIL: data mismatch\n");
707 		return -1;
708 	}
709 #endif
710 
711 	printf("\nProgram End\n");
712 	return 0;
713 }
714