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