| LibDriver W25QXX 1.0.0 W25QXX full function driver

driver_w25qxx.c
Go to the documentation of this file.
1
37 #include "driver_w25qxx.h"
38
42 #define CHIP_NAME "Winbond W25QXX"
43 #define MANUFACTURER_NAME "Winbond"
44 #define SUPPLY_VOLTAGE_MIN 2.7f
45 #define SUPPLY_VOLTAGE_MAX 3.6f
46 #define MAX_CURRENT 25.0f
47 #define TEMPERATURE_MIN -40.0f
48 #define TEMPERATURE_MAX 85.0f
49 #define DRIVER_VERSION 1000
54 #define W25QXX_COMMAND_WRITE_ENABLE 0x06
55 #define W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE 0x50
56 #define W25QXX_COMMAND_WRITE_DISABLE 0x04
57 #define W25QXX_COMMAND_READ_STATUS_REG1 0x05
58 #define W25QXX_COMMAND_READ_STATUS_REG2 0x35
59 #define W25QXX_COMMAND_READ_STATUS_REG3 0x15
60 #define W25QXX_COMMAND_WRITE_STATUS_REG1 0x01
61 #define W25QXX_COMMAND_WRITE_STATUS_REG2 0x31
62 #define W25QXX_COMMAND_WRITE_STATUS_REG3 0x11
63 #define W25QXX_COMMAND_CHIP_ERASE 0xC7
64 #define W25QXX_COMMAND_ERASE_PROGRAM_SUSPEND 0x75
65 #define W25QXX_COMMAND_ERASE_PROGRAM_RESUME 0x7A
66 #define W25QXX_COMMAND_POWER_DOWN 0xB9
67 #define W25QXX_COMMAND_RELEASE_POWER_DOWN 0xAB
68 #define W25QXX_COMMAND_READ_MANUFACTURER 0x90
69 #define W25QXX_COMMAND_JEDEC_ID 0x9F
70 #define W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_LOCK 0x7E
71 #define W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_UNLOCK 0x98
72 #define W25QXX_COMMAND_ENTER_QSPI_MODE 0x38
73 #define W25QXX_COMMAND_ENABLE_RESET 0x66
74 #define W25QXX_COMMAND_RESET_DEVICE 0x99
75 #define W25QXX_COMMAND_READ_UNIQUE_ID 0x4B
76 #define W25QXX_COMMAND_PAGE_PROGRAM 0x02
77 #define W25QXX_COMMAND_QUAD_PAGE_PROGRAM 0x32
78 #define W25QXX_COMMAND_SECTOR_ERASE_4K 0x20
79 #define W25QXX_COMMAND_BLOCK_ERASE_32K 0x52
80 #define W25QXX_COMMAND_BLOCK_ERASE_64K 0xD8
81 #define W25QXX_COMMAND_READ_DATA 0x03
82 #define W25QXX_COMMAND_FAST_READ 0x0B
83 #define W25QXX_COMMAND_FAST_READ_DUAL_OUTPUT 0x3B
84 #define W25QXX_COMMAND_FAST_READ_QUAD_OUTPUT 0x6B
85 #define W25QXX_COMMAND_READ_SFDP_REGISTER 0x5A
86 #define W25QXX_COMMAND_ERASE_SECURITY_REGISTER 0x44
87 #define W25QXX_COMMAND_PROGRAM_SECURITY_REGISTER 0x42
88 #define W25QXX_COMMAND_READ_SECURITY_REGISTER 0x48
89 #define W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK 0x36
90 #define W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK 0x39
91 #define W25QXX_COMMAND_READ_BLOCK_LOCK 0x3D
92 #define W25QXX_COMMAND_FAST_READ_DUAL_IO 0xBB
93 #define W25QXX_COMMAND_DEVICE_ID_DUAL_IO 0x92
94 #define W25QXX_COMMAND_SET_BURST_WITH_WRAP 0x77
95 #define W25QXX_COMMAND_FAST_READ_QUAD_IO 0xEB
96 #define W25QXX_COMMAND_WORD_READ_QUAD_IO 0xE7
97 #define W25QXX_COMMAND_OCTAL_WORD_READ_QUAD_IO 0xE3
98 #define W25QXX_COMMAND_DEVICE_ID_QUAD_IO 0x94
112 static uint8_t a_w25qxx_spi_write_read(w25qxx_handle_t *handle, uint8_t *in_buf, uint32_t in_len, uint8_t *out_buf, uint32_t out_len)
113 {
114 if (handle->spi_qspi_write_read(0x00, 0x00, 0x00000000, 0x00, 0x00, /* write read data */
115 0x00000000, 0x00, 0x00,
116 0x00, in_buf, in_len, out_buf, out_len, 1) != 0)
117 {
118 return 1; /* return error */
119 }
120 else
121 {
122 return 0; /* success return 0 */
123 }
124 }
125
148 static uint8_t a_w25qxx_qspi_write_read(w25qxx_handle_t *handle, uint8_t instruction, uint8_t instruction_line,
149 uint32_t address, uint8_t address_line, uint8_t address_len,
150 uint32_t alternate, uint8_t alternate_line, uint8_t alternate_len,
151 uint8_t dummy, uint8_t *in_buf, uint32_t in_len,
152 uint8_t *out_buf, uint32_t out_len, uint8_t data_line)
153 {
154 if (handle->spi_qspi_write_read(instruction, instruction_line, address, address_line, address_len, /* write read data */
155 alternate, alternate_line, alternate_len,
156 dummy, in_buf, in_len, out_buf, out_len, data_line) != 0)
157 {
158 return 1; /* return error */
159 }
160 else
161 {
162 return 0; /* success return 0 */
163 }
164 }
165
175 uint8_t w25qxx_set_dual_quad_spi(w25qxx_handle_t *handle, w25qxx_bool_t enable)
176 {
177 if (handle == NULL) /* check handle */
178 {
179 return 2; /* return error */
180 }
181
182 handle->dual_quad_spi_enable = (uint8_t)enable; /* set enable */
183
184 return 0; /* success return 0 */
185 }
186
196 uint8_t w25qxx_get_dual_quad_spi(w25qxx_handle_t *handle, w25qxx_bool_t *enable)
197 {
198 if (handle == NULL) /* check handle */
199 {
200 return 2; /* return error */
201 }
202
203 *enable = (w25qxx_bool_t)(handle->dual_quad_spi_enable); /* get enable */
204
205 return 0; /* success return 0 */
206 }
207
217 uint8_t w25qxx_set_type(w25qxx_handle_t *handle, w25qxx_type_t type)
218 {
219 if (handle == NULL) /* check handle */
220 {
221 return 2; /* return error */
222 }
223
224 handle->type = (uint16_t)type; /* set type */
225
226 return 0; /* success return 0 */
227 }
228
238 uint8_t w25qxx_get_type(w25qxx_handle_t *handle, w25qxx_type_t *type)
239 {
240 if (handle == NULL) /* check handle */
241 {
242 return 2; /* return error */
243 }
244
245 *type = (w25qxx_type_t)(handle->type); /* get type */
246
247 return 0; /* success return 0 */
248 }
249
259 uint8_t w25qxx_set_interface(w25qxx_handle_t *handle, w25qxx_interface_t interface)
260 {
261 if (handle == NULL) /* check handle */
262 {
263 return 2; /* return error */
264 }
265
266 handle->spi_qspi = (uint8_t)interface; /* set interface */
267
268 return 0; /* success return 0 */
269 }
270
280 uint8_t w25qxx_get_interface(w25qxx_handle_t *handle, w25qxx_interface_t *interface)
281 {
282 if (handle == NULL) /* check handle */
283 {
284 return 2; /* return error */
285 }
286
287 *interface = (w25qxx_interface_t)(handle->spi_qspi); /* get interface */
288
289 return 0; /* success return 0 */
290 }
291
304 uint8_t w25qxx_set_address_mode(w25qxx_handle_t *handle, w25qxx_address_mode_t mode)
305 {
306 uint8_t res;
307 uint8_t buf[1];
308
309 if (handle == NULL) /* check handle */
310 {
311 return 2; /* return error */
312 }
313 if (handle->inited != 1) /* check handle initialization */
314 {
315 return 3; /* return error */
316 }
317 if (handle->type < W25Q256) /* check type */
318 {
319 handle->debug_print("w25qxx: current type can't use this function.\n"); /* current type can't use this function */
320
321 return 4; /* return error */
322 }
323
324 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
325 {
326 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
327 {
328 if (mode == W25QXX_ADDRESS_MODE_3_BYTE) /* address 3 mode byte */
329 {
330 buf[0] = 0xE9; /* 3 byte mode */
331 }
332 else /* address 4 mode byte */
333 {
334 buf[0] = 0xB7; /* 4 byte mode */
335 }
336 res = a_w25qxx_qspi_write_read(handle, buf[0], 1,
337 0x00000000, 0x00, 0x00,
338 0x00000000, 0x00, 0x00,
339 0x00, NULL, 0x00,
340 NULL, 0x00, 0x00); /* qspi write read */
341 if (res != 0) /* check result */
342 {
343 handle->debug_print("w25qxx: set address mode failed.\n"); /* set address mode failed */
344
345 return 1; /* return error */
346 }
347 }
348 else /* single spi */
349 {
350 if (mode == W25QXX_ADDRESS_MODE_3_BYTE) /* address 3 mode byte */
351 {
352 buf[0] = 0xE9; /* 3 byte mode */
353 }
354 else /* address 4 mode byte */
355 {
356 buf[0] = 0xB7; /* 4 byte mode */
357 }
358 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
359 if (res != 0) /* check result */
360 {
361 handle->debug_print("w25qxx: set address mode failed.\n"); /* set address mode failed */
362
363 return 1; /* return error */
364 }
365 }
366 }
367 else /* qspi interface */
368 {
369 if (mode == W25QXX_ADDRESS_MODE_3_BYTE) /* address 3 mode byte */
370 {
371 buf[0] = 0xE9; /* 3 byte mode */
372 }
373 else /* address 4 mode byte */
374 {
375 buf[0] = 0xB7; /* 4 byte mode */
376 }
377 res = a_w25qxx_qspi_write_read(handle, buf[0], 4,
378 0x00000000, 0x00, 0x00,
379 0x00000000, 0x00, 0x00,
380 0x00, NULL, 0x00,
381 NULL, 0x00, 0x00); /* qspi write read */
382 if (res != 0) /* check result */
383 {
384 handle->debug_print("w25qxx: set address mode failed.\n"); /* set address mode failed */
385
386 return 1; /* return error */
387 }
388 }
389
390 handle->address_mode = (uint8_t)mode; /* set address mode */
391
392 return 0; /* success return 0 */
393 }
394
405 uint8_t w25qxx_get_address_mode(w25qxx_handle_t *handle, w25qxx_address_mode_t *mode)
406 {
407 if (handle == NULL) /* check handle */
408 {
409 return 2; /* return error */
410 }
411 if (handle->inited != 1) /* check handle initialization */
412 {
413 return 3; /* return error */
414 }
415
416 *mode = (w25qxx_address_mode_t)(handle->address_mode); /* get address mode */
417
418 return 0; /* success return 0 */
419 }
420
431 uint8_t w25qxx_enable_write(w25qxx_handle_t *handle)
432 {
433 uint8_t res;
434 uint8_t buf[1];
435
436 if (handle == NULL) /* check handle */
437 {
438 return 2; /* return error */
439 }
440 if (handle->inited != 1) /* check handle initialization */
441 {
442 return 3; /* return error */
443 }
444
445 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
446 {
447 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
448 {
449 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
450 0x00000000, 0x00, 0x00,
451 0x00000000, 0x00, 0x00,
452 0x00, NULL, 0x00,
453 NULL, 0x00, 0x00); /* qspi write read */
454 if (res != 0) /* check result */
455 {
456 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
457
458 return 1; /* return error */
459 }
460 }
461 else /* single spi */
462 {
463 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
464 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
465 if (res != 0) /* check result */
466 {
467 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
468
469 return 1; /* return error */
470 }
471 }
472 }
473 else /* qspi interface */
474 {
475 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
476 0x00000000, 0x00, 0x00,
477 0x00000000, 0x00, 0x00,
478 0x00, NULL, 0x00,
479 NULL, 0x00, 0x00); /* qspi write read */
480 if (res != 0) /* check result */
481 {
482 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
483
484 return 1; /* return error */
485 }
486 }
487
488 return 0; /* success return 0 */
489 }
490
501 uint8_t w25qxx_enable_volatile_sr_write(w25qxx_handle_t *handle)
502 {
503 uint8_t res;
504 uint8_t buf[1];
505
506 if (handle == NULL) /* check handle */
507 {
508 return 2; /* return error */
509 }
510 if (handle->inited != 1) /* check handle initialization */
511 {
512 return 3; /* return error */
513 }
514
515 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
516 {
517 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
518 {
519 res = a_w25qxx_qspi_write_read(handle,
520 W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 1,
521 0x00000000, 0x00, 0x00,
522 0x00000000, 0x00, 0x00,
523 0x00, NULL, 0x00,
524 NULL, 0x00, 0x00); /* qspi write read */
525 if (res != 0) /* check result */
526 {
527 handle->debug_print("w25qxx: sr write enable failed.\n"); /* sr write enable failed */
528
529 return 1; /* return error */
530 }
531 }
532 else /* single spi */
533 {
534 buf[0] = W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE; /* sr write enable command */
535 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
536 if (res != 0) /* check result */
537 {
538 handle->debug_print("w25qxx: sr write enable failed.\n"); /* sr write enable failed */
539
540 return 1; /* return error */
541 }
542 }
543 }
544 else /* qspi interface */
545 {
546 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 4,
547 0x00000000, 0x00, 0x00,
548 0x00000000, 0x00, 0x00,
549 0x00, NULL, 0x00,
550 NULL, 0x00, 0x00); /* qspi write read */
551 if (res != 0) /* check result */
552 {
553 handle->debug_print("w25qxx: sr write enable failed.\n"); /* sr write enable failed */
554
555 return 1; /* return error */
556 }
557 }
558
559 return 0; /* success return 0 */
560 }
561
572 uint8_t w25qxx_disable_write(w25qxx_handle_t *handle)
573 {
574 uint8_t res;
575 uint8_t buf[1];
576
577 if (handle == NULL) /* check handle */
578 {
579 return 2; /* return error */
580 }
581 if (handle->inited != 1) /* check handle initialization */
582 {
583 return 3; /* return error */
584 }
585
586 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
587 {
588 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
589 {
590 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_DISABLE, 1,
591 0x00000000, 0x00, 0x00,
592 0x00000000, 0x00, 0x00,
593 0x00, NULL, 0x00,
594 NULL, 0x00, 0x00); /* qspi write read */
595 if (res != 0) /* check result */
596 {
597 handle->debug_print("w25qxx: write disable failed.\n"); /* write disable failed */
598
599 return 1; /* return error */
600 }
601 }
602 else /* single spi */
603 {
604 buf[0] = W25QXX_COMMAND_WRITE_DISABLE; /* write disable command */
605 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi qspi write read */
606 if (res != 0) /* check result */
607 {
608 handle->debug_print("w25qxx: write disable failed.\n"); /* write disable failed */
609
610 return 1; /* return error */
611 }
612 }
613 }
614 else /* qspi interface */
615 {
616 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_DISABLE, 4,
617 0x00000000, 0x00, 0x00,
618 0x00000000, 0x00, 0x00,
619 0x00, NULL, 0x00,
620 NULL, 0x00, 0x00); /* qspi write read */
621 if (res != 0) /* check result */
622 {
623 handle->debug_print("w25qxx: write disable failed.\n"); /* write disable failed */
624
625 return 1; /* return error */
626 }
627 }
628
629 return 0; /* success return 0 */
630 }
631
643 uint8_t w25qxx_get_status1(w25qxx_handle_t *handle, uint8_t *status)
644 {
645 uint8_t res;
646 uint8_t buf[1];
647
648 if (handle == NULL) /* check handle */
649 {
650 return 2; /* return error */
651 }
652 if (handle->inited != 1) /* check handle initialization */
653 {
654 return 3; /* return error */
655 }
656
657 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
658 {
659 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
660 {
661 res = a_w25qxx_qspi_write_read(handle,
662 W25QXX_COMMAND_READ_STATUS_REG1, 1,
663 0x00000000, 0x00, 0x00,
664 0x00000000, 0x00, 0x00,
665 0x00, NULL, 0x00,
666 status, 1, 1); /* qspi write read */
667 if (res != 0) /* check result */
668 {
669 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
670
671 return 1; /* return error */
672 }
673 }
674 else /* single spi */
675 {
676 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
677 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf,
678 1, status, 1); /* spi write read */
679 if (res != 0) /* check result */
680 {
681 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
682
683 return 1; /* return error */
684 }
685 }
686 }
687 else /* qspi interface */
688 {
689 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
690 0x00000000, 0x00, 0x00,
691 0x00000000, 0x00, 0x00,
692 0x00, NULL, 0x00,
693 status, 1, 4); /* qspi write read */
694 if (res != 0) /* check result */
695 {
696 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
697
698 return 1; /* return error */
699 }
700 }
701
702 return 0; /* success return 0 */
703 }
704
716 uint8_t w25qxx_get_status2(w25qxx_handle_t *handle, uint8_t *status)
717 {
718 uint8_t res;
719 uint8_t buf[1];
720
721 if (handle == NULL) /* check handle */
722 {
723 return 2; /* return error */
724 }
725 if (handle->inited != 1) /* check handle initialization */
726 {
727 return 3; /* return error */
728 }
729
730 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
731 {
732 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
733 {
734 res = a_w25qxx_qspi_write_read(handle,
735 W25QXX_COMMAND_READ_STATUS_REG2, 1,
736 0x00000000, 0x00, 0x00,
737 0x00000000, 0x00, 0x00,
738 0x00, NULL, 0x00,
739 status, 1, 1); /* qspi write read */
740 if (res != 0) /* check result */
741 {
742 handle->debug_print("w25qxx: get status2 failed.\n"); /* get status2 failed */
743
744 return 1; /* return error */
745 }
746 }
747 else /* single spi */
748 {
749 buf[0] = W25QXX_COMMAND_READ_STATUS_REG2; /* read status2 command */
750 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf,
751 1, status, 1); /* spi write read */
752 if (res != 0) /* check result */
753 {
754 handle->debug_print("w25qxx: get status2 failed.\n"); /* get status2 failed */
755
756 return 1; /* return error */
757 }
758 }
759 }
760 else /* qspi interface */
761 {
762 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG2, 4,
763 0x00000000, 0x00, 0x00,
764 0x00000000, 0x00, 0x00,
765 0x00, NULL, 0x00,
766 status, 1, 4); /* qspi write read */
767 if (res != 0) /* check result */
768 {
769 handle->debug_print("w25qxx: get status2 failed.\n"); /* get status2 failed */
770
771 return 1; /* return error */
772 }
773 }
774
775 return 0; /* success return 0 */
776 }
777
789 uint8_t w25qxx_get_status3(w25qxx_handle_t *handle, uint8_t *status)
790 {
791 uint8_t res;
792 uint8_t buf[1];
793
794 if (handle == NULL) /* check handle */
795 {
796 return 2; /* return error */
797 }
798 if (handle->inited != 1) /* check handle initialization */
799 {
800 return 3; /* return error */
801 }
802
803 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
804 {
805 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
806 {
807 res = a_w25qxx_qspi_write_read(handle,
808 W25QXX_COMMAND_READ_STATUS_REG3, 1,
809 0x00000000, 0x00, 0x00,
810 0x00000000, 0x00, 0x00,
811 0x00, NULL, 0x00,
812 status, 1, 1); /* qspi write read */
813 if (res != 0) /* check result */
814 {
815 handle->debug_print("w25qxx: get status3 failed.\n"); /* get status3 failed */
816
817 return 1; /* return error */
818 }
819 }
820 else /* single spi */
821 {
822 buf[0] = W25QXX_COMMAND_READ_STATUS_REG3; /* read status3 command */
823 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1,
824 status, 1); /* spi write read */
825 if (res != 0) /* check result */
826 {
827 handle->debug_print("w25qxx: get status3 failed.\n"); /* get status3 failed */
828
829 return 1; /* return error */
830 }
831 }
832 }
833 else /* qspi interface */
834 {
835 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG3, 4,
836 0x00000000, 0x00, 0x00,
837 0x00000000, 0x00, 0x00,
838 0x00, NULL, 0x00,
839 status, 1, 4); /* qspi write read */
840 if (res != 0) /* check result */
841 {
842 handle->debug_print("w25qxx: get status3 failed.\n"); /* get status3 failed */
843
844 return 1; /* return error */
845 }
846 }
847
848 return 0; /* success return 0 */
849 }
850
863 uint8_t w25qxx_set_status1(w25qxx_handle_t *handle, uint8_t status)
864 {
865 uint8_t res;
866 uint8_t buf[2];
867 uint32_t timeout;
868 uint8_t status_check;
869
870 if (handle == NULL) /* check handle */
871 {
872 return 2; /* return error */
873 }
874 if (handle->inited != 1) /* check handle initialization */
875 {
876 return 3; /* return error */
877 }
878
879 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
880 {
881 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
882 {
883 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 1,
884 0x00000000, 0x00, 0x00,
885 0x00000000, 0x00, 0x00,
886 0x00, NULL, 0x00,
887 NULL, 0x00, 0x00); /* qspi write read */
888 if (res != 0) /* check result */
889 {
890 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
891
892 return 1; /* return error */
893 }
894 buf[0] = status; /* set status */
895 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_STATUS_REG1, 1,
896 0x00000000, 0x00, 0x00,
897 0x00000000, 0x00, 0x00,
898 0x00, (uint8_t *)buf, 1,
899 NULL, 0x00, 1); /* qspi write read */
900 if (res != 0) /* check result */
901 {
902 handle->debug_print("w25qxx: set status1 failed.\n"); /* set status1 failed */
903
904 return 1; /* return error */
905 }
906
907 timeout = 1000; /* max 1000 ms */
908 while (timeout != 0) /* check timeout */
909 {
910 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
911 0x00000000, 0x00, 0x00,
912 0x00000000, 0x00, 0x00,
913 0x00, NULL, 0x00,
914 (uint8_t *)&status_check, 1, 1); /* qspi write read */
915 if (res != 0) /* check result */
916 {
917 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
918
919 return 1; /* return error */
920 }
921 if ((status_check & 0x01) == 0x00) /* check status */
922 {
923 break; /* break */
924 }
925 timeout--; /* timeout-- */
926 handle->delay_ms(1); /* delay 1 ms */
927 }
928 if (timeout == 0) /* check timeout */
929 {
930 handle->debug_print("w25qxx: write status 1 timeout.\n"); /* write status 1 timeout */
931
932 return 4; /* return error */
933 }
934 else
935 {
936 return 0; /* success return 0 */
937 }
938 }
939 else /* single spi */
940 {
941 buf[0] = W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE; /* sr write enable command */
942 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
943 if (res != 0) /* check result */
944 {
945 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
946
947 return 1; /* return error */
948 }
949 buf[0] = W25QXX_COMMAND_WRITE_STATUS_REG1; /* write status1 command */
950 buf[1] = status; /* set status */
951 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
952 if (res != 0) /* check result */
953 {
954 handle->debug_print("w25qxx: set status1 failed.\n"); /* set status1 failed */
955
956 return 1; /* return error */
957 }
958
959 timeout = 1000; /* max 1000 ms */
960 while (timeout != 0) /* check timeout */
961 {
962 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
963 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1,
964 (uint8_t *)&status_check, 1); /* spi write read */
965 if (res != 0) /* check result */
966 {
967 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
968
969 return 1; /* return error */
970 }
971 if ((status_check & 0x01) == 0x00) /* check status */
972 {
973 break; /* break */
974 }
975 timeout--; /* timeout-- */
976 handle->delay_ms(1); /* delay 1 ms */
977 }
978 if (timeout == 0) /* check timeout */
979 {
980 handle->debug_print("w25qxx: write status 1 timeout.\n"); /* write status 1 timeout */
981
982 return 4; /* return error */
983 }
984 else
985 {
986 return 0; /* success return 0 */
987 }
988 }
989 }
990 else /* qspi interface */
991 {
992 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 4,
993 0x00000000, 0x00, 0x00,
994 0x00000000, 0x00, 0x00,
995 0x00, NULL, 0x00,
996 NULL, 0x00, 0x00); /* qspi write read */
997 if (res != 0) /* check result */
998 {
999 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1000
1001 return 1; /* return error */
1002 }
1003 buf[0] = status; /* set status */
1004 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_STATUS_REG1, 4,
1005 0x00000000, 0x00, 0x00,
1006 0x00000000, 0x00, 0x00,
1007 0x00, (uint8_t *)buf, 1,
1008 NULL, 0x00, 4); /* qspi write read */
1009 if (res != 0) /* check result */
1010 {
1011 handle->debug_print("w25qxx: set status1 failed.\n"); /* set status1 failed */
1012
1013 return 1; /* return error */
1014 }
1015
1016 timeout = 1000; /* max 1000 ms */
1017 while (timeout != 0) /* check timeout */
1018 {
1019 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
1020 0x00000000, 0x00, 0x00,
1021 0x00000000, 0x00, 0x00,
1022 0x00, NULL, 0x00,
1023 (uint8_t *)&status_check, 1, 4); /* qspi write read */
1024 if (res != 0) /* check result */
1025 {
1026 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1027
1028 return 1; /* return error */
1029 }
1030 if ((status_check & 0x01) == 0x00) /* check status */
1031 {
1032 break; /* break */
1033 }
1034 timeout--; /* timeout-- */
1035 handle->delay_ms(1); /* delay 1 ms */
1036 }
1037 if (timeout == 0) /* check timeout */
1038 {
1039 handle->debug_print("w25qxx: write status 1 timeout.\n"); /* write status 1 timeout */
1040
1041 return 4; /* return error */
1042 }
1043 else
1044 {
1045 return 0; /* success return 0 */
1046 }
1047 }
1048 }
1049
1062 uint8_t w25qxx_set_status2(w25qxx_handle_t *handle, uint8_t status)
1063 {
1064 uint8_t res;
1065 uint8_t buf[2];
1066 uint32_t timeout;
1067 uint8_t status_check;
1068
1069 if (handle == NULL) /* check handle */
1070 {
1071 return 2; /* return error */
1072 }
1073 if (handle->inited != 1) /* check handle initialization */
1074 {
1075 return 3; /* return error */
1076 }
1077
1078 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
1079 {
1080 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
1081 {
1082 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 1,
1083 0x00000000, 0x00, 0x00,
1084 0x00000000, 0x00, 0x00,
1085 0x00, NULL, 0x00,
1086 NULL, 0x00, 0x00); /* qspi write read */
1087 if (res != 0) /* check result */
1088 {
1089 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1090
1091 return 1; /* return error */
1092 }
1093 buf[0] = status; /* set status */
1094 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_STATUS_REG2, 1,
1095 0x00000000, 0x00, 0x00,
1096 0x00000000, 0x00, 0x00,
1097 0x00, (uint8_t *)buf, 1,
1098 NULL, 0x00, 1); /* qspi write read */
1099 if (res != 0) /* check result */
1100 {
1101 handle->debug_print("w25qxx: set status2 failed.\n"); /* set status2 failed */
1102
1103 return 1; /* return error */
1104 }
1105
1106 timeout = 1000; /* max 1000 ms */
1107 while (timeout != 0) /* check timeout */
1108 {
1109 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
1110 0x00000000, 0x00, 0x00,
1111 0x00000000, 0x00, 0x00,
1112 0x00, NULL, 0x00,
1113 (uint8_t *)&status_check, 1, 1); /* qspi write read */
1114 if (res != 0) /* check result */
1115 {
1116 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1117
1118 return 1; /* return error */
1119 }
1120 if ((status_check & 0x01) == 0x00) /* check status */
1121 {
1122 break; /* break */
1123 }
1124 timeout--; /* timeout-- */
1125 handle->delay_ms(1); /* delay 1 ms */
1126 }
1127 if (timeout == 0) /* check timeout */
1128 {
1129 handle->debug_print("w25qxx: write status 2 timeout.\n"); /* write status 2 timeout */
1130
1131 return 4; /* return error */
1132 }
1133 else
1134 {
1135 return 0; /* success return 0 */
1136 }
1137 }
1138 else /* single spi */
1139 {
1140 buf[0] = W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE; /* sr write enable command */
1141 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
1142 if (res != 0) /* check result */
1143 {
1144 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1145
1146 return 1; /* return error */
1147 }
1148 buf[0] = W25QXX_COMMAND_WRITE_STATUS_REG2; /* write status2 command */
1149 buf[1] = status; /* set status */
1150 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
1151 if (res != 0) /* check result */
1152 {
1153 handle->debug_print("w25qxx: set status2 failed.\n"); /* set status2 failed */
1154
1155 return 1; /* return error */
1156 }
1157
1158 timeout = 1000; /* max 1000 ms */
1159 while (timeout != 0) /* check timeout */
1160 {
1161 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
1162 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1,
1163 (uint8_t *)&status_check, 1); /* spi write read */
1164 if (res != 0) /* check result */
1165 {
1166 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1167
1168 return 1; /* return error */
1169 }
1170 if ((status_check & 0x01) == 0x00) /* check status */
1171 {
1172 break; /* break */
1173 }
1174 timeout--; /* timeout-- */
1175 handle->delay_ms(1); /* delay 1 ms */
1176 }
1177 if (timeout == 0) /* check timeout */
1178 {
1179 handle->debug_print("w25qxx: write status 2 timeout.\n"); /* write status 2 timeout */
1180
1181 return 4; /* return error */
1182 }
1183 else
1184 {
1185 return 0; /* success return 0 */
1186 }
1187 }
1188 }
1189 else /* qspi interface */
1190 {
1191 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 4,
1192 0x00000000, 0x00, 0x00,
1193 0x00000000, 0x00, 0x00,
1194 0x00, NULL, 0x00,
1195 NULL, 0x00, 0x00); /* qspi write read */
1196 if (res != 0) /* check result */
1197 {
1198 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1199
1200 return 1; /* return error */
1201 }
1202 buf[0] = status; /* set status */
1203 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_STATUS_REG2, 4,
1204 0x00000000, 0x00, 0x00,
1205 0x00000000, 0x00, 0x00,
1206 0x00, (uint8_t *)buf, 1,
1207 NULL, 0x00, 4); /* qspi write read */
1208 if (res != 0) /* check result */
1209 {
1210 handle->debug_print("w25qxx: set status2 failed.\n"); /* set status2 failed */
1211
1212 return 1; /* return error */
1213 }
1214
1215 timeout = 1000; /* max 1000 ms */
1216 while (timeout != 0) /* check timeout */
1217 {
1218 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
1219 0x00000000, 0x00, 0x00,
1220 0x00000000, 0x00, 0x00,
1221 0x00, NULL, 0x00,
1222 (uint8_t *)&status_check, 1, 4); /* qspi write read */
1223 if (res != 0) /* check result */
1224 {
1225 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1226
1227 return 1; /* return error */
1228 }
1229 if ((status_check & 0x01) == 0x00) /* check status */
1230 {
1231 break; /* break */
1232 }
1233 timeout--; /* timeout-- */
1234 handle->delay_ms(1); /* delay 1 ms */
1235 }
1236 if (timeout == 0) /* check timeout */
1237 {
1238 handle->debug_print("w25qxx: write status 2 timeout.\n"); /* write status 2 timeout */
1239
1240 return 4; /* return error */
1241 }
1242 else
1243 {
1244 return 0; /* success return 0 */
1245 }
1246 }
1247 }
1248
1261 uint8_t w25qxx_set_status3(w25qxx_handle_t *handle, uint8_t status)
1262 {
1263 uint8_t res;
1264 uint8_t buf[2];
1265 uint32_t timeout;
1266 uint8_t status_check;
1267
1268 if (handle == NULL) /* check handle */
1269 {
1270 return 2; /* return error */
1271 }
1272 if (handle->inited != 1) /* check handle initialization */
1273 {
1274 return 3; /* return error */
1275 }
1276
1277 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
1278 {
1279 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
1280 {
1281 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 1,
1282 0x00000000, 0x00, 0x00,
1283 0x00000000, 0x00, 0x00,
1284 0x00, NULL, 0x00,
1285 NULL, 0x00, 0x00); /* qspi write read */
1286 if (res != 0) /* check result */
1287 {
1288 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1289
1290 return 1; /* return error */
1291 }
1292 buf[0] = status; /* set status */
1293 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_STATUS_REG3, 1,
1294 0x00000000, 0x00, 0x00,
1295 0x00000000, 0x00, 0x00,
1296 0x00, (uint8_t *)buf, 1,
1297 NULL, 0x00, 1); /* qspi write read */
1298 if (res != 0) /* check result */
1299 {
1300 handle->debug_print("w25qxx: set status3 failed.\n"); /* set status3 failed */
1301
1302 return 1; /* return error */
1303 }
1304
1305 timeout = 1000; /* max 1000 ms */
1306 while (timeout != 0) /* check timeout */
1307 {
1308 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
1309 0x00000000, 0x00, 0x00,
1310 0x00000000, 0x00, 0x00,
1311 0x00, NULL, 0x00,
1312 (uint8_t *)&status_check, 1, 1); /* qspi write read */
1313 if (res != 0) /* check result */
1314 {
1315 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1316
1317 return 1; /* return error */
1318 }
1319 if ((status_check & 0x01) == 0x00) /* check status */
1320 {
1321 break; /* break */
1322 }
1323 timeout--; /* timeout-- */
1324 handle->delay_ms(1); /* delay 1 ms */
1325 }
1326 if (timeout == 0) /* check timeout */
1327 {
1328 handle->debug_print("w25qxx: write status 3 timeout.\n"); /* write status 3 timeout */
1329
1330 return 4; /* return error */
1331 }
1332 else
1333 {
1334 return 0; /* success return 0 */
1335 }
1336 }
1337 else /* single spi */
1338 {
1339 buf[0] = W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE; /* sr write enable command */
1340 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
1341 if (res != 0) /* check result */
1342 {
1343 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1344
1345 return 1; /* return error */
1346 }
1347 buf[0] = W25QXX_COMMAND_WRITE_STATUS_REG3; /* write status3 command */
1348 buf[1] = status; /* set status */
1349 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
1350 if (res != 0) /* check result */
1351 {
1352 handle->debug_print("w25qxx: set status3 failed.\n"); /* set status3 failed */
1353
1354 return 1; /* return error */
1355 }
1356
1357 timeout = 1000; /* max 1000 ms */
1358 while (timeout != 0) /* check timeout */
1359 {
1360 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
1361 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1,
1362 (uint8_t *)&status_check, 1); /* spi write read */
1363 if (res != 0) /* check result */
1364 {
1365 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1366
1367 return 1; /* return error */
1368 }
1369 if ((status_check & 0x01) == 0x00) /* check status */
1370 {
1371 break; /* break */
1372 }
1373 timeout--; /* timeout-- */
1374 handle->delay_ms(1); /* delay 1 ms */
1375 }
1376 if (timeout == 0) /* check timeout */
1377 {
1378 handle->debug_print("w25qxx: write status 3 timeout.\n"); /* write status 3 timeout */
1379
1380 return 4; /* return error */
1381 }
1382 else
1383 {
1384 return 0; /* success return 0 */
1385 }
1386 }
1387 }
1388 else /* qspi interface */
1389 {
1390 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 4,
1391 0x00000000, 0x00, 0x00,
1392 0x00000000, 0x00, 0x00,
1393 0x00, NULL, 0x00,
1394 NULL, 0x00, 0x00); /* qspi write read */
1395 if (res != 0) /* check result */
1396 {
1397 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1398
1399 return 1; /* return error */
1400 }
1401 buf[0] = status; /* set status */
1402 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_STATUS_REG3, 4,
1403 0x00000000, 0x00, 0x00,
1404 0x00000000, 0x00, 0x00,
1405 0x00, (uint8_t *)buf, 1,
1406 NULL, 0x00, 4); /* qspi write read */
1407 if (res != 0) /* check result */
1408 {
1409 handle->debug_print("w25qxx: set status3 failed.\n"); /* set status3 failed */
1410
1411 return 1; /* return error */
1412 }
1413
1414 timeout = 1000; /* max 1000 ms */
1415 while (timeout != 0) /* check timeout */
1416 {
1417 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
1418 0x00000000, 0x00, 0x00,
1419 0x00000000, 0x00, 0x00,
1420 0x00, NULL, 0x00,
1421 (uint8_t *)&status_check, 1, 4); /* qspi write read */
1422 if (res != 0) /* check result */
1423 {
1424 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1425
1426 return 1; /* return error */
1427 }
1428 if ((status_check & 0x01) == 0x00) /* check status */
1429 {
1430 break; /* break */
1431 }
1432 timeout--; /* timeout-- */
1433 handle->delay_ms(1); /* delay 1 ms */
1434 }
1435 if (timeout == 0) /* check timeout */
1436 {
1437 handle->debug_print("w25qxx: write status 3 timeout.\n"); /* write status 3 timeout */
1438
1439 return 4; /* return error */
1440 }
1441 else
1442 {
1443 return 0; /* success return 0 */
1444 }
1445 }
1446 }
1447
1459 uint8_t w25qxx_chip_erase(w25qxx_handle_t *handle)
1460 {
1461 uint8_t res;
1462 uint8_t status;
1463 uint8_t buf[1];
1464 uint32_t timeout;
1465
1466 if (handle == NULL) /* check handle */
1467 {
1468 return 2; /* return error */
1469 }
1470 if (handle->inited != 1) /* check handle initialization */
1471 {
1472 return 3; /* return error */
1473 }
1474
1475 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
1476 {
1477 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
1478 {
1479 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
1480 0x00000000, 0x00, 0x00,
1481 0x00000000, 0x00, 0x00,
1482 0x00, NULL, 0x00,
1483 NULL, 0x00, 0x00); /* qspi write read */
1484 if (res != 0) /* check result */
1485 {
1486 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1487
1488 return 1; /* return error */
1489 }
1490 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_CHIP_ERASE, 1,
1491 0x00000000, 0x00, 0x00,
1492 0x00000000, 0x00, 0x00,
1493 0x00, NULL, 0x00,
1494 NULL, 0x00, 0x00); /* qspi write read */
1495 if (res != 0) /* check result */
1496 {
1497 handle->debug_print("w25qxx: chip erase failed.\n"); /* chip erase failed */
1498
1499 return 1; /* return error */
1500 }
1501 timeout = 400 * 1000; /* max 400s */
1502 while (timeout != 0) /* check timeout */
1503 {
1504 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
1505 0x00000000, 0x00, 0x00,
1506 0x00000000, 0x00, 0x00,
1507 0x00, NULL, 0x00,
1508 (uint8_t *)&status, 1, 1); /* qspi write read */
1509 if (res != 0) /* check result */
1510 {
1511 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1512
1513 return 1; /* return error */
1514 }
1515 if ((status & 0x01) == 0x00) /* check status */
1516 {
1517 break; /* break */
1518 }
1519 timeout--; /* timeout-- */
1520 handle->delay_ms(1); /* delay 1 ms */
1521 }
1522 if (timeout == 0) /* check timeout */
1523 {
1524 handle->debug_print("w25qxx: erase timeout.\n"); /* erase timeout */
1525
1526 return 4; /* return error */
1527 }
1528 else
1529 {
1530 return 0; /* success return 0 */
1531 }
1532 }
1533 else /* single spi */
1534 {
1535 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
1536 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
1537 if (res != 0) /* check result */
1538 {
1539 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1540
1541 return 1; /* return error */
1542 }
1543 buf[0] = W25QXX_COMMAND_CHIP_ERASE; /* chip erase command */
1544 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi qspi write read */
1545 if (res != 0) /* check result */
1546 {
1547 handle->debug_print("w25qxx: chip erase failed.\n"); /* chip erase failed */
1548
1549 return 1; /* return error */
1550 }
1551 timeout = 400 * 1000; /* max 400s */
1552 while (timeout != 0) /* check timeout */
1553 {
1554 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
1555 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1,
1556 (uint8_t *)&status, 1); /* spi write read */
1557 if (res != 0) /* check result */
1558 {
1559 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1560
1561 return 1; /* return error */
1562 }
1563 if ((status & 0x01) == 0x00) /* check status */
1564 {
1565 break; /* break */
1566 }
1567 timeout--; /* timeout-- */
1568 handle->delay_ms(1); /* delay 1 ms */
1569 }
1570 if (timeout == 0) /* check timeout */
1571 {
1572 handle->debug_print("w25qxx: erase timeout.\n"); /* erase timeout */
1573
1574 return 4; /* return error */
1575 }
1576 else
1577 {
1578 return 0; /* success return 0 */
1579 }
1580 }
1581 }
1582 else /* qspi interface */
1583 {
1584 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
1585 0x00000000, 0x00, 0x00,
1586 0x00000000, 0x00, 0x00,
1587 0x00, NULL, 0x00,
1588 NULL, 0x00, 0x00); /* qspi write read */
1589 if (res != 0) /* check result */
1590 {
1591 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
1592
1593 return 1; /* return error */
1594 }
1595 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_CHIP_ERASE, 4,
1596 0x00000000, 0x00, 0x00,
1597 0x00000000, 0x00, 0x00,
1598 0x00, NULL, 0x00,
1599 NULL, 0x00, 0x00); /* qspi write read */
1600 if (res != 0) /* check result */
1601 {
1602 handle->debug_print("w25qxx: chip erase failed.\n"); /* chip erase failed */
1603
1604 return 1; /* return error */
1605 }
1606 timeout = 400 * 1000; /* max 400s */
1607 while (timeout != 0) /* check timeout */
1608 {
1609 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
1610 0x00000000, 0x00, 0x00,
1611 0x00000000, 0x00, 0x00,
1612 0x00, NULL, 0x00,
1613 (uint8_t *)&status, 1, 4); /* qspi write read */
1614 if (res != 0) /* check result */
1615 {
1616 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
1617
1618 return 1; /* return error */
1619 }
1620 if ((status & 0x01) == 0x00) /* check status */
1621 {
1622 break; /* break */
1623 }
1624 timeout--; /* timeout-- */
1625 handle->delay_ms(1); /* delay 1 ms */
1626 }
1627 if (timeout == 0) /* check timeout */
1628 {
1629 handle->debug_print("w25qxx: erase timeout.\n"); /* erase timeout */
1630
1631 return 4; /* return error */
1632 }
1633 else
1634 {
1635 return 0; /* success return 0 */
1636 }
1637 }
1638 }
1639
1650 uint8_t w25qxx_erase_program_suspend(w25qxx_handle_t *handle)
1651 {
1652 uint8_t res;
1653 uint8_t buf[1];
1654
1655 if (handle == NULL) /* check handle */
1656 {
1657 return 2; /* return error */
1658 }
1659 if (handle->inited != 1) /* check handle initialization */
1660 {
1661 return 3; /* return error */
1662 }
1663
1664 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
1665 {
1666 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
1667 {
1668 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_ERASE_PROGRAM_SUSPEND, 1,
1669 0x00000000, 0x00, 0x00,
1670 0x00000000, 0x00, 0x00,
1671 0x00, NULL, 0x00,
1672 NULL, 0x00, 0x00); /* qspi write read */
1673 if (res != 0) /* check result */
1674 {
1675 handle->debug_print("w25qxx: erase program suspend failed.\n"); /* erase program suspend failed */
1676
1677 return 1; /* return error */
1678 }
1679 }
1680 else /* single spi */
1681 {
1682 buf[0] = W25QXX_COMMAND_ERASE_PROGRAM_SUSPEND; /* erase program suspend command */
1683 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
1684 if (res != 0) /* check result */
1685 {
1686 handle->debug_print("w25qxx: erase program suspend failed.\n"); /* erase program suspend failed */
1687
1688 return 1; /* return error */
1689 }
1690
1691 return 0; /* success return 0 */
1692 }
1693 }
1694 else /* qspi interface */
1695 {
1696 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_ERASE_PROGRAM_SUSPEND, 4,
1697 0x00000000, 0x00, 0x00,
1698 0x00000000, 0x00, 0x00,
1699 0x00, NULL, 0x00,
1700 NULL, 0x00, 0x00); /* qspi write read */
1701 if (res != 0) /* check result */
1702 {
1703 handle->debug_print("w25qxx: erase program suspend failed.\n"); /* erase program suspend failed */
1704
1705 return 1; /* return error */
1706 }
1707 }
1708
1709 return 0; /* success return 0 */
1710 }
1711
1722 uint8_t w25qxx_erase_program_resume(w25qxx_handle_t *handle)
1723 {
1724 uint8_t res;
1725 uint8_t buf[1];
1726
1727 if (handle == NULL) /* check handle */
1728 {
1729 return 2; /* return error */
1730 }
1731 if (handle->inited != 1) /* check handle initialization */
1732 {
1733 return 3; /* return error */
1734 }
1735
1736 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
1737 {
1738 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
1739 {
1740 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_ERASE_PROGRAM_RESUME, 1,
1741 0x00000000, 0x00, 0x00,
1742 0x00000000, 0x00, 0x00,
1743 0x00, NULL, 0x00,
1744 NULL, 0x00, 0x00); /* qspi write read */
1745 if (res != 0) /* check result */
1746 {
1747 handle->debug_print("w25qxx: erase program resume failed.\n"); /* erase program resume failed */
1748
1749 return 1; /* return error */
1750 }
1751 }
1752 else /* single spi */
1753 {
1754 buf[0] = W25QXX_COMMAND_ERASE_PROGRAM_RESUME; /* erase program resume command */
1755 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
1756 if (res != 0) /* check result */
1757 {
1758 handle->debug_print("w25qxx: erase program resume failed.\n"); /* erase program resume failed */
1759
1760 return 1; /* return error */
1761 }
1762 }
1763 }
1764 else /* qspi interface */
1765 {
1766 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_ERASE_PROGRAM_RESUME, 4,
1767 0x00000000, 0x00, 0x00,
1768 0x00000000, 0x00, 0x00,
1769 0x00, NULL, 0x00,
1770 NULL, 0x00, 0x00); /* qspi write read */
1771 if (res != 0) /* check result */
1772 {
1773 handle->debug_print("w25qxx: erase program resume failed.\n"); /* erase program resume failed */
1774
1775 return 1; /* return error */
1776 }
1777 }
1778
1779 return 0; /* success return 0 */
1780 }
1781
1792 uint8_t w25qxx_power_down(w25qxx_handle_t *handle)
1793 {
1794 uint8_t res;
1795 uint8_t buf[1];
1796
1797 if (handle == NULL) /* check handle */
1798 {
1799 return 2; /* return error */
1800 }
1801 if (handle->inited != 1) /* check handle initialization */
1802 {
1803 return 3; /* return error */
1804 }
1805
1806 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
1807 {
1808 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
1809 {
1810 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_POWER_DOWN, 1,
1811 0x00000000, 0x00, 0x00,
1812 0x00000000, 0x00, 0x00,
1813 0x00, NULL, 0x00,
1814 NULL, 0x00, 0x00); /* qspi write read */
1815 if (res != 0) /* check result */
1816 {
1817 handle->debug_print("w25qxx: power down failed.\n"); /* power down failed */
1818
1819 return 1; /* return error */
1820 }
1821 }
1822 else /* single spi */
1823 {
1824 buf[0] = W25QXX_COMMAND_POWER_DOWN; /* power down command */
1825 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf,
1826 1, NULL, 0); /* spi write read */
1827 if (res != 0) /* check result */
1828 {
1829 handle->debug_print("w25qxx: power down failed.\n"); /* power down failed */
1830
1831 return 1; /* return error */
1832 }
1833 }
1834 }
1835 else /* qspi interface */
1836 {
1837 res = a_w25qxx_qspi_write_read(handle, 0xFF, 4,
1838 0x00000000, 0x00, 0x00,
1839 0x00000000, 0x00, 0x00,
1840 0, NULL, 0x00,
1841 NULL, 0x00, 0); /* spi write read */
1842 if (res != 0) /* check result */
1843 {
1844 handle->debug_print("w25qxx: exit qspi mode failed.\n"); /* exit qspi mode failed */
1845
1846 return 1; /* return error */
1847 }
1848 handle->delay_ms(10); /* delay 10 ms */
1849 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_POWER_DOWN, 4,
1850 0x00000000, 0x00, 0x00,
1851 0x00000000, 0x00, 0x00,
1852 0x00, NULL, 0x00,
1853 NULL, 0x00, 0x00); /* qspi write read */
1854 if (res != 0) /* check result */
1855 {
1856 handle->debug_print("w25qxx: power down failed.\n"); /* power down failed */
1857
1858 return 1; /* return error */
1859 }
1860 }
1861
1862 return 0; /* success return 0 */
1863 }
1864
1875 uint8_t w25qxx_release_power_down(w25qxx_handle_t *handle)
1876 {
1877 uint8_t res;
1878 uint8_t id;
1879 uint8_t buf[4];
1880
1881 if (handle == NULL) /* check handle */
1882 {
1883 return 2; /* return error */
1884 }
1885 if (handle->inited != 1) /* check handle initialization */
1886 {
1887 return 3; /* return error */
1888 }
1889
1890 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
1891 {
1892 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
1893 {
1894 res = a_w25qxx_qspi_write_read(handle,
1895 W25QXX_COMMAND_RELEASE_POWER_DOWN, 1,
1896 0x00000000, 0x00, 0x00,
1897 0x00000000, 0x00, 0x00,
1898 3 * 8, NULL, 0x00,
1899 (uint8_t *)&id, 1, 1); /* qspi write read */
1900 if (res != 0) /* check result */
1901 {
1902 handle->debug_print("w25qxx: release power down failed.\n"); /* release power down failed */
1903
1904 return 1; /* return error */
1905 }
1906 }
1907 else /* single spi */
1908 {
1909 buf[0] = W25QXX_COMMAND_RELEASE_POWER_DOWN; /* release power down command */
1910 buf[1] = 0xFF; /* dummy */
1911 buf[2] = 0xFF; /* dummy */
1912 buf[3] = 0xFF; /* dummy */
1913 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, (uint8_t *)&id, 1); /* spi write read */
1914 if (res != 0) /* check result */
1915 {
1916 handle->debug_print("w25qxx: release power down failed.\n"); /* release power down failed */
1917
1918 return 1; /* return error */
1919 }
1920 }
1921 }
1922 else /* qspi interface */
1923 {
1924 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_RELEASE_POWER_DOWN, 4,
1925 0x00000000, 0x00, 0x00,
1926 0x00000000, 0x00, 0x00,
1927 6, NULL, 0x00,
1928 (uint8_t *)&id, 1, 4); /* qspi write read */
1929 if (res != 0) /* check result */
1930 {
1931 handle->debug_print("w25qxx: release power down failed.\n"); /* release power down failed */
1932
1933 return 1; /* return error */
1934 }
1935 }
1936
1937 return 0; /* success return 0 */
1938 }
1939
1952 uint8_t w25qxx_get_manufacturer_device_id(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t *device_id)
1953 {
1954 uint8_t res;
1955 uint8_t buf[4];
1956 uint8_t out[2];
1957
1958 if (handle == NULL) /* check handle */
1959 {
1960 return 2; /* return error */
1961 }
1962 if (handle->inited != 1) /* check handle initialization */
1963 {
1964 return 3; /* return error */
1965 }
1966
1967 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
1968 {
1969 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
1970 {
1971 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_MANUFACTURER, 1,
1972 0x00000000, 1, 3,
1973 0x00000000, 0x00, 0x00,
1974 0, NULL, 0x00,
1975 (uint8_t *)out, 2, 1); /* qspi write read */
1976 if (res != 0) /* check result */
1977 {
1978 handle->debug_print("w25qxx: get manufacturer device id failed.\n"); /* get manufacturer device id failed */
1979
1980 return 1; /* return error */
1981 }
1982 *manufacturer = out[0]; /* set manufacturer */
1983 *device_id = out[1]; /* set device id */
1984 }
1985 else /* single spi */
1986 {
1987 buf[0] = W25QXX_COMMAND_READ_MANUFACTURER; /* read manufacturer command */
1988 buf[1] = 0x00; /* dummy */
1989 buf[2] = 0x00; /* dummy */
1990 buf[3] = 0x00; /* dummy */
1991 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4,
1992 (uint8_t *)out, 2); /* spi write read */
1993 if (res != 0) /* check result */
1994 {
1995 handle->debug_print("w25qxx: get manufacturer device id failed.\n"); /* get manufacturer device id failed */
1996
1997 return 1; /* return error */
1998 }
1999 *manufacturer = out[0]; /* set manufacturer */
2000 *device_id = out[1]; /* set device id */
2001 }
2002 }
2003 else /* qspi interface */
2004 {
2005 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_MANUFACTURER, 4,
2006 0x00000000, 4, 3,
2007 0x00000000, 0x00, 0x00,
2008 0, NULL, 0x00,
2009 (uint8_t *)out, 2, 4); /* qspi write read */
2010 if (res != 0) /* check result */
2011 {
2012 handle->debug_print("w25qxx: get manufacturer device id failed.\n"); /* get manufacturer device id failed */
2013
2014 return 1; /* return error */
2015 }
2016 *manufacturer = out[0]; /* set manufacturer */
2017 *device_id = out[1]; /* set device id */
2018 }
2019
2020 return 0; /* success return 0 */
2021 }
2022
2038 uint8_t w25qxx_get_manufacturer_device_id_dual_io(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t *device_id)
2039 {
2040 uint8_t res;
2041 uint8_t out[2];
2042
2043 if (handle == NULL) /* check handle */
2044 {
2045 return 2; /* return error */
2046 }
2047 if (handle->inited != 1) /* check handle initialization */
2048 {
2049 return 3; /* return error */
2050 }
2051
2052 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2053 {
2054 if (handle->dual_quad_spi_enable == 0) /* check spi */
2055 {
2056 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
2057
2058 return 6; /* return error */
2059 }
2060 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
2061 {
2062 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_DEVICE_ID_DUAL_IO, 1,
2063 0x00000000, 2, 3,
2064 0x000000FF, 2, 1,
2065 0x00, NULL, 0x00,
2066 (uint8_t *)out, 2, 2); /* spi write read */
2067 if (res != 0) /* check result */
2068 {
2069 handle->debug_print("w25qxx: get manufacturer device id dual io failed.\n"); /* get manufacturer device id dual io failed */
2070
2071 return 1; /* return error */
2072 }
2073 }
2074 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
2075 {
2076 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_DEVICE_ID_DUAL_IO, 1,
2077 0x00000000, 2, 4,
2078 0x000000FF, 2, 1,
2079 0x00, NULL, 0x00,
2080 (uint8_t *)out, 2, 2); /* spi write read */
2081 if (res != 0) /* check result */
2082 {
2083 handle->debug_print("w25qxx: get manufacturer device id dual io failed.\n"); /* get manufacturer device id dual io failed */
2084
2085 return 1; /* return error */
2086 }
2087 }
2088 else
2089 {
2090 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
2091
2092 return 4; /* return error */
2093 }
2094 *manufacturer = out[0]; /* set manufacturer */
2095 *device_id = out[1]; /* set device id */
2096 }
2097 else
2098 {
2099 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
2100
2101 return 5; /* return error */
2102 }
2103
2104 return 0; /* success return 0 */
2105 }
2106
2122 uint8_t w25qxx_get_manufacturer_device_id_quad_io(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t *device_id)
2123 {
2124 uint8_t res;
2125 uint8_t out[2];
2126
2127 if (handle == NULL) /* check handle */
2128 {
2129 return 2; /* return error */
2130 }
2131 if (handle->inited != 1) /* check handle initialization */
2132 {
2133 return 3; /* return error */
2134 }
2135
2136 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2137 {
2138 if (handle->dual_quad_spi_enable == 0) /* check spi */
2139 {
2140 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
2141
2142 return 6; /* return error */
2143 }
2144 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
2145 {
2146 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_DEVICE_ID_QUAD_IO, 1,
2147 0x00000000, 4, 3,
2148 0x000000FF, 4, 1,
2149 4, NULL, 0x00,
2150 (uint8_t *)out, 2, 4); /* spi write read */
2151 if (res != 0) /* check result */
2152 {
2153 handle->debug_print("w25qxx: get manufacturer device id quad io failed.\n"); /* get manufacturer device id quad io failed */
2154
2155 return 1; /* return error */
2156 }
2157 }
2158 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
2159 {
2160 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_DEVICE_ID_QUAD_IO, 1,
2161 0x00000000, 4, 4,
2162 0x000000FF, 4, 1,
2163 4, NULL, 0x00,
2164 (uint8_t *)out, 2, 4); /* spi write read */
2165 if (res != 0) /* check result */
2166 {
2167 handle->debug_print("w25qxx: get manufacturer device id quad io failed.\n"); /* get manufacturer device id quad io failed */
2168
2169 return 1; /* return error */
2170 }
2171 }
2172 else
2173 {
2174 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
2175
2176 return 4; /* return error */
2177 }
2178 *manufacturer = out[0]; /* set manufacturer */
2179 *device_id = out[1]; /* set device id */
2180 }
2181 else
2182 {
2183 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
2184
2185 return 5; /* return error */
2186 }
2187
2188 return 0; /* success return 0 */
2189 }
2190
2203 uint8_t w25qxx_get_jedec_id(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t device_id[2])
2204 {
2205 uint8_t res;
2206 uint8_t buf[1];
2207 uint8_t out[3];
2208
2209 if (handle == NULL) /* check handle */
2210 {
2211 return 2; /* return error */
2212 }
2213 if (handle->inited != 1) /* check handle initialization */
2214 {
2215 return 3; /* return error */
2216 }
2217
2218 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2219 {
2220 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
2221 {
2222 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_JEDEC_ID, 1,
2223 0x00000000, 0x00, 0x00,
2224 0x00000000, 0x00, 0x00,
2225 0, NULL, 0x00,
2226 (uint8_t *)out, 3, 1); /* qspi write read */
2227 if (res != 0) /* check result */
2228 {
2229 handle->debug_print("w25qxx: get jedec id failed.\n"); /* get jedec id failed */
2230
2231 return 1; /* return error */
2232 }
2233 *manufacturer = out[0]; /* set manufacturer */
2234 device_id[0] = out[1]; /* set device id 0 */
2235 device_id[1] = out[2]; /* set device id 1 */
2236 }
2237 else /* single spi */
2238 {
2239 buf[0] = W25QXX_COMMAND_JEDEC_ID; /* jedec id command */
2240 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1,
2241 (uint8_t *)out, 3); /* spi write read */
2242 if (res != 0) /* check result */
2243 {
2244 handle->debug_print("w25qxx: get jedec id failed.\n"); /* get jedec id failed */
2245
2246 return 1; /* return error */
2247 }
2248 *manufacturer = out[0]; /* set manufacturer */
2249 device_id[0] = out[1]; /* set device id 0 */
2250 device_id[1] = out[2]; /* set device id 1 */
2251 }
2252 }
2253 else /* qspi interface */
2254 {
2255 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_JEDEC_ID, 4,
2256 0x00000000, 0x00, 0x00,
2257 0x00000000, 0x00, 0x00,
2258 0, NULL, 0x00,
2259 (uint8_t *)out, 3, 4); /* qspi write read */
2260 if (res != 0) /* check result */
2261 {
2262 handle->debug_print("w25qxx: get jedec id failed.\n"); /* get jedec id failed */
2263
2264 return 1; /* return error */
2265 }
2266 *manufacturer = out[0]; /* set manufacturer */
2267 device_id[0] = out[1]; /* set device id 0 */
2268 device_id[1] = out[2]; /* set device id 1 */
2269 }
2270
2271 return 0; /* success return 0 */
2272 }
2273
2284 uint8_t w25qxx_global_block_lock(w25qxx_handle_t *handle)
2285 {
2286 uint8_t res;
2287 uint8_t buf[1];
2288
2289 if (handle == NULL) /* check handle */
2290 {
2291 return 2; /* return error */
2292 }
2293 if (handle->inited != 1) /* check handle initialization */
2294 {
2295 return 3; /* return error */
2296 }
2297
2298 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2299 {
2300 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
2301 {
2302 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_LOCK, 1,
2303 0x00000000, 0x00, 0x00,
2304 0x00000000, 0x00, 0x00,
2305 0, NULL, 0x00,
2306 NULL, 0x00, 0x00); /* qspi write read */
2307 if (res != 0) /* check result */
2308 {
2309 handle->debug_print("w25qxx: global block lock failed.\n"); /* global block lock failed */
2310
2311 return 1; /* return error */
2312 }
2313 }
2314 else /* single spi */
2315 {
2316 buf[0] = W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_LOCK; /* global block lock command */
2317 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
2318 if (res != 0) /* check result */
2319 {
2320 handle->debug_print("w25qxx: global block lock failed.\n"); /* global block lock failed */
2321
2322 return 1; /* return error */
2323 }
2324 }
2325 }
2326 else /* qspi interface */
2327 {
2328 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_LOCK, 4,
2329 0x00000000, 0x00, 0x00,
2330 0x00000000, 0x00, 0x00,
2331 0, NULL, 0x00,
2332 NULL, 0x00, 0x00); /* qspi write read */
2333 if (res != 0) /* check result */
2334 {
2335 handle->debug_print("w25qxx: global block lock failed.\n"); /* global block lock failed */
2336
2337 return 1; /* return error */
2338 }
2339 }
2340
2341 return 0; /* success return 0 */
2342 }
2343
2354 uint8_t w25qxx_global_block_unlock(w25qxx_handle_t *handle)
2355 {
2356 uint8_t res;
2357 uint8_t buf[1];
2358
2359 if (handle == NULL) /* check handle */
2360 {
2361 return 2; /* return error */
2362 }
2363 if (handle->inited != 1) /* check handle initialization */
2364 {
2365 return 3; /* return error */
2366 }
2367
2368 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2369 {
2370 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
2371 {
2372 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_UNLOCK, 1,
2373 0x00000000, 0x00, 0x00,
2374 0x00000000, 0x00, 0x00,
2375 0, NULL, 0x00,
2376 NULL, 0x00, 0x00); /* qspi write read */
2377 if (res != 0) /* check result */
2378 {
2379 handle->debug_print("w25qxx: global block unlock failed.\n"); /* global block unlock failed */
2380
2381 return 1; /* return error */
2382 }
2383 }
2384 else /* single spi */
2385 {
2386 buf[0] = W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_UNLOCK; /* global block unlock command */
2387 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi qspi write read */
2388 if (res != 0) /* check result */
2389 {
2390 handle->debug_print("w25qxx: global block unlock failed.\n"); /* global block unlock failed */
2391
2392 return 1; /* return error */
2393 }
2394 }
2395 }
2396 else /* qspi interface */
2397 {
2398 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_UNLOCK, 4,
2399 0x00000000, 0x00, 0x00,
2400 0x00000000, 0x00, 0x00,
2401 0, NULL, 0x00,
2402 NULL, 0x00, 0x00); /* qspi write read */
2403 if (res != 0) /* check result */
2404 {
2405 handle->debug_print("w25qxx: global block unlock failed.\n"); /* global block unlock failed */
2406
2407 return 1; /* return error */
2408 }
2409 }
2410
2411 return 0; /* success return 0 */
2412 }
2413
2427 uint8_t w25qxx_set_read_parameters(w25qxx_handle_t *handle, w25qxx_qspi_read_dummy_t dummy, w25qxx_qspi_read_wrap_length_t length)
2428 {
2429 uint8_t res;
2430 uint8_t buf[1];
2431
2432 if (handle == NULL) /* check handle */
2433 {
2434 return 2; /* return error */
2435 }
2436 if (handle->inited != 1) /* check handle initialization */
2437 {
2438 return 3; /* return error */
2439 }
2440
2441 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2442 {
2443 handle->debug_print("w25qxx: spi interface can't use this function.\n"); /* spi interface can't use this function */
2444
2445 return 4; /* return error */
2446 }
2447 else
2448 {
2449 handle->param = (uint8_t)((dummy << 4) | (length << 0)); /* set param */
2450 buf[0] = handle->param; /* set param */
2451 res = a_w25qxx_qspi_write_read(handle, 0xC0, 4,
2452 0x00000000, 0x00, 0x00,
2453 0x00000000, 0x00, 0x00,
2454 0, (uint8_t *)buf, 1,
2455 NULL, 0x00, 4); /* qspi write read */
2456 if (res != 0) /* check result */
2457 {
2458 handle->debug_print("w25qxx: set read parameters failed.\n"); /* set read parameters failed */
2459
2460 return 5; /* return error */
2461 }
2462 if (((buf[0] >> 4) & 0x03) == 0x00) /* if 0x00 */
2463 {
2464 handle->dummy = 2; /* dummy 2 */
2465 }
2466 else if (((buf[0] >> 4) & 0x03) == 0x01) /* if 0x01 */
2467 {
2468 handle->dummy = 4; /* dummy 4 */
2469 }
2470 else if (((buf[0] >> 4) & 0x03) == 0x02) /* if 0x02 */
2471 {
2472 handle->dummy = 6; /* dummy 6 */
2473 }
2474 else /* if 0x03 */
2475 {
2476 handle->dummy = 8; /* dummy 8 */
2477 }
2478 }
2479
2480 return 0; /* success return 0 */
2481 }
2482
2494 uint8_t w25qxx_enter_qspi_mode(w25qxx_handle_t *handle)
2495 {
2496 uint8_t res;
2497 uint8_t buf[1];
2498
2499 if (handle == NULL) /* check handle */
2500 {
2501 return 2; /* return error */
2502 }
2503 if (handle->inited != 1) /* check handle initialization */
2504 {
2505 return 3; /* return error */
2506 }
2507
2508 if (handle->spi_qspi == W25QXX_INTERFACE_QSPI) /* qspi interface */
2509 {
2510 handle->debug_print("w25qxx: qspi interface can't use this function.\n"); /* qspi interface can't use this function */
2511
2512 return 4; /* return error */
2513 }
2514 else
2515 {
2516 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_ENTER_QSPI_MODE, 1,
2517 0x00000000, 0x00, 0x00,
2518 0x00000000, 0x00, 0x00,
2519 0, NULL, 0x00,
2520 NULL, 0x00, 0x00); /* qspi write read */
2521 if (res != 0) /* check result */
2522 {
2523 handle->debug_print("w25qxx: enter qspi mode failed.\n"); /* enter qspi mode failed */
2524
2525 return 1; /* return error */
2526 }
2527 handle->delay_ms(10); /* delay 10 ms */
2528 buf[0] = handle->param; /* set param */
2529 res = a_w25qxx_qspi_write_read(handle, 0xC0, 4,
2530 0x00000000, 0x00, 0x00,
2531 0x00000000, 0x00, 0x00,
2532 0, (uint8_t *)buf, 1,
2533 NULL, 0x00, 4); /* qspi write read */
2534 if (res != 0) /* check result */
2535 {
2536 handle->debug_print("w25qxx: set read parameters failed.\n"); /* set read parameters failed */
2537
2538 return 5; /* return error */
2539 }
2540 if (((buf[0] >> 4) & 0x03) == 0x00) /* if 0x00 */
2541 {
2542 handle->dummy = 2; /* dummy 2 */
2543 }
2544 else if (((buf[0] >> 4) & 0x03) == 0x01) /* if 0x01 */
2545 {
2546 handle->dummy = 4; /* dummy 4 */
2547 }
2548 else if (((buf[0] >> 4) & 0x03) == 0x02) /* if 0x02 */
2549 {
2550 handle->dummy = 6; /* dummy 6 */
2551 }
2552 else /* if 0x03 */
2553 {
2554 handle->dummy = 8; /* dummy 8 */
2555 }
2556 }
2557
2558 return 0; /* success return 0 */
2559 }
2560
2572 uint8_t w25qxx_exit_qspi_mode(w25qxx_handle_t *handle)
2573 {
2574 uint8_t res;
2575
2576 if (handle == NULL) /* check handle */
2577 {
2578 return 2; /* return error */
2579 }
2580 if (handle->inited != 1) /* check handle initialization */
2581 {
2582 return 3; /* return error */
2583 }
2584
2585 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2586 {
2587 handle->debug_print("w25qxx: spi interface can't use this function.\n"); /* spi interface can't use this function */
2588
2589 return 4; /* return error */
2590 }
2591 else
2592 {
2593 res = a_w25qxx_qspi_write_read(handle, 0xFF, 4,
2594 0x00000000, 0x00, 0x00,
2595 0x00000000, 0x00, 0x00,
2596 0, NULL, 0x00,
2597 NULL, 0x00, 0x00); /* qspi write read */
2598 if (res != 0) /* check result */
2599 {
2600 handle->debug_print("w25qxx: exit qspi mode failed.\n"); /* exit qspi mode failed */
2601
2602 return 1; /* return error */
2603 }
2604 }
2605
2606 return 0; /* success return 0 */
2607 }
2608
2619 uint8_t w25qxx_enable_reset(w25qxx_handle_t *handle)
2620 {
2621 uint8_t res;
2622 uint8_t buf[1];
2623
2624 if (handle == NULL) /* check handle */
2625 {
2626 return 2; /* return error */
2627 }
2628 if (handle->inited != 1) /* check handle initialization */
2629 {
2630 return 3; /* return error */
2631 }
2632
2633 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2634 {
2635 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
2636 {
2637 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_ENABLE_RESET, 1,
2638 0x00000000, 0x00, 0x00,
2639 0x00000000, 0x00, 0x00,
2640 0, NULL, 0x00,
2641 NULL, 0x00, 0x00); /* qspi write read */
2642 if (res != 0) /* check result */
2643 {
2644 handle->debug_print("w25qxx: enable reset failed.\n"); /* enable reset failed */
2645
2646 return 1; /* return error */
2647 }
2648 }
2649 else /* single spi */
2650 {
2651 buf[0] = W25QXX_COMMAND_ENABLE_RESET; /* enable reset command */
2652 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf,
2653 1, NULL, 0); /* spi write read */
2654 if (res != 0) /* check result */
2655 {
2656 handle->debug_print("w25qxx: enable reset failed.\n"); /* enable reset failed */
2657
2658 return 1; /* return error */
2659 }
2660 }
2661 }
2662 else /* qspi interface */
2663 {
2664 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_ENABLE_RESET, 4,
2665 0x00000000, 0x00, 0x00,
2666 0x00000000, 0x00, 0x00,
2667 0, NULL, 0x00,
2668 NULL, 0x00, 0x00); /* qspi write read */
2669 if (res != 0) /* check result */
2670 {
2671 handle->debug_print("w25qxx: enable reset failed.\n"); /* enable reset failed */
2672
2673 return 1; /* return error */
2674 }
2675 }
2676
2677 return 0; /* success return 0 */
2678 }
2679
2690 uint8_t w25qxx_reset_device(w25qxx_handle_t *handle)
2691 {
2692 uint8_t res;
2693 uint8_t buf[1];
2694
2695 if (handle == NULL) /* check handle */
2696 {
2697 return 2; /* return error */
2698 }
2699 if (handle->inited != 1) /* check handle initialization */
2700 {
2701 return 3; /* return error */
2702 }
2703
2704 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2705 {
2706 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
2707 {
2708 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_RESET_DEVICE, 1,
2709 0x00000000, 0x00, 0x00,
2710 0x00000000, 0x00, 0x00,
2711 0, NULL, 0x00,
2712 NULL, 0x00, 0x00); /* qspi write read */
2713 if (res != 0) /* check result */
2714 {
2715 handle->debug_print("w25qxx: reset device failed.\n"); /* reset device failed */
2716
2717 return 1; /* return error */
2718 }
2719 }
2720 else /* single spi */
2721 {
2722 buf[0] = W25QXX_COMMAND_RESET_DEVICE; /* reset device command */
2723 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf,
2724 1, NULL, 0); /* spi write read */
2725 if (res != 0) /* check result */
2726 {
2727 handle->debug_print("w25qxx: reset device failed.\n"); /* reset device failed */
2728
2729 return 1; /* return error */
2730 }
2731 }
2732 }
2733 else /* qspi interface */
2734 {
2735 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_RESET_DEVICE, 4,
2736 0x00000000, 0x00, 0x00,
2737 0x00000000, 0x00, 0x00,
2738 0, NULL, 0x00,
2739 NULL, 0x00, 0x00); /* qspi write read */
2740 if (res != 0) /* check result */
2741 {
2742 handle->debug_print("w25qxx: reset device failed.\n"); /* reset device failed */
2743
2744 return 1; /* return error */
2745 }
2746 }
2747
2748 return 0; /* success return 0 */
2749 }
2750
2764 uint8_t w25qxx_get_unique_id(w25qxx_handle_t *handle, uint8_t id[8])
2765 {
2766 uint8_t res;
2767 uint8_t buf[6];
2768
2769 if (handle == NULL) /* check handle */
2770 {
2771 return 2; /* return error */
2772 }
2773 if (handle->inited != 1) /* check handle initialization */
2774 {
2775 return 3; /* return error */
2776 }
2777
2778 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2779 {
2780 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
2781 {
2782 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
2783 {
2784 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_UNIQUE_ID, 1,
2785 0x00000000, 0x00, 0x00,
2786 0x00000000, 0x00, 0x00,
2787 4 * 8, NULL, 0x00,
2788 (uint8_t *)id, 8, 1); /* qspi write read */
2789 if (res != 0) /* check result */
2790 {
2791 handle->debug_print("w25qxx: read unique id failed.\n"); /* read unique id failed */
2792
2793 return 1; /* return error */
2794 }
2795 }
2796 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
2797 {
2798 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_UNIQUE_ID, 1,
2799 0x00000000, 0x00, 0x00,
2800 0x00000000, 0x00, 0x00,
2801 5 * 8, NULL, 0x00,
2802 (uint8_t *)id, 8, 1); /* qspi write read */
2803 if (res != 0) /* check result */
2804 {
2805 handle->debug_print("w25qxx: read unique id failed.\n"); /* read unique id failed */
2806
2807 return 1; /* return error */
2808 }
2809 }
2810 else
2811 {
2812 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
2813
2814 return 4; /* return error */
2815 }
2816 }
2817 else /* single spi */
2818 {
2819 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
2820 {
2821 buf[0] = W25QXX_COMMAND_READ_UNIQUE_ID; /* read unique id command */
2822 buf[1] = 0x00; /* dummy */
2823 buf[2] = 0x00; /* dummy */
2824 buf[3] = 0x00; /* dummy */
2825 buf[4] = 0x00; /* dummy */
2826 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, (uint8_t *)id, 8); /* spi write read */
2827 if (res != 0) /* check result */
2828 {
2829 handle->debug_print("w25qxx: read unique id failed.\n"); /* read unique id failed */
2830
2831 return 1; /* return error */
2832 }
2833 }
2834 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
2835 {
2836 buf[0] = W25QXX_COMMAND_READ_UNIQUE_ID; /* read unique id command */
2837 buf[1] = 0x00; /* dummy */
2838 buf[2] = 0x00; /* dummy */
2839 buf[3] = 0x00; /* dummy */
2840 buf[4] = 0x00; /* dummy */
2841 buf[5] = 0x00; /* dummy */
2842 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 6, (uint8_t *)id, 8); /* spi write read */
2843 if (res != 0) /* check result */
2844 {
2845 handle->debug_print("w25qxx: read unique id failed.\n"); /* read unique id failed */
2846
2847 return 1; /* return error */
2848 }
2849 }
2850 else
2851 {
2852 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
2853
2854 return 4; /* return error */
2855 }
2856 }
2857 }
2858 else /* qspi interface */
2859 {
2860 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
2861
2862 return 5; /* return error */
2863 }
2864
2865 return 0; /* success return 0 */
2866 }
2867
2880 uint8_t w25qxx_get_sfdp(w25qxx_handle_t *handle, uint8_t sfdp[256])
2881 {
2882 uint8_t res;
2883 uint8_t buf[5];
2884
2885 if (handle == NULL) /* check handle */
2886 {
2887 return 2; /* return error */
2888 }
2889 if (handle->inited != 1) /* check handle initialization */
2890 {
2891 return 3; /* return error */
2892 }
2893
2894 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2895 {
2896 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
2897 {
2898 res = a_w25qxx_qspi_write_read(handle,
2899 W25QXX_COMMAND_READ_SFDP_REGISTER, 1,
2900 0x00000000, 1, 3,
2901 0x00000000, 0x00, 0x00,
2902 8, NULL, 0x00,
2903 (uint8_t *)sfdp, 256, 1); /* qspi write read */
2904 if (res != 0) /* check result */
2905 {
2906 handle->debug_print("w25qxx: read unique id failed.\n"); /* read unique id failed */
2907
2908 return 1; /* return error */
2909 }
2910 }
2911 else /* single spi */
2912 {
2913 buf[0] = W25QXX_COMMAND_READ_SFDP_REGISTER; /* read sfdp command */
2914 buf[1] = 0x00; /* 0x00 */
2915 buf[2] = 0x00; /* 0x00 */
2916 buf[3] = 0x00; /* 0x00 */
2917 buf[4] = 0x00; /* dummy */
2918 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5,
2919 (uint8_t *)sfdp, 256); /* spi write read */
2920 if (res != 0) /* check result */
2921 {
2922 handle->debug_print("w25qxx: get sfdp failed.\n"); /* get sfdp failed */
2923
2924 return 1; /* return error */
2925 }
2926 }
2927 }
2928 else /* qspi interface */
2929 {
2930 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
2931
2932 return 4; /* return error */
2933 }
2934
2935 return 0; /* success return 0 */
2936 }
2937
2952 uint8_t w25qxx_erase_security_register(w25qxx_handle_t *handle, w25qxx_security_register_t num)
2953 {
2954 uint8_t res;
2955 uint8_t status;
2956 uint32_t timeout;
2957 uint8_t buf[5];
2958
2959 if (handle == NULL) /* check handle */
2960 {
2961 return 2; /* return error */
2962 }
2963 if (handle->inited != 1) /* check handle initialization */
2964 {
2965 return 3; /* return error */
2966 }
2967
2968 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
2969 {
2970 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
2971 {
2972 res = a_w25qxx_qspi_write_read(handle,
2973 W25QXX_COMMAND_WRITE_ENABLE, 1,
2974 0x00000000, 0x00, 0x00,
2975 0x00000000, 0x00, 0x00,
2976 0x00, NULL, 0x00,
2977 NULL, 0x00, 0x00); /* qspi write read */
2978 if (res != 0) /* check result */
2979 {
2980 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
2981
2982 return 1; /* return error */
2983 }
2984 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
2985 {
2986 res = a_w25qxx_qspi_write_read(handle,
2987 W25QXX_COMMAND_ERASE_SECURITY_REGISTER, 1,
2988 num << 8, 1, 3,
2989 0x00000000, 0x00, 0x00,
2990 0x00, NULL, 0x00,
2991 NULL, 0x00, 0x00); /* qspi write read */
2992 if (res != 0) /* check result */
2993 {
2994 handle->debug_print("w25qxx: erase security register failed.\n"); /* erase security register failed */
2995
2996 return 1; /* return error */
2997 }
2998 }
2999 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
3000 {
3001 res = a_w25qxx_qspi_write_read(handle,
3002 W25QXX_COMMAND_ERASE_SECURITY_REGISTER, 1,
3003 num << 8, 1, 4,
3004 0x00000000, 0x00, 0x00,
3005 0x00, NULL, 0x00,
3006 NULL, 0x00, 0x00); /* qspi write read */
3007 if (res != 0) /* check result */
3008 {
3009 handle->debug_print("w25qxx: erase security register failed.\n"); /* erase security register failed */
3010
3011 return 1; /* return error */
3012 }
3013 }
3014 else
3015 {
3016 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3017
3018 return 4; /* return error */
3019 }
3020
3021 timeout = 100 * 100; /* max 1000 ms */
3022 while (timeout != 0) /* check timeout */
3023 {
3024 res = a_w25qxx_qspi_write_read(handle,
3025 W25QXX_COMMAND_READ_STATUS_REG1, 1,
3026 0x00000000, 0x00, 0x00,
3027 0x00000000, 0x00, 0x00,
3028 0x00, NULL, 0x00,
3029 (uint8_t *)&status, 1, 1); /* qspi write read */
3030 if (res != 0) /* check result */
3031 {
3032 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
3033
3034 return 1; /* return error */
3035 }
3036 if ((status & 0x01) == 0x00) /* check status */
3037 {
3038 break; /* break */
3039 }
3040 timeout--; /* timeout-- */
3041 handle->delay_us(10); /* delay 10 us */
3042 }
3043 if (timeout == 0)
3044 {
3045 handle->debug_print("w25qxx: erase security register timeout.\n"); /* erase security register timeout */
3046
3047 return 6; /* return error */
3048 }
3049 }
3050 else /* single spi */
3051 {
3052 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
3053 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
3054 if (res != 0) /* check result */
3055 {
3056 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3057
3058 return 1; /* return error */
3059 }
3060 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3061 {
3062 buf[0] = W25QXX_COMMAND_ERASE_SECURITY_REGISTER; /* erase security register command */
3063 buf[1] = 0x00; /* 0x00 */
3064 buf[2] = num; /* num */
3065 buf[3] = 0x00; /* 0x00 */
3066 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, NULL, 0); /* spi write read */
3067 if (res != 0) /* check result */
3068 {
3069 handle->debug_print("w25qxx: erase security register failed.\n"); /* erase security register failed */
3070
3071 return 1; /* return error */
3072 }
3073 }
3074 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
3075 {
3076 buf[0] = W25QXX_COMMAND_ERASE_SECURITY_REGISTER; /* erase security register command */
3077 buf[1] = 0x00; /* 0x00 */
3078 buf[2] = 0x00; /* 0x00 */
3079 buf[3] = num; /* num */
3080 buf[4] = 0x00; /* 0x00 */
3081 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, NULL, 0); /* spi write read */
3082 if (res != 0) /* check result */
3083 {
3084 handle->debug_print("w25qxx: erase security register failed.\n"); /* erase security register failed */
3085
3086 return 1; /* return error */
3087 }
3088 }
3089 else
3090 {
3091 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3092
3093 return 4; /* return error */
3094 }
3095
3096 timeout = 100 * 100; /* max 1000 ms */
3097 while (timeout != 0) /* check timeout */
3098 {
3099 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
3100 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, (uint8_t *)&status, 1); /* spi write read */
3101 if (res != 0) /* check result */
3102 {
3103 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
3104
3105 return 1; /* return error */
3106 }
3107 if ((status & 0x01) == 0x00) /* check status */
3108 {
3109 break; /* break */
3110 }
3111 timeout--; /* timeout-- */
3112 handle->delay_us(10); /* delay 10 us */
3113 }
3114 if (timeout == 0)
3115 {
3116 handle->debug_print("w25qxx: erase security register timeout.\n"); /* erase security register timeout */
3117
3118 return 6; /* return error */
3119 }
3120 }
3121 }
3122 else /* qspi interface */
3123 {
3124 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
3125
3126 return 5; /* return error */
3127 }
3128
3129 return 0; /* success return 0 */
3130 }
3131
3147 uint8_t w25qxx_program_security_register(w25qxx_handle_t *handle, w25qxx_security_register_t num, uint8_t data[256])
3148 {
3149 uint8_t res;
3150 uint8_t status;
3151 uint32_t timeout;
3152 uint8_t buf[5];
3153
3154 if (handle == NULL) /* check handle */
3155 {
3156 return 2; /* return error */
3157 }
3158 if (handle->inited != 1) /* check handle initialization */
3159 {
3160 return 3; /* return error */
3161 }
3162
3163 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
3164 {
3165 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
3166 {
3167 res = a_w25qxx_qspi_write_read(handle,
3168 W25QXX_COMMAND_WRITE_ENABLE, 1,
3169 0x00000000, 0x00, 0x00,
3170 0x00000000, 0x00, 0x00,
3171 0x00, NULL, 0x00,
3172 NULL, 0x00, 0x00); /* qspi write read */
3173 if (res != 0) /* check result */
3174 {
3175 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3176
3177 return 1; /* return error */
3178 }
3179 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3180 {
3181 res = a_w25qxx_qspi_write_read(handle,
3182 W25QXX_COMMAND_PROGRAM_SECURITY_REGISTER, 1,
3183 num << 8, 1, 3,
3184 0x00000000, 0x00, 0x00,
3185 0x00, data, 256,
3186 NULL, 0x00, 1); /* qspi write read */
3187 if (res != 0) /* check result */
3188 {
3189 handle->debug_print("w25qxx: program security register failed.\n"); /* program security register failed */
3190
3191 return 1; /* return error */
3192 }
3193 }
3194 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
3195 {
3196 res = a_w25qxx_qspi_write_read(handle,
3197 W25QXX_COMMAND_PROGRAM_SECURITY_REGISTER, 1,
3198 num << 8, 1, 4,
3199 0x00000000, 0x00, 0x00,
3200 0x00, data, 256,
3201 NULL, 0x00, 1); /* qspi write read */
3202 if (res != 0) /* check result */
3203 {
3204 handle->debug_print("w25qxx: program security register failed.\n"); /* program security register failed */
3205
3206 return 1; /* return error */
3207 }
3208 }
3209 else
3210 {
3211 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3212
3213 return 4; /* return error */
3214 }
3215
3216 timeout = 3 * 100; /* max 3 ms */
3217 while (timeout != 0) /* check timeout */
3218 {
3219 res = a_w25qxx_qspi_write_read(handle,
3220 W25QXX_COMMAND_READ_STATUS_REG1, 1,
3221 0x00000000, 0x00, 0x00,
3222 0x00000000, 0x00, 0x00,
3223 0x00, NULL, 0x00,
3224 (uint8_t *)&status, 1, 1); /* qspi write read */
3225 if (res != 0) /* check result */
3226 {
3227 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
3228
3229 return 1; /* return error */
3230 }
3231 if ((status & 0x01) == 0x00) /* check status */
3232 {
3233 break; /* break */
3234 }
3235 timeout--; /* timeout-- */
3236 handle->delay_us(10); /* delay 10 us */
3237 }
3238 if (timeout == 0)
3239 {
3240 handle->debug_print("w25qxx: program security register timeout.\n"); /* program security register timeout */
3241
3242 return 6; /* return error */
3243 }
3244 }
3245 else /* single spi */
3246 {
3247 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
3248 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
3249 if (res != 0) /* check result */
3250 {
3251 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3252
3253 return 1; /* return error */
3254 }
3255 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3256 {
3257 handle->buf[0] = W25QXX_COMMAND_PROGRAM_SECURITY_REGISTER; /* program security register command */
3258 handle->buf[1] = 0x00; /* 0x00 */
3259 handle->buf[2] = num; /* num */
3260 handle->buf[3] = 0x00; /* 0x00 */
3261 memcpy(&handle->buf[4], data, 256); /* copy data */
3262 res = a_w25qxx_spi_write_read(handle, (uint8_t *)handle->buf, 260, NULL, 0); /* spi write read */
3263 if (res != 0) /* check result */
3264 {
3265 handle->debug_print("w25qxx: program security register failed.\n"); /* program security register failed */
3266
3267 return 1; /* return error */
3268 }
3269 }
3270 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
3271 {
3272 handle->buf[0] = W25QXX_COMMAND_PROGRAM_SECURITY_REGISTER; /* program security register command */
3273 handle->buf[1] = 0x00; /* 0x00 */
3274 handle->buf[2] = 0x00; /* 0x00 */
3275 handle->buf[3] = num; /* num */
3276 handle->buf[4] = 0x00; /* 0x00 */
3277 memcpy(&handle->buf[5], data, 256); /* copy data */
3278 res = a_w25qxx_spi_write_read(handle, (uint8_t *)handle->buf, 261, NULL, 0); /* spi write read */
3279 if (res != 0) /* check result */
3280 {
3281 handle->debug_print("w25qxx: program security register failed.\n"); /* program security register failed */
3282
3283 return 1; /* return error */
3284 }
3285 }
3286 else
3287 {
3288 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3289
3290 return 4; /* return error */
3291 }
3292
3293 timeout = 3 * 100; /* max 3 ms */
3294 while (timeout != 0) /* check timeout */
3295 {
3296 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
3297 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, (uint8_t *)&status, 1); /* spi write read */
3298 if (res != 0) /* check result */
3299 {
3300 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
3301
3302 return 1; /* return error */
3303 }
3304 if ((status & 0x01) == 0x00) /* check status */
3305 {
3306 break; /* break */
3307 }
3308 timeout--; /* timeout-- */
3309 handle->delay_us(10); /* delay 10 us */
3310 }
3311 if (timeout == 0)
3312 {
3313 handle->debug_print("w25qxx: program security register timeout.\n"); /* program security register timeout */
3314
3315 return 6; /* return error */
3316 }
3317 }
3318 }
3319 else /* qspi interface */
3320 {
3321 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
3322
3323 return 5; /* return error */
3324 }
3325
3326 return 0; /* success return 0 */
3327 }
3328
3344 uint8_t w25qxx_read_security_register(w25qxx_handle_t *handle, w25qxx_security_register_t num, uint8_t data[256])
3345 {
3346 uint8_t res;
3347 uint8_t buf[6];
3348
3349 if (handle == NULL) /* check handle */
3350 {
3351 return 2; /* return error */
3352 }
3353 if (handle->inited != 1) /* check handle initialization */
3354 {
3355 return 3; /* return error */
3356 }
3357
3358 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
3359 {
3360 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
3361 {
3362 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3363 {
3364 res = a_w25qxx_qspi_write_read(handle,
3365 W25QXX_COMMAND_READ_SECURITY_REGISTER, 1,
3366 num << 8, 1, 3,
3367 0x00000000, 0x00, 0x00,
3368 8, NULL, 0x00,
3369 data, 256, 1); /* qspi write read */
3370 if (res != 0) /* check result */
3371 {
3372 handle->debug_print("w25qxx: read security register failed.\n"); /* read security register failed */
3373
3374 return 1; /* return error */
3375 }
3376 }
3377 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256)) /* 4 address mode */
3378 {
3379 res = a_w25qxx_qspi_write_read(handle,
3380 W25QXX_COMMAND_READ_SECURITY_REGISTER, 1,
3381 num << 8, 1, 4,
3382 0x00000000, 0x00, 0x00,
3383 8, NULL, 0x00,
3384 data, 256, 1); /* qspi write read */
3385 if (res != 0) /* check result */
3386 {
3387 handle->debug_print("w25qxx: read security register failed.\n"); /* read security register failed */
3388
3389 return 1; /* return error */
3390 }
3391 }
3392 else
3393 {
3394 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3395
3396 return 4; /* return error */
3397 }
3398 }
3399 else /* single spi */
3400 {
3401 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3402 {
3403 buf[0] = W25QXX_COMMAND_READ_SECURITY_REGISTER; /* read security register command */
3404 buf[1] = 0x00; /* 0x00 */
3405 buf[2] = num; /* num */
3406 buf[3] = 0x00; /* 0x00 */
3407 buf[4] = 0x00; /* dummy */
3408 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, data, 256); /* spi write read */
3409 if (res != 0) /* check result */
3410 {
3411 handle->debug_print("w25qxx: read security register failed.\n"); /* read security register failed */
3412
3413 return 1; /* return error */
3414 }
3415 }
3416 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
3417 {
3418 buf[0] = W25QXX_COMMAND_READ_SECURITY_REGISTER; /* read security register command */
3419 buf[1] = 0x00; /* 0x00 */
3420 buf[2] = 0x00; /* 0x00 */
3421 buf[3] = num; /* num */
3422 buf[4] = 0x00; /* 0x00 */
3423 buf[5] = 0x00; /* dummy */
3424 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 6, data, 256); /* spi write read */
3425 if (res != 0) /* check result */
3426 {
3427 handle->debug_print("w25qxx: read security register failed.\n"); /* read security register failed */
3428
3429 return 1; /* return error */
3430 }
3431 }
3432 else
3433 {
3434 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3435
3436 return 4; /* return error */
3437 }
3438 }
3439 }
3440 else /* qspi interface */
3441 {
3442 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
3443
3444 return 5; /* return error */
3445 }
3446
3447 return 0; /* success return 0 */
3448 }
3449
3465 uint8_t w25qxx_only_spi_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
3466 {
3467 uint8_t res;
3468 uint8_t buf[5];
3469
3470 if (handle == NULL) /* check handle */
3471 {
3472 return 2; /* return error */
3473 }
3474 if (handle->inited != 1) /* check handle initialization */
3475 {
3476 return 3; /* return error */
3477 }
3478
3479 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
3480 {
3481 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
3482 {
3483 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3484 {
3485 if (handle->type >= W25Q256) /* >128Mb */
3486 {
3487 res = a_w25qxx_qspi_write_read(handle,
3488 W25QXX_COMMAND_WRITE_ENABLE, 1,
3489 0x00000000, 0x00, 0x00,
3490 0x00000000, 0x00, 0x00,
3491 0x00, NULL, 0x00,
3492 NULL, 0x00, 0x00); /* qspi write read */
3493 if (res != 0) /* check result */
3494 {
3495 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3496
3497 return 1; /* return error */
3498 }
3499 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
3500 res = a_w25qxx_qspi_write_read(handle,
3501 0xC5, 1,
3502 0x00000000, 0x00, 0x00,
3503 0x00000000, 0x00, 0x00,
3504 0x00, (uint8_t *)buf, 1,
3505 NULL, 0x00, 1); /* qspi write read */
3506 if (res != 0) /* check result */
3507 {
3508 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
3509
3510 return 1; /* return error */
3511 }
3512
3513 }
3514 res = a_w25qxx_qspi_write_read(handle,
3515 W25QXX_COMMAND_READ_DATA, 1,
3516 addr, 1, 3,
3517 0x00000000, 0x00, 0x00,
3518 0x00, NULL, 0x00,
3519 data, len, 1); /* qspi write read */
3520 if (res != 0) /* check result */
3521 {
3522 handle->debug_print("w25qxx: only spi read failed.\n"); /* only spi read failed */
3523
3524 return 1; /* return error */
3525 }
3526 }
3527 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) &&
3528 (handle->type >= W25Q256)) /* check address mode */
3529 {
3530 res = a_w25qxx_qspi_write_read(handle,
3531 W25QXX_COMMAND_READ_DATA, 1,
3532 addr, 1, 4,
3533 0x00000000, 0x00, 0x00,
3534 0x00, NULL, 0x00,
3535 data, len, 1); /* qspi write read */
3536 if (res != 0) /* check result */
3537 {
3538 handle->debug_print("w25qxx: only spi read failed.\n"); /* only spi read failed */
3539
3540 return 1; /* return error */
3541 }
3542 }
3543 else
3544 {
3545 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3546
3547 return 4; /* return error */
3548 }
3549 }
3550 else /* single spi */
3551 {
3552 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3553 {
3554 if (handle->type >= W25Q256) /* >128Mb */
3555 {
3556 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
3557 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
3558 if (res != 0) /* check result */
3559 {
3560 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3561
3562 return 1; /* return error */
3563 }
3564 buf[0] = 0xC5; /* write extended addr register command */
3565 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
3566 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
3567 if (res != 0) /* check result */
3568 {
3569 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
3570
3571 return 1; /* return error */
3572 }
3573 }
3574 buf[0] = W25QXX_COMMAND_READ_DATA; /* only spi read command */
3575 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
3576 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
3577 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
3578 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, (uint8_t *)data, (uint32_t)len); /* spi write read */
3579 if (res != 0) /* check result */
3580 {
3581 handle->debug_print("w25qxx: only spi read failed.\n"); /* only spi read failed */
3582
3583 return 1; /* return error */
3584 }
3585 }
3586 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) &&
3587 (handle->type >= W25Q256)) /* check address mode */
3588 {
3589 buf[0] = W25QXX_COMMAND_READ_DATA; /* only spi read command */
3590 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
3591 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
3592 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
3593 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
3594 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, (uint8_t *)data, (uint32_t)len); /* spi write read */
3595 if (res != 0) /* check result */
3596 {
3597 handle->debug_print("w25qxx: only spi read failed.\n"); /* only spi read failed */
3598
3599 return 1; /* return error */
3600 }
3601 }
3602 else
3603 {
3604 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3605
3606 return 4; /* return error */
3607 }
3608 }
3609 }
3610 else
3611 {
3612 handle->debug_print("w25qxx: only spi interface can use this function.\n"); /* only spi interface can use this function */
3613
3614 return 5; /* return error */
3615 }
3616
3617 return 0; /* success return 0 */
3618 }
3619
3634 uint8_t w25qxx_fast_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
3635 {
3636 uint8_t res;
3637 uint8_t buf[6];
3638
3639 if (handle == NULL) /* check handle */
3640 {
3641 return 2; /* return error */
3642 }
3643 if (handle->inited != 1) /* check handle initialization */
3644 {
3645 return 3; /* return error */
3646 }
3647
3648 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
3649 {
3650 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
3651 {
3652 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3653 {
3654 if (handle->type >= W25Q256) /* >128Mb */
3655 {
3656 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
3657 0x00000000, 0x00, 0x00,
3658 0x00000000, 0x00, 0x00,
3659 0x00, NULL, 0x00,
3660 NULL, 0x00, 0x00); /* qspi write read */
3661 if (res != 0) /* check result */
3662 {
3663 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3664
3665 return 1; /* return error */
3666 }
3667 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
3668 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
3669 0x00000000, 0x00, 0x00,
3670 0x00000000, 0x00, 0x00,
3671 0, (uint8_t *)buf, 0x01,
3672 NULL, 0x00, 1); /* spi write read */
3673 if (res != 0) /* check result */
3674 {
3675 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
3676
3677 return 1; /* return error */
3678 }
3679 }
3680 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 1,
3681 addr, 1, 3,
3682 0x00000000, 0x00, 0x00,
3683 8, NULL, 0x00,
3684 data, len, 1); /* spi write read */
3685 if (res != 0) /* check result */
3686 {
3687 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
3688
3689 return 1; /* return error */
3690 }
3691 }
3692 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
3693 {
3694 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 1,
3695 addr, 1, 4,
3696 0x00000000, 0x00, 0x00,
3697 8, NULL, 0x00,
3698 data, len, 1); /* spi write read */
3699 if (res != 0) /* check result */
3700 {
3701 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
3702
3703 return 1; /* return error */
3704 }
3705 }
3706 else
3707 {
3708 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3709
3710 return 4; /* return error */
3711 }
3712 }
3713 else /* single spi */
3714 {
3715 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3716 {
3717 if (handle->type >= W25Q256) /* >128Mb */
3718 {
3719 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
3720 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
3721 if (res != 0) /* check result */
3722 {
3723 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3724
3725 return 1; /* return error */
3726 }
3727 buf[0] = 0xC5; /* write extended addr register command */
3728 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
3729 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
3730 if (res != 0) /* check result */
3731 {
3732 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
3733
3734 return 1; /* return error */
3735 }
3736 }
3737 buf[0] = W25QXX_COMMAND_FAST_READ; /* fast read command */
3738 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
3739 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
3740 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
3741 buf[4] = 0x00; /* dummy */
3742 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, (uint8_t *)data, (uint32_t)len); /* spi write read */
3743 if (res != 0) /* check result */
3744 {
3745 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
3746
3747 return 1; /* return error */
3748 }
3749 }
3750 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE)
3751 && (handle->type >= W25Q256)) /* check address mode */
3752 {
3753 buf[0] = W25QXX_COMMAND_FAST_READ; /* fast read command */
3754 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
3755 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
3756 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
3757 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
3758 buf[5] = 0x00; /* dummy */
3759 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 6, (uint8_t *)data, (uint32_t)len); /* spi write read */
3760 if (res != 0) /* check result */
3761 {
3762 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
3763
3764 return 1; /* return error */
3765 }
3766 }
3767 else
3768 {
3769 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3770
3771 return 4; /* return error */
3772 }
3773 }
3774 }
3775 else /* qspi interface */
3776 {
3777 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3778 {
3779 if (handle->type >= W25Q256) /* >128Mb */
3780 {
3781 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
3782 0x00000000, 0x00, 0x00,
3783 0x00000000, 0x00, 0x00,
3784 0x00, NULL, 0x00,
3785 NULL, 0x00, 0x00); /* qspi write read */
3786 if (res != 0) /* check result */
3787 {
3788 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3789
3790 return 1; /* return error */
3791 }
3792 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
3793 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
3794 0x00000000, 0x00, 0x00,
3795 0x00000000, 0x00, 0x00,
3796 0, (uint8_t *)buf, 0x01,
3797 NULL, 0x00, 4); /* spi write read */
3798 if (res != 0) /* check result */
3799 {
3800 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
3801
3802 return 1; /* return error */
3803 }
3804 }
3805 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 4,
3806 addr, 4, 3,
3807 0x00000000, 0x00, 0x00,
3808 handle->dummy, NULL, 0x00,
3809 data, len, 4); /* spi write read */
3810 if (res != 0) /* check result */
3811 {
3812 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
3813
3814 return 1; /* return error */
3815 }
3816 }
3817 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
3818 {
3819 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 4,
3820 addr, 4, 4,
3821 0x00000000, 0x00, 0x00,
3822 handle->dummy, NULL, 0x00, /* spi write */
3823 data, len, 4); /* spi write read */
3824 if (res != 0) /* check result */
3825 {
3826 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
3827
3828 return 1; /* return error */
3829 }
3830 }
3831 else
3832 {
3833 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3834
3835 return 4; /* return error */
3836 }
3837 }
3838
3839 return 0; /* success return 0 */
3840 }
3841
3858 uint8_t w25qxx_fast_read_dual_output(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
3859 {
3860 uint8_t res;
3861 uint8_t buf[1];
3862
3863 if (handle == NULL) /* check handle */
3864 {
3865 return 2; /* return error */
3866 }
3867 if (handle->inited != 1) /* check handle initialization */
3868 {
3869 return 3; /* return error */
3870 }
3871
3872 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
3873 {
3874 if (handle->dual_quad_spi_enable == 0) /* check spi */
3875 {
3876 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
3877
3878 return 6; /* return error */
3879 }
3880 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3881 {
3882 if (handle->type >= W25Q256) /* >128Mb */
3883 {
3884 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
3885 0x00000000, 0x00, 0x00,
3886 0x00000000, 0x00, 0x00,
3887 0x00, NULL, 0x00,
3888 NULL, 0x00, 0x00); /* qspi write read */
3889 if (res != 0) /* check result */
3890 {
3891 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
3892
3893 return 1; /* return error */
3894 }
3895 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
3896 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
3897 0x00000000, 0x00, 0x00,
3898 0x00000000, 0x00, 0x00,
3899 0, (uint8_t *)buf, 0x01,
3900 NULL, 0x00, 1); /* spi write read */
3901 if (res != 0) /* check result */
3902 {
3903 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
3904
3905 return 1; /* return error */
3906 }
3907 }
3908 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_DUAL_OUTPUT, 1,
3909 addr, 1, 3,
3910 0x00000000, 0x00, 0x00,
3911 8, NULL, 0x00, /* spi write */
3912 data, len, 2); /* spi write read */
3913 if (res != 0) /* check result */
3914 {
3915 handle->debug_print("w25qxx: fast read dual output failed.\n"); /* fast read dual output failed */
3916
3917 return 1; /* return error */
3918 }
3919 }
3920 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
3921 {
3922 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_DUAL_OUTPUT, 1,
3923 addr, 1, 4,
3924 0x00000000, 0x00, 0x00,
3925 8, NULL, 0x00, /* spi write */
3926 data, len, 2); /* spi write read */
3927 if (res != 0) /* check result */
3928 {
3929 handle->debug_print("w25qxx: fast read dual output failed.\n"); /* fast read dual output failed */
3930
3931 return 1; /* return error */
3932 }
3933 }
3934 else
3935 {
3936 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
3937
3938 return 4; /* return error */
3939 }
3940 }
3941 else
3942 {
3943 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
3944
3945 return 5; /* return error */
3946 }
3947
3948 return 0; /* success return 0 */
3949 }
3950
3967 uint8_t w25qxx_fast_read_quad_output(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
3968 {
3969 uint8_t res;
3970 uint8_t buf[1];
3971
3972 if (handle == NULL) /* check handle */
3973 {
3974 return 2; /* return error */
3975 }
3976 if (handle->inited != 1) /* check handle initialization */
3977 {
3978 return 3; /* return error */
3979 }
3980
3981 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
3982 {
3983 if (handle->dual_quad_spi_enable == 0) /* check spi */
3984 {
3985 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
3986
3987 return 6; /* return error */
3988 }
3989 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
3990 {
3991 if (handle->type >= W25Q256) /* >128Mb */
3992 {
3993 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
3994 0x00000000, 0x00, 0x00,
3995 0x00000000, 0x00, 0x00,
3996 0x00, NULL, 0x00,
3997 NULL, 0x00, 0x00); /* qspi write read */
3998 if (res != 0) /* check result */
3999 {
4000 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4001
4002 return 1; /* return error */
4003 }
4004 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4005 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
4006 0x00000000, 0x00, 0x00,
4007 0x00000000, 0x00, 0x00,
4008 0, (uint8_t *)buf, 0x01,
4009 NULL, 0x00, 1); /* spi write read */
4010 if (res != 0) /* check result */
4011 {
4012 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4013
4014 return 1; /* return error */
4015 }
4016 }
4017 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_QUAD_OUTPUT, 1,
4018 addr, 1, 3,
4019 0x00000000, 0x00, 0x00,
4020 8, NULL, 0x00, /* spi write */
4021 data, len, 4); /* spi write read */
4022 if (res != 0) /* check result */
4023 {
4024 handle->debug_print("w25qxx: fast read quad output failed.\n"); /* fast read quad output failed */
4025
4026 return 1; /* return error */
4027 }
4028 }
4029 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
4030 {
4031 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_QUAD_OUTPUT, 1,
4032 addr, 1, 4,
4033 0x00000000, 0x00, 0x00,
4034 8, NULL, 0x00, /* spi write */
4035 data, len, 4); /* spi write read */
4036 if (res != 0) /* check result */
4037 {
4038 handle->debug_print("w25qxx: fast read quad output failed.\n"); /* fast read quad output failed */
4039
4040 return 1; /* return error */
4041 }
4042 }
4043 else
4044 {
4045 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4046
4047 return 4; /* return error */
4048 }
4049 }
4050 else
4051 {
4052 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
4053
4054 return 5; /* return error */
4055 }
4056
4057 return 0; /* success return 0 */
4058 }
4059
4076 uint8_t w25qxx_fast_read_dual_io(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
4077 {
4078 uint8_t res;
4079 uint8_t buf[1];
4080
4081 if (handle == NULL) /* check handle */
4082 {
4083 return 2; /* return error */
4084 }
4085 if (handle->inited != 1) /* check handle initialization */
4086 {
4087 return 3; /* return error */
4088 }
4089
4090 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
4091 {
4092 if (handle->dual_quad_spi_enable == 0) /* check spi */
4093 {
4094 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
4095
4096 return 6; /* return error */
4097 }
4098 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4099 {
4100 if (handle->type >= W25Q256) /* >128Mb */
4101 {
4102 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
4103 0x00000000, 0x00, 0x00,
4104 0x00000000, 0x00, 0x00,
4105 0x00, NULL, 0x00,
4106 NULL, 0x00, 0x00); /* qspi write read */
4107 if (res != 0) /* check result */
4108 {
4109 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4110
4111 return 1; /* return error */
4112 }
4113 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4114 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
4115 0x00000000, 0x00, 0x00,
4116 0x00000000, 0x00, 0x00,
4117 0, (uint8_t *)buf, 0x01,
4118 NULL, 0x00, 1); /* spi write read */
4119 if (res != 0) /* check result */
4120 {
4121 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4122
4123 return 1; /* return error */
4124 }
4125 }
4126 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_DUAL_IO, 1,
4127 addr, 2, 3,
4128 0x000000FF, 2, 1,
4129 0, NULL, 0x00, /* spi write */
4130 data, len, 2); /* spi write read */
4131 if (res != 0) /* check result */
4132 {
4133 handle->debug_print("w25qxx: fast read dual io failed.\n"); /* fast read dual io failed */
4134
4135 return 1; /* return error */
4136 }
4137 }
4138 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
4139 {
4140 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_DUAL_IO, 1,
4141 addr, 2, 4,
4142 0x000000FF, 2, 1,
4143 0, NULL, 0x00, /* spi write */
4144 data, len, 2); /* spi write read */
4145 if (res != 0) /* check result */
4146 {
4147 handle->debug_print("w25qxx: fast read dual io failed.\n"); /* fast read io output failed */
4148
4149 return 1; /* return error */
4150 }
4151 }
4152 else
4153 {
4154 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4155
4156 return 4; /* return error */
4157 }
4158 }
4159 else
4160 {
4161 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
4162
4163 return 5; /* return error */
4164 }
4165
4166 return 0; /* success return 0 */
4167 }
4168
4184 uint8_t w25qxx_fast_read_quad_io(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
4185 {
4186 uint8_t res;
4187 uint8_t buf[1];
4188
4189 if (handle == NULL) /* check handle */
4190 {
4191 return 2; /* return error */
4192 }
4193 if (handle->inited != 1) /* check handle initialization */
4194 {
4195 return 3; /* return error */
4196 }
4197
4198 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
4199 {
4200 if (handle->dual_quad_spi_enable == 0) /* check spi */
4201 {
4202 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
4203
4204 return 6; /* return error */
4205 }
4206 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4207 {
4208 if (handle->type >= W25Q256) /* >128Mb */
4209 {
4210 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
4211 0x00000000, 0x00, 0x00,
4212 0x00000000, 0x00, 0x00,
4213 0x00, NULL, 0x00,
4214 NULL, 0x00, 0x00); /* qspi write read */
4215 if (res != 0) /* check result */
4216 {
4217 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4218
4219 return 1; /* return error */
4220 }
4221 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4222 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
4223 0x00000000, 0x00, 0x00,
4224 0x00000000, 0x00, 0x00,
4225 0, (uint8_t *)buf, 0x01,
4226 NULL, 0x00, 1); /* spi write read */
4227 if (res != 0) /* check result */
4228 {
4229 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4230
4231 return 1; /* return error */
4232 }
4233 }
4234 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_QUAD_IO, 1,
4235 addr, 4, 3,
4236 0x000000FF, 4, 1,
4237 4, NULL, 0x00, /* spi write */
4238 data, len, 4); /* spi write read */
4239 if (res != 0) /* check result */
4240 {
4241 handle->debug_print("w25qxx: fast read quad io failed.\n"); /* fast read quad io failed */
4242
4243 return 1; /* return error */
4244 }
4245 }
4246 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
4247 {
4248 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_QUAD_IO, 1,
4249 addr, 4, 4,
4250 0x000000FF, 4, 1,
4251 4, NULL, 0x00, /* spi write */
4252 data, len, 4); /* spi write read */
4253 if (res != 0) /* check result */
4254 {
4255 handle->debug_print("w25qxx: fast read quad io failed.\n"); /* fast quad io output failed */
4256
4257 return 1; /* return error */
4258 }
4259 }
4260 else
4261 {
4262 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4263
4264 return 4; /* return error */
4265 }
4266 }
4267 else
4268 {
4269 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4270 {
4271 if (handle->type >= W25Q256) /* >128Mb */
4272 {
4273 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
4274 0x00000000, 0x00, 0x00,
4275 0x00000000, 0x00, 0x00,
4276 0x00, NULL, 0x00,
4277 NULL, 0x00, 0x00); /* qspi write read */
4278 if (res != 0) /* check result */
4279 {
4280 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4281
4282 return 1; /* return error */
4283 }
4284 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4285 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
4286 0x00000000, 0x00, 0x00,
4287 0x00000000, 0x00, 0x00,
4288 0, (uint8_t *)buf, 0x01,
4289 NULL, 0x00, 4); /* spi write read */
4290 if (res != 0) /* check result */
4291 {
4292 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4293
4294 return 1; /* return error */
4295 }
4296 }
4297 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_QUAD_IO, 4,
4298 addr, 4, 3,
4299 0x000000FF, 4, 1,
4300 handle->dummy, NULL, 0x00,
4301 data, len, 4); /* spi write read */
4302 if (res != 0) /* check result */
4303 {
4304 handle->debug_print("w25qxx: fast read quad io failed.\n"); /* fast read quad io failed */
4305
4306 return 1; /* return error */
4307 }
4308 }
4309 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
4310 {
4311 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ_QUAD_IO, 4,
4312 addr, 4, 4,
4313 0x000000FF, 4, 1,
4314 handle->dummy, NULL, 0x00,
4315 data, len, 4); /* spi write read */
4316 if (res != 0) /* check result */
4317 {
4318 handle->debug_print("w25qxx: fast read quad io failed.\n"); /* fast quad io output failed */
4319
4320 return 1; /* return error */
4321 }
4322 }
4323 else
4324 {
4325 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4326
4327 return 4; /* return error */
4328 }
4329 }
4330
4331 return 0; /* success return 0 */
4332 }
4333
4350 uint8_t w25qxx_word_read_quad_io(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
4351 {
4352 uint8_t res;
4353 uint8_t buf[1];
4354
4355 if (handle == NULL) /* check handle */
4356 {
4357 return 2; /* return error */
4358 }
4359 if (handle->inited != 1) /* check handle initialization */
4360 {
4361 return 3; /* return error */
4362 }
4363
4364 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
4365 {
4366 if (handle->dual_quad_spi_enable == 0) /* check spi */
4367 {
4368 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
4369
4370 return 6; /* return error */
4371 }
4372 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4373 {
4374 if (handle->type >= W25Q256) /* >128Mb */
4375 {
4376 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
4377 0x00000000, 0x00, 0x00,
4378 0x00000000, 0x00, 0x00,
4379 0x00, NULL, 0x00,
4380 NULL, 0x00, 0x00); /* qspi write read */
4381 if (res != 0) /* check result */
4382 {
4383 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4384
4385 return 1; /* return error */
4386 }
4387 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4388 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
4389 0x00000000, 0x00, 0x00,
4390 0x00000000, 0x00, 0x00,
4391 0, (uint8_t *)buf, 0x01,
4392 NULL, 0x00, 1); /* spi write read */
4393 if (res != 0) /* check result */
4394 {
4395 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4396
4397 return 1; /* return error */
4398 }
4399 }
4400 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WORD_READ_QUAD_IO, 1,
4401 addr, 4, 3,
4402 0x000000FF, 4, 1,
4403 2, NULL, 0x00, /* spi write */
4404 data, len, 4); /* spi write read */
4405 if (res != 0) /* check result */
4406 {
4407 handle->debug_print("w25qxx: word read quad io failed.\n"); /* word read quad io failed */
4408
4409 return 1; /* return error */
4410 }
4411 }
4412 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
4413 {
4414 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WORD_READ_QUAD_IO, 1,
4415 addr, 4, 4,
4416 0x000000FF, 4, 1,
4417 2, NULL, 0x00, /* spi write */
4418 data, len, 4); /* spi write read */
4419 if (res != 0) /* check result */
4420 {
4421 handle->debug_print("w25qxx: word read quad io failed.\n"); /* word read quad io failed */
4422
4423 return 1; /* return error */
4424 }
4425 }
4426 else
4427 {
4428 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4429
4430 return 4; /* return error */
4431 }
4432 }
4433 else
4434 {
4435 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
4436
4437 return 5; /* return error */
4438 }
4439
4440 return 0; /* success return 0 */
4441 }
4442
4459 uint8_t w25qxx_octal_word_read_quad_io(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
4460 {
4461 uint8_t res;
4462 uint8_t buf[1];
4463
4464 if (handle == NULL) /* check handle */
4465 {
4466 return 2; /* return error */
4467 }
4468 if (handle->inited != 1) /* check handle initialization */
4469 {
4470 return 3; /* return error */
4471 }
4472
4473 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
4474 {
4475 if (handle->dual_quad_spi_enable == 0) /* check spi */
4476 {
4477 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
4478
4479 return 6; /* return error */
4480 }
4481 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4482 {
4483 if (handle->type >= W25Q256) /* >128Mb */
4484 {
4485 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
4486 0x00000000, 0x00, 0x00,
4487 0x00000000, 0x00, 0x00,
4488 0x00, NULL, 0x00,
4489 NULL, 0x00, 0x00); /* qspi write read */
4490 if (res != 0) /* check result */
4491 {
4492 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4493
4494 return 1; /* return error */
4495 }
4496 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4497 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
4498 0x00000000, 0x00, 0x00,
4499 0x00000000, 0x00, 0x00,
4500 0, (uint8_t *)buf, 0x01,
4501 NULL, 0x00, 1); /* spi write read */
4502 if (res != 0) /* check result */
4503 {
4504 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4505
4506 return 1; /* return error */
4507 }
4508 }
4509 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_OCTAL_WORD_READ_QUAD_IO, 1,
4510 addr, 4, 3,
4511 0x000000FF, 4, 1,
4512 0, NULL, 0x00, /* spi write */
4513 data, len, 4); /* spi write read */
4514 if (res != 0) /* check result */
4515 {
4516 handle->debug_print("w25qxx: octal word read quad io failed.\n"); /* octal word read quad io failed */
4517
4518 return 1; /* return error */
4519 }
4520 }
4521 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
4522 {
4523 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_OCTAL_WORD_READ_QUAD_IO, 1,
4524 addr, 4, 4,
4525 0x000000FF, 4, 1,
4526 0, NULL, 0x00, /* spi write */
4527 data, len, 4); /* spi write read */
4528 if (res != 0) /* check result */
4529 {
4530 handle->debug_print("w25qxx: octal word read quad io failed.\n"); /* octal word read quad io failed */
4531
4532 return 1; /* return error */
4533 }
4534 }
4535 else
4536 {
4537 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4538
4539 return 4; /* return error */
4540 }
4541 }
4542 else
4543 {
4544 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
4545
4546 return 5; /* return error */
4547 }
4548
4549 return 0; /* success return 0 */
4550 }
4551
4569 uint8_t w25qxx_page_program(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint16_t len)
4570 {
4571 uint8_t res;
4572 uint8_t status;
4573 uint32_t timeout;
4574 uint8_t buf[2];
4575
4576 if (handle == NULL) /* check handle */
4577 {
4578 return 2; /* return error */
4579 }
4580 if (handle->inited != 1) /* check handle initialization */
4581 {
4582 return 3; /* return error */
4583 }
4584 if ((addr % 256) != 0) /* check address */
4585 {
4586 handle->debug_print("w25qxx: addr is invalid.\n"); /* addr is invalid */
4587
4588 return 4; /* return error */
4589 }
4590 if (len > 256) /* check address */
4591 {
4592 handle->debug_print("w25qxx: length is over 256.\n"); /* length is over 256 */
4593
4594 return 7; /* return error */
4595 }
4596
4597 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
4598 {
4599 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
4600 {
4601 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
4602 0x00000000, 0x00, 0x00,
4603 0x00000000, 0x00, 0x00,
4604 0x00, NULL, 0x00,
4605 NULL, 0x00, 0x00); /* qspi write read */
4606 if (res != 0) /* check result */
4607 {
4608 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4609
4610 return 1; /* return error */
4611 }
4612 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4613 {
4614 if (handle->type >= W25Q256) /* >128Mb */
4615 {
4616 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4617 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
4618 0x00000000, 0x00, 0x00,
4619 0x00000000, 0x00, 0x00,
4620 0, (uint8_t *)buf, 0x01,
4621 NULL, 0x00, 1); /* spi write read */
4622 if (res != 0) /* check result */
4623 {
4624 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4625
4626 return 1; /* return error */
4627 }
4628 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
4629 0x00000000, 0x00, 0x00,
4630 0x00000000, 0x00, 0x00,
4631 0x00, NULL, 0x00,
4632 NULL, 0x00, 0x00); /* qspi write read */
4633 if (res != 0) /* check result */
4634 {
4635 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4636
4637 return 1; /* return error */
4638 }
4639 }
4640 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_PAGE_PROGRAM, 1,
4641 addr, 1, 3,
4642 0x00000000, 0x00, 0x00,
4643 0, data, len,
4644 NULL, 0x00, 1); /* spi write read */
4645 if (res != 0) /* check result */
4646 {
4647 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
4648
4649 return 1; /* return error */
4650 }
4651 }
4652 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
4653 {
4654 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_PAGE_PROGRAM, 1,
4655 addr, 1, 4,
4656 0x00000000, 0x00, 0x00,
4657 0, data, len,
4658 NULL, 0x00, 1); /* spi write read */
4659 if (res != 0) /* check result */
4660 {
4661 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
4662
4663 return 1; /* return error */
4664 }
4665 }
4666 else
4667 {
4668 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4669
4670 return 5; /* return error */
4671 }
4672
4673 timeout = 3 * 100; /* max 3 ms */
4674 while (timeout != 0) /* check timeout */
4675 {
4676 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
4677 0x00000000, 0x00, 0x00,
4678 0x00000000, 0x00, 0x00,
4679 0, NULL, 0,
4680 (uint8_t *)&status, 1, 1); /* spi write read */
4681 if (res != 0) /* check result */
4682 {
4683 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
4684
4685 return 1; /* return error */
4686 }
4687 if ((status & 0x01) == 0x00) /* check status */
4688 {
4689 break; /* break */
4690 }
4691 timeout--; /* timeout-- */
4692 handle->delay_us(10); /* delay 10 us */
4693 }
4694 if (timeout == 0)
4695 {
4696 handle->debug_print("w25qxx: page program timeout.\n"); /* page program timeout */
4697
4698 return 6; /* return error */
4699 }
4700 }
4701 else /* single spi */
4702 {
4703 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
4704 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
4705 if (res != 0) /* check result */
4706 {
4707 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4708
4709 return 1; /* return error */
4710 }
4711 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4712 {
4713 if (handle->type >= W25Q256) /* >128Mb */
4714 {
4715 buf[0] = 0xC5; /* write extended addr register command */
4716 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4717 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
4718 if (res != 0) /* check result */
4719 {
4720 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4721
4722 return 1; /* return error */
4723 }
4724 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
4725 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
4726 if (res != 0) /* check result */
4727 {
4728 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4729
4730 return 1; /* return error */
4731 }
4732 }
4733 handle->buf[0] = W25QXX_COMMAND_PAGE_PROGRAM; /* page program command */
4734 handle->buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
4735 handle->buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
4736 handle->buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
4737 memcpy(&handle->buf[4], data, len); /* copy data */
4738 res = a_w25qxx_spi_write_read(handle, (uint8_t *)handle->buf, 4 + len, NULL, 0); /* spi write read */
4739 if (res != 0) /* check result */
4740 {
4741 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
4742
4743 return 1; /* return error */
4744 }
4745 }
4746 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE)
4747 && (handle->type >= W25Q256)) /* 4 address mode */
4748 {
4749 handle->buf[0] = W25QXX_COMMAND_PAGE_PROGRAM; /* page program command */
4750 handle->buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4751 handle->buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
4752 handle->buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
4753 handle->buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
4754 memcpy(&handle->buf[5], data, len); /* copy data */
4755 res = a_w25qxx_spi_write_read(handle, (uint8_t *)handle->buf, 5 + len, NULL, 0); /* spi write read */
4756 if (res != 0) /* check result */
4757 {
4758 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
4759
4760 return 1; /* return error */
4761 }
4762 }
4763 else
4764 {
4765 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4766
4767 return 5; /* return error */
4768 }
4769
4770 timeout = 3 * 100; /* max 3 ms */
4771 while (timeout != 0) /* check timeout */
4772 {
4773 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
4774 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, (uint8_t *)&status, 1); /* spi write read */
4775 if (res != 0) /* check result */
4776 {
4777 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
4778
4779 return 1; /* return error */
4780 }
4781 if ((status & 0x01) == 0x00) /* check status */
4782 {
4783 break; /* break */
4784 }
4785 timeout--; /* timeout-- */
4786 handle->delay_us(10); /* delay 10 us */
4787 }
4788 if (timeout == 0)
4789 {
4790 handle->debug_print("w25qxx: page program timeout.\n"); /* page program timeout */
4791
4792 return 6; /* return error */
4793 }
4794 }
4795 }
4796 else
4797 {
4798 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
4799 0x00000000, 0x00, 0x00,
4800 0x00000000, 0x00, 0x00,
4801 0x00, NULL, 0x00,
4802 NULL, 0x00, 0x00); /* qspi write read */
4803 if (res != 0) /* check result */
4804 {
4805 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4806
4807 return 1; /* return error */
4808 }
4809 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4810 {
4811 if (handle->type >= W25Q256) /* >128Mb */
4812 {
4813 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4814 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
4815 0x00000000, 0x00, 0x00,
4816 0x00000000, 0x00, 0x00,
4817 0, (uint8_t *)buf, 0x01,
4818 NULL, 0x00, 4); /* spi write read */
4819 if (res != 0) /* check result */
4820 {
4821 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4822
4823 return 1; /* return error */
4824 }
4825 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
4826 0x00000000, 0x00, 0x00,
4827 0x00000000, 0x00, 0x00,
4828 0x00, NULL, 0x00,
4829 NULL, 0x00, 0x00); /* qspi write read */
4830 if (res != 0) /* check result */
4831 {
4832 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4833
4834 return 1; /* return error */
4835 }
4836 }
4837 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_PAGE_PROGRAM, 4,
4838 addr, 4, 3,
4839 0x00000000, 0x00, 0x00,
4840 0, data, len,
4841 NULL, 0x00, 4); /* spi write read */
4842 if (res != 0) /* check result */
4843 {
4844 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
4845
4846 return 1; /* return error */
4847 }
4848 }
4849 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
4850 {
4851 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_PAGE_PROGRAM, 4,
4852 addr, 4, 4,
4853 0x00000000, 0x00, 0x00,
4854 0, data, len,
4855 NULL, 0x00, 4); /* spi write read */
4856 if (res != 0) /* check result */
4857 {
4858 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
4859
4860 return 1; /* return error */
4861 }
4862 }
4863 else
4864 {
4865 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
4866
4867 return 5; /* return error */
4868 }
4869
4870 timeout = 3 * 100; /* max 3 ms */
4871 while (timeout != 0) /* check timeout */
4872 {
4873 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
4874 0x00000000, 0x00, 0x00,
4875 0x00000000, 0x00, 0x00,
4876 0, NULL, 0,
4877 (uint8_t *)&status, 1, 4); /* spi write read */
4878 if (res != 0) /* check result */
4879 {
4880 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
4881
4882 return 1; /* return error */
4883 }
4884 if ((status & 0x01) == 0x00) /* check status */
4885 {
4886 break; /* break */
4887 }
4888 timeout--; /* timeout-- */
4889 handle->delay_us(10); /* delay 10 us */
4890 }
4891 if (timeout == 0)
4892 {
4893 handle->debug_print("w25qxx: page program timeout.\n"); /* page program timeout */
4894
4895 return 6; /* return error */
4896 }
4897 }
4898
4899 return 0; /* success return 0 */
4900 }
4901
4920 uint8_t w25qxx_page_program_quad_input(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint16_t len)
4921 {
4922 uint8_t res;
4923 uint8_t status;
4924 uint32_t timeout;
4925 uint8_t buf[2];
4926
4927 if (handle == NULL) /* check handle */
4928 {
4929 return 2; /* return error */
4930 }
4931 if (handle->inited != 1) /* check handle initialization */
4932 {
4933 return 3; /* return error */
4934 }
4935 if ((addr % 256) != 0) /* check address */
4936 {
4937 handle->debug_print("w25qxx: addr is invalid.\n"); /* addr is invalid */
4938
4939 return 4; /* return error */
4940 }
4941 if (len > 256) /* check address */
4942 {
4943 handle->debug_print("w25qxx: length is over 256.\n"); /* length is over 256 */
4944
4945 return 7; /* return error */
4946 }
4947
4948 if (handle->spi_qspi == W25QXX_INTERFACE_QSPI) /* qspi interface */
4949 {
4950 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
4951
4952 return 5; /* return error */
4953 }
4954 else
4955 {
4956 if (handle->dual_quad_spi_enable == 0) /* check spi */
4957 {
4958 handle->debug_print("w25qxx: standard spi can't use this function failed.\n"); /* standard spi can't use this function failed */
4959
4960 return 8; /* return error */
4961 }
4962 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
4963 0x00000000, 0x00, 0x00,
4964 0x00000000, 0x00, 0x00,
4965 0x00, NULL, 0x00,
4966 NULL, 0x00, 0x00); /* qspi write read */
4967 if (res != 0) /* check result */
4968 {
4969 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4970
4971 return 1; /* return error */
4972 }
4973 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
4974 {
4975 if (handle->type >= W25Q256) /* >128Mb */
4976 {
4977 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
4978 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
4979 0x00000000, 0x00, 0x00,
4980 0x00000000, 0x00, 0x00,
4981 0, (uint8_t *)buf, 0x01,
4982 NULL, 0x00, 1); /* spi write read */
4983 if (res != 0) /* check result */
4984 {
4985 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
4986
4987 return 1; /* return error */
4988 }
4989 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
4990 0x00000000, 0x00, 0x00,
4991 0x00000000, 0x00, 0x00,
4992 0x00, NULL, 0x00,
4993 NULL, 0x00, 0x00); /* qspi write read */
4994 if (res != 0) /* check result */
4995 {
4996 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
4997
4998 return 1; /* return error */
4999 }
5000 }
5001 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_QUAD_PAGE_PROGRAM, 1,
5002 addr, 1, 3,
5003 0x00000000, 0x00, 0x00,
5004 0, data, len,
5005 NULL, 0x00, 4); /* spi write read */
5006 if (res != 0) /* check result */
5007 {
5008 handle->debug_print("w25qxx: quad page program failed.\n"); /* quad page program failed */
5009
5010 return 1; /* return error */
5011 }
5012 }
5013 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
5014 {
5015 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_QUAD_PAGE_PROGRAM, 1,
5016 addr, 1, 4,
5017 0x00000000, 0x00, 0x00,
5018 0, data, len,
5019 NULL, 0x00, 4); /* spi write read */
5020 if (res != 0) /* check result */
5021 {
5022 handle->debug_print("w25qxx: quad page program failed.\n"); /* quad page program failed */
5023
5024 return 1; /* return error */
5025 }
5026 }
5027 else
5028 {
5029 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5030
5031 return 5; /* return error */
5032 }
5033
5034 timeout = 3 * 100; /* max 3 ms */
5035 while (timeout != 0) /* check timeout */
5036 {
5037 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
5038 0x00000000, 0x00, 0x00,
5039 0x00000000, 0x00, 0x00,
5040 0, NULL, 0,
5041 (uint8_t *)&status, 1, 1); /* spi write read */
5042 if (res != 0) /* check result */
5043 {
5044 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5045
5046 return 1; /* return error */
5047 }
5048 if ((status & 0x01) == 0x00) /* check status */
5049 {
5050 break; /* break */
5051 }
5052 timeout--; /* timeout-- */
5053 handle->delay_us(10); /* delay 10 us */
5054 }
5055 if (timeout == 0)
5056 {
5057 handle->debug_print("w25qxx: quad page program timeout.\n"); /* quad page program timeout */
5058
5059 return 6; /* return error */
5060 }
5061 }
5062
5063 return 0; /* success return 0 */
5064 }
5065
5080 uint8_t w25qxx_sector_erase_4k(w25qxx_handle_t *handle, uint32_t addr)
5081 {
5082 uint8_t res;
5083 uint8_t status;
5084 uint32_t timeout;
5085 uint8_t buf[5];
5086
5087 if (handle == NULL) /* check handle */
5088 {
5089 return 2; /* return error */
5090 }
5091 if (handle->inited != 1) /* check handle initialization */
5092 {
5093 return 3; /* return error */
5094 }
5095 if ((addr % 4096) != 0) /* check address */
5096 {
5097 handle->debug_print("w25qxx: addr is invalid.\n"); /* addr is invalid */
5098
5099 return 4; /* return error */
5100 }
5101
5102 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
5103 {
5104 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
5105 {
5106 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
5107 0x00000000, 0x00, 0x00,
5108 0x00000000, 0x00, 0x00,
5109 0x00, NULL, 0x00,
5110 NULL, 0x00, 0x00); /* qspi write read */
5111 if (res != 0) /* check result */
5112 {
5113 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5114
5115 return 1; /* return error */
5116 }
5117 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5118 {
5119 if (handle->type >= W25Q256) /* >128Mb */
5120 {
5121 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5122 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
5123 0x00000000, 0x00, 0x00,
5124 0x00000000, 0x00, 0x00,
5125 0, (uint8_t *)buf, 0x01,
5126 NULL, 0x00, 1); /* spi write read */
5127 if (res != 0) /* check result */
5128 {
5129 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
5130
5131 return 1; /* return error */
5132 }
5133 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
5134 0x00000000, 0x00, 0x00,
5135 0x00000000, 0x00, 0x00,
5136 0x00, NULL, 0x00,
5137 NULL, 0x00, 0x00); /* qspi write read */
5138 if (res != 0) /* check result */
5139 {
5140 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5141
5142 return 1; /* return error */
5143 }
5144 }
5145 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_SECTOR_ERASE_4K, 1,
5146 addr, 1, 3,
5147 0x00000000, 0x00, 0x00,
5148 0, NULL, 0x00,
5149 NULL, 0x00, 0x00); /* spi write read */
5150 if (res != 0) /* check result */
5151 {
5152 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
5153
5154 return 1; /* return error */
5155 }
5156 }
5157 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
5158 {
5159 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_SECTOR_ERASE_4K, 1,
5160 addr, 1, 4,
5161 0x00000000, 0x00, 0x00,
5162 0, NULL, 0x00,
5163 NULL, 0x00, 0x00); /* spi write read */
5164 if (res != 0) /* check result */
5165 {
5166 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
5167
5168 return 1; /* return error */
5169 }
5170 }
5171 else
5172 {
5173 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5174
5175 return 5; /* return error */
5176 }
5177
5178 timeout = 400; /* max 400 ms */
5179 while (timeout != 0) /* check timeout */
5180 {
5181 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
5182 0x00000000, 0x00, 0x00,
5183 0x00000000, 0x00, 0x00,
5184 0, NULL, 0,
5185 (uint8_t *)&status, 1, 1); /* spi write read */
5186 if (res != 0) /* check result */
5187 {
5188 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5189
5190 return 1; /* return error */
5191 }
5192 if ((status & 0x01) == 0x00) /* check status */
5193 {
5194 break; /* break */
5195 }
5196 timeout--; /* timeout-- */
5197 handle->delay_ms(1); /* delay 1 ms */
5198 }
5199 if (timeout == 0)
5200 {
5201 handle->debug_print("w25qxx: sector erase 4k timeout.\n"); /* sector erase 4k timeout */
5202
5203 return 6; /* return error */
5204 }
5205 }
5206 else /* single spi */
5207 {
5208 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
5209 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
5210 if (res != 0) /* check result */
5211 {
5212 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5213
5214 return 1; /* return error */
5215 }
5216 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5217 {
5218 if (handle->type >= W25Q256) /* >128Mb */
5219 {
5220 buf[0] = 0xC5; /* write extended addr register command */
5221 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5222 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
5223 if (res != 0) /* check result */
5224 {
5225 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
5226
5227 return 1; /* return error */
5228 }
5229 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
5230 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
5231 if (res != 0) /* check result */
5232 {
5233 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5234
5235 return 1; /* return error */
5236 }
5237 }
5238 buf[0] = W25QXX_COMMAND_SECTOR_ERASE_4K; /* sector erase 4k command */
5239 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
5240 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
5241 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
5242 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, NULL, 0); /* spi write read */
5243 if (res != 0) /* check result */
5244 {
5245 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
5246
5247 return 1; /* return error */
5248 }
5249 }
5250 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE)
5251 && (handle->type >= W25Q256))
5252 {
5253 buf[0] = W25QXX_COMMAND_SECTOR_ERASE_4K; /* sector erase 4k command */
5254 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5255 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
5256 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
5257 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
5258 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, NULL, 0); /* spi write read */
5259 if (res != 0) /* check result */
5260 {
5261 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
5262
5263 return 1; /* return error */
5264 }
5265 }
5266 else
5267 {
5268 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5269
5270 return 5; /* return error */
5271 }
5272
5273 timeout = 400; /* max 400 ms */
5274 while (timeout != 0) /* check timeout */
5275 {
5276 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
5277 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, (uint8_t *)&status, 1); /* spi write read */
5278 if (res != 0) /* check result */
5279 {
5280 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5281
5282 return 1; /* return error */
5283 }
5284 if ((status & 0x01) == 0x00) /* check status */
5285 {
5286 break; /* break */
5287 }
5288 timeout--; /* timeout-- */
5289 handle->delay_ms(1); /* delay 1 ms */
5290 }
5291 if (timeout == 0)
5292 {
5293 handle->debug_print("w25qxx: sector erase 4k timeout.\n"); /* sector erase 4k timeout */
5294
5295 return 6; /* return error */
5296 }
5297 }
5298 }
5299 else
5300 {
5301 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
5302 0x00000000, 0x00, 0x00,
5303 0x00000000, 0x00, 0x00,
5304 0x00, NULL, 0x00,
5305 NULL, 0x00, 0x00); /* qspi write read */
5306 if (res != 0) /* check result */
5307 {
5308 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5309
5310 return 1; /* return error */
5311 }
5312 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5313 {
5314 if (handle->type >= W25Q256) /* >128Mb */
5315 {
5316 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5317 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
5318 0x00000000, 0x00, 0x00,
5319 0x00000000, 0x00, 0x00,
5320 0, (uint8_t *)buf, 0x01,
5321 NULL, 0x00, 4); /* spi write read */
5322 if (res != 0) /* check result */
5323 {
5324 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
5325
5326 return 1; /* return error */
5327 }
5328 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
5329 0x00000000, 0x00, 0x00,
5330 0x00000000, 0x00, 0x00,
5331 0x00, NULL, 0x00,
5332 NULL, 0x00, 0x00); /* qspi write read */
5333 if (res != 0) /* check result */
5334 {
5335 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5336
5337 return 1; /* return error */
5338 }
5339 }
5340 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_SECTOR_ERASE_4K, 4,
5341 addr, 4, 3,
5342 0x00000000, 0x00, 0x00,
5343 0, NULL, 0x00,
5344 NULL, 0x00, 0x00); /* spi write read */
5345 if (res != 0) /* check result */
5346 {
5347 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
5348
5349 return 1; /* return error */
5350 }
5351 }
5352 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
5353 {
5354 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_SECTOR_ERASE_4K, 4,
5355 addr, 4, 4,
5356 0x00000000, 0x00, 0x00,
5357 0, NULL, 0x00,
5358 NULL, 0x00, 0x00); /* spi write read */
5359 if (res != 0) /* check result */
5360 {
5361 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
5362
5363 return 1; /* return error */
5364 }
5365 }
5366 else
5367 {
5368 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5369
5370 return 5; /* return error */
5371 }
5372
5373 timeout = 400; /* max 400 ms */
5374 while (timeout != 0) /* check timeout */
5375 {
5376 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
5377 0x00000000, 0x00, 0x00,
5378 0x00000000, 0x00, 0x00,
5379 0, NULL, 0,
5380 (uint8_t *)&status, 1, 4); /* spi write read */
5381 if (res != 0) /* check result */
5382 {
5383 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5384
5385 return 1; /* return error */
5386 }
5387 if ((status & 0x01) == 0x00) /* check status */
5388 {
5389 break; /* break */
5390 }
5391 timeout--; /* timeout-- */
5392 handle->delay_ms(1); /* delay 1 ms */
5393 }
5394 if (timeout == 0)
5395 {
5396 handle->debug_print("w25qxx: sector erase 4k timeout.\n"); /* sector erase 4k timeout */
5397
5398 return 6; /* return error */
5399 }
5400 }
5401
5402 return 0; /* success return 0 */
5403 }
5404
5419 uint8_t w25qxx_block_erase_32k(w25qxx_handle_t *handle, uint32_t addr)
5420 {
5421 uint8_t res;
5422 uint8_t status;
5423 uint32_t timeout;
5424 uint8_t buf[5];
5425
5426 if (handle == NULL) /* check handle */
5427 {
5428 return 2; /* return error */
5429 }
5430 if (handle->inited != 1) /* check handle initialization */
5431 {
5432 return 3; /* return error */
5433 }
5434 if ((addr % (32 * 1024)) != 0) /* check address */
5435 {
5436 handle->debug_print("w25qxx: addr is invalid.\n"); /* addr is invalid */
5437
5438 return 4; /* return error */
5439 }
5440
5441 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
5442 {
5443 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
5444 {
5445 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
5446 0x00000000, 0x00, 0x00,
5447 0x00000000, 0x00, 0x00,
5448 0x00, NULL, 0x00,
5449 NULL, 0x00, 0x00); /* qspi write read */
5450 if (res != 0) /* check result */
5451 {
5452 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5453
5454 return 1; /* return error */
5455 }
5456 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5457 {
5458 if (handle->type >= W25Q256) /* >128Mb */
5459 {
5460 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5461 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
5462 0x00000000, 0x00, 0x00,
5463 0x00000000, 0x00, 0x00,
5464 0, (uint8_t *)buf, 0x01,
5465 NULL, 0x00, 1); /* spi write read */
5466 if (res != 0) /* check result */
5467 {
5468 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
5469
5470 return 1; /* return error */
5471 }
5472 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
5473 0x00000000, 0x00, 0x00,
5474 0x00000000, 0x00, 0x00,
5475 0x00, NULL, 0x00,
5476 NULL, 0x00, 0x00); /* qspi write read */
5477 if (res != 0) /* check result */
5478 {
5479 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5480
5481 return 1; /* return error */
5482 }
5483 }
5484 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_BLOCK_ERASE_32K, 1,
5485 addr, 1, 3,
5486 0x00000000, 0x00, 0x00,
5487 0, NULL, 0x00,
5488 NULL, 0x00, 0x00); /* spi write read */
5489 if (res != 0) /* check result */
5490 {
5491 handle->debug_print("w25qxx: block erase 32k failed.\n"); /* block erase 32k failed */
5492
5493 return 1; /* return error */
5494 }
5495 }
5496 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
5497 {
5498 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_BLOCK_ERASE_32K, 1,
5499 addr, 1, 4,
5500 0x00000000, 0x00, 0x00,
5501 0, NULL, 0x00,
5502 NULL, 0x00, 0x00); /* spi write read */
5503 if (res != 0) /* check result */
5504 {
5505 handle->debug_print("w25qxx: block erase 32k failed.\n"); /* block erase 32k failed */
5506
5507 return 1; /* return error */
5508 }
5509 }
5510 else
5511 {
5512 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5513
5514 return 5; /* return error */
5515 }
5516
5517 timeout = 1600; /* max 1600 ms */
5518 while (timeout != 0) /* check timeout */
5519 {
5520 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
5521 0x00000000, 0x00, 0x00,
5522 0x00000000, 0x00, 0x00,
5523 0, NULL, 0,
5524 (uint8_t *)&status, 1, 1); /* spi write read */
5525 if (res != 0) /* check result */
5526 {
5527 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5528
5529 return 1; /* return error */
5530 }
5531 if ((status & 0x01) == 0x00) /* check status */
5532 {
5533 break; /* break */
5534 }
5535 timeout--; /* timeout-- */
5536 handle->delay_ms(1); /* delay 1 ms */
5537 }
5538 if (timeout == 0)
5539 {
5540 handle->debug_print("w25qxx: block erase 32k timeout.\n"); /* block erase 32k timeout */
5541
5542 return 6; /* return error */
5543 }
5544 }
5545 else /* single spi */
5546 {
5547 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
5548 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
5549 if (res != 0) /* check result */
5550 {
5551 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5552
5553 return 1; /* return error */
5554 }
5555 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5556 {
5557 if (handle->type >= W25Q256) /* >128Mb */
5558 {
5559 buf[0] = 0xC5; /* write extended addr register command */
5560 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5561 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
5562 if (res != 0) /* check result */
5563 {
5564 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
5565
5566 return 1; /* return error */
5567 }
5568 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
5569 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
5570 if (res != 0) /* check result */
5571 {
5572 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5573
5574 return 1; /* return error */
5575 }
5576 }
5577 buf[0] = W25QXX_COMMAND_BLOCK_ERASE_32K; /* block erase 32k command */
5578 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
5579 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
5580 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
5581 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, NULL, 0); /* spi write read */
5582 if (res != 0) /* check result */
5583 {
5584 handle->debug_print("w25qxx: block erase 32k failed.\n"); /* block erase 32k failed */
5585
5586 return 1; /* return error */
5587 }
5588 }
5589 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE)
5590 && (handle->type >= W25Q256))
5591 {
5592 buf[0] = W25QXX_COMMAND_BLOCK_ERASE_32K; /* block erase 32k command */
5593 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5594 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
5595 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
5596 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
5597 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, NULL, 0); /* spi write read */
5598 if (res != 0) /* check result */
5599 {
5600 handle->debug_print("w25qxx: block erase 32k failed.\n"); /* block erase 32k failed */
5601
5602 return 1; /* return error */
5603 }
5604 }
5605 else
5606 {
5607 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5608
5609 return 5; /* return error */
5610 }
5611
5612 timeout = 1600; /* max 1600 ms */
5613 while (timeout != 0) /* check timeout */
5614 {
5615 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
5616 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, (uint8_t *)&status, 1); /* spi write read */
5617 if (res != 0) /* check result */
5618 {
5619 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5620
5621 return 1; /* return error */
5622 }
5623 if ((status & 0x01) == 0x00) /* check status */
5624 {
5625 break; /* break */
5626 }
5627 timeout--; /* timeout-- */
5628 handle->delay_ms(1); /* delay 1 ms */
5629 }
5630 if (timeout == 0)
5631 {
5632 handle->debug_print("w25qxx: block erase 32k timeout.\n"); /* block erase 32k timeout */
5633
5634 return 6; /* return error */
5635 }
5636 }
5637 }
5638 else
5639 {
5640 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
5641 0x00000000, 0x00, 0x00,
5642 0x00000000, 0x00, 0x00,
5643 0x00, NULL, 0x00,
5644 NULL, 0x00, 0x00); /* qspi write read */
5645 if (res != 0) /* check result */
5646 {
5647 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5648
5649 return 1; /* return error */
5650 }
5651 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5652 {
5653 if (handle->type >= W25Q256) /* >128Mb */
5654 {
5655 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5656 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
5657 0x00000000, 0x00, 0x00,
5658 0x00000000, 0x00, 0x00,
5659 0, (uint8_t *)buf, 0x01,
5660 NULL, 0x00, 4); /* spi write read */
5661 if (res != 0) /* check result */
5662 {
5663 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
5664
5665 return 1; /* return error */
5666 }
5667 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
5668 0x00000000, 0x00, 0x00,
5669 0x00000000, 0x00, 0x00,
5670 0x00, NULL, 0x00,
5671 NULL, 0x00, 0x00); /* qspi write read */
5672 if (res != 0) /* check result */
5673 {
5674 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5675
5676 return 1; /* return error */
5677 }
5678 }
5679 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_BLOCK_ERASE_32K, 4,
5680 addr, 4, 3,
5681 0x00000000, 0x00, 0x00,
5682 0, NULL, 0x00,
5683 NULL, 0x00, 0x00); /* spi write read */
5684 if (res != 0) /* check result */
5685 {
5686 handle->debug_print("w25qxx: block erase 32k failed.\n"); /* block erase 32k failed */
5687
5688 return 1; /* return error */
5689 }
5690 }
5691 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
5692 {
5693 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_BLOCK_ERASE_32K, 4,
5694 addr, 4, 4,
5695 0x00000000, 0x00, 0x00,
5696 0, NULL, 0x00,
5697 NULL, 0x00, 0x00); /* spi write read */
5698 if (res != 0) /* check result */
5699 {
5700 handle->debug_print("w25qxx: block erase 32k failed.\n"); /* block erase 32k failed */
5701
5702 return 1; /* return error */
5703 }
5704 }
5705 else
5706 {
5707 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5708
5709 return 5; /* return error */
5710 }
5711
5712 timeout = 1600; /* max 1600 ms */
5713 while (timeout != 0) /* check timeout */
5714 {
5715 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
5716 0x00000000, 0x00, 0x00,
5717 0x00000000, 0x00, 0x00,
5718 0, NULL, 0,
5719 (uint8_t *)&status, 1, 4); /* spi write read */
5720 if (res != 0) /* check result */
5721 {
5722 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5723
5724 return 1; /* return error */
5725 }
5726 if ((status & 0x01) == 0x00) /* check status */
5727 {
5728 break; /* break */
5729 }
5730 timeout--; /* timeout-- */
5731 handle->delay_ms(1); /* delay 1 ms */
5732 }
5733 if (timeout == 0)
5734 {
5735 handle->debug_print("w25qxx: block erase 32k timeout.\n"); /* block erase 32k timeout */
5736
5737 return 6; /* return error */
5738 }
5739 }
5740
5741 return 0; /* success return 0 */
5742 }
5743
5758 uint8_t w25qxx_block_erase_64k(w25qxx_handle_t *handle, uint32_t addr)
5759 {
5760 uint8_t res;
5761 uint8_t status;
5762 uint32_t timeout;
5763 uint8_t buf[5];
5764
5765 if (handle == NULL) /* check handle */
5766 {
5767 return 2; /* return error */
5768 }
5769 if (handle->inited != 1) /* check handle initialization */
5770 {
5771 return 3; /* return error */
5772 }
5773 if ((addr % (64 * 1024)) != 0) /* check address */
5774 {
5775 handle->debug_print("w25qxx: addr is invalid.\n"); /* addr is invalid */
5776
5777 return 4; /* return error */
5778 }
5779
5780 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
5781 {
5782 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
5783 {
5784 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
5785 0x00000000, 0x00, 0x00,
5786 0x00000000, 0x00, 0x00,
5787 0x00, NULL, 0x00,
5788 NULL, 0x00, 0x00); /* qspi write read */
5789 if (res != 0) /* check result */
5790 {
5791 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5792
5793 return 1; /* return error */
5794 }
5795 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5796 {
5797 if (handle->type >= W25Q256) /* >128Mb */
5798 {
5799 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5800 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
5801 0x00000000, 0x00, 0x00,
5802 0x00000000, 0x00, 0x00,
5803 0, (uint8_t *)buf, 0x01,
5804 NULL, 0x00, 1); /* spi write read */
5805 if (res != 0) /* check result */
5806 {
5807 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
5808
5809 return 1; /* return error */
5810 }
5811 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
5812 0x00000000, 0x00, 0x00,
5813 0x00000000, 0x00, 0x00,
5814 0x00, NULL, 0x00,
5815 NULL, 0x00, 0x00); /* qspi write read */
5816 if (res != 0) /* check result */
5817 {
5818 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5819
5820 return 1; /* return error */
5821 }
5822 }
5823 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_BLOCK_ERASE_64K, 1,
5824 addr, 1, 3,
5825 0x00000000, 0x00, 0x00,
5826 0, NULL, 0x00,
5827 NULL, 0x00, 0x00); /* spi write read */
5828 if (res != 0) /* check result */
5829 {
5830 handle->debug_print("w25qxx: block erase 64k failed.\n"); /* block erase 64k failed */
5831
5832 return 1; /* return error */
5833 }
5834 }
5835 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
5836 {
5837 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_BLOCK_ERASE_64K, 1,
5838 addr, 1, 4,
5839 0x00000000, 0x00, 0x00,
5840 0, NULL, 0x00,
5841 NULL, 0x00, 0x00); /* spi write read */
5842 if (res != 0) /* check result */
5843 {
5844 handle->debug_print("w25qxx: block erase 64k failed.\n"); /* block erase 64k failed */
5845
5846 return 1; /* return error */
5847 }
5848 }
5849 else
5850 {
5851 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5852
5853 return 5; /* return error */
5854 }
5855
5856 timeout = 2000; /* max 2000 ms */
5857 while (timeout != 0) /* check timeout */
5858 {
5859 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
5860 0x00000000, 0x00, 0x00,
5861 0x00000000, 0x00, 0x00,
5862 0, NULL, 0,
5863 (uint8_t *)&status, 1, 1); /* spi write read */
5864 if (res != 0) /* check result */
5865 {
5866 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5867
5868 return 1; /* return error */
5869 }
5870 if ((status & 0x01) == 0x00) /* check status */
5871 {
5872 break; /* break */
5873 }
5874 timeout--; /* timeout-- */
5875 handle->delay_ms(1); /* delay 1 ms */
5876 }
5877 if (timeout == 0)
5878 {
5879 handle->debug_print("w25qxx: block erase 64k timeout.\n"); /* block erase 64k timeout */
5880
5881 return 6; /* return error */
5882 }
5883 }
5884 else /* single spi */
5885 {
5886 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
5887 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
5888 if (res != 0) /* check result */
5889 {
5890 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5891
5892 return 1; /* return error */
5893 }
5894 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5895 {
5896 if (handle->type >= W25Q256) /* >128Mb */
5897 {
5898 buf[0] = 0xC5; /* write extended addr register command */
5899 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5900 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
5901 if (res != 0) /* check result */
5902 {
5903 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
5904
5905 return 1; /* return error */
5906 }
5907 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
5908 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
5909 if (res != 0) /* check result */
5910 {
5911 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5912
5913 return 1; /* return error */
5914 }
5915 }
5916 buf[0] = W25QXX_COMMAND_BLOCK_ERASE_64K; /* block erase 64k command */
5917 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
5918 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
5919 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
5920 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, NULL, 0); /* spi write read */
5921 if (res != 0) /* check result */
5922 {
5923 handle->debug_print("w25qxx: block erase 64k failed.\n"); /* block erase 64k failed */
5924
5925 return 1; /* return error */
5926 }
5927 }
5928 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
5929 {
5930 buf[0] = W25QXX_COMMAND_BLOCK_ERASE_64K; /* block erase 64k command */
5931 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5932 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
5933 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
5934 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
5935 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, NULL, 0); /* spi write read */
5936 if (res != 0) /* check result */
5937 {
5938 handle->debug_print("w25qxx: block erase 64k failed.\n"); /* block erase 64k failed */
5939
5940 return 1; /* return error */
5941 }
5942 }
5943 else
5944 {
5945 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
5946
5947 return 5; /* return error */
5948 }
5949
5950 timeout = 2000; /* max 2000 ms */
5951 while (timeout != 0) /* check timeout */
5952 {
5953 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
5954 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, (uint8_t *)&status, 1); /* spi write read */
5955 if (res != 0) /* check result */
5956 {
5957 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
5958
5959 return 1; /* return error */
5960 }
5961 if ((status & 0x01) == 0x00) /* check status */
5962 {
5963 break; /* break */
5964 }
5965 timeout--; /* timeout-- */
5966 handle->delay_ms(1); /* delay 1 ms */
5967 }
5968 if (timeout == 0)
5969 {
5970 handle->debug_print("w25qxx: block erase 64k timeout.\n"); /* block erase 64k timeout */
5971
5972 return 6; /* return error */
5973 }
5974 }
5975 }
5976 else
5977 {
5978 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
5979 0x00000000, 0x00, 0x00,
5980 0x00000000, 0x00, 0x00,
5981 0x00, NULL, 0x00,
5982 NULL, 0x00, 0x00); /* qspi write read */
5983 if (res != 0) /* check result */
5984 {
5985 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
5986
5987 return 1; /* return error */
5988 }
5989 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
5990 {
5991 if (handle->type >= W25Q256) /* >128Mb */
5992 {
5993 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
5994 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
5995 0x00000000, 0x00, 0x00,
5996 0x00000000, 0x00, 0x00,
5997 0, (uint8_t *)buf, 0x01,
5998 NULL, 0x00, 4); /* spi write read */
5999 if (res != 0) /* check result */
6000 {
6001 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6002
6003 return 1; /* return error */
6004 }
6005 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
6006 0x00000000, 0x00, 0x00,
6007 0x00000000, 0x00, 0x00,
6008 0x00, NULL, 0x00,
6009 NULL, 0x00, 0x00); /* qspi write read */
6010 if (res != 0) /* check result */
6011 {
6012 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6013
6014 return 1; /* return error */
6015 }
6016 }
6017 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_BLOCK_ERASE_64K, 4,
6018 addr, 4, 3,
6019 0x00000000, 0x00, 0x00,
6020 0, NULL, 0x00,
6021 NULL, 0x00, 0x00); /* spi write read */
6022 if (res != 0) /* check result */
6023 {
6024 handle->debug_print("w25qxx: block erase 64k failed.\n"); /* block erase 64k failed */
6025
6026 return 1; /* return error */
6027 }
6028 }
6029 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6030 {
6031 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_BLOCK_ERASE_64K, 4,
6032 addr, 4, 4,
6033 0x00000000, 0x00, 0x00,
6034 0, NULL, 0x00,
6035 NULL, 0x00, 0x00); /* spi write read */
6036 if (res != 0) /* check result */
6037 {
6038 handle->debug_print("w25qxx: block erase 64k failed.\n"); /* block erase 64k failed */
6039
6040 return 1; /* return error */
6041 }
6042 }
6043 else
6044 {
6045 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6046
6047 return 5; /* return error */
6048 }
6049
6050 timeout = 2000; /* max 2000 ms */
6051 while (timeout != 0) /* check timeout */
6052 {
6053 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
6054 0x00000000, 0x00, 0x00,
6055 0x00000000, 0x00, 0x00,
6056 0, NULL, 0,
6057 (uint8_t *)&status, 1, 4); /* spi write read */
6058 if (res != 0) /* check result */
6059 {
6060 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
6061
6062 return 1; /* return error */
6063 }
6064 if ((status & 0x01) == 0x00) /* check status */
6065 {
6066 break; /* break */
6067 }
6068 timeout--; /* timeout-- */
6069 handle->delay_ms(1); /* delay 1 ms */
6070 }
6071 if (timeout == 0)
6072 {
6073 handle->debug_print("w25qxx: block erase 64k timeout.\n"); /* block erase 64k timeout */
6074
6075 return 6; /* return error */
6076 }
6077 }
6078
6079 return 0; /* success return 0 */
6080 }
6081
6094 uint8_t w25qxx_individual_block_lock(w25qxx_handle_t *handle, uint32_t addr)
6095 {
6096 uint8_t res;
6097 uint8_t buf[5];
6098
6099 if (handle == NULL) /* check handle */
6100 {
6101 return 2; /* return error */
6102 }
6103 if (handle->inited != 1) /* check handle initialization */
6104 {
6105 return 3; /* return error */
6106 }
6107
6108 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
6109 {
6110 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
6111 {
6112 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6113 {
6114 if (handle->type >= W25Q256) /* >128Mb */
6115 {
6116 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
6117 0x00000000, 0x00, 0x00,
6118 0x00000000, 0x00, 0x00,
6119 0x00, NULL, 0x00,
6120 NULL, 0x00, 0x00); /* qspi write read */
6121 if (res != 0) /* check result */
6122 {
6123 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6124
6125 return 1; /* return error */
6126 }
6127 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6128 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
6129 0x00000000, 0x00, 0x00,
6130 0x00000000, 0x00, 0x00,
6131 0, (uint8_t *)buf, 0x01,
6132 NULL, 0x00, 1); /* spi write read */
6133 if (res != 0) /* check result */
6134 {
6135 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6136
6137 return 1; /* return error */
6138 }
6139 }
6140 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK, 1,
6141 addr, 1, 3,
6142 0x00000000, 0x00, 0x00,
6143 0, NULL, 0x00,
6144 NULL, 0x00, 0x00); /* spi write read */
6145 if (res != 0) /* check result */
6146 {
6147 handle->debug_print("w25qxx: individual block lock failed.\n"); /* individual block lock failed */
6148
6149 return 1; /* return error */
6150 }
6151 }
6152 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6153 {
6154 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK, 1,
6155 addr, 1, 4,
6156 0x00000000, 0x00, 0x00,
6157 0, NULL, 0x00,
6158 NULL, 0x00, 0x00); /* spi write read */
6159 if (res != 0) /* check result */
6160 {
6161 handle->debug_print("w25qxx: individual block lock failed.\n"); /* individual block lock failed */
6162
6163 return 1; /* return error */
6164 }
6165 }
6166 else
6167 {
6168 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6169
6170 return 4; /* return error */
6171 }
6172 }
6173 else /* single spi */
6174 {
6175 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6176 {
6177 if (handle->type >= W25Q256) /* >128Mb */
6178 {
6179 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
6180 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
6181 if (res != 0) /* check result */
6182 {
6183 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6184
6185 return 1; /* return error */
6186 }
6187 buf[0] = 0xC5; /* write extended addr register command */
6188 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6189 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
6190 if (res != 0) /* check result */
6191 {
6192 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6193
6194 return 1; /* return error */
6195 }
6196 }
6197 buf[0] = W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK; /* individual block lock command */
6198 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
6199 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
6200 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
6201 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, NULL, 0); /* spi write read */
6202 if (res != 0) /* check result */
6203 {
6204 handle->debug_print("w25qxx: individual block lock failed.\n"); /* individual block lock failed */
6205
6206 return 1; /* return error */
6207 }
6208 }
6209 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6210 {
6211 buf[0] = W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK; /* individual block lock command */
6212 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6213 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
6214 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
6215 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
6216 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, NULL, 0); /* spi write read */
6217 if (res != 0) /* check result */
6218 {
6219 handle->debug_print("w25qxx: individual block lock failed.\n"); /* individual block lock failed */
6220
6221 return 1; /* return error */
6222 }
6223 }
6224 else
6225 {
6226 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6227
6228 return 4; /* return error */
6229 }
6230 }
6231 }
6232 else
6233 {
6234 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6235 {
6236 if (handle->type >= W25Q256) /* >128Mb */
6237 {
6238 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
6239 0x00000000, 0x00, 0x00,
6240 0x00000000, 0x00, 0x00,
6241 0x00, NULL, 0x00,
6242 NULL, 0x00, 0x00); /* qspi write read */
6243 if (res != 0) /* check result */
6244 {
6245 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6246
6247 return 1; /* return error */
6248 }
6249 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6250 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
6251 0x00000000, 0x00, 0x00,
6252 0x00000000, 0x00, 0x00,
6253 0, (uint8_t *)buf, 0x01,
6254 NULL, 0x00, 4); /* spi write read */
6255 if (res != 0) /* check result */
6256 {
6257 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6258
6259 return 1; /* return error */
6260 }
6261 }
6262 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK, 4,
6263 addr, 4, 3,
6264 0x00000000, 0x00, 0x00,
6265 0, NULL, 0x00,
6266 NULL, 0x00, 0x00); /* spi write read */
6267 if (res != 0) /* check result */
6268 {
6269 handle->debug_print("w25qxx: individual block lock failed.\n"); /* individual block lock failed */
6270
6271 return 1; /* return error */
6272 }
6273 }
6274 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6275 {
6276 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK, 4,
6277 addr, 4, 4,
6278 0x00000000, 0x00, 0x00,
6279 0, NULL, 0x00,
6280 NULL, 0x00, 0x00); /* spi write read */
6281 if (res != 0) /* check result */
6282 {
6283 handle->debug_print("w25qxx: individual block lock failed.\n"); /* individual block lock failed */
6284
6285 return 1; /* return error */
6286 }
6287 }
6288 else
6289 {
6290 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6291
6292 return 4; /* return error */
6293 }
6294 }
6295
6296 return 0; /* success return 0 */
6297 }
6298
6311 uint8_t w25qxx_individual_block_unlock(w25qxx_handle_t *handle, uint32_t addr)
6312 {
6313 uint8_t res;
6314 uint8_t buf[5];
6315
6316 if (handle == NULL) /* check handle */
6317 {
6318 return 2; /* return error */
6319 }
6320 if (handle->inited != 1) /* check handle initialization */
6321 {
6322 return 3; /* return error */
6323 }
6324
6325 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
6326 {
6327 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
6328 {
6329 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6330 {
6331 if (handle->type >= W25Q256) /* >128Mb */
6332 {
6333 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
6334 0x00000000, 0x00, 0x00,
6335 0x00000000, 0x00, 0x00,
6336 0x00, NULL, 0x00,
6337 NULL, 0x00, 0x00); /* qspi write read */
6338 if (res != 0) /* check result */
6339 {
6340 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6341
6342 return 1; /* return error */
6343 }
6344 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6345 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
6346 0x00000000, 0x00, 0x00,
6347 0x00000000, 0x00, 0x00,
6348 0, (uint8_t *)buf, 0x01,
6349 NULL, 0x00, 1); /* spi write read */
6350 if (res != 0) /* check result */
6351 {
6352 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6353
6354 return 1; /* return error */
6355 }
6356 }
6357 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK, 1,
6358 addr, 1, 3,
6359 0x00000000, 0x00, 0x00,
6360 0, NULL, 0x00,
6361 NULL, 0x00, 0x00); /* spi write read */
6362 if (res != 0) /* check result */
6363 {
6364 handle->debug_print("w25qxx: individual block unlock failed.\n"); /* individual unblock lock failed */
6365
6366 return 1; /* return error */
6367 }
6368 }
6369 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6370 {
6371 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK, 1,
6372 addr, 1, 4,
6373 0x00000000, 0x00, 0x00,
6374 0, NULL, 0x00,
6375 NULL, 0x00, 0x00); /* spi write read */
6376 if (res != 0) /* check result */
6377 {
6378 handle->debug_print("w25qxx: individual block unlock failed.\n"); /* individual block unlock failed */
6379
6380 return 1; /* return error */
6381 }
6382 }
6383 else
6384 {
6385 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6386
6387 return 4; /* return error */
6388 }
6389 }
6390 else /* single spi */
6391 {
6392 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6393 {
6394 if (handle->type >= W25Q256) /* >128Mb */
6395 {
6396 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
6397 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
6398 if (res != 0) /* check result */
6399 {
6400 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6401
6402 return 1; /* return error */
6403 }
6404 buf[0] = 0xC5; /* write extended addr register command */
6405 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6406 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
6407 if (res != 0) /* check result */
6408 {
6409 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6410
6411 return 1; /* return error */
6412 }
6413 }
6414 buf[0] = W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK; /* individual block unlock command */
6415 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
6416 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
6417 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
6418 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, NULL, 0); /* spi write read */
6419 if (res != 0) /* check result */
6420 {
6421 handle->debug_print("w25qxx: individual block unlock failed.\n"); /* individual block unlock failed */
6422
6423 return 1; /* return error */
6424 }
6425 }
6426 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6427 {
6428 buf[0] = W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK; /* individual block unlock command */
6429 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6430 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
6431 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
6432 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
6433 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, NULL, 0); /* spi write read */
6434 if (res != 0) /* check result */
6435 {
6436 handle->debug_print("w25qxx: individual block unlock failed.\n"); /* individual block unlock failed */
6437
6438 return 1; /* return error */
6439 }
6440 }
6441 else
6442 {
6443 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6444
6445 return 4; /* return error */
6446 }
6447 }
6448 }
6449 else
6450 {
6451 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6452 {
6453 if (handle->type >= W25Q256) /* >128Mb */
6454 {
6455 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
6456 0x00000000, 0x00, 0x00,
6457 0x00000000, 0x00, 0x00,
6458 0x00, NULL, 0x00,
6459 NULL, 0x00, 0x00); /* qspi write read */
6460 if (res != 0) /* check result */
6461 {
6462 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6463
6464 return 1; /* return error */
6465 }
6466 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6467 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
6468 0x00000000, 0x00, 0x00,
6469 0x00000000, 0x00, 0x00,
6470 0, (uint8_t *)buf, 0x01,
6471 NULL, 0x00, 4); /* spi write read */
6472 if (res != 0) /* check result */
6473 {
6474 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6475
6476 return 1; /* return error */
6477 }
6478 }
6479 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK, 4,
6480 addr, 4, 3,
6481 0x00000000, 0x00, 0x00,
6482 0, NULL, 0x00,
6483 NULL, 0x00, 0x00); /* spi write read */
6484 if (res != 0) /* check result */
6485 {
6486 handle->debug_print("w25qxx: individual block unlock failed.\n"); /* individual unblock lock failed */
6487
6488 return 1; /* return error */
6489 }
6490 }
6491 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6492 {
6493 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK, 4,
6494 addr, 4, 4,
6495 0x00000000, 0x00, 0x00,
6496 0, NULL, 0x00,
6497 NULL, 0x00, 0x00); /* spi write read */
6498 if (res != 0) /* check result */
6499 {
6500 handle->debug_print("w25qxx: individual block unlock failed.\n"); /* individual block unlock failed */
6501
6502 return 1; /* return error */
6503 }
6504 }
6505 else
6506 {
6507 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6508
6509 return 4; /* return error */
6510 }
6511 }
6512
6513 return 0; /* success return 0 */
6514 }
6515
6529 uint8_t w25qxx_read_block_lock(w25qxx_handle_t *handle, uint32_t addr, uint8_t *value)
6530 {
6531 uint8_t res;
6532 uint8_t buf[5];
6533
6534 if (handle == NULL) /* check handle */
6535 {
6536 return 2; /* return error */
6537 }
6538 if (handle->inited != 1) /* check handle initialization */
6539 {
6540 return 3; /* return error */
6541 }
6542
6543 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
6544 {
6545 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
6546 {
6547 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6548 {
6549 if (handle->type >= W25Q256) /* >128Mb */
6550 {
6551 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
6552 0x00000000, 0x00, 0x00,
6553 0x00000000, 0x00, 0x00,
6554 0x00, NULL, 0x00,
6555 NULL, 0x00, 0x00); /* qspi write read */
6556 if (res != 0) /* check result */
6557 {
6558 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6559
6560 return 1; /* return error */
6561 }
6562 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6563 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
6564 0x00000000, 0x00, 0x00,
6565 0x00000000, 0x00, 0x00,
6566 0, (uint8_t *)buf, 0x01,
6567 NULL, 0x00, 1); /* spi write read */
6568 if (res != 0) /* check result */
6569 {
6570 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6571
6572 return 1; /* return error */
6573 }
6574 }
6575 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_BLOCK_LOCK, 1,
6576 addr, 1, 3,
6577 0x00000000, 0x00, 0x00,
6578 0, NULL, 0x00,
6579 value, 1, 1); /* spi write read */
6580 if (res != 0) /* check result */
6581 {
6582 handle->debug_print("w25qxx: read block lock failed.\n"); /* read block lock failed */
6583
6584 return 1; /* return error */
6585 }
6586 }
6587 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6588 {
6589 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_BLOCK_LOCK, 1,
6590 addr, 1, 4,
6591 0x00000000, 0x00, 0x00,
6592 0, NULL, 0x00,
6593 value, 1, 1); /* spi write read */
6594 if (res != 0) /* check result */
6595 {
6596 handle->debug_print("w25qxx: read block lock failed.\n"); /* read block lock failed */
6597
6598 return 1; /* return error */
6599 }
6600 }
6601 else
6602 {
6603 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6604
6605 return 4; /* return error */
6606 }
6607 }
6608 else /* single spi */
6609 {
6610 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6611 {
6612 if (handle->type >= W25Q256) /* >128Mb */
6613 {
6614 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
6615 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
6616 if (res != 0) /* check result */
6617 {
6618 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6619
6620 return 1; /* return error */
6621 }
6622 buf[0] = 0xC5; /* write extended addr register command */
6623 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6624 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
6625 if (res != 0) /* check result */
6626 {
6627 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6628
6629 return 1; /* return error */
6630 }
6631 }
6632 buf[0] = W25QXX_COMMAND_READ_BLOCK_LOCK; /* read block lock command */
6633 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
6634 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
6635 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
6636 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, value, 1); /* spi write read */
6637 if (res != 0) /* check result */
6638 {
6639 handle->debug_print("w25qxx: read block lock failed.\n"); /* read block lock failed */
6640
6641 return 1; /* return error */
6642 }
6643 }
6644 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6645 {
6646 buf[0] = W25QXX_COMMAND_READ_BLOCK_LOCK; /* read block lock command */
6647 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6648 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
6649 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
6650 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
6651 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, value, 1); /* spi write read */
6652 if (res != 0) /* check result */
6653 {
6654 handle->debug_print("w25qxx: read block lock failed.\n"); /* read block lock failed */
6655
6656 return 1; /* return error */
6657 }
6658 }
6659 else
6660 {
6661 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6662
6663 return 4; /* return error */
6664 }
6665 }
6666 }
6667 else
6668 {
6669 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
6670 {
6671 if (handle->type >= W25Q256) /* >128Mb */
6672 {
6673 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
6674 0x00000000, 0x00, 0x00,
6675 0x00000000, 0x00, 0x00,
6676 0x00, NULL, 0x00,
6677 NULL, 0x00, 0x00); /* qspi write read */
6678 if (res != 0) /* check result */
6679 {
6680 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
6681
6682 return 1; /* return error */
6683 }
6684 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
6685 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
6686 0x00000000, 0x00, 0x00,
6687 0x00000000, 0x00, 0x00,
6688 0, (uint8_t *)buf, 0x01,
6689 NULL, 0x00, 4); /* spi write read */
6690 if (res != 0) /* check result */
6691 {
6692 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
6693
6694 return 1; /* return error */
6695 }
6696 }
6697 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_BLOCK_LOCK, 4,
6698 addr, 4, 3,
6699 0x00000000, 0x00, 0x00,
6700 0, NULL, 0x00,
6701 value, 1, 4); /* spi write read */
6702 if (res != 0) /* check result */
6703 {
6704 handle->debug_print("w25qxx: read block lock failed.\n"); /* read block lock failed */
6705
6706 return 1; /* return error */
6707 }
6708 }
6709 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
6710 {
6711 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_BLOCK_LOCK, 4,
6712 addr, 4, 4,
6713 0x00000000, 0x00, 0x00,
6714 0, NULL, 0x00,
6715 value, 1, 4); /* spi write read */
6716 if (res != 0) /* check result */
6717 {
6718 handle->debug_print("w25qxx: read block lock failed.\n"); /* read block lock failed */
6719
6720 return 1; /* return error */
6721 }
6722 }
6723 else
6724 {
6725 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
6726
6727 return 4; /* return error */
6728 }
6729 }
6730
6731 return 0; /* success return 0 */
6732 }
6733
6746 uint8_t w25qxx_set_burst_with_wrap(w25qxx_handle_t *handle, w25qxx_burst_wrap_t wrap)
6747 {
6748 uint8_t res;
6749 uint8_t buf[5];
6750
6751 if (handle == NULL) /* check handle */
6752 {
6753 return 2; /* return error */
6754 }
6755 if (handle->inited != 1) /* check handle initialization */
6756 {
6757 return 3; /* return error */
6758 }
6759
6760 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
6761 {
6762 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
6763 {
6764 buf[0] = wrap;
6765 res = a_w25qxx_qspi_write_read(handle,
6766 W25QXX_COMMAND_SET_BURST_WITH_WRAP, 1,
6767 0x00000000, 0x00, 0x00,
6768 0x00000000, 0x00, 0x00,
6769 3 * 8, (uint8_t *)buf, 1,
6770 NULL, 0x00, 1); /* spi write read */
6771 if (res != 0) /* check result */
6772 {
6773 handle->debug_print("w25qxx: set burst with wrap failed.\n"); /* set burst with wrap failed */
6774
6775 return 1; /* return error */
6776 }
6777 }
6778 else /* single spi */
6779 {
6780 buf[0] = W25QXX_COMMAND_SET_BURST_WITH_WRAP; /* set burst with wrap command */
6781 buf[1] = 0x00; /* dummy */
6782 buf[2] = 0x00; /* dummy */
6783 buf[3] = 0x00; /* dummy */
6784 buf[4] = wrap; /* wrap */
6785 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, NULL, 0); /* spi write read */
6786 if (res != 0) /* check result */
6787 {
6788 handle->debug_print("w25qxx: set burst with wrap failed.\n"); /* set burst with wrap failed */
6789
6790 return 1; /* return error */
6791 }
6792 }
6793 }
6794 else
6795 {
6796 handle->debug_print("w25qxx: qspi can't use this function.\n"); /* qspi can't use this function */
6797
6798 return 4; /* return error */
6799 }
6800
6801 return 0; /* success return 0 */
6802 }
6803
6819 uint8_t w25qxx_init(w25qxx_handle_t *handle)
6820 {
6821 uint8_t res;
6822 uint8_t status;
6823 uint8_t buf[4];
6824 uint8_t out[2];
6825 uint16_t id;
6826
6827 if (handle == NULL) /* check handle */
6828 {
6829 return 2; /* return error */
6830 }
6831 if (handle->debug_print == NULL) /* check debug_print */
6832 {
6833 return 3; /* return error */
6834 }
6835 if (handle->spi_qspi_init == NULL) /* check spi_qspi_init */
6836 {
6837 handle->debug_print("w25qxx: spi_qspi_init is null.\n"); /* spi_qspi_init is null */
6838
6839 return 3; /* return error */
6840 }
6841 if (handle->spi_qspi_deinit == NULL) /* check spi_qspi_deinit */
6842 {
6843 handle->debug_print("w25qxx: spi_qspi_deinit is null.\n"); /* spi_qspi_deinit is null */
6844
6845 return 3; /* return error */
6846 }
6847 if (handle->spi_qspi_write_read == NULL) /* check spi_qspi_write_read */
6848 {
6849 handle->debug_print("w25qxx: spi_qspi_write_read is null.\n"); /* spi_qspi_write_read is null */
6850
6851 return 3; /* return error */
6852 }
6853 if (handle->delay_us == NULL) /* check delay_us */
6854 {
6855 handle->debug_print("w25qxx: delay_us is null.\n"); /* delay_us is null */
6856
6857 return 3; /* return error */
6858 }
6859 if (handle->delay_ms == NULL) /* check delay_ms */
6860 {
6861 handle->debug_print("w25qxx: delay_ms is null.\n"); /* delay_ms is null */
6862
6863 return 3; /* return error */
6864 }
6865
6866 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
6867 {
6868 res = handle->spi_qspi_init(); /* spi init */
6869 if (res != 0) /* check result */
6870 {
6871 handle->debug_print("w25qxx: spi init failed.\n"); /* spi init failed */
6872
6873 return 1; /* return error */
6874 }
6875 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
6876 {
6877 res = a_w25qxx_qspi_write_read(handle,
6878 W25QXX_COMMAND_RELEASE_POWER_DOWN, 1,
6879 0x00000000, 0x00, 0x00,
6880 0x00000000, 0x00, 0x00,
6881 3 * 8, NULL, 0x00,
6882 (uint8_t *)&id, 1, 1); /* spi write read */
6883 if (res != 0) /* check result */
6884 {
6885 handle->debug_print("w25qxx: release power down failed.\n"); /* release power down failed */
6886 (void)handle->spi_qspi_deinit();
6888 return 1; /* return error */
6889 }
6890 res = a_w25qxx_qspi_write_read(handle,
6891 W25QXX_COMMAND_ENABLE_RESET, 1,
6892 0x00000000, 0x00, 0x00,
6893 0x00000000, 0x00, 0x00,
6894 0x00, NULL, 0x00,
6895 NULL, 0x00, 0x00); /* spi write read */
6896 if (res != 0) /* check result */
6897 {
6898 handle->debug_print("w25qxx: enable reset failed.\n"); /* enable reset failed */
6899 (void)handle->spi_qspi_deinit();
6901 return 7; /* return error */
6902 }
6903 res = a_w25qxx_qspi_write_read(handle,
6904 W25QXX_COMMAND_RESET_DEVICE, 1,
6905 0x00000000, 0x00, 0x00,
6906 0x00000000, 0x00, 0x00,
6907 0x00, NULL, 0x00,
6908 NULL, 0x00, 0x00); /* spi write read */
6909 if (res != 0) /* check result */
6910 {
6911 handle->debug_print("w25qxx: reset device failed.\n"); /* reset device failed */
6912 (void)handle->spi_qspi_deinit();
6914 return 7; /* return error */
6915 }
6916 handle->delay_ms(10); /* delay 10 ms */
6917 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_MANUFACTURER, 1,
6918 0x00000000, 1, 3,
6919 0x00000000, 0x00, 0x00,
6920 0, NULL, 0x00,
6921 (uint8_t *)out, 2, 1); /* qspi write read */
6922 if (res != 0) /* check result */
6923 {
6924 handle->debug_print("w25qxx: get manufacturer device id failed.\n"); /* get manufacturer device id failed */
6925 (void)handle->spi_qspi_deinit();
6927 return 1; /* return error */
6928 }
6929 id = (uint16_t)out[0] << 8 | out[1]; /* set id */
6930 if (id != handle->type) /* check id */
6931 {
6932 handle->debug_print("w25qxx: id is invalid.\n"); /* id is invalid */
6933 (void)handle->spi_qspi_deinit();
6935 return 6; /* return error */
6936 }
6937 if (handle->type >= W25Q256)
6938 {
6939 res = a_w25qxx_qspi_write_read(handle, 0xE9, 1,
6940 0x00000000, 0, 0,
6941 0x00000000, 0x00, 0x00,
6942 0, NULL, 0x00,
6943 NULL, 0, 0); /* qspi write read */
6944 if (res != 0) /* check result */
6945 {
6946 handle->debug_print("w25qxx: enter 3 byte mode failed.\n"); /* enter 3 byte mode failed */
6947 (void)handle->spi_qspi_deinit();
6949 return 1; /* return error */
6950 }
6951 }
6952 }
6953 else /* single spi */
6954 {
6955 buf[0] = W25QXX_COMMAND_RELEASE_POWER_DOWN; /* release power down command */
6956 buf[1] = 0xFF; /* dummy */
6957 buf[2] = 0xFF; /* dummy */
6958 buf[3] = 0xFF; /* dummy */
6959 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4,
6960 (uint8_t *)&id, 1); /* spi write read */
6961 if (res != 0) /* check result */
6962 {
6963 handle->debug_print("w25qxx: release power down failed.\n"); /* release power down failed */
6964 (void)handle->spi_qspi_deinit();
6966 return 1; /* return error */
6967 }
6968 buf[0] = W25QXX_COMMAND_ENABLE_RESET; /* enable reset command */
6969 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
6970 if (res != 0) /* check result */
6971 {
6972 handle->debug_print("w25qxx: enable reset failed.\n"); /* enable reset failed */
6973 (void)handle->spi_qspi_deinit();
6975 return 7; /* return error */
6976 }
6977 buf[0] = W25QXX_COMMAND_RESET_DEVICE; /* reset device command */
6978 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
6979 if (res != 0) /* check result */
6980 {
6981 handle->debug_print("w25qxx: reset device failed.\n"); /* reset device failed */
6982 (void)handle->spi_qspi_deinit();
6984 return 7; /* return error */
6985 }
6986 handle->delay_ms(10); /* delay 10 ms */
6987 buf[0] = W25QXX_COMMAND_READ_MANUFACTURER; /* read manufacturer command */
6988 buf[1] = 0x00; /* dummy */
6989 buf[2] = 0x00; /* dummy */
6990 buf[3] = 0x00; /* dummy */
6991 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4,
6992 (uint8_t *)out, 2); /* spi write read */
6993 if (res != 0) /* check result */
6994 {
6995 handle->debug_print("w25qxx: get manufacturer device id failed.\n"); /* get manufacturer device id failed */
6996 (void)handle->spi_qspi_deinit();
6998 return 4; /* return error */
6999 }
7000 id = (uint16_t)out[0] << 8 | out[1]; /* set id */
7001 if (id != handle->type) /* check id */
7002 {
7003 handle->debug_print("w25qxx: id is invalid.\n"); /* id is invalid */
7004 (void)handle->spi_qspi_deinit();
7006 return 6; /* return error */
7007 }
7008 if (handle->type >= W25Q256)
7009 {
7010 buf[0] = 0xE9; /* 3 byte mode */
7011 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
7012 if (res != 0) /* check result */
7013 {
7014 handle->debug_print("w25qxx: set address mode failed.\n"); /* set address mode failed */
7015 (void)handle->spi_qspi_deinit();
7017 return 8; /* return error */
7018 }
7019 }
7020 }
7021 }
7022 else
7023 {
7024 res = handle->spi_qspi_init(); /* qspi init */
7025 if (res != 0) /* check result */
7026 {
7027 handle->debug_print("w25qxx: qspi init failed.\n"); /* qspi init failed */
7028
7029 return 1; /* return error */
7030 }
7031 res = a_w25qxx_qspi_write_read(handle,
7032 W25QXX_COMMAND_RELEASE_POWER_DOWN, 1,
7033 0x00000000, 0x00, 0x00,
7034 0x00000000, 0x00, 0x00,
7035 3 * 8, NULL, 0x00,
7036 (uint8_t *)&id, 1, 1); /* spi write read */
7037 if (res != 0) /* check result */
7038 {
7039 handle->debug_print("w25qxx: release power down failed.\n"); /* release power down failed */
7040 (void)handle->spi_qspi_deinit();
7042 return 1; /* return error */
7043 }
7044 res = a_w25qxx_qspi_write_read(handle,
7045 W25QXX_COMMAND_ENABLE_RESET, 1,
7046 0x00000000, 0x00, 0x00,
7047 0x00000000, 0x00, 0x00,
7048 0x00, NULL, 0x00,
7049 NULL, 0x00, 0x00); /* spi write read */
7050 if (res != 0) /* check result */
7051 {
7052 handle->debug_print("w25qxx: enable reset failed.\n"); /* enable reset failed */
7053 (void)handle->spi_qspi_deinit();
7055 return 7; /* return error */
7056 }
7057 res = a_w25qxx_qspi_write_read(handle,
7058 W25QXX_COMMAND_RESET_DEVICE, 1,
7059 0x00000000, 0x00, 0x00,
7060 0x00000000, 0x00, 0x00,
7061 0x00, NULL, 0x00,
7062 NULL, 0x00, 0x00); /* spi write read */
7063 if (res != 0) /* check result */
7064 {
7065 handle->debug_print("w25qxx: reset device failed.\n"); /* reset device failed */
7066 (void)handle->spi_qspi_deinit();
7068 return 7; /* return error */
7069 }
7070 handle->delay_ms(10); /* delay 10 ms */
7071 res = a_w25qxx_qspi_write_read(handle,
7072 W25QXX_COMMAND_READ_STATUS_REG2, 1,
7073 0x00000000, 0x00, 0x00,
7074 0x00000000, 0x00, 0x00,
7075 0x00, NULL, 0x00,
7076 (uint8_t *)&status, 1, 1); /* spi write read */
7077 if (res != 0) /* check result */
7078 {
7079 handle->debug_print("w25qxx: read status 2 failed.\n"); /* read status 2 failed */
7080 (void)handle->spi_qspi_deinit();
7082 return 5; /* return error */
7083 }
7084 if ((status & 0x02) == 0) /* check status */
7085 {
7086 res = a_w25qxx_qspi_write_read(handle,
7087 W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE, 1,
7088 0x00000000, 0x00, 0x00,
7089 0x00000000, 0x00, 0x00,
7090 0x00, NULL, 0x00,
7091 NULL, 0x00, 0x00); /* spi write read */
7092 if (res != 0) /* check result */
7093 {
7094 handle->debug_print("w25qxx: set sr write enable failed.\n"); /* set sr write enable failed */
7095 (void)handle->spi_qspi_deinit();
7097 return 5; /* return error */
7098 }
7099 res = a_w25qxx_qspi_write_read(handle,
7100 W25QXX_COMMAND_WRITE_STATUS_REG2, 1,
7101 0x00000000, 0x00, 0x00,
7102 0x00000000, 0x00, 0x00,
7103 0x00, NULL, 0x00,
7104 NULL, 0x00, 0x00); /* spi write read */
7105 if (res != 0) /* check result */
7106 {
7107 handle->debug_print("w25qxx: write status 2 failed.\n"); /* write status 2 failed */
7108 (void)handle->spi_qspi_deinit();
7110 return 5; /* return error */
7111 }
7112 }
7113 res = a_w25qxx_qspi_write_read(handle,
7114 W25QXX_COMMAND_ENTER_QSPI_MODE, 1,
7115 0x00000000, 0x00, 0x00,
7116 0x00000000, 0x00, 0x00,
7117 0x00, NULL, 0x00,
7118 NULL, 0x00, 0x00); /* spi write read */
7119 if (res != 0) /* check result */
7120 {
7121 handle->debug_print("w25qxx: enter qspi failed.\n"); /* enter qspi failed */
7122 (void)handle->spi_qspi_deinit();
7124 return 5; /* return error */
7125 }
7126 handle->delay_ms(10); /* delay 10 ms */
7127 buf[0] = 3 << 4; /* set 8 read dummy */
7128 handle->param = buf[0]; /* set param */
7129 handle->dummy = 8; /* set dummy */
7130 res = a_w25qxx_qspi_write_read(handle, 0xC0, 4,
7131 0x00000000, 0x00, 0x00,
7132 0x00000000, 0x00, 0x00,
7133 0, (uint8_t *)buf, 1,
7134 NULL, 0x00, 4); /* qspi write read */
7135 if (res != 0) /* check result */
7136 {
7137 handle->debug_print("w25qxx: set read parameters failed.\n"); /* set read parameters failed */
7138 (void)handle->spi_qspi_deinit();
7140 return 5; /* return error */
7141 }
7142 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_MANUFACTURER, 4,
7143 0x00000000, 4, 3,
7144 0x00000000, 0x00, 0x00,
7145 0, NULL, 0x00,
7146 (uint8_t *)out, 2, 4); /* qspi write read */
7147 if (res != 0) /* check result */
7148 {
7149 handle->debug_print("w25qxx: get manufacturer device id failed.\n"); /* get manufacturer device id failed */
7150 (void)handle->spi_qspi_deinit();
7152 return 1; /* return error */
7153 }
7154 id = (uint16_t)out[0] << 8 | out[1]; /* set id */
7155 if (id != handle->type) /* check id */
7156 {
7157 handle->debug_print("w25qxx: id is invalid.\n"); /* id is invalid */
7158 (void)handle->spi_qspi_deinit();
7160 return 6; /* return error */
7161 }
7162 if (handle->type >= W25Q256)
7163 {
7164 res = a_w25qxx_qspi_write_read(handle, 0xE9, 4,
7165 0x00000000, 0, 0,
7166 0x00000000, 0x00, 0x00,
7167 0, NULL, 0x00,
7168 NULL, 0, 0); /* qspi write read */
7169 if (res != 0) /* check result */
7170 {
7171 handle->debug_print("w25qxx: enter 3 byte mode failed.\n"); /* enter 3 byte mode failed */
7172 (void)handle->spi_qspi_deinit();
7174 return 1; /* return error */
7175 }
7176 }
7177 }
7178 handle->address_mode = W25QXX_ADDRESS_MODE_3_BYTE; /* set address mode */
7179 handle->inited = 1; /* initialize inited */
7180
7181 return 0; /* success return 0 */
7182 }
7183
7195 uint8_t w25qxx_deinit(w25qxx_handle_t *handle)
7196 {
7197 uint8_t res;
7198 uint8_t buf[1];
7199
7200 if (handle == NULL) /* check handle */
7201 {
7202 return 2; /* return error */
7203 }
7204 if (handle->inited != 1) /* check handle initialization */
7205 {
7206 return 3; /* return error */
7207 }
7208
7209 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
7210 {
7211 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
7212 {
7213 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_POWER_DOWN, 1,
7214 0x00000000, 0x00, 0x00,
7215 0x00000000, 0x00, 0x00,
7216 0, NULL, 0x00,
7217 NULL, 0x00, 0); /* spi write read */
7218 if (res != 0) /* check result */
7219 {
7220 handle->debug_print("w25qxx: power down failed.\n"); /* power down failed */
7221
7222 return 4; /* return error */
7223 }
7224 }
7225 else /* single spi */
7226 {
7227 buf[0] = W25QXX_COMMAND_POWER_DOWN; /* power down command */
7228 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf,
7229 1, NULL, 0); /* spi write read */
7230 if (res != 0) /* check result */
7231 {
7232 handle->debug_print("w25qxx: power down failed.\n"); /* power down failed */
7233
7234 return 4; /* return error */
7235 }
7236 }
7237 }
7238 else /* qspi interface */
7239 {
7240 res = a_w25qxx_qspi_write_read(handle, 0xFF, 4,
7241 0x00000000, 0x00, 0x00,
7242 0x00000000, 0x00, 0x00,
7243 0, NULL, 0x00,
7244 NULL, 0x00, 0); /* spi write read */
7245 if (res != 0) /* check result */
7246 {
7247 handle->debug_print("w25qxx: exit qspi mode failed.\n"); /* exit qspi mode failed */
7248
7249 return 1; /* return error */
7250 }
7251 handle->delay_ms(10); /* delay 10 ms */
7252 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_POWER_DOWN, 1,
7253 0x00000000, 0x00, 0x00,
7254 0x00000000, 0x00, 0x00,
7255 0, NULL, 0x00,
7256 NULL, 0x00, 0); /* spi write read */
7257 if (res != 0) /* check result */
7258 {
7259 handle->debug_print("w25qxx: power down failed.\n"); /* power down failed */
7260
7261 return 4; /* return error */
7262 }
7263 }
7264 res = handle->spi_qspi_deinit(); /* qspi deinit */
7265 if (res != 0) /* check result */
7266 {
7267 handle->debug_print("w25qxx: spi or qspi deinit failed.\n"); /* spi or qspi deinit failed */
7268
7269 return 1; /* return error */
7270 }
7271
7272 return 0; /* success return 0 */
7273 }
7274
7289 uint8_t w25qxx_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
7290 {
7291 uint8_t res;
7292 uint8_t buf[6];
7293
7294 if (handle == NULL) /* check handle */
7295 {
7296 return 2; /* return error */
7297 }
7298 if (handle->inited != 1) /* check handle initialization */
7299 {
7300 return 3; /* return error */
7301 }
7302
7303 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
7304 {
7305 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
7306 {
7307 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7308 {
7309 if (handle->type >= W25Q256) /* >128Mb */
7310 {
7311 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
7312 0x00000000, 0x00, 0x00,
7313 0x00000000, 0x00, 0x00,
7314 0x00, NULL, 0x00,
7315 NULL, 0x00, 0x00); /* qspi write read */
7316 if (res != 0) /* check result */
7317 {
7318 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7319
7320 return 1; /* return error */
7321 }
7322 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7323 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
7324 0x00000000, 0x00, 0x00,
7325 0x00000000, 0x00, 0x00,
7326 0, (uint8_t *)buf, 0x01,
7327 NULL, 0x00, 1); /* spi write read */
7328 if (res != 0) /* check result */
7329 {
7330 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7331
7332 return 1; /* return error */
7333 }
7334 }
7335 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 1,
7336 addr, 1, 3,
7337 0x00000000, 0x00, 0x00,
7338 8, NULL, 0x00, /* spi write */
7339 data, len, 1); /* spi write read */
7340 if (res != 0) /* check result */
7341 {
7342 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7343
7344 return 1; /* return error */
7345 }
7346 }
7347 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
7348 {
7349 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 1,
7350 addr, 1, 4,
7351 0x00000000, 0x00, 0x00,
7352 8, NULL, 0x00, /* spi write */
7353 data, len, 1); /* spi write read */
7354 if (res != 0) /* check result */
7355 {
7356 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7357
7358 return 1; /* return error */
7359 }
7360 }
7361 else
7362 {
7363 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7364
7365 return 4; /* return error */
7366 }
7367 }
7368 else /* single spi */
7369 {
7370 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7371 {
7372 if (handle->type >= W25Q256) /* >128Mb */
7373 {
7374 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
7375 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
7376 if (res != 0) /* check result */
7377 {
7378 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7379
7380 return 1; /* return error */
7381 }
7382 buf[0] = 0xC5; /* write extended addr register command */
7383 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7384 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
7385 if (res != 0) /* check result */
7386 {
7387 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7388
7389 return 1; /* return error */
7390 }
7391 }
7392 buf[0] = W25QXX_COMMAND_FAST_READ; /* fast read command */
7393 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
7394 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
7395 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
7396 buf[4] = 0x00; /* dummy */
7397 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, (uint8_t *)data, (uint32_t)len); /* spi write read */
7398 if (res != 0) /* check result */
7399 {
7400 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7401
7402 return 1; /* return error */
7403 }
7404 }
7405 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE)
7406 && (handle->type >= W25Q256)) /* check address mode */
7407 {
7408 buf[0] = W25QXX_COMMAND_FAST_READ; /* fast read command */
7409 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7410 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
7411 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
7412 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
7413 buf[5] = 0x00; /* dummy */
7414 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 6, (uint8_t *)data, (uint32_t)len); /* spi write read */
7415 if (res != 0) /* check result */
7416 {
7417 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7418
7419 return 1; /* return error */
7420 }
7421 }
7422 else
7423 {
7424 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7425
7426 return 4; /* return error */
7427 }
7428 }
7429 }
7430 else /* qspi interface */
7431 {
7432 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7433 {
7434 if (handle->type >= W25Q256) /* >128Mb */
7435 {
7436 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
7437 0x00000000, 0x00, 0x00,
7438 0x00000000, 0x00, 0x00,
7439 0x00, NULL, 0x00,
7440 NULL, 0x00, 0x00); /* qspi write read */
7441 if (res != 0) /* check result */
7442 {
7443 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7444
7445 return 1; /* return error */
7446 }
7447 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7448 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
7449 0x00000000, 0x00, 0x00,
7450 0x00000000, 0x00, 0x00,
7451 0, (uint8_t *)buf, 0x01,
7452 NULL, 0x00, 4); /* spi write read */
7453 if (res != 0) /* check result */
7454 {
7455 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7456
7457 return 1; /* return error */
7458 }
7459 }
7460 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 4,
7461 addr, 4, 3,
7462 0x00000000, 0x00, 0x00,
7463 handle->dummy, NULL, 0x00, /* spi write */
7464 data, len, 4); /* spi write read */
7465 if (res != 0) /* check result */
7466 {
7467 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7468
7469 return 1; /* return error */
7470 }
7471 }
7472 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
7473 {
7474 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 4,
7475 addr, 4, 4,
7476 0x00000000, 0x00, 0x00,
7477 handle->dummy, NULL, 0x00, /* spi write */
7478 data, len, 4); /* spi write read */
7479 if (res != 0) /* check result */
7480 {
7481 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7482
7483 return 1; /* return error */
7484 }
7485 }
7486 else
7487 {
7488 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7489
7490 return 4; /* return error */
7491 }
7492 }
7493
7494 return 0; /* success return 0 */
7495 }
7496
7508 static uint8_t a_w25qxx_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
7509 {
7510 uint8_t res;
7511 uint8_t buf[6];
7512
7513 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
7514 {
7515 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
7516 {
7517 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7518 {
7519 if (handle->type >= W25Q256) /* >128Mb */
7520 {
7521 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
7522 0x00000000, 0x00, 0x00,
7523 0x00000000, 0x00, 0x00,
7524 0x00, NULL, 0x00,
7525 NULL, 0x00, 0x00); /* qspi write read */
7526 if (res != 0) /* check result */
7527 {
7528 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7529
7530 return 1; /* return error */
7531 }
7532 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7533 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
7534 0x00000000, 0x00, 0x00,
7535 0x00000000, 0x00, 0x00,
7536 0, (uint8_t *)buf, 0x01,
7537 NULL, 0x00, 1); /* spi write read */
7538 if (res != 0) /* check result */
7539 {
7540 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7541
7542 return 1; /* return error */
7543 }
7544 }
7545 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 1,
7546 addr, 1, 3,
7547 0x00000000, 0x00, 0x00,
7548 8, NULL, 0x00,
7549 data, len, 1); /* spi write read */
7550 if (res != 0) /* check result */
7551 {
7552 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7553
7554 return 1; /* return error */
7555 }
7556 }
7557 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
7558 {
7559 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 1,
7560 addr, 1, 4,
7561 0x00000000, 0x00, 0x00,
7562 8, NULL, 0x00,
7563 data, len, 1); /* spi write read */
7564 if (res != 0) /* check result */
7565 {
7566 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7567
7568 return 1; /* return error */
7569 }
7570 }
7571 else
7572 {
7573 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7574
7575 return 1; /* return error */
7576 }
7577 }
7578 else
7579 {
7580 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7581 {
7582 if (handle->type >= W25Q256) /* >128Mb */
7583 {
7584 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
7585 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
7586 if (res != 0) /* check result */
7587 {
7588 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7589
7590 return 1; /* return error */
7591 }
7592 buf[0] = 0xC5; /* write extended addr register command */
7593 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7594 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
7595 if (res != 0) /* check result */
7596 {
7597 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7598
7599 return 1; /* return error */
7600 }
7601 }
7602 buf[0] = W25QXX_COMMAND_FAST_READ; /* fast read command */
7603 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
7604 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
7605 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
7606 buf[4] = 0x00; /* dummy */
7607 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, (uint8_t *)data, (uint32_t)len); /* spi write read */
7608 if (res != 0) /* check result */
7609 {
7610 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7611
7612 return 1; /* return error */
7613 }
7614 }
7615 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256)) /* check address mode */
7616 {
7617 buf[0] = W25QXX_COMMAND_FAST_READ; /* fast read command */
7618 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7619 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
7620 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
7621 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
7622 buf[5] = 0x00; /* dummy */
7623 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 6, (uint8_t *)data, (uint32_t)len); /* spi write read */
7624 if (res != 0) /* check result */
7625 {
7626 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7627
7628 return 1; /* return error */
7629 }
7630 }
7631 else
7632 {
7633 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7634
7635 return 1; /* return error */
7636 }
7637 }
7638 }
7639 else /* qspi interface */
7640 {
7641 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7642 {
7643 if (handle->type >= W25Q256) /* >128Mb */
7644 {
7645 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
7646 0x00000000, 0x00, 0x00,
7647 0x00000000, 0x00, 0x00,
7648 0x00, NULL, 0x00,
7649 NULL, 0x00, 0x00); /* qspi write read */
7650 if (res != 0) /* check result */
7651 {
7652 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7653
7654 return 1; /* return error */
7655 }
7656 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7657 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
7658 0x00000000, 0x00, 0x00,
7659 0x00000000, 0x00, 0x00,
7660 0, (uint8_t *)buf, 0x01,
7661 NULL, 0x00, 4); /* spi write read */
7662 if (res != 0) /* check result */
7663 {
7664 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7665
7666 return 1; /* return error */
7667 }
7668 }
7669 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 4,
7670 addr, 4, 3,
7671 0x00000000, 0x00, 0x00,
7672 handle->dummy, NULL, 0x00, /* spi write */
7673 data, len, 4); /* spi write read */
7674 if (res != 0) /* check result */
7675 {
7676 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7677
7678 return 1; /* return error */
7679 }
7680 }
7681 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
7682 {
7683 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_FAST_READ, 4,
7684 addr, 4, 4,
7685 0x00000000, 0x00, 0x00,
7686 handle->dummy, NULL, 0x00, /* spi write */
7687 data, len, 4); /* spi write read */
7688 if (res != 0) /* check result */
7689 {
7690 handle->debug_print("w25qxx: fast read failed.\n"); /* fast read failed */
7691
7692 return 1; /* return error */
7693 }
7694 }
7695 else
7696 {
7697 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7698
7699 return 1; /* return error */
7700 }
7701 }
7702
7703 return 0; /* success return 0 */
7704 }
7705
7715 static uint8_t a_w25qxx_erase_sector(w25qxx_handle_t *handle, uint32_t addr)
7716 {
7717 uint8_t res;
7718 uint8_t status;
7719 uint32_t timeout;
7720 uint8_t buf[5];
7721
7722 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
7723 {
7724 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
7725 {
7726 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
7727 0x00000000, 0x00, 0x00,
7728 0x00000000, 0x00, 0x00,
7729 0x00, NULL, 0x00,
7730 NULL, 0x00, 0x00); /* qspi write read */
7731 if (res != 0) /* check result */
7732 {
7733 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7734
7735 return 1; /* return error */
7736 }
7737 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7738 {
7739 if (handle->type >= W25Q256) /* >128Mb */
7740 {
7741 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7742 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
7743 0x00000000, 0x00, 0x00,
7744 0x00000000, 0x00, 0x00,
7745 0, (uint8_t *)buf, 0x01,
7746 NULL, 0x00, 1); /* spi write read */
7747 if (res != 0) /* check result */
7748 {
7749 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7750
7751 return 1; /* return error */
7752 }
7753 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
7754 0x00000000, 0x00, 0x00,
7755 0x00000000, 0x00, 0x00,
7756 0x00, NULL, 0x00,
7757 NULL, 0x00, 0x00); /* qspi write read */
7758 if (res != 0) /* check result */
7759 {
7760 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7761
7762 return 1; /* return error */
7763 }
7764 }
7765 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_SECTOR_ERASE_4K, 1,
7766 addr, 1, 3,
7767 0x00000000, 0x00, 0x00,
7768 0, NULL, 0x00,
7769 NULL, 0x00, 0x00); /* spi write read */
7770 if (res != 0) /* check result */
7771 {
7772 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
7773
7774 return 1; /* return error */
7775 }
7776 }
7777 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
7778 {
7779 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_SECTOR_ERASE_4K, 1,
7780 addr, 1, 4,
7781 0x00000000, 0x00, 0x00,
7782 0, NULL, 0x00,
7783 NULL, 0x00, 0x00); /* spi write read */
7784 if (res != 0) /* check result */
7785 {
7786 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
7787
7788 return 1; /* return error */
7789 }
7790 }
7791 else
7792 {
7793 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7794
7795 return 1; /* return error */
7796 }
7797
7798 timeout = 400; /* max 400 ms */
7799 while (timeout != 0) /* check timeout */
7800 {
7801 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
7802 0x00000000, 0x00, 0x00,
7803 0x00000000, 0x00, 0x00,
7804 0, NULL, 0,
7805 (uint8_t *)&status, 1, 1); /* spi write read */
7806 if (res != 0) /* check result */
7807 {
7808 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
7809
7810 return 1; /* return error */
7811 }
7812 if ((status & 0x01) == 0x00) /* check status */
7813 {
7814 break; /* break */
7815 }
7816 timeout--; /* timeout-- */
7817 handle->delay_ms(1); /* delay 1 ms */
7818 }
7819 if (timeout == 0)
7820 {
7821 handle->debug_print("w25qxx: sector erase 4k timeout.\n"); /* sector erase 4k timeout */
7822
7823 return 1; /* return error */
7824 }
7825 }
7826 else /* single spi */
7827 {
7828 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
7829 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
7830 if (res != 0) /* check result */
7831 {
7832 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7833
7834 return 1; /* return error */
7835 }
7836 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7837 {
7838 if (handle->type >= W25Q256) /* >128Mb */
7839 {
7840 buf[0] = 0xC5; /* write extended addr register command */
7841 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7842 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
7843 if (res != 0) /* check result */
7844 {
7845 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7846
7847 return 1; /* return error */
7848 }
7849 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
7850 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
7851 if (res != 0) /* check result */
7852 {
7853 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7854
7855 return 1; /* return error */
7856 }
7857 }
7858 buf[0] = W25QXX_COMMAND_SECTOR_ERASE_4K; /* sector erase 4k command */
7859 buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
7860 buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
7861 buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
7862 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 4, NULL, 0); /* spi write read */
7863 if (res != 0) /* check result */
7864 {
7865 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
7866
7867 return 1; /* return error */
7868 }
7869 }
7870 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
7871 {
7872 buf[0] = W25QXX_COMMAND_SECTOR_ERASE_4K; /* sector erase 4k command */
7873 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7874 buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
7875 buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
7876 buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
7877 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 5, NULL, 0); /* spi write read */
7878 if (res != 0) /* check result */
7879 {
7880 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
7881
7882 return 1; /* return error */
7883 }
7884 }
7885 else
7886 {
7887 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7888
7889 return 1; /* return error */
7890 }
7891
7892 timeout = 400; /* max 400 ms */
7893 while (timeout != 0) /* check timeout */
7894 {
7895 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
7896 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, (uint8_t *)&status, 1); /* spi write read */
7897 if (res != 0) /* check result */
7898 {
7899 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
7900
7901 return 1; /* return error */
7902 }
7903 if ((status & 0x01) == 0x00) /* check status */
7904 {
7905 break; /* break */
7906 }
7907 timeout--; /* timeout-- */
7908 handle->delay_ms(1); /* delay 1 ms */
7909 }
7910 if (timeout == 0)
7911 {
7912 handle->debug_print("w25qxx: sector erase 4k timeout.\n"); /* sector erase 4k timeout */
7913
7914 return 1; /* return error */
7915 }
7916 }
7917 }
7918 else
7919 {
7920 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
7921 0x00000000, 0x00, 0x00,
7922 0x00000000, 0x00, 0x00,
7923 0x00, NULL, 0x00,
7924 NULL, 0x00, 0x00); /* qspi write read */
7925 if (res != 0) /* check result */
7926 {
7927 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7928
7929 return 1; /* return error */
7930 }
7931 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
7932 {
7933 if (handle->type >= W25Q256) /* >128Mb */
7934 {
7935 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
7936 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
7937 0x00000000, 0x00, 0x00,
7938 0x00000000, 0x00, 0x00,
7939 0, (uint8_t *)buf, 0x01,
7940 NULL, 0x00, 4); /* spi write read */
7941 if (res != 0) /* check result */
7942 {
7943 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
7944
7945 return 1; /* return error */
7946 }
7947 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
7948 0x00000000, 0x00, 0x00,
7949 0x00000000, 0x00, 0x00,
7950 0x00, NULL, 0x00,
7951 NULL, 0x00, 0x00); /* qspi write read */
7952 if (res != 0) /* check result */
7953 {
7954 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
7955
7956 return 1; /* return error */
7957 }
7958 }
7959 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_SECTOR_ERASE_4K, 4,
7960 addr, 4, 3,
7961 0x00000000, 0x00, 0x00,
7962 0, NULL, 0x00,
7963 NULL, 0x00, 0x00); /* spi write read */
7964 if (res != 0) /* check result */
7965 {
7966 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
7967
7968 return 1; /* return error */
7969 }
7970 }
7971 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
7972 {
7973 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_SECTOR_ERASE_4K, 4,
7974 addr, 4, 4,
7975 0x00000000, 0x00, 0x00,
7976 0, NULL, 0x00,
7977 NULL, 0x00, 0x00); /* spi write read */
7978 if (res != 0) /* check result */
7979 {
7980 handle->debug_print("w25qxx: sector erase 4k failed.\n"); /* sector erase 4k failed */
7981
7982 return 1; /* return error */
7983 }
7984 }
7985 else
7986 {
7987 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
7988
7989 return 1; /* return error */
7990 }
7991
7992 timeout = 400; /* max 400 ms */
7993 while (timeout != 0) /* check timeout */
7994 {
7995 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
7996 0x00000000, 0x00, 0x00,
7997 0x00000000, 0x00, 0x00,
7998 0, NULL, 0,
7999 (uint8_t *)&status, 1, 4); /* spi write read */
8000 if (res != 0) /* check result */
8001 {
8002 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
8003
8004 return 1; /* return error */
8005 }
8006 if ((status & 0x01) == 0x00) /* check status */
8007 {
8008 break; /* break */
8009 }
8010 timeout--; /* timeout-- */
8011 handle->delay_ms(1); /* delay 1 ms */
8012 }
8013 if (timeout == 0)
8014 {
8015 handle->debug_print("w25qxx: sector erase 4k timeout.\n"); /* sector erase 4k timeout */
8016
8017 return 1; /* return error */
8018 }
8019 }
8020
8021 return 0; /* success return 0 */
8022 }
8023
8035 static uint8_t a_w25qxx_page_program(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint16_t len)
8036 {
8037 uint8_t res;
8038 uint8_t status;
8039 uint32_t timeout;
8040 uint8_t buf[2];
8041
8042 if (handle->spi_qspi == W25QXX_INTERFACE_SPI) /* spi interface */
8043 {
8044 if (handle->dual_quad_spi_enable != 0) /* enable dual quad spi */
8045 {
8046 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
8047 0x00000000, 0x00, 0x00,
8048 0x00000000, 0x00, 0x00,
8049 0x00, NULL, 0x00,
8050 NULL, 0x00, 0x00); /* qspi write read */
8051 if (res != 0) /* check result */
8052 {
8053 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
8054
8055 return 1; /* return error */
8056 }
8057 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
8058 {
8059 if (handle->type >= W25Q256) /* >128Mb */
8060 {
8061 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
8062 res = a_w25qxx_qspi_write_read(handle, 0xC5, 1,
8063 0x00000000, 0x00, 0x00,
8064 0x00000000, 0x00, 0x00,
8065 0, (uint8_t *)buf, 0x01,
8066 NULL, 0x00, 1); /* spi write read */
8067 if (res != 0) /* check result */
8068 {
8069 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
8070
8071 return 1; /* return error */
8072 }
8073 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 1,
8074 0x00000000, 0x00, 0x00,
8075 0x00000000, 0x00, 0x00,
8076 0x00, NULL, 0x00,
8077 NULL, 0x00, 0x00); /* qspi write read */
8078 if (res != 0) /* check result */
8079 {
8080 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
8081
8082 return 1; /* return error */
8083 }
8084 }
8085 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_PAGE_PROGRAM, 1,
8086 addr, 1, 3,
8087 0x00000000, 0x00, 0x00,
8088 0, data, len,
8089 NULL, 0x00, 1); /* spi write read */
8090 if (res != 0) /* check result */
8091 {
8092 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8093
8094 return 1; /* return error */
8095 }
8096 }
8097 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
8098 {
8099 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_PAGE_PROGRAM, 1,
8100 addr, 1, 4,
8101 0x00000000, 0x00, 0x00,
8102 0, data, len,
8103 NULL, 0x00, 1); /* spi write read */
8104 if (res != 0) /* check result */
8105 {
8106 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8107
8108 return 1; /* return error */
8109 }
8110 }
8111 else
8112 {
8113 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
8114
8115 return 1; /* return error */
8116 }
8117
8118 timeout = 3 * 100; /* max 3 ms */
8119 while (timeout != 0) /* check timeout */
8120 {
8121 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 1,
8122 0x00000000, 0x00, 0x00,
8123 0x00000000, 0x00, 0x00,
8124 0, NULL, 0,
8125 (uint8_t *)&status, 1, 1); /* spi write read */
8126 if (res != 0) /* check result */
8127 {
8128 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8129
8130 return 1; /* return error */
8131 }
8132 if ((status & 0x01) == 0x00) /* check status */
8133 {
8134 break; /* break */
8135 }
8136 timeout--; /* timeout-- */
8137 handle->delay_us(10); /* delay 10 us */
8138 }
8139 if (timeout == 0)
8140 {
8141 handle->debug_print("w25qxx: page program timeout.\n"); /* page program timeout */
8142
8143 return 1; /* return error */
8144 }
8145 }
8146 else /* single spi */
8147 {
8148 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
8149 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
8150 if (res != 0) /* check result */
8151 {
8152 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
8153
8154 return 1; /* return error */
8155 }
8156 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
8157 {
8158 if (handle->type >= W25Q256) /* >128Mb */
8159 {
8160 buf[0] = 0xC5; /* write extended addr register command */
8161 buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
8162 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 2, NULL, 0); /* spi write read */
8163 if (res != 0) /* check result */
8164 {
8165 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
8166
8167 return 1; /* return error */
8168 }
8169 buf[0] = W25QXX_COMMAND_WRITE_ENABLE; /* write enable command */
8170 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, NULL, 0); /* spi write read */
8171 if (res != 0) /* check result */
8172 {
8173 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
8174
8175 return 1; /* return error */
8176 }
8177 }
8178 handle->buf[0] = W25QXX_COMMAND_PAGE_PROGRAM; /* page program command */
8179 handle->buf[1] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
8180 handle->buf[2] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
8181 handle->buf[3] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
8182 memcpy(&handle->buf[4], data, len); /* copy data */
8183 res = a_w25qxx_spi_write_read(handle, (uint8_t *)handle->buf, 4 + len, NULL, 0); /* spi write read */
8184 if (res != 0) /* check result */
8185 {
8186 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8187
8188 return 1; /* return error */
8189 }
8190 }
8191 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE)
8192 && (handle->type >= W25Q256)) /* 4 address mode */
8193 {
8194 handle->buf[0] = W25QXX_COMMAND_PAGE_PROGRAM; /* page program command */
8195 handle->buf[1] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
8196 handle->buf[2] = (addr >> 16) & 0xFF; /* 23 - 16 bits */
8197 handle->buf[3] = (addr >> 8) & 0xFF; /* 15 - 8 bits */
8198 handle->buf[4] = (addr >> 0) & 0xFF; /* 7 - 0 bits */
8199 memcpy(&handle->buf[5], data, len); /* copy data */
8200 res = a_w25qxx_spi_write_read(handle, (uint8_t *)handle->buf, 5 + len, NULL, 0); /* spi write read */
8201 if (res != 0) /* check result */
8202 {
8203 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8204
8205 return 1; /* return error */
8206 }
8207 }
8208 else
8209 {
8210 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
8211
8212 return 1; /* return error */
8213 }
8214
8215 timeout = 3 * 100; /* max 3 ms */
8216 while (timeout != 0) /* check timeout */
8217 {
8218 buf[0] = W25QXX_COMMAND_READ_STATUS_REG1; /* read status1 command */
8219 res = a_w25qxx_spi_write_read(handle, (uint8_t *)buf, 1, (uint8_t *)&status, 1); /* spi write read */
8220 if (res != 0) /* check result */
8221 {
8222 handle->debug_print("w25qxx: get status1 failed.\n"); /* get status1 failed */
8223
8224 return 1; /* return error */
8225 }
8226 if ((status & 0x01) == 0x00) /* check status */
8227 {
8228 break; /* break */
8229 }
8230 timeout--; /* timeout-- */
8231 handle->delay_us(10); /* delay 10 us */
8232 }
8233 if (timeout == 0)
8234 {
8235 handle->debug_print("w25qxx: page program timeout.\n"); /* page program timeout */
8236
8237 return 1; /* return error */
8238 }
8239 }
8240 }
8241 else
8242 {
8243 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
8244 0x00000000, 0x00, 0x00,
8245 0x00000000, 0x00, 0x00,
8246 0x00, NULL, 0x00,
8247 NULL, 0x00, 0x00); /* qspi write read */
8248 if (res != 0) /* check result */
8249 {
8250 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
8251
8252 return 1; /* return error */
8253 }
8254 if (handle->address_mode == W25QXX_ADDRESS_MODE_3_BYTE) /* 3 address mode */
8255 {
8256 if (handle->type >= W25Q256) /* >128Mb */
8257 {
8258 buf[0] = (addr >> 24) & 0xFF; /* 31 - 24 bits */
8259 res = a_w25qxx_qspi_write_read(handle, 0xC5, 4,
8260 0x00000000, 0x00, 0x00,
8261 0x00000000, 0x00, 0x00,
8262 0, (uint8_t *)buf, 0x01,
8263 NULL, 0x00, 4); /* spi write read */
8264 if (res != 0) /* check result */
8265 {
8266 handle->debug_print("w25qxx: write extended addr register failed.\n"); /* write extended addr register failed */
8267
8268 return 1; /* return error */
8269 }
8270 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_WRITE_ENABLE, 4,
8271 0x00000000, 0x00, 0x00,
8272 0x00000000, 0x00, 0x00,
8273 0x00, NULL, 0x00,
8274 NULL, 0x00, 0x00); /* qspi write read */
8275 if (res != 0) /* check result */
8276 {
8277 handle->debug_print("w25qxx: write enable failed.\n"); /* write enable failed */
8278
8279 return 1; /* return error */
8280 }
8281 }
8282 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_PAGE_PROGRAM, 4,
8283 addr, 4, 3,
8284 0x00000000, 0x00, 0x00,
8285 0, data, len,
8286 NULL, 0x00, 4); /* spi write read */
8287 if (res != 0) /* check result */
8288 {
8289 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8290
8291 return 1; /* return error */
8292 }
8293 }
8294 else if ((handle->address_mode == W25QXX_ADDRESS_MODE_4_BYTE) && (handle->type >= W25Q256))
8295 {
8296 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_PAGE_PROGRAM, 4,
8297 addr, 4, 4,
8298 0x00000000, 0x00, 0x00,
8299 0, data, len,
8300 NULL, 0x00, 4); /* spi write read */
8301 if (res != 0) /* check result */
8302 {
8303 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8304
8305 return 1; /* return error */
8306 }
8307 }
8308 else
8309 {
8310 handle->debug_print("w25qxx: address mode is invalid.\n"); /* address mode is invalid */
8311
8312 return 1; /* return error */
8313 }
8314
8315 timeout = 3 * 100; /* max 3 ms */
8316 while (timeout != 0) /* check timeout */
8317 {
8318 res = a_w25qxx_qspi_write_read(handle, W25QXX_COMMAND_READ_STATUS_REG1, 4,
8319 0x00000000, 0x00, 0x00,
8320 0x00000000, 0x00, 0x00,
8321 0, NULL, 0,
8322 (uint8_t *)&status, 1, 4); /* spi write read */
8323 if (res != 0) /* check result */
8324 {
8325 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8326
8327 return 1; /* return error */
8328 }
8329 if ((status & 0x01) == 0x00) /* check status */
8330 {
8331 break; /* break */
8332 }
8333 timeout--; /* timeout-- */
8334 handle->delay_us(10); /* delay 10 us */
8335 }
8336 if (timeout == 0)
8337 {
8338 handle->debug_print("w25qxx: page program timeout.\n"); /* page program timeout */
8339
8340 return 1; /* return error */
8341 }
8342 }
8343
8344 return 0; /* success return 0 */
8345 }
8346
8358 static uint8_t a_w25qxx_write_no_check(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
8359 {
8360 uint8_t res;
8361 uint16_t page_remain;
8362
8363 page_remain = 256 - addr % 256; /* get remain */
8364 if (len <= page_remain) /* check length */
8365 {
8366 page_remain = (uint16_t)len; /* page remain */
8367 }
8368 while( 1) /* loop */
8369 {
8370 res = a_w25qxx_page_program(handle, addr, data, page_remain); /* page program */
8371 if (res != 0)
8372 {
8373 handle->debug_print("w25qxx: page program failed.\n"); /* page program failed */
8374
8375 return 1; /* return error */
8376 }
8377 if (len == page_remain) /* check length */
8378 {
8379 break; /* break loop */
8380 }
8381 else
8382 {
8383 data += page_remain; /* data + page_remain */
8384 addr += page_remain; /* address + page_remain */
8385 len -= page_remain; /* length - page_remain */
8386 if (len > 256) /* check length */
8387 {
8388 page_remain = 256; /* set page remain */
8389 }
8390 else
8391 {
8392 page_remain = (uint16_t)len; /* set length */
8393 }
8394 }
8395 }
8396
8397 return 0; /* success return 0 */
8398 }
8399
8415 uint8_t w25qxx_write(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
8416 {
8417 uint8_t res;
8418 uint32_t sec_pos;
8419 uint32_t sec_off;
8420 uint32_t sec_remain;
8421 uint32_t i;
8422
8423 if (handle == NULL) /* check handle */
8424 {
8425 return 2; /* return error */
8426 }
8427 if (handle->inited != 1) /* check handle initialization */
8428 {
8429 return 3; /* return error */
8430 }
8431
8432 sec_pos = addr / 4096; /* get sector position */
8433 sec_off = addr % 4096; /* get sector offset */
8434 sec_remain = 4096 - sec_off; /* get sector remain */
8435 if (len <= sec_remain) /* check length */
8436 {
8437 sec_remain = len; /* set remain */
8438 }
8439 while(1) /* loop */
8440 {
8441 res = a_w25qxx_read(handle, sec_pos * 4096, handle->buf_4k, 4096); /* read 4k data */
8442 if (res != 0)
8443 {
8444 handle->debug_print("w25qxx: read failed.\n"); /* read failed */
8445
8446 return 4; /* return error */
8447 }
8448 for (i = 0; i< sec_remain; i++) /* sec_remain length */
8449 {
8450 if (handle->buf_4k[sec_off + i] != 0xFF) /* check 0xFF */
8451 {
8452 break; /* break loop */
8453 }
8454 }
8455 if (i < sec_remain) /* not all is 0xFF */
8456 {
8457 res = a_w25qxx_erase_sector(handle, sec_pos * 4096); /* erase sector */
8458 if (res != 0)
8459 {
8460 handle->debug_print("w25qxx: erase sector failed.\n"); /* erase sector failed */
8461
8462 return 5; /* return error */
8463 }
8464 for (i = 0; i<sec_remain; i++) /* sec_remain length */
8465 {
8466 handle->buf_4k[i + sec_off] = data[i]; /* copy data */
8467 }
8468 res = a_w25qxx_write_no_check(handle, sec_pos * 4096, handle->buf_4k, 4096); /* write data no check */
8469 if (res != 0) /* check result */
8470 {
8471 handle->debug_print("w25qxx: write failed.\n"); /* write failed */
8472
8473 return 1; /* return error */
8474 }
8475 }
8476 else
8477 {
8478 res = a_w25qxx_write_no_check(handle, addr, data, sec_remain); /* write data */
8479 if (res != 0) /* check result */
8480 {
8481 handle->debug_print("w25qxx: write failed.\n"); /* write failed */
8482
8483 return 1; /* return error */
8484 }
8485 }
8486 if (len == sec_remain) /* check length length*/
8487 {
8488 break; /* break loop */
8489 }
8490 else
8491 {
8492 sec_pos++; /* sector++ */
8493 sec_off = 0; /* set offset */
8494 data += sec_remain; /* data + remain */
8495 addr += sec_remain; /* addr + remain */
8496 len -= sec_remain; /* len - remain */
8497 if (len > 4096) /* check length */
8498 {
8499 sec_remain = 4096; /* set 4096 */
8500 }
8501 else
8502 {
8503 sec_remain = len; /* set length */
8504 }
8505 }
8506 }
8507
8508 return 0; /* success return 0 */
8509 }
8510
8535 uint8_t w25qxx_write_read_reg(w25qxx_handle_t *handle, uint8_t instruction, uint8_t instruction_line,
8536 uint32_t address, uint8_t address_line, uint8_t address_len,
8537 uint32_t alternate, uint8_t alternate_line, uint8_t alternate_len,
8538 uint8_t dummy, uint8_t *in_buf, uint32_t in_len,
8539 uint8_t *out_buf, uint32_t out_len, uint8_t data_line)
8540 {
8541
8542 if (handle == NULL) /* check handle */
8543 {
8544 return 2; /* return error */
8545 }
8546 if (handle->inited != 1) /* check handle initialization */
8547 {
8548 return 3; /* return error */
8549 }
8550
8551 return a_w25qxx_qspi_write_read(handle, instruction, instruction_line,
8552 address, address_line, address_len,
8553 alternate, alternate_line, alternate_len,
8554 dummy, in_buf, in_len,
8555 out_buf, out_len, data_line); /* write and read */
8556 }
8557
8566 uint8_t w25qxx_info(w25qxx_info_t *info)
8567 {
8568 if (info == NULL) /* check handle */
8569 {
8570 return 2; /* return error */
8571 }
8572
8573 memset(info, 0, sizeof(w25qxx_info_t)); /* initialize w25qxx info structure */
8574 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
8575 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
8576 strncpy(info->interface, "SPI QSPI", 16); /* copy interface name */
8577 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
8578 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
8579 info->max_current_ma = MAX_CURRENT; /* set maximum current */
8580 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
8581 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
8582 info->driver_version = DRIVER_VERSION; /* set driver version */
8583
8584 return 0; /* success return 0 */
8585 }
W25QXX_COMMAND_ENTER_QSPI_MODE
#define W25QXX_COMMAND_ENTER_QSPI_MODE
Definition: driver_w25qxx.c:72
W25QXX_COMMAND_READ_STATUS_REG3
#define W25QXX_COMMAND_READ_STATUS_REG3
Definition: driver_w25qxx.c:59
W25QXX_COMMAND_ERASE_PROGRAM_RESUME
#define W25QXX_COMMAND_ERASE_PROGRAM_RESUME
Definition: driver_w25qxx.c:65
W25QXX_COMMAND_READ_BLOCK_LOCK
#define W25QXX_COMMAND_READ_BLOCK_LOCK
Definition: driver_w25qxx.c:91
W25QXX_COMMAND_FAST_READ_DUAL_IO
#define W25QXX_COMMAND_FAST_READ_DUAL_IO
Definition: driver_w25qxx.c:92
W25QXX_COMMAND_READ_DATA
#define W25QXX_COMMAND_READ_DATA
Definition: driver_w25qxx.c:81
MAX_CURRENT
#define MAX_CURRENT
Definition: driver_w25qxx.c:46
W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK
#define W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK
Definition: driver_w25qxx.c:89
W25QXX_COMMAND_WRITE_DISABLE
#define W25QXX_COMMAND_WRITE_DISABLE
Definition: driver_w25qxx.c:56
W25QXX_COMMAND_DEVICE_ID_DUAL_IO
#define W25QXX_COMMAND_DEVICE_ID_DUAL_IO
Definition: driver_w25qxx.c:93
W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK
#define W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK
Definition: driver_w25qxx.c:90
W25QXX_COMMAND_ERASE_PROGRAM_SUSPEND
#define W25QXX_COMMAND_ERASE_PROGRAM_SUSPEND
Definition: driver_w25qxx.c:64
W25QXX_COMMAND_READ_STATUS_REG2
#define W25QXX_COMMAND_READ_STATUS_REG2
Definition: driver_w25qxx.c:58
W25QXX_COMMAND_WRITE_STATUS_REG2
#define W25QXX_COMMAND_WRITE_STATUS_REG2
Definition: driver_w25qxx.c:61
W25QXX_COMMAND_BLOCK_ERASE_64K
#define W25QXX_COMMAND_BLOCK_ERASE_64K
Definition: driver_w25qxx.c:80
W25QXX_COMMAND_READ_SECURITY_REGISTER
#define W25QXX_COMMAND_READ_SECURITY_REGISTER
Definition: driver_w25qxx.c:88
W25QXX_COMMAND_FAST_READ_QUAD_OUTPUT
#define W25QXX_COMMAND_FAST_READ_QUAD_OUTPUT
Definition: driver_w25qxx.c:84
W25QXX_COMMAND_JEDEC_ID
#define W25QXX_COMMAND_JEDEC_ID
Definition: driver_w25qxx.c:69
W25QXX_COMMAND_READ_SFDP_REGISTER
#define W25QXX_COMMAND_READ_SFDP_REGISTER
Definition: driver_w25qxx.c:85
W25QXX_COMMAND_CHIP_ERASE
#define W25QXX_COMMAND_CHIP_ERASE
Definition: driver_w25qxx.c:63
SUPPLY_VOLTAGE_MAX
#define SUPPLY_VOLTAGE_MAX
Definition: driver_w25qxx.c:45
W25QXX_COMMAND_READ_UNIQUE_ID
#define W25QXX_COMMAND_READ_UNIQUE_ID
Definition: driver_w25qxx.c:75
W25QXX_COMMAND_WRITE_STATUS_REG3
#define W25QXX_COMMAND_WRITE_STATUS_REG3
Definition: driver_w25qxx.c:62
W25QXX_COMMAND_ENABLE_RESET
#define W25QXX_COMMAND_ENABLE_RESET
Definition: driver_w25qxx.c:73
W25QXX_COMMAND_SECTOR_ERASE_4K
#define W25QXX_COMMAND_SECTOR_ERASE_4K
Definition: driver_w25qxx.c:78
W25QXX_COMMAND_POWER_DOWN
#define W25QXX_COMMAND_POWER_DOWN
Definition: driver_w25qxx.c:66
W25QXX_COMMAND_DEVICE_ID_QUAD_IO
#define W25QXX_COMMAND_DEVICE_ID_QUAD_IO
Definition: driver_w25qxx.c:98
W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE
#define W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE
Definition: driver_w25qxx.c:55
W25QXX_COMMAND_FAST_READ_QUAD_IO
#define W25QXX_COMMAND_FAST_READ_QUAD_IO
Definition: driver_w25qxx.c:95
W25QXX_COMMAND_QUAD_PAGE_PROGRAM
#define W25QXX_COMMAND_QUAD_PAGE_PROGRAM
Definition: driver_w25qxx.c:77
W25QXX_COMMAND_ERASE_SECURITY_REGISTER
#define W25QXX_COMMAND_ERASE_SECURITY_REGISTER
Definition: driver_w25qxx.c:86
W25QXX_COMMAND_BLOCK_ERASE_32K
#define W25QXX_COMMAND_BLOCK_ERASE_32K
Definition: driver_w25qxx.c:79
W25QXX_COMMAND_FAST_READ_DUAL_OUTPUT
#define W25QXX_COMMAND_FAST_READ_DUAL_OUTPUT
Definition: driver_w25qxx.c:83
TEMPERATURE_MAX
#define TEMPERATURE_MAX
Definition: driver_w25qxx.c:48
W25QXX_COMMAND_PROGRAM_SECURITY_REGISTER
#define W25QXX_COMMAND_PROGRAM_SECURITY_REGISTER
Definition: driver_w25qxx.c:87
W25QXX_COMMAND_WRITE_STATUS_REG1
#define W25QXX_COMMAND_WRITE_STATUS_REG1
Definition: driver_w25qxx.c:60
W25QXX_COMMAND_WORD_READ_QUAD_IO
#define W25QXX_COMMAND_WORD_READ_QUAD_IO
Definition: driver_w25qxx.c:96
MANUFACTURER_NAME
#define MANUFACTURER_NAME
Definition: driver_w25qxx.c:43
TEMPERATURE_MIN
#define TEMPERATURE_MIN
Definition: driver_w25qxx.c:47
SUPPLY_VOLTAGE_MIN
#define SUPPLY_VOLTAGE_MIN
Definition: driver_w25qxx.c:44
W25QXX_COMMAND_RESET_DEVICE
#define W25QXX_COMMAND_RESET_DEVICE
Definition: driver_w25qxx.c:74
W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_UNLOCK
#define W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_UNLOCK
Definition: driver_w25qxx.c:71
W25QXX_COMMAND_FAST_READ
#define W25QXX_COMMAND_FAST_READ
Definition: driver_w25qxx.c:82
W25QXX_COMMAND_OCTAL_WORD_READ_QUAD_IO
#define W25QXX_COMMAND_OCTAL_WORD_READ_QUAD_IO
Definition: driver_w25qxx.c:97
W25QXX_COMMAND_SET_BURST_WITH_WRAP
#define W25QXX_COMMAND_SET_BURST_WITH_WRAP
Definition: driver_w25qxx.c:94
W25QXX_COMMAND_RELEASE_POWER_DOWN
#define W25QXX_COMMAND_RELEASE_POWER_DOWN
Definition: driver_w25qxx.c:67
CHIP_NAME
#define CHIP_NAME
chip information definition
Definition: driver_w25qxx.c:42
W25QXX_COMMAND_READ_STATUS_REG1
#define W25QXX_COMMAND_READ_STATUS_REG1
Definition: driver_w25qxx.c:57
DRIVER_VERSION
#define DRIVER_VERSION
Definition: driver_w25qxx.c:49
W25QXX_COMMAND_PAGE_PROGRAM
#define W25QXX_COMMAND_PAGE_PROGRAM
Definition: driver_w25qxx.c:76
W25QXX_COMMAND_WRITE_ENABLE
#define W25QXX_COMMAND_WRITE_ENABLE
chip command definition
Definition: driver_w25qxx.c:54
W25QXX_COMMAND_READ_MANUFACTURER
#define W25QXX_COMMAND_READ_MANUFACTURER
Definition: driver_w25qxx.c:68
W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_LOCK
#define W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_LOCK
Definition: driver_w25qxx.c:70
driver_w25qxx.h
driver w25qxx header file
w25qxx_erase_program_resume
uint8_t w25qxx_erase_program_resume(w25qxx_handle_t *handle)
resume erase or program
Definition: driver_w25qxx.c:1722
w25qxx_enable_volatile_sr_write
uint8_t w25qxx_enable_volatile_sr_write(w25qxx_handle_t *handle)
enable volatile sr writing
Definition: driver_w25qxx.c:501
w25qxx_get_unique_id
uint8_t w25qxx_get_unique_id(w25qxx_handle_t *handle, uint8_t id[8])
get the unique id
Definition: driver_w25qxx.c:2764
w25qxx_get_manufacturer_device_id_dual_io
uint8_t w25qxx_get_manufacturer_device_id_dual_io(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t *device_id)
get the manufacturer && device id information with dual io
Definition: driver_w25qxx.c:2038
w25qxx_page_program_quad_input
uint8_t w25qxx_page_program_quad_input(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint16_t len)
quad page program with quad input
Definition: driver_w25qxx.c:4920
w25qxx_get_sfdp
uint8_t w25qxx_get_sfdp(w25qxx_handle_t *handle, uint8_t sfdp[256])
get the sfdp
Definition: driver_w25qxx.c:2880
w25qxx_set_status1
uint8_t w25qxx_set_status1(w25qxx_handle_t *handle, uint8_t status)
set the status 1
Definition: driver_w25qxx.c:863
w25qxx_reset_device
uint8_t w25qxx_reset_device(w25qxx_handle_t *handle)
reset the device
Definition: driver_w25qxx.c:2690
w25qxx_qspi_read_wrap_length_t
w25qxx_qspi_read_wrap_length_t
w25qxx qspi read wrap length enumeration definition
Definition: driver_w25qxx.h:123
w25qxx_read_security_register
uint8_t w25qxx_read_security_register(w25qxx_handle_t *handle, w25qxx_security_register_t num, uint8_t data[256])
read the security register
Definition: driver_w25qxx.c:3344
w25qxx_program_security_register
uint8_t w25qxx_program_security_register(w25qxx_handle_t *handle, w25qxx_security_register_t num, uint8_t data[256])
program the security register
Definition: driver_w25qxx.c:3147
w25qxx_individual_block_lock
uint8_t w25qxx_individual_block_lock(w25qxx_handle_t *handle, uint32_t addr)
lock the individual block
Definition: driver_w25qxx.c:6094
w25qxx_read_block_lock
uint8_t w25qxx_read_block_lock(w25qxx_handle_t *handle, uint32_t addr, uint8_t *value)
read the block lock
Definition: driver_w25qxx.c:6529
w25qxx_get_manufacturer_device_id_quad_io
uint8_t w25qxx_get_manufacturer_device_id_quad_io(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t *device_id)
get the manufacturer && device id information with quad io
Definition: driver_w25qxx.c:2122
w25qxx_exit_qspi_mode
uint8_t w25qxx_exit_qspi_mode(w25qxx_handle_t *handle)
exit the qspi mode
Definition: driver_w25qxx.c:2572
w25qxx_global_block_unlock
uint8_t w25qxx_global_block_unlock(w25qxx_handle_t *handle)
unlock the whole block
Definition: driver_w25qxx.c:2354
w25qxx_qspi_read_dummy_t
w25qxx_qspi_read_dummy_t
w25qxx qspi read dummy enumeration definition
Definition: driver_w25qxx.h:112
w25qxx_fast_read_dual_output
uint8_t w25qxx_fast_read_dual_output(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read with dual output in the fast mode
Definition: driver_w25qxx.c:3858
w25qxx_individual_block_unlock
uint8_t w25qxx_individual_block_unlock(w25qxx_handle_t *handle, uint32_t addr)
unlock the individual block
Definition: driver_w25qxx.c:6311
w25qxx_security_register_t
w25qxx_security_register_t
w25qxx security register enumeration definition
Definition: driver_w25qxx.h:135
w25qxx_octal_word_read_quad_io
uint8_t w25qxx_octal_word_read_quad_io(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
octal word read with quad io
Definition: driver_w25qxx.c:4459
w25qxx_get_jedec_id
uint8_t w25qxx_get_jedec_id(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t device_id[2])
get the jedec id information
Definition: driver_w25qxx.c:2203
w25qxx_burst_wrap_t
w25qxx_burst_wrap_t
w25qxx burst wrap enumeration definition
Definition: driver_w25qxx.h:145
w25qxx_get_status3
uint8_t w25qxx_get_status3(w25qxx_handle_t *handle, uint8_t *status)
get the status 3
Definition: driver_w25qxx.c:789
w25qxx_set_read_parameters
uint8_t w25qxx_set_read_parameters(w25qxx_handle_t *handle, w25qxx_qspi_read_dummy_t dummy, w25qxx_qspi_read_wrap_length_t length)
set the read parameters
Definition: driver_w25qxx.c:2427
w25qxx_get_status2
uint8_t w25qxx_get_status2(w25qxx_handle_t *handle, uint8_t *status)
get the status 2
Definition: driver_w25qxx.c:716
w25qxx_enter_qspi_mode
uint8_t w25qxx_enter_qspi_mode(w25qxx_handle_t *handle)
enter the qspi mode
Definition: driver_w25qxx.c:2494
w25qxx_get_status1
uint8_t w25qxx_get_status1(w25qxx_handle_t *handle, uint8_t *status)
get the status 1
Definition: driver_w25qxx.c:643
w25qxx_set_status2
uint8_t w25qxx_set_status2(w25qxx_handle_t *handle, uint8_t status)
set the status 2
Definition: driver_w25qxx.c:1062
w25qxx_global_block_lock
uint8_t w25qxx_global_block_lock(w25qxx_handle_t *handle)
lock the whole block
Definition: driver_w25qxx.c:2284
w25qxx_enable_reset
uint8_t w25qxx_enable_reset(w25qxx_handle_t *handle)
enable the reset
Definition: driver_w25qxx.c:2619
w25qxx_fast_read_quad_io
uint8_t w25qxx_fast_read_quad_io(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read with quad io in the fast mode
Definition: driver_w25qxx.c:4184
w25qxx_disable_write
uint8_t w25qxx_disable_write(w25qxx_handle_t *handle)
disable writing
Definition: driver_w25qxx.c:572
w25qxx_set_burst_with_wrap
uint8_t w25qxx_set_burst_with_wrap(w25qxx_handle_t *handle, w25qxx_burst_wrap_t wrap)
set the burst with wrap
Definition: driver_w25qxx.c:6746
w25qxx_erase_program_suspend
uint8_t w25qxx_erase_program_suspend(w25qxx_handle_t *handle)
suspend erase or program
Definition: driver_w25qxx.c:1650
w25qxx_fast_read_dual_io
uint8_t w25qxx_fast_read_dual_io(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read with dual io in the fast mode
Definition: driver_w25qxx.c:4076
w25qxx_word_read_quad_io
uint8_t w25qxx_word_read_quad_io(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
word read with quad io
Definition: driver_w25qxx.c:4350
w25qxx_set_status3
uint8_t w25qxx_set_status3(w25qxx_handle_t *handle, uint8_t status)
set the status 3
Definition: driver_w25qxx.c:1261
w25qxx_enable_write
uint8_t w25qxx_enable_write(w25qxx_handle_t *handle)
enable writing
Definition: driver_w25qxx.c:431
w25qxx_erase_security_register
uint8_t w25qxx_erase_security_register(w25qxx_handle_t *handle, w25qxx_security_register_t num)
erase the security register
Definition: driver_w25qxx.c:2952
w25qxx_fast_read_quad_output
uint8_t w25qxx_fast_read_quad_output(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read with quad output in the fast mode
Definition: driver_w25qxx.c:3967
w25qxx_chip_erase
uint8_t w25qxx_chip_erase(w25qxx_handle_t *handle)
erase the chip
Definition: driver_w25qxx.c:1459
w25qxx_release_power_down
uint8_t w25qxx_release_power_down(w25qxx_handle_t *handle)
release power down
Definition: driver_w25qxx.c:1875
w25qxx_only_spi_read
uint8_t w25qxx_only_spi_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read only in the spi interface
Definition: driver_w25qxx.c:3465
w25qxx_block_erase_32k
uint8_t w25qxx_block_erase_32k(w25qxx_handle_t *handle, uint32_t addr)
erase the 32k block
Definition: driver_w25qxx.c:5419
w25qxx_get_address_mode
uint8_t w25qxx_get_address_mode(w25qxx_handle_t *handle, w25qxx_address_mode_t *mode)
get the chip address mode
Definition: driver_w25qxx.c:405
w25qxx_set_interface
uint8_t w25qxx_set_interface(w25qxx_handle_t *handle, w25qxx_interface_t interface)
set the chip interface
Definition: driver_w25qxx.c:259
w25qxx_page_program
uint8_t w25qxx_page_program(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint16_t len)
page program
Definition: driver_w25qxx.c:4569
w25qxx_set_dual_quad_spi
uint8_t w25qxx_set_dual_quad_spi(w25qxx_handle_t *handle, w25qxx_bool_t enable)
enable or disable the dual quad spi
Definition: driver_w25qxx.c:175
w25qxx_get_type
uint8_t w25qxx_get_type(w25qxx_handle_t *handle, w25qxx_type_t *type)
get the chip type
Definition: driver_w25qxx.c:238
w25qxx_type_t
w25qxx_type_t
w25qxx type enumeration definition
Definition: driver_w25qxx.h:63
w25qxx_get_interface
uint8_t w25qxx_get_interface(w25qxx_handle_t *handle, w25qxx_interface_t *interface)
get the chip interface
Definition: driver_w25qxx.c:280
w25qxx_init
uint8_t w25qxx_init(w25qxx_handle_t *handle)
initialize the chip
Definition: driver_w25qxx.c:6819
w25qxx_get_manufacturer_device_id
uint8_t w25qxx_get_manufacturer_device_id(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t *device_id)
get the manufacturer && device id information
Definition: driver_w25qxx.c:1952
w25qxx_info
uint8_t w25qxx_info(w25qxx_info_t *info)
get chip's information
Definition: driver_w25qxx.c:8566
w25qxx_sector_erase_4k
uint8_t w25qxx_sector_erase_4k(w25qxx_handle_t *handle, uint32_t addr)
erase the 4k sector
Definition: driver_w25qxx.c:5080
w25qxx_deinit
uint8_t w25qxx_deinit(w25qxx_handle_t *handle)
close the chip
Definition: driver_w25qxx.c:7195
w25qxx_address_mode_t
w25qxx_address_mode_t
w25qxx address mode enumeration definition
Definition: driver_w25qxx.h:94
w25qxx_set_type
uint8_t w25qxx_set_type(w25qxx_handle_t *handle, w25qxx_type_t type)
set the chip type
Definition: driver_w25qxx.c:217
w25qxx_write
uint8_t w25qxx_write(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
write data
Definition: driver_w25qxx.c:8415
w25qxx_fast_read
uint8_t w25qxx_fast_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read in the fast mode
Definition: driver_w25qxx.c:3634
w25qxx_interface_t
w25qxx_interface_t
w25qxx interface enumeration definition
Definition: driver_w25qxx.h:76
w25qxx_set_address_mode
uint8_t w25qxx_set_address_mode(w25qxx_handle_t *handle, w25qxx_address_mode_t mode)
set the chip address mode
Definition: driver_w25qxx.c:304
w25qxx_get_dual_quad_spi
uint8_t w25qxx_get_dual_quad_spi(w25qxx_handle_t *handle, w25qxx_bool_t *enable)
get the dual quad spi status
Definition: driver_w25qxx.c:196
w25qxx_power_down
uint8_t w25qxx_power_down(w25qxx_handle_t *handle)
power down
Definition: driver_w25qxx.c:1792
w25qxx_read
uint8_t w25qxx_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read data
Definition: driver_w25qxx.c:7289
w25qxx_block_erase_64k
uint8_t w25qxx_block_erase_64k(w25qxx_handle_t *handle, uint32_t addr)
erase the 64k block
Definition: driver_w25qxx.c:5758
w25qxx_bool_t
w25qxx_bool_t
w25qxx bool enumeration definition
Definition: driver_w25qxx.h:85
W25Q256
@ W25Q256
Definition: driver_w25qxx.h:69
W25QXX_ADDRESS_MODE_3_BYTE
@ W25QXX_ADDRESS_MODE_3_BYTE
Definition: driver_w25qxx.h:95
W25QXX_ADDRESS_MODE_4_BYTE
@ W25QXX_ADDRESS_MODE_4_BYTE
Definition: driver_w25qxx.h:96
W25QXX_INTERFACE_QSPI
@ W25QXX_INTERFACE_QSPI
Definition: driver_w25qxx.h:78
W25QXX_INTERFACE_SPI
@ W25QXX_INTERFACE_SPI
Definition: driver_w25qxx.h:77
w25qxx_write_read_reg
uint8_t w25qxx_write_read_reg(w25qxx_handle_t *handle, uint8_t instruction, uint8_t instruction_line, uint32_t address, uint8_t address_line, uint8_t address_len, uint32_t alternate, uint8_t alternate_line, uint8_t alternate_len, uint8_t dummy, uint8_t *in_buf, uint32_t in_len, uint8_t *out_buf, uint32_t out_len, uint8_t data_line)
write and read register
Definition: driver_w25qxx.c:8535
w25qxx_handle_s
w25qxx handle structure definition
Definition: driver_w25qxx.h:210
w25qxx_handle_s::inited
uint8_t inited
Definition: driver_w25qxx.h:221
w25qxx_handle_s::buf
uint8_t buf[256+6]
Definition: driver_w25qxx.h:228
w25qxx_handle_s::spi_qspi_write_read
uint8_t(* spi_qspi_write_read)(uint8_t instruction, uint8_t instruction_line, uint32_t address, uint8_t address_line, uint8_t address_len, uint32_t alternate, uint8_t alternate_line, uint8_t alternate_len, uint8_t dummy, uint8_t *in_buf, uint32_t in_len, uint8_t *out_buf, uint32_t out_len, uint8_t data_line)
Definition: driver_w25qxx.h:213
w25qxx_handle_s::param
uint8_t param
Definition: driver_w25qxx.h:224
w25qxx_handle_s::delay_ms
void(* delay_ms)(uint32_t ms)
Definition: driver_w25qxx.h:218
w25qxx_handle_s::spi_qspi_deinit
uint8_t(* spi_qspi_deinit)(void)
Definition: driver_w25qxx.h:212
w25qxx_handle_s::address_mode
uint8_t address_mode
Definition: driver_w25qxx.h:223
w25qxx_handle_s::debug_print
void(* debug_print)(const char *const fmt,...)
Definition: driver_w25qxx.h:220
w25qxx_handle_s::delay_us
void(* delay_us)(uint32_t us)
Definition: driver_w25qxx.h:219
w25qxx_handle_s::spi_qspi
uint8_t spi_qspi
Definition: driver_w25qxx.h:227
w25qxx_handle_s::dual_quad_spi_enable
uint8_t dual_quad_spi_enable
Definition: driver_w25qxx.h:226
w25qxx_handle_s::buf_4k
uint8_t buf_4k[4096+1]
Definition: driver_w25qxx.h:229
w25qxx_handle_s::type
uint16_t type
Definition: driver_w25qxx.h:222
w25qxx_handle_s::spi_qspi_init
uint8_t(* spi_qspi_init)(void)
Definition: driver_w25qxx.h:211
w25qxx_handle_s::dummy
uint8_t dummy
Definition: driver_w25qxx.h:225
w25qxx_info_s
w25qxx information structure definition
Definition: driver_w25qxx.h:236
w25qxx_info_s::temperature_max
float temperature_max
Definition: driver_w25qxx.h:244
w25qxx_info_s::supply_voltage_max_v
float supply_voltage_max_v
Definition: driver_w25qxx.h:241
w25qxx_info_s::driver_version
uint32_t driver_version
Definition: driver_w25qxx.h:245
w25qxx_info_s::interface
char interface[16]
Definition: driver_w25qxx.h:239
w25qxx_info_s::temperature_min
float temperature_min
Definition: driver_w25qxx.h:243
w25qxx_info_s::max_current_ma
float max_current_ma
Definition: driver_w25qxx.h:242
w25qxx_info_s::manufacturer_name
char manufacturer_name[32]
Definition: driver_w25qxx.h:238
w25qxx_info_s::supply_voltage_min_v
float supply_voltage_min_v
Definition: driver_w25qxx.h:240
w25qxx_info_s::chip_name
char chip_name[32]
Definition: driver_w25qxx.h:237