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