1 /*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef _HARDWARE_FLASH_H
8 #define _HARDWARE_FLASH_H
9
10 #include "pico.h"
11
12 /** \file flash.h
13 * \defgroup hardware_flash hardware_flash
14 *
15 * \brief Low level flash programming and erase API
16 *
17 * Note these functions are *unsafe* if you are using both cores, and the other
18 * is executing from flash concurrently with the operation. In this case, you
19 * must perform your own synchronisation to make sure that no XIP accesses take
20 * place during flash programming. One option is to use the
21 * \ref multicore_lockout functions.
22 *
23 * Likewise they are *unsafe* if you have interrupt handlers or an interrupt
24 * vector table in flash, so you must disable interrupts before calling in
25 * this case.
26 *
27 * If PICO_NO_FLASH=1 is not defined (i.e. if the program is built to run from
28 * flash) then these functions will make a static copy of the second stage
29 * bootloader in SRAM, and use this to reenter execute-in-place mode after
30 * programming or erasing flash, so that they can safely be called from
31 * flash-resident code.
32 *
33 * \subsection flash_example Example
34 * \include flash_program.c
35 */
36
37 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_FLASH, Enable/disable assertions in the hardware_flash module, type=bool, default=0, group=hardware_flash
38 #ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_FLASH
39 #ifdef PARAM_ASSERTIONS_ENABLED_FLASH // backwards compatibility with SDK < 2.0.0
40 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_FLASH PARAM_ASSERTIONS_ENABLED_FLASH
41 #else
42 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_FLASH 0
43 #endif
44 #endif
45 #define FLASH_PAGE_SIZE (1u << 8)
46 #define FLASH_SECTOR_SIZE (1u << 12)
47 #define FLASH_BLOCK_SIZE (1u << 16)
48
49 #ifndef FLASH_UNIQUE_ID_SIZE_BYTES
50 #define FLASH_UNIQUE_ID_SIZE_BYTES 8
51 #endif
52
53 // PICO_CONFIG: PICO_FLASH_SIZE_BYTES, size of primary flash in bytes, type=int, default=Usually provided via board header, group=hardware_flash
54
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58
59 /*! \brief Erase areas of flash
60 * \ingroup hardware_flash
61 *
62 * \param flash_offs Offset into flash, in bytes, to start the erase. Must be aligned to a 4096-byte flash sector.
63 * \param count Number of bytes to be erased. Must be a multiple of 4096 bytes (one sector).
64 *
65 * @note Erasing a flash sector sets all the bits in all the pages in that sector to one.
66 * You can then "program" flash pages in the sector to turn some of the bits to zero.
67 * Once a bit is set to zero it can only be changed back to one by erasing the whole sector again.
68 */
69 void flash_range_erase(uint32_t flash_offs, size_t count);
70
71 /*! \brief Program flash
72 * \ingroup hardware_flash
73 *
74 * \param flash_offs Flash address of the first byte to be programmed. Must be aligned to a 256-byte flash page.
75 * \param data Pointer to the data to program into flash
76 * \param count Number of bytes to program. Must be a multiple of 256 bytes (one page).
77 *
78 * @note: Programming a flash page effectively changes some of the bits from one to zero.
79 * The only way to change a zero bit back to one is to "erase" the whole sector that the page resides in.
80 * So you may need to make sure you have called flash_range_erase before calling flash_range_program.
81 */
82
83 void flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count);
84
85 /*! \brief Get flash unique 64 bit identifier
86 * \ingroup hardware_flash
87 *
88 * Use a standard 4Bh RUID instruction to retrieve the 64 bit unique
89 * identifier from a flash device attached to the QSPI interface. Since there
90 * is a 1:1 association between the MCU and this flash, this also serves as a
91 * unique identifier for the board.
92 *
93 * \param id_out Pointer to an 8-byte buffer to which the ID will be written
94 */
95 void flash_get_unique_id(uint8_t *id_out);
96
97 /*! \brief Execute bidirectional flash command
98 * \ingroup hardware_flash
99 *
100 * Low-level function to execute a serial command on a flash device attached
101 * to the QSPI interface. Bytes are simultaneously transmitted and received
102 * from txbuf and to rxbuf. Therefore, both buffers must be the same length,
103 * count, which is the length of the overall transaction. This is useful for
104 * reading metadata from the flash chip, such as device ID or SFDP
105 * parameters.
106 *
107 * The XIP cache is flushed following each command, in case flash state
108 * has been modified. Like other hardware_flash functions, the flash is not
109 * accessible for execute-in-place transfers whilst the command is in
110 * progress, so entering a flash-resident interrupt handler or executing flash
111 * code on the second core concurrently will be fatal. To avoid these pitfalls
112 * it is recommended that this function only be used to extract flash metadata
113 * during startup, before the main application begins to run: see the
114 * implementation of pico_get_unique_id() for an example of this.
115 *
116 * \param txbuf Pointer to a byte buffer which will be transmitted to the flash
117 * \param rxbuf Pointer to a byte buffer where data received from the flash will be written. txbuf and rxbuf may be the same buffer.
118 * \param count Length in bytes of txbuf and of rxbuf
119 */
120 void flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count);
121
122 void flash_flush_cache(void);
123
124 #if !PICO_RP2040
125 typedef enum {
126 FLASH_DEVINFO_SIZE_NONE = 0x0,
127 FLASH_DEVINFO_SIZE_8K = 0x1,
128 FLASH_DEVINFO_SIZE_16K = 0x2,
129 FLASH_DEVINFO_SIZE_32K = 0x3,
130 FLASH_DEVINFO_SIZE_64K = 0x4,
131 FLASH_DEVINFO_SIZE_128K = 0x5,
132 FLASH_DEVINFO_SIZE_256K = 0x6,
133 FLASH_DEVINFO_SIZE_512K = 0x7,
134 FLASH_DEVINFO_SIZE_1M = 0x8,
135 FLASH_DEVINFO_SIZE_2M = 0x9,
136 FLASH_DEVINFO_SIZE_4M = 0xa,
137 FLASH_DEVINFO_SIZE_8M = 0xb,
138 FLASH_DEVINFO_SIZE_16M = 0xc,
139 FLASH_DEVINFO_SIZE_MAX = 0xc
140 } flash_devinfo_size_t;
141
142 /*! \brief Convert a flash/PSRAM size enum to an integer size in bytes
143 * \ingroup hardware_flash
144 */
flash_devinfo_size_to_bytes(flash_devinfo_size_t size)145 static inline uint32_t flash_devinfo_size_to_bytes(flash_devinfo_size_t size) {
146 if (size == FLASH_DEVINFO_SIZE_NONE) {
147 return 0;
148 } else {
149 return 4096u << (uint)size;
150 }
151 }
152
153 /*! \brief Convert an integer flash/PSRAM size in bytes to a size enum, as
154 ! stored in OTP and used by the ROM.
155 * \ingroup hardware_flash
156 */
flash_devinfo_bytes_to_size(uint32_t bytes)157 static inline flash_devinfo_size_t flash_devinfo_bytes_to_size(uint32_t bytes) {
158 // Must be zero or a power of two
159 valid_params_if(HARDWARE_FLASH, (bytes & (bytes - 1)) == 0u);
160 uint sectors = bytes / 4096u;
161 if (sectors <= 1u) {
162 return FLASH_DEVINFO_SIZE_NONE;
163 } else {
164 return (flash_devinfo_size_t) __builtin_ctz(sectors);
165 }
166 }
167
168 /*! \brief Get the size of the QSPI device attached to chip select cs, according to FLASH_DEVINFO
169 * \ingroup hardware_flash
170 *
171 * \param cs Chip select index: 0 is QMI chip select 0 (QSPI CS pin), 1 is QMI chip select 1.
172 *
173 * The bootrom reads the FLASH_DEVINFO OTP data entry from OTP into boot RAM during startup. This
174 * contains basic information about the flash device which can be queried without communicating
175 * with the external device.(There are several methods to determine the size of a QSPI device over
176 * QSPI, but none are universally supported.)
177 *
178 * Since the FLASH_DEVINFO information is stored in boot RAM at runtime, it can be updated. Updates
179 * made in this way persist until the next reboot. The ROM uses this device information to control
180 * some low-level flash API behaviour, such as issuing an XIP exit sequence to CS 1 if its size is
181 * nonzero.
182 *
183 * If the macro PICO_FLASH_SIZE_BYTES is specified, this overrides the value for chip select 0. This
184 * can be specified in a board header if a board is always equipped with the same size of flash.
185 */
186 flash_devinfo_size_t flash_devinfo_get_cs_size(uint cs);
187
188 /*! \brief Update the size of the QSPI device attached to chip select cs in the runtime copy
189 * of FLASH_DEVINFO.
190 *
191 * \ingroup hardware_flash
192 *
193 * \param cs Chip select index: 0 is QMI chip select 0 (QSPI CS pin), 1 is QMI chip select 1.
194 *
195 * \param size The size of the attached device, or FLASH_DEVINFO_SIZE_NONE if there is none on this
196 * chip select.
197 *
198 * The bootrom maintains a copy in boot RAM of the FLASH_DEVINFO information read from OTP during
199 * startup. This function updates that copy to reflect runtime information about the sizes of
200 * attached QSPI devices.
201 *
202 * This controls the behaviour of some ROM flash APIs, such as bounds checking addresses for
203 * erase/programming in the checked_flash_op() API, or issuing an XIP exit sequence to CS 1 in
204 * flash_exit_xip() if the size is nonzero.
205 */
206 void flash_devinfo_set_cs_size(uint cs, flash_devinfo_size_t size);
207
208 /*! \brief Check whether all attached devices support D8h block erase with 64k size, according to
209 * FLASH_DEVINFO.
210 *
211 * \ingroup hardware_flash
212 *
213 * This controls whether checked_flash_op() ROM API uses D8h 64k block erase where possible, for
214 * faster erase times. If not, this ROM API always uses 20h 4k sector erase.
215 *
216 * The bootrom loads this flag from the OTP FLASH_DEVINFO data entry during startup, and stores it
217 * in boot RAM. You can update the boot RAM copy based on runtime knowledge of the attached QSPI
218 * devices.
219 */
220 bool flash_devinfo_get_d8h_erase_supported(void);
221
222 /*! \brief Specify whether all attached devices support D8h block erase with 64k size, in the
223 * runtime copy of FLASH_DEVINFO
224 *
225 * \ingroup hardware_flash
226 *
227 * This function updates the boot RAM copy of OTP FLASH_DEVINFO. The flag passed here is visible to
228 * ROM APIs, and is also returned in the next call to flash_devinfo_get_d8h_erase_supported()
229 */
230 void flash_devinfo_set_d8h_erase_supported(bool supported);
231
232 /*! \brief Check the GPIO allocated for each chip select, according to FLASH_DEVINFO
233 * \ingroup hardware_flash
234 *
235 * \param cs Chip select index (only the value 1 is supported on RP2350)
236 */
237 uint flash_devinfo_get_cs_gpio(uint cs);
238
239 /*! \brief Update the GPIO allocated for each chip select in the runtime copy of FLASH_DEVINFO
240 * \ingroup hardware_flash
241 *
242 * \param cs Chip select index (only the value 1 is supported on RP2350)
243 *
244 * \param gpio GPIO index (must be less than NUM_BANK0_GPIOS)
245 */
246 void flash_devinfo_set_cs_gpio(uint cs, uint gpio);
247
248 #endif // !PICO_RP2040
249
250 #ifdef __cplusplus
251 }
252 #endif
253
254 #endif
255