ChibiOS 21.11.5
hal_xsnor_micron_n25q_impl.inc
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 Giovanni Di Sirio.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file hal_xsnor_micron_n25q_impl.inc
19 * @brief Template of SNOR Micron N25Q source.
20 * @note This is a template file, can be edited directly.
21 *
22 * @addtogroup HAL_XSNOR_MICRON_N25Q
23 * @{
24 */
25
26/* This is an, automatically generated, implementation file that can be
27 manually edited, it is not re-generated if already present.*/
28
29#define PAGE_SIZE 256U
30#define PAGE_MASK (PAGE_SIZE - 1U)
31
32/**
33 * @name Command codes
34 * @{
35 */
36#define CMD_RESET_ENABLE 0x66
37#define CMD_RESET_MEMORY 0x99
38#define CMD_READ_ID 0x9F
39#define CMD_MULTIPLE_IO_READ_ID 0xAF
40#define CMD_READ_DISCOVERY_PARAMETER 0x5A
41#define CMD_READ 0x03
42#define CMD_READ4B 0x13
43#define CMD_FAST_READ 0x0B
44#define CMD_FAST_READ4B 0x0C
45#define CMD_WRITE_ENABLE 0x06
46#define CMD_WRITE_DISABLE 0x04
47#define CMD_READ_STATUS_REGISTER 0x05
48#define CMD_WRITE_STATUS_REGISTER 0x01
49#define CMD_READ_LOCK_REGISTER 0xE8
50#define CMD_WRITE_LOCK_REGISTER 0xE5
51#define CMD_READ_FLAG_STATUS_REGISTER 0x70
52#define CMD_CLEAR_FLAG_STATUS_REGISTER 0x50
53#define CMD_READ_NV_CONFIGURATION_REGISTER 0xB5
54#define CMD_WRITE_NV_CONFIGURATION_REGISTER 0xB1
55#define CMD_READ_V_CONF_REGISTER 0x85
56#define CMD_WRITE_V_CONF_REGISTER 0x81
57#define CMD_READ_ENHANCED_V_CONF_REGISTER 0x65
58#define CMD_WRITE_ENHANCED_V_CONF_REGISTER 0x61
59#define CMD_PAGE_PROGRAM 0x02
60#define CMD_PAGE_PROGRAM4B 0x12
61#define CMD_SUBSECTOR_ERASE 0x20
62#define CMD_SUBSECTOR_ERASE4B 0x21
63#define CMD_SECTOR_ERASE 0xD8
64#define CMD_SECTOR_ERASE4B 0xDC
65#define CMD_BULK_ERASE 0xC7
66#define CMD_PROGRAM_ERASE_RESUME 0x7A
67#define CMD_PROGRAM_ERASE_SUSPEND 0x75
68#define CMD_READ_OTP_ARRAY 0x4B
69#define CMD_PROGRAM_OTP_ARRAY 0x42
70/** @} */
71
72/**
73 * @name Flags status register bits
74 * @{
75 */
76#define FLAGS_PROGRAM_ERASE 0x80U
77#define FLAGS_ERASE_SUSPEND 0x40U
78#define FLAGS_ERASE_ERROR 0x20U
79#define FLAGS_PROGRAM_ERROR 0x10U
80#define FLAGS_VPP_ERROR 0x08U
81#define FLAGS_PROGRAM_SUSPEND 0x04U
82#define FLAGS_PROTECTION_ERROR 0x02U
83#define FLAGS_RESERVED 0x01U
84#define FLAGS_ALL_ERRORS (FLAGS_ERASE_ERROR | \
85 FLAGS_PROGRAM_ERROR | \
86 FLAGS_VPP_ERROR | \
87 FLAGS_PROTECTION_ERROR)
88/** @} */
89
90#if (XSNOR_USE_WSPI == TRUE) || defined(__DOXYGEN__)
117
144
171
198
225
252
253/* 1x N25Q_CMD_RESET_ENABLE command.*/
255 .cmd = CMD_RESET_ENABLE,
257 .addr = 0,
258 .alt = 0,
259 .dummy = 0
260};
261
262/* 1x N25Q_CMD_RESET_MEMORY command.*/
264 .cmd = CMD_RESET_MEMORY,
266 .addr = 0,
267 .alt = 0,
268 .dummy = 0
269};
270
271/* 2x CMD_RESET_ENABLE command.*/
273 .cmd = CMD_RESET_ENABLE,
275 .addr = 0,
276 .alt = 0,
277 .dummy = 0
278};
279
280/* 2x CMD_RESET_MEMORY command.*/
282 .cmd = CMD_RESET_MEMORY,
284 .addr = 0,
285 .alt = 0,
286 .dummy = 0
287};
288
289/* 4x CMD_RESET_ENABLE command.*/
291 .cmd = CMD_RESET_ENABLE,
293 .addr = 0,
294 .alt = 0,
295 .dummy = 0
296};
297
298/* 4x CMD_RESET_MEMORY command.*/
300 .cmd = CMD_RESET_MEMORY,
302 .addr = 0,
303 .alt = 0,
304 .dummy = 0
305};
306#endif /* XSNOR_USE_WSPI == TRUE */
307
308/* Device identifiers.*/
309static const uint8_t n25q_manufacturer_ids[] = {0x20};
310static const uint8_t n25q_memory_type_ids[] = {0xBA, 0xBB};
311
312/*===========================================================================*/
313/* Module local functions. */
314/*===========================================================================*/
315
316static bool n25q_find_id(const uint8_t *set, size_t size, uint8_t element) {
317 size_t i;
318
319 for (i = 0; i < size; i++) {
320 if (set[i] == element) {
321 return true;
322 }
323 }
324 return false;
325}
326
328
329 do {
330 if ((self->config->options & N25Q_OPT_NICE_WAITING) != 0U) {
332 }
333
334 /* Read status command.*/
336 1U, &self->config->buffers->databuf[0]);
337 } while ((self->config->buffers->databuf[0] & FLAGS_PROGRAM_ERASE) == 0U);
338
339 /* Checking for errors.*/
340 if ((self->config->buffers->databuf[0] & FLAGS_ALL_ERRORS) != 0U) {
341 /* Clearing status register.*/
343
344 /* Program operation failed.*/
345 return FLASH_ERROR_PROGRAM;
346 }
347
348 return FLASH_NO_ERROR;
349}
350
351static inline bool n25q_spi_4bytes(const hal_xsnor_micron_n25q_c *self) {
352
353 return (self->descriptor.attributes & FLASH_ATTR_SPI_4BYTES_ADDR_HINT) != 0U;
354}
355
356#if (XSNOR_USE_WSPI == TRUE) || defined(__DOXYGEN__)
358
359 /* Configuration to be written.*/
360 self->config->buffers->databuf[0] = ((self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK) << 4U) | 0x07U;
361
362 /* Activating XIP mode in the device.*/
365 1, &self->config->buffers->databuf[0]);
366}
367
369 wspi_command_t cmd;
370
371 /* Resetting XIP mode by reading one byte without XIP confirmation bit.
372 The XIP confirmation bit is sent by using one ALT byte over 4 lines,
373 because of this 2 cycles are subtracted to the dymmy cycles.*/
374 cmd.cmd = 0U;
375 cmd.addr = 0U;
376 cmd.alt = 0xFFU;
377 cmd.dummy = (self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK) - 2U;
380 WSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/
382
383 /* Variant part of the command configuration.*/
384 switch (self->config->bus_type) {
387 break;
390 break;
393 break;
394 default:
395 osalDbgAssert(false, "invalid bus type");
396 }
397
398 /* Resetting XIP.*/
399 wspiReceive(self->config->bus.wspi.drv, &cmd,
400 1, &self->config->buffers->databuf[0]);
401
402 /* Enabling write operation.*/
404
405 /* Configuration to be written.*/
406 self->config->buffers->databuf[0] = ((self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK) << 4U) | 0x0FU;
407
408 /* Rewriting volatile configuration register.*/
410 1, &self->config->buffers->databuf[0]);
411}
412
414
415 /* If the device is in one bit mode then the following commands are
416 rejected because shorter than 8 bits. If the device is in multiple
417 bits mode then the commands are accepted and the device is reset to
418 one bit mode.*/
419 if (self->config->bus_type == XSNOR_BUS_MODE_WSPI_4LINES) {
420
421 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_enable_4);
422 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_memory_4);
423 }
424 else if (self->config->bus_type == XSNOR_BUS_MODE_WSPI_2LINES) {
425
426 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_enable_2);
427 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_memory_2);
428 }
429
430 /* Now the device should be in one bit mode for sure and we perform a
431 device reset.*/
432 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_enable_1);
433 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_memory_1);
434}
435
436static void n25q_read_id(hal_xsnor_micron_n25q_c *self, uint8_t *buf) {
437 wspi_command_t cmd;
438
439 /* This command is always one line.*/
441 cmd.cmd = CMD_READ_ID;
442 cmd.addr = 0U;
443 cmd.alt = 0U;
444 cmd.dummy = 0U;
445 wspiReceive(self->config->bus.wspi.drv, &cmd, 3U, buf);
446}
447#endif /* XSNOR_USE_WSPI == TRUE */
448
449/*===========================================================================*/
450/* Module exported functions. */
451/*===========================================================================*/
452
453/*===========================================================================*/
454/* Module class "hal_xsnor_micron_n25q_c" methods. */
455/*===========================================================================*/
456
457/**
458 * @name Methods implementations of hal_xsnor_micron_n25q_c
459 * @{
460 */
461/**
462 * @brief Implementation of object creation.
463 * @note This function is meant to be used by derived classes.
464 *
465 * @param[out] ip Pointer to a @p hal_xsnor_micron_n25q_c
466 * instance to be initialized.
467 * @param[in] vmt VMT pointer for the new object.
468 * @return A new reference to the object.
469 */
470void *__n25q_objinit_impl(void *ip, const void *vmt) {
472
473 /* Initialization of the ancestors-defined parts.*/
475
476 /* Initialization code.*/
477 self->descriptor.attributes = FLASH_ATTR_ERASED_IS_ONE |
480 self->descriptor.page_size = 256U;
481 self->descriptor.sectors_count = 0U; /* Overwritten.*/
482 self->descriptor.sectors = NULL;
483 self->descriptor.sectors_size = 0U;
484 self->descriptor.address = 0U;
485 self->descriptor.size = 0U; /* Overwritten.*/
486
487 return self;
488}
489
490/**
491 * @brief Implementation of object finalization.
492 * @note This function is meant to be used by derived classes.
493 *
494 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
495 * instance to be disposed.
496 */
497void __n25q_dispose_impl(void *ip) {
499
500 /* Finalization code.*/
501 /* Implementation.*/
502
503 /* Finalization of the ancestors-defined parts.*/
505}
506
507/**
508 * @brief Override of method @p xsnor_device_init().
509 *
510 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
511 * instance.
512 * @return An error code.
513 */
516 const xsnor_config_t *config = self->config;
517
518 /* Bus type and width setup, only necessary if WSPI is in use.*/
519#if XSNOR_USE_WSPI == TRUE
520 switch (config->bus_type) {
522 self->commands = NULL;
523 break;
525 self->commands = &cmd1l;
526 break;
528 self->commands = &cmd2l;
529 break;
531 self->commands = &cmd4l;
532 break;
533 default:
534 osalDbgAssert(false, "invalid bus type");
535 self->commands = NULL;
537 }
538#endif
539
540#if XSNOR_USE_BOTH == TRUE
541 if (config->bus_type == XSNOR_BUS_MODE_SPI)
542#endif
543#if XSNOR_USE_SPI == TRUE
544 {
545 /* Initialization procedure in the SPI case.
546 Reading device ID.*/
548 3U, &config->buffers->databuf[0]);
549
550 /* Manufacturer identifier.*/
553 config->buffers->databuf[0])) {
555 }
556
557 /* Memory identifier.*/
560 config->buffers->databuf[1])) {
562 }
563 }
564#endif /* XSNOR_USE_SPI == TRUE */
565#if XSNOR_USE_BOTH == TRUE
566 else
567#endif
568#if XSNOR_USE_WSPI == TRUE
569 {
570 /* Attempting a reset of the XIP mode, it could be in an unexpected state
571 because a CPU reset does not reset the memory too.*/
572 n25q_reset_xip(self);
573
574 /* Attempting a reset of the device, it could be in an unexpected state
575 because a CPU reset does not reset the memory too.*/
576 n25q_reset_memory(self);
577
578 /* Reading device ID and unique ID.*/
579 n25q_read_id(self, &config->buffers->databuf[0]);
580
581 /* Manufacturer identifier.*/
584 config->buffers->databuf[0])) {
586 }
587
588 /* Memory identifier.*/
591 config->buffers->databuf[1])) {
593 }
594
595 /* Setting up final bus width.*/
596 if ((config->options & N25Q_OPT_NO_WIDTH_SWITCH) == 0U) {
597 wspi_command_t cmd;
598
599 /* We need to switch in the volatile register, write enable in one
600 line mode.*/
602 cmd.cmd = CMD_WRITE_ENABLE;
603 cmd.addr = 0U;
604 cmd.alt = 0U;
605 cmd.dummy = 0U;
606 wspiCommand(config->bus.wspi.drv, &cmd);
607
608 /* Bus width configuration.*/
611 cmd.addr = 0U;
612 cmd.alt = 0U;
613 cmd.dummy = 0U;
614 switch (config->bus_type) {
616 config->buffers->databuf[0] = 0xCFU;
617 break;
619 config->buffers->databuf[0] = 0x8FU;
620 break;
622 config->buffers->databuf[0] = 0x4FU;
623 break;
624 default:
625 osalDbgAssert(false, "invalid bus type");
626 }
627 wspiSend(config->bus.wspi.drv, &cmd,
628 1, &config->buffers->databuf[0]);
629
630 /* Dummy cycles configuration.*/
632 config->buffers->databuf[0] = ((config->options & N25Q_OPT_DUMMY_CYCLES_MASK) << 4U) | 0x0FU;
634 1, &config->buffers->databuf[0]);
635
636 /* Reading again the memory ID using final settings for confirmation that
637 bus switch actually occurred.*/
639
640 /* Manufacturer identifier.*/
643 config->buffers->databuf[0])) {
645 }
646
647 /* Memory identifier.*/
650 config->buffers->databuf[1])) {
652 }
653 }
654 else {
655 /* No need to switch.*/
656 }
657 }
658#endif /* XSNOR_USE_WSPI == TRUE */
659
660 /* Variable parts of the descriptor.*/
661 if ((self->config->options & N25Q_OPT_USE_SUBSECTORS) != 0U) {
662 self->descriptor.sectors_size = 0x00001000U;
663 }
664 else {
665 self->descriptor.sectors_size = 0x00010000U;
666 }
667 self->descriptor.size = (uint32_t)(1U << ((size_t)config->buffers->databuf[2] & 0x1FU));
668 self->descriptor.sectors_count = self->descriptor.size / self->descriptor.sectors_size;
669
670 if (self->descriptor.size > 0x01000000U) {
671 self->descriptor.attributes |= FLASH_ATTR_SPI_4BYTES_ADDR_HINT;
672 }
673 else {
674 self->descriptor.attributes &= ~FLASH_ATTR_SPI_4BYTES_ADDR_HINT;
675 }
676
677#if XSNOR_USE_WSPI == TRUE
678 switch (config->bus_type) {
680 break;
682 self->commands = n25q_spi_4bytes(self) ? &cmd1l_4b : &cmd1l;
683 break;
685 self->commands = n25q_spi_4bytes(self) ? &cmd2l_4b : &cmd2l;
686 break;
688 self->commands = n25q_spi_4bytes(self) ? &cmd4l_4b : &cmd4l;
689 break;
690 default:
691 break;
692 }
693#endif
694
695 return FLASH_NO_ERROR;
696}
697
698/**
699 * @brief Override of method @p xsnor_device_read().
700 *
701 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
702 * instance.
703 * @param[in] offset Flash offset.
704 * @param[in] n Number of bytes to be read.
705 * @param[out] rp Pointer to the data buffer.
706 * @return An error code.
707 */
709 uint8_t *rp) {
711
712 if (self->config->bus_type == XSNOR_BUS_MODE_SPI) {
713 /* Using normal read command because it does not require dummy cycles.*/
716 offset, n, rp);
717 }
718 else {
719 /* Fast read in order to leverage multiple lines.*/
721 n25q_spi_4bytes(self) ?
723 offset,
724 self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK,
725 n, rp);
726 }
727 return FLASH_NO_ERROR;
728}
729
730/**
731 * @brief Override of method @p xsnor_device_program().
732 *
733 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
734 * instance.
735 * @param[in] offset Flash offset.
736 * @param[in] n Number of bytes to be programmed.
737 * @param[in] pp Pointer to the data buffer.
738 * @return An error code.
739 */
741 const uint8_t *pp) {
743
744 /* Data is programmed page by page.*/
745 while (n > 0U) {
746 flash_error_t err;
747
748 /* Data size that can be written in a single program page operation.*/
749 size_t chunk = (size_t)(((offset | PAGE_MASK) + 1U) - offset);
750 if (chunk > n) {
751 chunk = n;
752 }
753
754 /* Enabling write operation.*/
756
757 /* Page program command.*/
759 n25q_spi_4bytes(self) ?
761 offset, chunk, pp);
762
763 /* Wait for status and check errors.*/
764 err = n25q_poll_status(self);
765 if (err != FLASH_NO_ERROR) {
766
767 return err;
768 }
769
770 /* Next page.*/
771 offset += chunk;
772 pp += chunk;
773 n -= chunk;
774 }
775
776 return FLASH_NO_ERROR;
777}
778
779/**
780 * @brief Override of method @p xsnor_device_start_erase_all().
781 *
782 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
783 * instance.
784 * @return An error code.
785 */
788
789 /* Enabling write operation.*/
791
792 /* Bulk erase command.*/
794
795 return FLASH_NO_ERROR;
796}
797
798/**
799 * @brief Override of method @p xsnor_device_start_erase_sector().
800 *
801 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
802 * instance.
803 * @param[in] sector Sector to be erased.
804 * @return An error code.
805 */
808 flash_offset_t offset = (flash_offset_t)(sector * self->descriptor.sectors_size);
809
810 /* Enabling write operation.*/
812
813 /* Sector erase command.*/
814 if ((self->config->options & N25Q_OPT_USE_SUBSECTORS) != 0U) {
816 n25q_spi_4bytes(self) ?
818 offset);
819 }
820 else {
822 n25q_spi_4bytes(self) ?
824 offset);
825 }
826
827 return FLASH_NO_ERROR;
828}
829
830/**
831 * @brief Override of method @p xsnor_device_query_erase().
832 *
833 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
834 * instance.
835 * @param[out] msec Recommended time, in milliseconds, that should
836 * be spent before calling this function again,
837 * can be @p NULL
838 * @return An error code.
839 */
840flash_error_t __n25q_query_erase_impl(void *ip, unsigned *msec) {
842
843 /* Read status command.*/
845 1, &self->config->buffers->databuf[0]);
846
847 /* If the P/E bit is zero (busy) or the flash in a suspended state then
848 report that the operation is still in progress.*/
849 if (((self->config->buffers->databuf[0] & FLAGS_PROGRAM_ERASE) == 0U) ||
850 ((self->config->buffers->databuf[0] & FLAGS_ERASE_SUSPEND) != 0U)) {
851
852 /* Recommended time before polling again, this is a simplified
853 implementation.*/
854 if (msec != NULL) {
855 *msec = 1U;
856 }
857
858 return FLASH_BUSY_ERASING;
859 }
860
861 /* Checking for errors.*/
862 if ((self->config->buffers->databuf[0] & FLAGS_ALL_ERRORS) != 0U) {
863
864 /* Clearing status register.*/
866
867 /* Erase operation failed.*/
868 return FLASH_ERROR_ERASE;
869 }
870
871 return FLASH_NO_ERROR;
872}
873
874/**
875 * @brief Override of method @p xsnor_device_verify_erase().
876 *
877 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
878 * instance.
879 * @param[in] sector Sector to be verified.
880 * @return An error code.
881 */
884 flash_offset_t offset;
885 size_t n;
886
887 /* Read command.*/
888 offset = (flash_offset_t)(sector * self->descriptor.sectors_size);
889 n = self->descriptor.sectors_size;
890 while (n > 0U) {
891 uint8_t *p;
892
893 __n25q_read_impl(self, offset,
894 XSNOR_BUFFER_SIZE, &self->config->buffers->databuf[0]);
895
896 /* Checking for erased state of current buffer.*/
897 for (p = &self->config->buffers->databuf[0];
898 p < &self->config->buffers->databuf[XSNOR_BUFFER_SIZE];
899 p++) {
900
901 if (*p != 0xFFU) {
902 return FLASH_ERROR_VERIFY;
903 }
904 }
905
906 offset += XSNOR_BUFFER_SIZE;
908 }
909
910 return FLASH_NO_ERROR;
911}
912
913/**
914 * @brief Override of method @p xsnor_device_mmap_on().
915 *
916 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
917 * instance.
918 * @param[out] addrp Pointer to the memory mapped memory or @p NULL
919 * @return An error code.
920 */
921flash_error_t __n25q_mmap_on_impl(void *ip, uint8_t **addrp) {
923
924#if XSNOR_USE_BOTH == TRUE
925 if (self->config->bus_type == XSNOR_BUS_MODE_SPI) {
927 }
928#endif
929
930#if XSNOR_USE_WSPI == FALSE
932#else /* XSNOR_USE_WSPI == TRUE */
933 {
934 wspi_command_t cmd;
935
936 /* Bus acquisition.*/
938
939 /* Activating XIP mode in the device.*/
940 n25q_activate_xip(self);
941
942 /* Starting WSPI memory mapped mode.*/
945 WSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/
949 cmd.addr = 0U;
950 cmd.alt = 0U;
951 cmd.dummy = (self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK) - 2U;
952
953 /* Variant part of the command configuration.*/
954 switch (self->config->bus_type) {
959 break;
964 break;
969 break;
970 default:
971 osalDbgAssert(false, "invalid bus type");
972 }
973 wspiMapFlash(self->config->bus.wspi.drv, &cmd, addrp);
974
975 /* Bus release.*/
977
978 return FLASH_NO_ERROR;
979 }
980#endif
981}
982
983/**
984 * @brief Override of method @p xsnor_device_mmap_off().
985 *
986 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
987 * instance.
988 */
989void __n25q_mmap_off_impl(void *ip) {
991
992#if XSNOR_USE_WSPI == TRUE
993 /* Bus acquisition.*/
995
996 /* Stopping WSPI memory mapped mode.*/
997 wspiUnmapFlash(self->config->bus.wspi.drv);
998
999 n25q_reset_xip(self);
1000
1001 /* Bus release.*/
1002 __xsnor_bus_release(self);
1003#endif
1004}
1005/** @} */
1006
1007/**
1008 * @brief VMT structure of SNOR Micron N25Q driver class.
1009 * @note It is public because accessed by the inlined constructor.
1010 */
1012 .dispose = __n25q_dispose_impl,
1013 .init = __n25q_init_impl,
1014 .read = __n25q_read_impl,
1015 .program = __n25q_program_impl,
1016 .start_erase_all = __n25q_start_erase_all_impl,
1017 .start_erase_sector = __n25q_start_erase_sector_impl,
1018 .query_erase = __n25q_query_erase_impl,
1019 .verify_erase = __n25q_verify_erase_impl,
1020 .mmap_on = __n25q_mmap_on_impl,
1021 .mmap_off = __n25q_mmap_off_impl
1022};
1023
1024/** @} */
1025
static const struct EFlashDriverVMT vmt
Definition hal_efl.c:71
uint32_t flash_sector_t
Type of a flash sector number.
Definition hal_flash.h:117
uint32_t flash_offset_t
Type of a flash offset.
Definition hal_flash.h:112
#define FLASH_ATTR_REWRITABLE
Programmed pages can be programmed again.
Definition hal_flash.h:48
#define FLASH_ATTR_SUSPEND_ERASE_CAPABLE
The device is able to suspend erase operations.
Definition hal_flash.h:68
flash_error_t
Type of a flash error code.
Definition hal_flash.h:98
#define FLASH_ATTR_ERASED_IS_ONE
Defines one as the erased bit state.
Definition hal_flash.h:39
@ FLASH_ERROR_ERASE
Definition hal_flash.h:103
@ FLASH_ERROR_HW_FAILURE
Definition hal_flash.h:105
@ FLASH_BUSY_ERASING
Definition hal_flash.h:100
@ FLASH_ERROR_UNIMPLEMENTED
Definition hal_flash.h:106
@ FLASH_ERROR_PROGRAM
Definition hal_flash.h:102
@ FLASH_ERROR_VERIFY
Definition hal_flash.h:104
@ FLASH_NO_ERROR
Definition hal_flash.h:99
#define FLASH_ATTR_SPI_4BYTES_ADDR_HINT
Hint to use 4 bytes addresses in SPI protocol.
void __xsnor_dispose_impl(void *ip)
Implementation of object finalization.
#define XSNOR_BUS_MODE_WSPI_2LINES
void __xsnor_bus_cmd_send(void *ip, uint32_t cmd, size_t n, const uint8_t *p)
Sends a command followed by a data transmit phase.
#define XSNOR_BUFFER_SIZE
Non-cacheable operations buffer.
#define __xsnor_bus_release(self)
#define XSNOR_BUS_MODE_SPI
#define XSNOR_BUS_MODE_WSPI_1LINE
void * __xsnor_objinit_impl(void *ip, const void *vmt)
Implementation of object creation.
void __xsnor_bus_cmd_addr_send(void *ip, uint32_t cmd, flash_offset_t offset, size_t n, const uint8_t *p)
Sends a command followed by a flash address and a data transmit phase.
void __xsnor_bus_cmd_addr(void *ip, uint32_t cmd, flash_offset_t offset)
Sends a command followed by a flash address.
#define XSNOR_BUS_MODE_WSPI_4LINES
void __xsnor_bus_cmd(void *ip, uint32_t cmd)
Sends a naked command.
struct xsnor_config xsnor_config_t
Type of a SNOR configuration structure.
void __xsnor_bus_cmd_addr_dummy_receive(void *ip, uint32_t cmd, flash_offset_t offset, uint32_t dummy, size_t n, uint8_t *p)
Sends a complete header followed by a data receive phase.
void __xsnor_bus_cmd_receive(void *ip, uint32_t cmd, size_t n, uint8_t *p)
Sends a command followed by a data receive phase.
struct xsnor_commands xsnor_commands_t
Type of a commands configuration structure.
void __xsnor_bus_cmd_addr_receive(void *ip, uint32_t cmd, flash_offset_t offset, size_t n, uint8_t *p)
Sends a command followed by a flash address and a data receive phase.
#define __xsnor_bus_acquire(self)
#define FLAGS_ALL_ERRORS
static const wspi_command_t cmd_reset_enable_2
#define CMD_CLEAR_FLAG_STATUS_REGISTER
#define N25Q_OPT_NICE_WAITING
Delays insertion.
#define CMD_SUBSECTOR_ERASE
#define CMD_READ4B
#define CMD_PAGE_PROGRAM
#define CMD_SUBSECTOR_ERASE4B
#define FLAGS_ERASE_SUSPEND
#define CMD_SECTOR_ERASE4B
static const xsnor_commands_t cmd1l_4b
static void n25q_reset_memory(hal_xsnor_micron_n25q_c *self)
static bool n25q_spi_4bytes(const hal_xsnor_micron_n25q_c *self)
flash_error_t __n25q_mmap_on_impl(void *ip, uint8_t **addrp)
Override of method xsnor_device_mmap_on().
static const wspi_command_t cmd_reset_memory_2
flash_error_t __n25q_start_erase_sector_impl(void *ip, flash_sector_t sector)
Override of method xsnor_device_start_erase_sector().
#define CMD_SECTOR_ERASE
void * __n25q_objinit_impl(void *ip, const void *vmt)
Implementation of object creation.
static void n25q_reset_xip(hal_xsnor_micron_n25q_c *self)
static void n25q_activate_xip(hal_xsnor_micron_n25q_c *self)
#define CMD_FAST_READ4B
static const uint8_t n25q_memory_type_ids[]
flash_error_t __n25q_read_impl(void *ip, flash_offset_t offset, size_t n, uint8_t *rp)
Override of method xsnor_device_read().
#define N25Q_OPT_NO_WIDTH_SWITCH
Switch bus width on initialization.
static const wspi_command_t cmd_reset_enable_1
static const wspi_command_t cmd_reset_memory_4
#define CMD_FAST_READ
flash_error_t __n25q_start_erase_all_impl(void *ip)
Override of method xsnor_device_start_erase_all().
#define CMD_WRITE_ENABLE
const struct hal_xsnor_micron_n25q_vmt __hal_xsnor_micron_n25q_vmt
VMT structure of SNOR Micron N25Q driver class.
static const xsnor_commands_t cmd4l
flash_error_t __n25q_query_erase_impl(void *ip, unsigned *msec)
Override of method xsnor_device_query_erase().
#define CMD_RESET_MEMORY
static const xsnor_commands_t cmd2l_4b
flash_error_t __n25q_init_impl(void *ip)
Override of method xsnor_device_init().
static flash_error_t n25q_poll_status(hal_xsnor_micron_n25q_c *self)
void __n25q_dispose_impl(void *ip)
Implementation of object finalization.
#define FLAGS_PROGRAM_ERASE
static const xsnor_commands_t cmd1l
#define CMD_WRITE_ENHANCED_V_CONF_REGISTER
#define CMD_BULK_ERASE
#define CMD_PAGE_PROGRAM4B
static const xsnor_commands_t cmd4l_4b
#define CMD_MULTIPLE_IO_READ_ID
#define CMD_READ_FLAG_STATUS_REGISTER
#define CMD_RESET_ENABLE
#define N25Q_OPT_USE_SUBSECTORS
Use 4kB sub-sectors rather than 64kB sectors.
flash_error_t __n25q_program_impl(void *ip, flash_offset_t offset, size_t n, const uint8_t *pp)
Override of method xsnor_device_program().
#define CMD_WRITE_V_CONF_REGISTER
static void n25q_read_id(hal_xsnor_micron_n25q_c *self, uint8_t *buf)
#define CMD_READ_ID
#define N25Q_OPT_DUMMY_CYCLES_MASK
Mask of the dummy cycles field.
void __n25q_mmap_off_impl(void *ip)
Override of method xsnor_device_mmap_off().
static const wspi_command_t cmd_reset_memory_1
static const wspi_command_t cmd_reset_enable_4
static const uint8_t n25q_manufacturer_ids[]
static const xsnor_commands_t cmd2l
flash_error_t __n25q_verify_erase_impl(void *ip, flash_sector_t sector)
Override of method xsnor_device_verify_erase().
static bool n25q_find_id(const uint8_t *set, size_t size, uint8_t element)
#define osalDbgAssert(c, remark)
Condition assertion.
Definition osal.h:264
#define osalThreadSleepMilliseconds(msecs)
Delays the invoking thread for the specified number of milliseconds.
Definition osal.h:522
void wspiMapFlash(WSPIDriver *wspip, const wspi_command_t *cmdp, uint8_t **addrp)
Maps in memory space a WSPI flash device.
Definition hal_wspi.c:346
#define WSPI_CFG_ADDR_MODE_FOUR_LINES
Definition hal_wspi.h:215
#define WSPI_CFG_ADDR_SIZE_24
Definition hal_wspi.h:223
#define WSPI_CFG_ALT_MODE_FOUR_LINES
Definition hal_wspi.h:230
bool wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, uint8_t *rxbuf)
Sends a command then receives data over the WSPI bus.
Definition hal_wspi.c:311
#define WSPI_CFG_DATA_MODE_FOUR_LINES
Definition hal_wspi.h:245
#define WSPI_CFG_CMD_MODE_NONE
Definition hal_wspi.h:197
#define WSPI_CFG_ADDR_MODE_ONE_LINE
Definition hal_wspi.h:213
#define WSPI_CFG_CMD_MODE_FOUR_LINES
Definition hal_wspi.h:200
#define WSPI_CFG_ADDR_MODE_NONE
Definition hal_wspi.h:212
#define WSPI_CFG_DATA_MODE_TWO_LINES
Definition hal_wspi.h:244
bool wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp)
Sends a command without data phase.
Definition hal_wspi.c:237
bool wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, const uint8_t *txbuf)
Sends a command with data over the WSPI bus.
Definition hal_wspi.c:273
#define WSPI_CFG_CMD_MODE_TWO_LINES
Definition hal_wspi.h:199
#define WSPI_CFG_SIOO
Definition hal_wspi.h:252
#define WSPI_CFG_ALT_SIZE_8
Definition hal_wspi.h:236
void wspiUnmapFlash(WSPIDriver *wspip)
Unmaps from memory space a WSPI flash device.
Definition hal_wspi.c:372
#define WSPI_CFG_CMD_SIZE_8
Definition hal_wspi.h:206
#define WSPI_CFG_ADDR_SIZE_32
Definition hal_wspi.h:224
#define WSPI_CFG_DATA_MODE_ONE_LINE
Definition hal_wspi.h:243
#define WSPI_CFG_CMD_MODE_ONE_LINE
Definition hal_wspi.h:198
#define WSPI_CFG_DATA_MODE_NONE
Definition hal_wspi.h:242
#define WSPI_CFG_ALT_MODE_NONE
Definition hal_wspi.h:227
#define WSPI_CFG_ADDR_MODE_TWO_LINES
Definition hal_wspi.h:214
Class hal_xsnor_micron_n25q_c virtual methods table.
Type of a WSPI command descriptor.
Definition hal_wspi.h:101
uint32_t dummy
Number of dummy cycles to be inserted.
Definition hal_wspi.h:121
uint32_t cfg
Transfer configuration field.
Definition hal_wspi.h:105
uint32_t alt
Alternate phase data.
Definition hal_wspi.h:117
uint32_t addr
Address phase data.
Definition hal_wspi.h:113
uint32_t cmd
Command phase data.
Definition hal_wspi.h:109
uint8_t databuf[XSNOR_BUFFER_SIZE]
Non-cacheable data buffer.
WSPIDriver * drv
WSPI driver to be used for physical communication.
int bus_type
Bus type selection switch.
int options
Device-dependent options, used by subclasses only.
union xsnor_bus_configs bus
WSPI driver configuration.
xsnor_buffers_t * buffers
Pointer to the non-cacheable buffers.
struct xsnor_bus_wspi wspi