LibDriver W25QXX  1.0.0
W25QXX full-featured 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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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,
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 
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,
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,
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,
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 
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 = 1000 * 1000; /* max 1000s */
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 = 1000 * 1000; /* max 1000s */
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 = 1000 * 1000; /* max 1000s */
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 
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 
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 
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 
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,
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 
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 
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 
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 
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 
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 
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 
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,
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 
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,
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,
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,
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,
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 
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,
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,
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,
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,
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 
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,
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,
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,
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,
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,
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 
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,
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 
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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 
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 
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 }
#define W25QXX_COMMAND_ENTER_QSPI_MODE
Definition: driver_w25qxx.c:72
#define W25QXX_COMMAND_READ_STATUS_REG3
Definition: driver_w25qxx.c:59
#define W25QXX_COMMAND_ERASE_PROGRAM_RESUME
Definition: driver_w25qxx.c:65
#define W25QXX_COMMAND_READ_BLOCK_LOCK
Definition: driver_w25qxx.c:91
#define W25QXX_COMMAND_FAST_READ_DUAL_IO
Definition: driver_w25qxx.c:92
#define W25QXX_COMMAND_READ_DATA
Definition: driver_w25qxx.c:81
#define MAX_CURRENT
Definition: driver_w25qxx.c:46
#define W25QXX_COMMAND_INDIVIDUAL_BLOCK_LOCK
Definition: driver_w25qxx.c:89
#define W25QXX_COMMAND_WRITE_DISABLE
Definition: driver_w25qxx.c:56
#define W25QXX_COMMAND_DEVICE_ID_DUAL_IO
Definition: driver_w25qxx.c:93
#define W25QXX_COMMAND_INDIVIDUAL_BLOCK_UNLOCK
Definition: driver_w25qxx.c:90
#define W25QXX_COMMAND_ERASE_PROGRAM_SUSPEND
Definition: driver_w25qxx.c:64
#define W25QXX_COMMAND_READ_STATUS_REG2
Definition: driver_w25qxx.c:58
#define W25QXX_COMMAND_WRITE_STATUS_REG2
Definition: driver_w25qxx.c:61
#define W25QXX_COMMAND_BLOCK_ERASE_64K
Definition: driver_w25qxx.c:80
#define W25QXX_COMMAND_READ_SECURITY_REGISTER
Definition: driver_w25qxx.c:88
#define W25QXX_COMMAND_FAST_READ_QUAD_OUTPUT
Definition: driver_w25qxx.c:84
#define W25QXX_COMMAND_JEDEC_ID
Definition: driver_w25qxx.c:69
#define W25QXX_COMMAND_READ_SFDP_REGISTER
Definition: driver_w25qxx.c:85
#define W25QXX_COMMAND_CHIP_ERASE
Definition: driver_w25qxx.c:63
#define SUPPLY_VOLTAGE_MAX
Definition: driver_w25qxx.c:45
#define W25QXX_COMMAND_READ_UNIQUE_ID
Definition: driver_w25qxx.c:75
#define W25QXX_COMMAND_WRITE_STATUS_REG3
Definition: driver_w25qxx.c:62
#define W25QXX_COMMAND_ENABLE_RESET
Definition: driver_w25qxx.c:73
#define W25QXX_COMMAND_SECTOR_ERASE_4K
Definition: driver_w25qxx.c:78
#define W25QXX_COMMAND_POWER_DOWN
Definition: driver_w25qxx.c:66
#define W25QXX_COMMAND_DEVICE_ID_QUAD_IO
Definition: driver_w25qxx.c:98
#define W25QXX_COMMAND_VOLATILE_SR_WRITE_ENABLE
Definition: driver_w25qxx.c:55
#define W25QXX_COMMAND_FAST_READ_QUAD_IO
Definition: driver_w25qxx.c:95
#define W25QXX_COMMAND_QUAD_PAGE_PROGRAM
Definition: driver_w25qxx.c:77
#define W25QXX_COMMAND_ERASE_SECURITY_REGISTER
Definition: driver_w25qxx.c:86
#define W25QXX_COMMAND_BLOCK_ERASE_32K
Definition: driver_w25qxx.c:79
#define W25QXX_COMMAND_FAST_READ_DUAL_OUTPUT
Definition: driver_w25qxx.c:83
#define TEMPERATURE_MAX
Definition: driver_w25qxx.c:48
#define W25QXX_COMMAND_PROGRAM_SECURITY_REGISTER
Definition: driver_w25qxx.c:87
#define W25QXX_COMMAND_WRITE_STATUS_REG1
Definition: driver_w25qxx.c:60
#define W25QXX_COMMAND_WORD_READ_QUAD_IO
Definition: driver_w25qxx.c:96
#define MANUFACTURER_NAME
Definition: driver_w25qxx.c:43
#define TEMPERATURE_MIN
Definition: driver_w25qxx.c:47
#define SUPPLY_VOLTAGE_MIN
Definition: driver_w25qxx.c:44
#define W25QXX_COMMAND_RESET_DEVICE
Definition: driver_w25qxx.c:74
#define W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_UNLOCK
Definition: driver_w25qxx.c:71
#define W25QXX_COMMAND_FAST_READ
Definition: driver_w25qxx.c:82
#define W25QXX_COMMAND_OCTAL_WORD_READ_QUAD_IO
Definition: driver_w25qxx.c:97
#define W25QXX_COMMAND_SET_BURST_WITH_WRAP
Definition: driver_w25qxx.c:94
#define W25QXX_COMMAND_RELEASE_POWER_DOWN
Definition: driver_w25qxx.c:67
#define CHIP_NAME
chip information definition
Definition: driver_w25qxx.c:42
#define W25QXX_COMMAND_READ_STATUS_REG1
Definition: driver_w25qxx.c:57
#define DRIVER_VERSION
Definition: driver_w25qxx.c:49
#define W25QXX_COMMAND_PAGE_PROGRAM
Definition: driver_w25qxx.c:76
#define W25QXX_COMMAND_WRITE_ENABLE
chip command definition
Definition: driver_w25qxx.c:54
#define W25QXX_COMMAND_READ_MANUFACTURER
Definition: driver_w25qxx.c:68
#define W25QXX_COMMAND_GLOBAL_BLOCK_SECTOR_LOCK
Definition: driver_w25qxx.c:70
driver w25qxx header file
uint8_t w25qxx_erase_program_resume(w25qxx_handle_t *handle)
resume erase or program
uint8_t w25qxx_enable_volatile_sr_write(w25qxx_handle_t *handle)
enable volatile sr writing
uint8_t w25qxx_get_unique_id(w25qxx_handle_t *handle, uint8_t id[8])
get the unique id
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
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
uint8_t w25qxx_get_sfdp(w25qxx_handle_t *handle, uint8_t sfdp[256])
get the sfdp
uint8_t w25qxx_set_status1(w25qxx_handle_t *handle, uint8_t status)
set the status 1
uint8_t w25qxx_reset_device(w25qxx_handle_t *handle)
reset the device
w25qxx_qspi_read_wrap_length_t
w25qxx qspi read wrap length enumeration definition
uint8_t w25qxx_read_security_register(w25qxx_handle_t *handle, w25qxx_security_register_t num, uint8_t data[256])
read the 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
uint8_t w25qxx_individual_block_lock(w25qxx_handle_t *handle, uint32_t addr)
lock the individual block
uint8_t w25qxx_read_block_lock(w25qxx_handle_t *handle, uint32_t addr, uint8_t *value)
read the block lock
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
uint8_t w25qxx_exit_qspi_mode(w25qxx_handle_t *handle)
exit the qspi mode
uint8_t w25qxx_global_block_unlock(w25qxx_handle_t *handle)
unlock the whole block
w25qxx_qspi_read_dummy_t
w25qxx qspi read dummy enumeration definition
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
uint8_t w25qxx_individual_block_unlock(w25qxx_handle_t *handle, uint32_t addr)
unlock the individual block
w25qxx_security_register_t
w25qxx security register enumeration definition
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
uint8_t w25qxx_get_jedec_id(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t device_id[2])
get the jedec id information
w25qxx_burst_wrap_t
w25qxx burst wrap enumeration definition
uint8_t w25qxx_get_status3(w25qxx_handle_t *handle, uint8_t *status)
get the status 3
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
uint8_t w25qxx_get_status2(w25qxx_handle_t *handle, uint8_t *status)
get the status 2
uint8_t w25qxx_enter_qspi_mode(w25qxx_handle_t *handle)
enter the qspi mode
uint8_t w25qxx_get_status1(w25qxx_handle_t *handle, uint8_t *status)
get the status 1
uint8_t w25qxx_set_status2(w25qxx_handle_t *handle, uint8_t status)
set the status 2
uint8_t w25qxx_global_block_lock(w25qxx_handle_t *handle)
lock the whole block
uint8_t w25qxx_enable_reset(w25qxx_handle_t *handle)
enable the reset
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
uint8_t w25qxx_disable_write(w25qxx_handle_t *handle)
disable writing
uint8_t w25qxx_set_burst_with_wrap(w25qxx_handle_t *handle, w25qxx_burst_wrap_t wrap)
set the burst with wrap
uint8_t w25qxx_erase_program_suspend(w25qxx_handle_t *handle)
suspend erase or program
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
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
uint8_t w25qxx_set_status3(w25qxx_handle_t *handle, uint8_t status)
set the status 3
uint8_t w25qxx_enable_write(w25qxx_handle_t *handle)
enable writing
uint8_t w25qxx_erase_security_register(w25qxx_handle_t *handle, w25qxx_security_register_t num)
erase the security register
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
uint8_t w25qxx_chip_erase(w25qxx_handle_t *handle)
erase the chip
uint8_t w25qxx_release_power_down(w25qxx_handle_t *handle)
release power down
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
uint8_t w25qxx_block_erase_32k(w25qxx_handle_t *handle, uint32_t addr)
erase the 32k block
uint8_t w25qxx_get_address_mode(w25qxx_handle_t *handle, w25qxx_address_mode_t *mode)
get the chip address mode
uint8_t w25qxx_set_interface(w25qxx_handle_t *handle, w25qxx_interface_t interface)
set the chip interface
uint8_t w25qxx_page_program(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint16_t len)
page program
uint8_t w25qxx_set_dual_quad_spi(w25qxx_handle_t *handle, w25qxx_bool_t enable)
enable or disable the dual quad spi
uint8_t w25qxx_get_type(w25qxx_handle_t *handle, w25qxx_type_t *type)
get the chip type
w25qxx_type_t
w25qxx type enumeration definition
Definition: driver_w25qxx.h:63
uint8_t w25qxx_get_interface(w25qxx_handle_t *handle, w25qxx_interface_t *interface)
get the chip interface
uint8_t w25qxx_init(w25qxx_handle_t *handle)
initialize the chip
uint8_t w25qxx_get_manufacturer_device_id(w25qxx_handle_t *handle, uint8_t *manufacturer, uint8_t *device_id)
get the manufacturer && device id information
uint8_t w25qxx_info(w25qxx_info_t *info)
get chip's information
uint8_t w25qxx_sector_erase_4k(w25qxx_handle_t *handle, uint32_t addr)
erase the 4k sector
uint8_t w25qxx_deinit(w25qxx_handle_t *handle)
close the chip
w25qxx_address_mode_t
w25qxx address mode enumeration definition
Definition: driver_w25qxx.h:97
uint8_t w25qxx_set_type(w25qxx_handle_t *handle, w25qxx_type_t type)
set the chip type
uint8_t w25qxx_write(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
write data
uint8_t w25qxx_fast_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read in the fast mode
w25qxx_interface_t
w25qxx interface enumeration definition
Definition: driver_w25qxx.h:79
uint8_t w25qxx_set_address_mode(w25qxx_handle_t *handle, w25qxx_address_mode_t mode)
set the chip address mode
uint8_t w25qxx_get_dual_quad_spi(w25qxx_handle_t *handle, w25qxx_bool_t *enable)
get the dual quad spi status
uint8_t w25qxx_power_down(w25qxx_handle_t *handle)
power down
uint8_t w25qxx_read(w25qxx_handle_t *handle, uint32_t addr, uint8_t *data, uint32_t len)
read data
uint8_t w25qxx_block_erase_64k(w25qxx_handle_t *handle, uint32_t addr)
erase the 64k block
w25qxx_bool_t
w25qxx bool enumeration definition
Definition: driver_w25qxx.h:88
@ W25Q256
Definition: driver_w25qxx.h:69
@ W25QXX_ADDRESS_MODE_3_BYTE
Definition: driver_w25qxx.h:98
@ W25QXX_ADDRESS_MODE_4_BYTE
Definition: driver_w25qxx.h:99
@ W25QXX_INTERFACE_QSPI
Definition: driver_w25qxx.h:81
@ W25QXX_INTERFACE_SPI
Definition: driver_w25qxx.h:80
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
w25qxx handle structure definition
uint8_t buf[256+6]
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)
void(* delay_ms)(uint32_t ms)
uint8_t(* spi_qspi_deinit)(void)
uint8_t address_mode
void(* debug_print)(const char *const fmt,...)
void(* delay_us)(uint32_t us)
uint8_t dual_quad_spi_enable
uint8_t buf_4k[4096+1]
uint8_t(* spi_qspi_init)(void)
w25qxx information structure definition
float temperature_max
float supply_voltage_max_v
uint32_t driver_version
char interface[16]
float temperature_min
float max_current_ma
char manufacturer_name[32]
float supply_voltage_min_v
char chip_name[32]