1 /*
2 * Copyright (c) 2018 - 2024, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef NRF_VMC_H__
35 #define NRF_VMC_H__
36
37 #include <nrfx.h>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * Value representing number of RAM sections.
45 *
46 * This symbol is needed to determine elements in enumerators.
47 */
48 #if defined(NRF5340_XXAA_APPLICATION)
49 #define VMC_RAM_SECTION_COUNT 16
50 #elif defined(NRF5340_XXAA_NETWORK) || defined(NRF9160_XXAA) || defined(NRF9120_XXAA)
51 #define VMC_RAM_SECTION_COUNT 4
52 #if !defined(VMC_FEATURE_RAM_REGISTERS_COUNT)
53 #define VMC_FEATURE_RAM_REGISTERS_COUNT 4
54 #endif
55 #endif
56
57 /**
58 * @defgroup nrf_vmc_hal VMC HAL
59 * @{
60 * @ingroup nrf_vmc
61 * @brief Hardware access layer for managing the Volatile Memory Controller (VMC) peripheral.
62 */
63
64 /** @brief Power configuration bits for each section in particular RAM block. */
65 typedef enum
66 {
67 NRF_VMC_POWER_S0 = VMC_RAM_POWER_S0POWER_Msk, ///< Keep retention on RAM section S0 of the particular RAM block when RAM section is switched off.
68 NRF_VMC_POWER_S1 = VMC_RAM_POWER_S1POWER_Msk, ///< Keep retention on RAM section S1 of the particular RAM block when RAM section is switched off.
69 NRF_VMC_POWER_S2 = VMC_RAM_POWER_S2POWER_Msk, ///< Keep retention on RAM section S2 of the particular RAM block when RAM section is switched off.
70 NRF_VMC_POWER_S3 = VMC_RAM_POWER_S3POWER_Msk, ///< Keep retention on RAM section S3 of the particular RAM block when RAM section is switched off.
71 #if (VMC_RAM_SECTION_COUNT > 4) || defined(__NRFX_DOXYGEN__)
72 NRF_VMC_POWER_S4 = VMC_RAM_POWER_S4POWER_Msk, ///< Keep retention on RAM section S4 of the particular RAM block when RAM section is switched off.
73 NRF_VMC_POWER_S5 = VMC_RAM_POWER_S5POWER_Msk, ///< Keep retention on RAM section S5 of the particular RAM block when RAM section is switched off.
74 NRF_VMC_POWER_S6 = VMC_RAM_POWER_S6POWER_Msk, ///< Keep retention on RAM section S6 of the particular RAM block when RAM section is switched off.
75 NRF_VMC_POWER_S7 = VMC_RAM_POWER_S7POWER_Msk, ///< Keep retention on RAM section S7 of the particular RAM block when RAM section is switched off.
76 NRF_VMC_POWER_S8 = VMC_RAM_POWER_S8POWER_Msk, ///< Keep retention on RAM section S8 of the particular RAM block when RAM section is switched off.
77 NRF_VMC_POWER_S9 = VMC_RAM_POWER_S9POWER_Msk, ///< Keep retention on RAM section S9 of the particular RAM block when RAM section is switched off.
78 NRF_VMC_POWER_S10 = VMC_RAM_POWER_S10POWER_Msk, ///< Keep retention on RAM section S10 of the particular RAM block when RAM section is switched off.
79 NRF_VMC_POWER_S11 = VMC_RAM_POWER_S11POWER_Msk, ///< Keep retention on RAM section S11 of the particular RAM block when RAM section is switched off.
80 NRF_VMC_POWER_S12 = VMC_RAM_POWER_S12POWER_Msk, ///< Keep retention on RAM section S12 of the particular RAM block when RAM section is switched off.
81 NRF_VMC_POWER_S13 = VMC_RAM_POWER_S13POWER_Msk, ///< Keep retention on RAM section S13 of the particular RAM block when RAM section is switched off.
82 NRF_VMC_POWER_S14 = VMC_RAM_POWER_S14POWER_Msk, ///< Keep retention on RAM section S14 of the particular RAM block when RAM section is switched off.
83 NRF_VMC_POWER_S15 = VMC_RAM_POWER_S15POWER_Msk, ///< Keep retention on RAM section S15 of the particular RAM block when RAM section is switched off.
84 #endif
85 } nrf_vmc_power_t;
86
87 #if defined(__GNUC__)
88 #pragma GCC diagnostic push
89 #pragma GCC diagnostic ignored "-Wpedantic"
90 #endif
91
92 /** @brief Retention configuration bits for each section in particular RAM block. */
93 typedef enum
94 {
95 NRF_VMC_RETENTION_S0 = VMC_RAM_POWER_S0RETENTION_Msk, ///< Keep RAM section S0 of the particular RAM block on or off in System ON mode.
96 NRF_VMC_RETENTION_S1 = VMC_RAM_POWER_S1RETENTION_Msk, ///< Keep RAM section S1 of the particular RAM block on or off in System ON mode.
97 NRF_VMC_RETENTION_S2 = VMC_RAM_POWER_S2RETENTION_Msk, ///< Keep RAM section S2 of the particular RAM block on or off in System ON mode.
98 NRF_VMC_RETENTION_S3 = VMC_RAM_POWER_S3RETENTION_Msk, ///< Keep RAM section S3 of the particular RAM block on or off in System ON mode.
99 #if (VMC_RAM_SECTION_COUNT > 4) || defined(__NRFX_DOXYGEN__)
100 NRF_VMC_RETENTION_S4 = VMC_RAM_POWER_S4RETENTION_Msk, ///< Keep RAM section S4 of the particular RAM block on or off in System ON mode.
101 NRF_VMC_RETENTION_S5 = VMC_RAM_POWER_S5RETENTION_Msk, ///< Keep RAM section S5 of the particular RAM block on or off in System ON mode.
102 NRF_VMC_RETENTION_S6 = VMC_RAM_POWER_S6RETENTION_Msk, ///< Keep RAM section S6 of the particular RAM block on or off in System ON mode.
103 NRF_VMC_RETENTION_S7 = VMC_RAM_POWER_S7RETENTION_Msk, ///< Keep RAM section S7 of the particular RAM block on or off in System ON mode.
104 NRF_VMC_RETENTION_S8 = VMC_RAM_POWER_S8RETENTION_Msk, ///< Keep RAM section S8 of the particular RAM block on or off in System ON mode.
105 NRF_VMC_RETENTION_S9 = VMC_RAM_POWER_S9RETENTION_Msk, ///< Keep RAM section S9 of the particular RAM block on or off in System ON mode.
106 NRF_VMC_RETENTION_S10 = VMC_RAM_POWER_S10RETENTION_Msk, ///< Keep RAM section S10 of the particular RAM block on or off in System ON mode.
107 NRF_VMC_RETENTION_S11 = VMC_RAM_POWER_S11RETENTION_Msk, ///< Keep RAM section S11 of the particular RAM block on or off in System ON mode.
108 NRF_VMC_RETENTION_S12 = VMC_RAM_POWER_S12RETENTION_Msk, ///< Keep RAM section S12 of the particular RAM block on or off in System ON mode.
109 NRF_VMC_RETENTION_S13 = VMC_RAM_POWER_S13RETENTION_Msk, ///< Keep RAM section S13 of the particular RAM block on or off in System ON mode.
110 NRF_VMC_RETENTION_S14 = VMC_RAM_POWER_S14RETENTION_Msk, ///< Keep RAM section S14 of the particular RAM block on or off in System ON mode.
111 NRF_VMC_RETENTION_S15 = VMC_RAM_POWER_S15RETENTION_Msk, ///< Keep RAM section S15 of the particular RAM block on or off in System ON mode.
112 #endif
113 } nrf_vmc_retention_t;
114
115 #if defined(__GNUC__)
116 #pragma GCC diagnostic pop
117 #endif
118
119 /**
120 * @brief Function for setting power configuration for the particular RAM block.
121 *
122 * @note Overrides current configuration.
123 *
124 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
125 * @param[in] ram_block_num RAM block number.
126 * @param[in] power_mask Bitmask with sections configuration of particular RAM block.
127 * @ref nrf_vmc_power_t should be use to prepare this bitmask.
128 * @param[in] retention_mask Bitmask with sections configuration of particular RAM block.
129 * @ref nrf_vmc_retention_t should be use to prepare this bitmask.
130 */
131 NRF_STATIC_INLINE void nrf_vmc_ram_block_config(NRF_VMC_Type * p_reg,
132 uint8_t ram_block_num,
133 uint32_t power_mask,
134 uint32_t retention_mask);
135
136 /**
137 * @brief Function for clearing power configuration for the particular RAM block.
138 *
139 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
140 * @param[in] ram_block_num RAM block number.
141 */
142 NRF_STATIC_INLINE void nrf_vmc_ram_block_clear(NRF_VMC_Type * p_reg, uint8_t ram_block_num);
143
144 /**
145 * @brief Function for setting power configuration for the particular RAM block.
146 *
147 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
148 * @param[in] ram_block_num RAM block number.
149 * @param[in] sect_power Paricular section of the RAM block.
150 */
151 NRF_STATIC_INLINE void nrf_vmc_ram_block_power_set(NRF_VMC_Type * p_reg,
152 uint8_t ram_block_num,
153 nrf_vmc_power_t sect_power);
154
155 /**
156 * @brief Function for setting power configuration for all available RAM blocks.
157 *
158 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
159 */
160 NRF_STATIC_INLINE void nrf_vmc_ram_block_power_all_set(NRF_VMC_Type * p_reg);
161
162 /**
163 * @brief Function for clearing power configuration for the particular RAM block.
164 *
165 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
166 * @param[in] ram_block_num RAM block number.
167 * @param[in] sect_power Paricular section of the RAM block.
168 */
169 NRF_STATIC_INLINE void nrf_vmc_ram_block_power_clear(NRF_VMC_Type * p_reg,
170 uint8_t ram_block_num,
171 nrf_vmc_power_t sect_power);
172
173 /**
174 * @brief Function for getting power configuration of the particular RAM block.
175 *
176 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
177 * @param[in] ram_block_num RAM block number.
178 *
179 * @return Bitmask with power configuration of sections of particular RAM block.
180 */
181 NRF_STATIC_INLINE uint32_t nrf_vmc_ram_block_power_mask_get(NRF_VMC_Type const * p_reg,
182 uint8_t ram_block_num);
183
184 /**
185 * @brief Function for setting retention configuration for the particular RAM block.
186 *
187 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
188 * @param[in] ram_block_num RAM block number.
189 * @param[in] sect_retention Paricular section of the RAM block.
190 */
191 NRF_STATIC_INLINE void nrf_vmc_ram_block_retention_set(NRF_VMC_Type * p_reg,
192 uint8_t ram_block_num,
193 nrf_vmc_retention_t sect_retention);
194
195 /**
196 * @brief Function for setting retention configuration for all available RAM blocks.
197 *
198 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
199 */
200 NRF_STATIC_INLINE void nrf_vmc_ram_block_retention_all_set(NRF_VMC_Type * p_reg);
201
202 /**
203 * @brief Function for clearing retention configuration for the particular RAM block.
204 *
205 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
206 * @param[in] ram_block_num RAM block number.
207 * @param[in] sect_retention Paricular section of the RAM block.
208 */
209 NRF_STATIC_INLINE void nrf_vmc_ram_block_retention_clear(NRF_VMC_Type * p_reg,
210 uint8_t ram_block_num,
211 nrf_vmc_retention_t sect_retention);
212
213 /**
214 * @brief Function for getting retention configuration of the particular RAM block.
215 *
216 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
217 * @param[in] ram_block_num RAM block number.
218 *
219 * @return Bitmask with retention configuration of sections of particular RAM block
220 */
221 NRF_STATIC_INLINE uint32_t nrf_vmc_ram_block_retention_mask_get(NRF_VMC_Type const * p_reg,
222 uint8_t ram_block_num);
223
224 #ifndef NRF_DECLARE_ONLY
225
nrf_vmc_ram_block_config(NRF_VMC_Type * p_reg,uint8_t ram_block_num,uint32_t power_mask,uint32_t retention_mask)226 NRF_STATIC_INLINE void nrf_vmc_ram_block_config(NRF_VMC_Type * p_reg,
227 uint8_t ram_block_num,
228 uint32_t power_mask,
229 uint32_t retention_mask)
230 {
231 p_reg->RAM[ram_block_num].POWER =
232 (power_mask & (NRFX_BIT_MASK(VMC_RAM_SECTION_COUNT) << VMC_RAM_POWER_S0POWER_Pos)) |
233 (retention_mask & (NRFX_BIT_MASK(VMC_RAM_SECTION_COUNT) <<
234 VMC_RAM_POWER_S0RETENTION_Pos));
235 // Ensure that memory write operation is completed.
236 __DSB();
237 }
238
nrf_vmc_ram_block_clear(NRF_VMC_Type * p_reg,uint8_t ram_block_num)239 NRF_STATIC_INLINE void nrf_vmc_ram_block_clear(NRF_VMC_Type * p_reg, uint8_t ram_block_num)
240 {
241 p_reg->RAM[ram_block_num].POWER = 0;
242 }
243
nrf_vmc_ram_block_power_set(NRF_VMC_Type * p_reg,uint8_t ram_block_num,nrf_vmc_power_t sect_power)244 NRF_STATIC_INLINE void nrf_vmc_ram_block_power_set(NRF_VMC_Type * p_reg,
245 uint8_t ram_block_num,
246 nrf_vmc_power_t sect_power)
247 {
248 p_reg->RAM[ram_block_num].POWERSET = (uint32_t)sect_power;
249 // Ensure that memory write operation is completed.
250 __DSB();
251 }
252
nrf_vmc_ram_block_power_all_set(NRF_VMC_Type * p_reg)253 NRF_STATIC_INLINE void nrf_vmc_ram_block_power_all_set(NRF_VMC_Type * p_reg)
254 {
255 for (size_t i = 0; i < VMC_FEATURE_RAM_REGISTERS_COUNT; i++)
256 {
257 p_reg->RAM[i].POWERSET = NRF_VMC_POWER_S0 | NRF_VMC_POWER_S1 |
258 NRF_VMC_POWER_S2 | NRF_VMC_POWER_S3 |
259 #if (VMC_RAM_SECTION_COUNT > 4)
260 NRF_VMC_POWER_S4 | NRF_VMC_POWER_S5 |
261 NRF_VMC_POWER_S6 | NRF_VMC_POWER_S7 |
262 NRF_VMC_POWER_S8 | NRF_VMC_POWER_S9 |
263 NRF_VMC_POWER_S10 | NRF_VMC_POWER_S11 |
264 NRF_VMC_POWER_S12 | NRF_VMC_POWER_S13 |
265 NRF_VMC_POWER_S14 | NRF_VMC_POWER_S15 |
266 #endif
267 0;
268 }
269 // Ensure that memory write operation is completed.
270 __DSB();
271 }
272
nrf_vmc_ram_block_power_clear(NRF_VMC_Type * p_reg,uint8_t ram_block_num,nrf_vmc_power_t sect_power)273 NRF_STATIC_INLINE void nrf_vmc_ram_block_power_clear(NRF_VMC_Type * p_reg,
274 uint8_t ram_block_num,
275 nrf_vmc_power_t sect_power)
276 {
277 p_reg->RAM[ram_block_num].POWERCLR = (uint32_t)sect_power;
278 }
279
nrf_vmc_ram_block_power_mask_get(NRF_VMC_Type const * p_reg,uint8_t ram_block_num)280 NRF_STATIC_INLINE uint32_t nrf_vmc_ram_block_power_mask_get(NRF_VMC_Type const * p_reg,
281 uint8_t ram_block_num)
282 {
283 return p_reg->RAM[ram_block_num].POWER & (NRFX_BIT_MASK(VMC_RAM_SECTION_COUNT) <<
284 VMC_RAM_POWER_S0POWER_Pos);
285 }
286
nrf_vmc_ram_block_retention_set(NRF_VMC_Type * p_reg,uint8_t ram_block_num,nrf_vmc_retention_t sect_retention)287 NRF_STATIC_INLINE void nrf_vmc_ram_block_retention_set(NRF_VMC_Type * p_reg,
288 uint8_t ram_block_num,
289 nrf_vmc_retention_t sect_retention)
290 {
291 p_reg->RAM[ram_block_num].POWERSET = (uint32_t)sect_retention;
292 // Ensure that memory write operation is completed.
293 __DSB();
294 }
295
nrf_vmc_ram_block_retention_all_set(NRF_VMC_Type * p_reg)296 NRF_STATIC_INLINE void nrf_vmc_ram_block_retention_all_set(NRF_VMC_Type * p_reg)
297 {
298 for (size_t i = 0; i < VMC_FEATURE_RAM_REGISTERS_COUNT; i++)
299 {
300 p_reg->RAM[i].POWERSET = NRF_VMC_RETENTION_S0 | NRF_VMC_RETENTION_S1 |
301 NRF_VMC_RETENTION_S2 | NRF_VMC_RETENTION_S3 |
302 #if (VMC_RAM_SECTION_COUNT > 4)
303 NRF_VMC_RETENTION_S4 | NRF_VMC_RETENTION_S5 |
304 NRF_VMC_RETENTION_S6 | NRF_VMC_RETENTION_S7 |
305 NRF_VMC_RETENTION_S8 | NRF_VMC_RETENTION_S9 |
306 NRF_VMC_RETENTION_S10 | NRF_VMC_RETENTION_S11 |
307 NRF_VMC_RETENTION_S12 | NRF_VMC_RETENTION_S13 |
308 NRF_VMC_RETENTION_S14 | NRF_VMC_RETENTION_S15 |
309 #endif
310 0;
311 }
312 // Ensure that memory write operation is completed.
313 __DSB();
314 }
315
nrf_vmc_ram_block_retention_clear(NRF_VMC_Type * p_reg,uint8_t ram_block_num,nrf_vmc_retention_t sect_retention)316 NRF_STATIC_INLINE void nrf_vmc_ram_block_retention_clear(NRF_VMC_Type * p_reg,
317 uint8_t ram_block_num,
318 nrf_vmc_retention_t sect_retention)
319 {
320 p_reg->RAM[ram_block_num].POWERCLR = (uint32_t)sect_retention;
321 }
322
nrf_vmc_ram_block_retention_mask_get(NRF_VMC_Type const * p_reg,uint8_t ram_block_num)323 NRF_STATIC_INLINE uint32_t nrf_vmc_ram_block_retention_mask_get(NRF_VMC_Type const * p_reg,
324 uint8_t ram_block_num)
325 {
326 return p_reg->RAM[ram_block_num].POWER & (NRFX_BIT_MASK(VMC_RAM_SECTION_COUNT) <<
327 VMC_RAM_POWER_S0RETENTION_Pos);
328 }
329
330 #endif // NRF_DECLARE_ONLY
331
332 /** @} */
333
334 #ifdef __cplusplus
335 }
336 #endif
337
338 #endif // NRF_VMC_H__
339