ChibiOS/HAL 9.0.0
hal_xsnor_micron_n25q_impl.inc
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006..2025 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_FAST_READ 0x0B
43#define CMD_WRITE_ENABLE 0x06
44#define CMD_WRITE_DISABLE 0x04
45#define CMD_READ_STATUS_REGISTER 0x05
46#define CMD_WRITE_STATUS_REGISTER 0x01
47#define CMD_READ_LOCK_REGISTER 0xE8
48#define CMD_WRITE_LOCK_REGISTER 0xE5
49#define CMD_READ_FLAG_STATUS_REGISTER 0x70
50#define CMD_CLEAR_FLAG_STATUS_REGISTER 0x50
51#define CMD_READ_NV_CONFIGURATION_REGISTER 0xB5
52#define CMD_WRITE_NV_CONFIGURATION_REGISTER 0xB1
53#define CMD_READ_V_CONF_REGISTER 0x85
54#define CMD_WRITE_V_CONF_REGISTER 0x81
55#define CMD_READ_ENHANCED_V_CONF_REGISTER 0x65
56#define CMD_WRITE_ENHANCED_V_CONF_REGISTER 0x61
57#define CMD_PAGE_PROGRAM 0x02
58#define CMD_SUBSECTOR_ERASE 0x20
59#define CMD_SECTOR_ERASE 0xD8
60#define CMD_BULK_ERASE 0xC7
61#define CMD_PROGRAM_ERASE_RESUME 0x7A
62#define CMD_PROGRAM_ERASE_SUSPEND 0x75
63#define CMD_READ_OTP_ARRAY 0x4B
64#define CMD_PROGRAM_OTP_ARRAY 0x42
65/** @} */
66
67/**
68 * @name Flags status register bits
69 * @{
70 */
71#define FLAGS_PROGRAM_ERASE 0x80U
72#define FLAGS_ERASE_SUSPEND 0x40U
73#define FLAGS_ERASE_ERROR 0x20U
74#define FLAGS_PROGRAM_ERROR 0x10U
75#define FLAGS_VPP_ERROR 0x08U
76#define FLAGS_PROGRAM_SUSPEND 0x04U
77#define FLAGS_PROTECTION_ERROR 0x02U
78#define FLAGS_RESERVED 0x01U
79#define FLAGS_ALL_ERRORS (FLAGS_ERASE_ERROR | \
80 FLAGS_PROGRAM_ERROR | \
81 FLAGS_VPP_ERROR | \
82 FLAGS_PROTECTION_ERROR)
83/** @} */
84
85#if (XSNOR_USE_WSPI == TRUE) || defined(__DOXYGEN__)
112
139
166
167/* 1x N25Q_CMD_RESET_ENABLE command.*/
169 .cmd = CMD_RESET_ENABLE,
171 .addr = 0,
172 .alt = 0,
173 .dummy = 0
174};
175
176/* 1x N25Q_CMD_RESET_MEMORY command.*/
178 .cmd = CMD_RESET_MEMORY,
180 .addr = 0,
181 .alt = 0,
182 .dummy = 0
183};
184
185/* 2x CMD_RESET_ENABLE command.*/
187 .cmd = CMD_RESET_ENABLE,
189 .addr = 0,
190 .alt = 0,
191 .dummy = 0
192};
193
194/* 2x CMD_RESET_MEMORY command.*/
196 .cmd = CMD_RESET_MEMORY,
198 .addr = 0,
199 .alt = 0,
200 .dummy = 0
201};
202
203/* 4x CMD_RESET_ENABLE command.*/
205 .cmd = CMD_RESET_ENABLE,
207 .addr = 0,
208 .alt = 0,
209 .dummy = 0
210};
211
212/* 4x CMD_RESET_MEMORY command.*/
214 .cmd = CMD_RESET_MEMORY,
216 .addr = 0,
217 .alt = 0,
218 .dummy = 0
219};
220#endif /* XSNOR_USE_WSPI == TRUE */
221
222/* Device identifiers.*/
223static const uint8_t n25q_manufacturer_ids[] = {0x20};
224static const uint8_t n25q_memory_type_ids[] = {0xBA, 0xBB};
225
226/*===========================================================================*/
227/* Module local functions. */
228/*===========================================================================*/
229
230static bool n25q_find_id(const uint8_t *set, size_t size, uint8_t element) {
231 size_t i;
232
233 for (i = 0; i < size; i++) {
234 if (set[i] == element) {
235 return true;
236 }
237 }
238 return false;
239}
240
242
243 do {
244 if ((self->config->options & N25Q_OPT_NICE_WAITING) != 0U) {
246 }
247
248 /* Read status command.*/
250 1U, &self->config->buffers->databuf[0]);
251 } while ((self->config->buffers->databuf[0] & FLAGS_PROGRAM_ERASE) == 0U);
252
253 /* Checking for errors.*/
254 if ((self->config->buffers->databuf[0] & FLAGS_ALL_ERRORS) != 0U) {
255 /* Clearing status register.*/
257
258 /* Program operation failed.*/
259 return FLASH_ERROR_PROGRAM;
260 }
261
262 return FLASH_NO_ERROR;
263}
264
265#if (XSNOR_USE_WSPI == TRUE) || defined(__DOXYGEN__)
267
268 /* Configuration to be written.*/
269 self->config->buffers->databuf[0] = ((self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK) << 4U) | 0x07U;
270
271 /* Activating XIP mode in the device.*/
274 1, &self->config->buffers->databuf[0]);
275}
276
278 wspi_command_t cmd;
279
280 /* Resetting XIP mode by reading one byte without XIP confirmation bit.
281 The XIP confirmation bit is sent by using one ALT byte over 4 lines,
282 because of this 2 cycles are subtracted to the dymmy cycles.*/
283 cmd.cmd = 0U;
284 cmd.addr = 0U;
285 cmd.alt = 0xFFU;
286 cmd.dummy = (self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK) - 2U;
289 WSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/
291
292 /* Variant part of the command configuration.*/
293 switch (self->config->bus_type) {
296 break;
299 break;
302 break;
303 default:
304 osalDbgAssert(false, "invalid bus type");
305 }
306
307 /* Resetting XIP.*/
308 wspiReceive(self->config->bus.wspi.drv, &cmd,
309 1, &self->config->buffers->databuf[0]);
310
311 /* Enabling write operation.*/
313
314 /* Configuration to be written.*/
315 self->config->buffers->databuf[0] = ((self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK) << 4U) | 0x0FU;
316
317 /* Rewriting volatile configuration register.*/
319 1, &self->config->buffers->databuf[0]);
320}
321
323
324 /* If the device is in one bit mode then the following commands are
325 rejected because shorter than 8 bits. If the device is in multiple
326 bits mode then the commands are accepted and the device is reset to
327 one bit mode.*/
328 if (self->config->bus_type == XSNOR_BUS_MODE_WSPI_4LINES) {
329
330 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_enable_4);
331 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_memory_4);
332 }
333 else if (self->config->bus_type == XSNOR_BUS_MODE_WSPI_2LINES) {
334
335 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_enable_2);
336 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_memory_2);
337 }
338
339 /* Now the device should be in one bit mode for sure and we perform a
340 device reset.*/
341 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_enable_1);
342 wspiCommand(self->config->bus.wspi.drv, &cmd_reset_memory_1);
343}
344
345static void n25q_read_id(hal_xsnor_micron_n25q_c *self, uint8_t *buf) {
346 wspi_command_t cmd;
347
348 /* This command is always one line.*/
350 cmd.cmd = CMD_READ_ID;
351 cmd.addr = 0U;
352 cmd.alt = 0U;
353 cmd.dummy = 0U;
354 wspiReceive(self->config->bus.wspi.drv, &cmd, 3U, buf);
355}
356#endif /* XSNOR_USE_WSPI == TRUE */
357
358/*===========================================================================*/
359/* Module exported functions. */
360/*===========================================================================*/
361
362/*===========================================================================*/
363/* Module class "hal_xsnor_micron_n25q_c" methods. */
364/*===========================================================================*/
365
366/**
367 * @name Methods implementations of hal_xsnor_micron_n25q_c
368 * @{
369 */
370/**
371 * @brief Implementation of object creation.
372 * @note This function is meant to be used by derived classes.
373 *
374 * @param[out] ip Pointer to a @p hal_xsnor_micron_n25q_c
375 * instance to be initialized.
376 * @param[in] vmt VMT pointer for the new object.
377 * @return A new reference to the object.
378 */
379void *__n25q_objinit_impl(void *ip, const void *vmt) {
381
382 /* Initialization of the ancestors-defined parts.*/
384
385 /* Initialization code.*/
386 self->descriptor.attributes = FLASH_ATTR_ERASED_IS_ONE |
389 self->descriptor.page_size = 256U;
390 self->descriptor.sectors_count = 0U; /* Overwritten.*/
391 self->descriptor.sectors = NULL;
392 self->descriptor.sectors_size = 0U;
393 self->descriptor.address = 0U;
394 self->descriptor.size = 0U; /* Overwritten.*/
395
396 return self;
397}
398
399/**
400 * @brief Implementation of object finalization.
401 * @note This function is meant to be used by derived classes.
402 *
403 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
404 * instance to be disposed.
405 */
406void __n25q_dispose_impl(void *ip) {
408
409 /* Finalization code.*/
410 /* Implementation.*/
411
412 /* Finalization of the ancestors-defined parts.*/
414}
415
416/**
417 * @brief Override of method @p xsnor_device_init().
418 *
419 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
420 * instance.
421 * @return An error code.
422 */
425 const xsnor_config_t *config = self->config;
426
427 /* Bus type and width setup, only necessary if WSPI is in use.*/
428#if XSNOR_USE_WSPI == TRUE
429 switch (config->bus_type) {
431 self->commands = NULL;
432 break;
434 self->commands = &cmd1l;
435 break;
437 self->commands = &cmd2l;
438 break;
440 self->commands = &cmd4l;
441 break;
442 default:
443 osalDbgAssert(false, "invalid bus type");
444 self->commands = NULL;
446 }
447#endif
448
449#if XSNOR_USE_BOTH == TRUE
450 if (config->bus_type == XSNOR_BUS_MODE_SPI)
451#endif
452#if XSNOR_USE_SPI == TRUE
453 {
454 /* Initialization procedure in the SPI case.
455 Reading device ID.*/
457 3U, &config->buffers->databuf[0]);
458
459 /* Manufacturer identifier.*/
462 config->buffers->databuf[0])) {
464 }
465
466 /* Memory identifier.*/
469 config->buffers->databuf[1])) {
471 }
472 }
473#endif /* XSNOR_USE_SPI == TRUE */
474#if XSNOR_USE_BOTH == TRUE
475 else
476#endif
477#if XSNOR_USE_WSPI == TRUE
478 {
479 /* Attempting a reset of the XIP mode, it could be in an unexpected state
480 because a CPU reset does not reset the memory too.*/
481 n25q_reset_xip(self);
482
483 /* Attempting a reset of the device, it could be in an unexpected state
484 because a CPU reset does not reset the memory too.*/
485 n25q_reset_memory(self);
486
487 /* Reading device ID and unique ID.*/
488 n25q_read_id(self, &config->buffers->databuf[0]);
489
490 /* Manufacturer identifier.*/
493 config->buffers->databuf[0])) {
495 }
496
497 /* Memory identifier.*/
500 config->buffers->databuf[1])) {
502 }
503
504 /* Setting up final bus width.*/
505 if ((config->options & N25Q_OPT_NO_WIDTH_SWITCH) == 0U) {
506 wspi_command_t cmd;
507
508 /* We need to switch in the volatile register, write enable in one
509 line mode.*/
511 cmd.cmd = CMD_WRITE_ENABLE;
512 cmd.addr = 0U;
513 cmd.alt = 0U;
514 cmd.dummy = 0U;
515 wspiCommand(config->bus.wspi.drv, &cmd);
516
517 /* Bus width configuration.*/
520 cmd.addr = 0U;
521 cmd.alt = 0U;
522 cmd.dummy = 0U;
523 switch (config->bus_type) {
525 config->buffers->databuf[0] = 0xCFU;
526 break;
528 config->buffers->databuf[0] = 0x8FU;
529 break;
531 config->buffers->databuf[0] = 0x4FU;
532 break;
533 default:
534 osalDbgAssert(false, "invalid bus type");
535 }
536 wspiSend(config->bus.wspi.drv, &cmd,
537 1, &config->buffers->databuf[0]);
538
539 /* Dummy cycles configuration.*/
541 config->buffers->databuf[0] = ((config->options & N25Q_OPT_DUMMY_CYCLES_MASK) << 4U) | 0x0FU;
543 1, &config->buffers->databuf[0]);
544
545 /* Reading again the memory ID using final settings for confirmation that
546 bus switch actually occurred.*/
548
549 /* Manufacturer identifier.*/
552 config->buffers->databuf[0])) {
554 }
555
556 /* Memory identifier.*/
559 config->buffers->databuf[1])) {
561 }
562 }
563 else {
564 /* No need to switch.*/
565 }
566 }
567#endif /* XSNOR_USE_WSPI == TRUE */
568
569 /* Variable parts of the descriptor.*/
570 if ((self->config->options & N25Q_OPT_USE_SUBSECTORS) != 0U) {
571 self->descriptor.sectors_size = 0x00001000U;
572 }
573 else {
574 self->descriptor.sectors_size = 0x00010000U;
575 }
576 self->descriptor.sectors_count = (1U << (size_t)config->buffers->databuf[2]) / self->descriptor.sectors_size;
577 self->descriptor.size = (size_t)self->descriptor.sectors_count * self->descriptor.sectors_size;
578
579 return FLASH_NO_ERROR;
580}
581
582/**
583 * @brief Override of method @p xsnor_device_read().
584 *
585 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
586 * instance.
587 * @param[in] offset Flash offset.
588 * @param[in] n Number of bytes to be read.
589 * @param[out] rp Pointer to the data buffer.
590 * @return An error code.
591 */
593 uint8_t *rp) {
595
596 if (self->config->bus_type == XSNOR_BUS_MODE_SPI) {
597 /* Using normal read command because it does not require dummy cycles.*/
598 __xsnor_bus_cmd_addr_receive(self, CMD_READ, offset, n, rp);
599 }
600 else {
601 /* Fast read in order to leverage multiple lines.*/
603 self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK,
604 n, rp);
605 }
606 return FLASH_NO_ERROR;
607}
608
609/**
610 * @brief Override of method @p xsnor_device_program().
611 *
612 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
613 * instance.
614 * @param[in] offset Flash offset.
615 * @param[in] n Number of bytes to be programmed.
616 * @param[in] pp Pointer to the data buffer.
617 * @return An error code.
618 */
620 const uint8_t *pp) {
622
623 /* Data is programmed page by page.*/
624 while (n > 0U) {
625 flash_error_t err;
626
627 /* Data size that can be written in a single program page operation.*/
628 size_t chunk = (size_t)(((offset | PAGE_MASK) + 1U) - offset);
629 if (chunk > n) {
630 chunk = n;
631 }
632
633 /* Enabling write operation.*/
635
636 /* Page program command.*/
637 __xsnor_bus_cmd_addr_send(self, CMD_PAGE_PROGRAM, offset, chunk, pp);
638
639 /* Wait for status and check errors.*/
640 err = n25q_poll_status(self);
641 if (err != FLASH_NO_ERROR) {
642
643 return err;
644 }
645
646 /* Next page.*/
647 offset += chunk;
648 pp += chunk;
649 n -= chunk;
650 }
651
652 return FLASH_NO_ERROR;
653}
654
655/**
656 * @brief Override of method @p xsnor_device_start_erase_all().
657 *
658 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
659 * instance.
660 * @return An error code.
661 */
664
665 /* Enabling write operation.*/
667
668 /* Bulk erase command.*/
670
671 return FLASH_NO_ERROR;
672}
673
674/**
675 * @brief Override of method @p xsnor_device_start_erase_sector().
676 *
677 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
678 * instance.
679 * @param[in] sector Sector to be erased.
680 * @return An error code.
681 */
684 flash_offset_t offset = (flash_offset_t)(sector * self->descriptor.sectors_size);
685
686 /* Enabling write operation.*/
688
689 /* Sector erase command.*/
690 if ((self->config->options & N25Q_OPT_USE_SUBSECTORS) != 0U) {
692 }
693 else {
695 }
696
697 return FLASH_NO_ERROR;
698}
699
700/**
701 * @brief Override of method @p xsnor_device_query_erase().
702 *
703 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
704 * instance.
705 * @param[out] msec Recommended time, in milliseconds, that should
706 * be spent before calling this function again,
707 * can be @p NULL
708 * @return An error code.
709 */
710flash_error_t __n25q_query_erase_impl(void *ip, unsigned *msec) {
712
713 /* Read status command.*/
715 1, &self->config->buffers->databuf[0]);
716
717 /* If the P/E bit is zero (busy) or the flash in a suspended state then
718 report that the operation is still in progress.*/
719 if (((self->config->buffers->databuf[0] & FLAGS_PROGRAM_ERASE) == 0U) ||
720 ((self->config->buffers->databuf[0] & FLAGS_ERASE_SUSPEND) != 0U)) {
721
722 /* Recommended time before polling again, this is a simplified
723 implementation.*/
724 if (msec != NULL) {
725 *msec = 1U;
726 }
727
728 return FLASH_BUSY_ERASING;
729 }
730
731 /* Checking for errors.*/
732 if ((self->config->buffers->databuf[0] & FLAGS_ALL_ERRORS) != 0U) {
733
734 /* Clearing status register.*/
736
737 /* Erase operation failed.*/
738 return FLASH_ERROR_ERASE;
739 }
740
741 return FLASH_NO_ERROR;
742}
743
744/**
745 * @brief Override of method @p xsnor_device_verify_erase().
746 *
747 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
748 * instance.
749 * @param[in] sector Sector to be verified.
750 * @return An error code.
751 */
754 flash_offset_t offset;
755 size_t n;
756
757 /* Read command.*/
758 offset = (flash_offset_t)(sector * self->descriptor.sectors_size);
759 n = self->descriptor.sectors_size;
760 while (n > 0U) {
761 uint8_t *p;
762
763 __n25q_read_impl(self, offset,
764 XSNOR_BUFFER_SIZE, &self->config->buffers->databuf[0]);
765
766 /* Checking for erased state of current buffer.*/
767 for (p = &self->config->buffers->databuf[0];
768 p < &self->config->buffers->databuf[XSNOR_BUFFER_SIZE];
769 p++) {
770
771 if (*p != 0xFFU) {
772 return FLASH_ERROR_VERIFY;
773 }
774 }
775
776 offset += XSNOR_BUFFER_SIZE;
778 }
779
780 return FLASH_NO_ERROR;
781}
782
783/**
784 * @brief Override of method @p xsnor_device_mmap_on().
785 *
786 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
787 * instance.
788 * @param[out] addrp Pointer to the memory mapped memory or @p NULL
789 * @return An error code.
790 */
791flash_error_t __n25q_mmap_on_impl(void *ip, uint8_t **addrp) {
793
794#if XSNOR_USE_BOTH == TRUE
795 if (self->config->bus_type == XSNOR_BUS_MODE_SPI) {
797 }
798#endif
799
800#if XSNOR_USE_WSPI == FALSE
802#else /* XSNOR_USE_WSPI == TRUE */
803 {
804 wspi_command_t cmd;
805
806 /* Bus acquisition.*/
808
809 /* Activating XIP mode in the device.*/
810 n25q_activate_xip(self);
811
812 /* Starting WSPI memory mapped mode.*/
814 WSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/
817 cmd.cmd = CMD_FAST_READ;
818 cmd.addr = 0U;
819 cmd.alt = 0U;
820 cmd.dummy = (self->config->options & N25Q_OPT_DUMMY_CYCLES_MASK) - 2U;
821
822 /* Variant part of the command configuration.*/
823 switch (self->config->bus_type) {
828 break;
833 break;
838 break;
839 default:
840 osalDbgAssert(false, "invalid bus type");
841 }
842 wspiMapFlash(self->config->bus.wspi.drv, &cmd, addrp);
843
844 /* Bus release.*/
846
847 return FLASH_NO_ERROR;
848 }
849#endif
850}
851
852/**
853 * @brief Override of method @p xsnor_device_mmap_off().
854 *
855 * @param[in,out] ip Pointer to a @p hal_xsnor_micron_n25q_c
856 * instance.
857 */
858void __n25q_mmap_off_impl(void *ip) {
860
861#if XSNOR_USE_WSPI == TRUE
862 /* Bus acquisition.*/
864
865 /* Stopping WSPI memory mapped mode.*/
866 wspiUnmapFlash(self->config->bus.wspi.drv);
867
868 n25q_reset_xip(self);
869
870 /* Bus release.*/
872#endif
873}
874/** @} */
875
876/**
877 * @brief VMT structure of SNOR Micron N25Q driver class.
878 * @note It is public because accessed by the inlined constructor.
879 */
881 .dispose = __n25q_dispose_impl,
882 .init = __n25q_init_impl,
883 .read = __n25q_read_impl,
884 .program = __n25q_program_impl,
885 .start_erase_all = __n25q_start_erase_all_impl,
886 .start_erase_sector = __n25q_start_erase_sector_impl,
887 .query_erase = __n25q_query_erase_impl,
888 .verify_erase = __n25q_verify_erase_impl,
889 .mmap_on = __n25q_mmap_on_impl,
890 .mmap_off = __n25q_mmap_off_impl
891};
892
893/** @} */
894
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
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_PAGE_PROGRAM
#define FLAGS_ERASE_SUSPEND
static void n25q_reset_memory(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)
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
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_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_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