1 /*
2 * Copyright (c) 2023 - 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_EXMIF_H__
35 #define NRF_EXMIF_H__
36
37 #include <nrfx.h>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * @defgroup nrf_exmif_hal EXMIF HAL
45 * @{
46 * @ingroup nrf_exmif
47 * @brief Hardware access layer for managing the External Memory Interface (EXMIF) peripheral.
48 */
49
50 /** @brief Maximum EXMIF memory size. */
51 #define NRF_EXMIF_MAX_MEMORY_DEVICE_SIZE 0x10000000UL
52
53 /** @brief Maximum number of EXMIF memory devices. */
54 #define NRF_EXMIF_MAX_NUMBER_OF_DEVICES 2
55
56 /** @brief EXMIF tasks. */
57 typedef enum
58 {
59 NRF_EXMIF_TASK_START = offsetof(NRF_EXMIF_Type, TASKS_START), ///< Start EXMIF peripheral power and clocks.
60 NRF_EXMIF_TASK_STOP = offsetof(NRF_EXMIF_Type, TASKS_STOP) ///< Stop EXMIF peripheral power and clocks.
61 } nrf_exmif_task_t;
62
63 /**
64 * @brief Structure for configuration of mapping of the memory device to the EXMIF peripheral.
65 *
66 * @note @p offset is subtracted from incoming address to produce an address used for an external
67 * memory device. It can be calculated using following equation:
68 * offset = incoming AXI address - expected base address of the memory device
69 */
70 typedef struct
71 {
72 uint32_t offset; ///< EXMIF address mapping offset.
73 uint32_t size; ///< EXMIF address mapping memory size.
74 } nrf_exmif_config_t;
75
76 /**
77 * @brief Function for activating the specified EXMIF task.
78 *
79 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
80 * @param[in] task Task to be activated.
81 */
82 NRF_STATIC_INLINE void nrf_exmif_task_trigger(NRF_EXMIF_Type * p_reg,
83 nrf_exmif_task_t task);
84
85 /**
86 * @brief Function for getting the address of the specified EXMIF task register.
87 *
88 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
89 * @param[in] task The specified task.
90 *
91 * @return Address of the specified task register.
92 */
93 NRF_STATIC_INLINE uint32_t nrf_exmif_task_address_get(NRF_EXMIF_Type const * p_reg,
94 nrf_exmif_task_t task);
95
96 /**
97 * @brief Function for enabling or disabling EXMIF reset state.
98 *
99 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
100 * @param[in] enable True if reset state is to be enabled, false otherwise.
101 */
102 NRF_STATIC_INLINE void nrf_exmif_reset_set(NRF_EXMIF_Type * p_reg,
103 bool enable);
104
105 /**
106 * @brief Function for enabling or disabling locked APB access to serial memory controller.
107 *
108 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
109 * @param[in] enable True if locked APB access is to be enabled, false otherwise.
110 */
111 NRF_STATIC_INLINE void nrf_exmif_locked_access_set(NRF_EXMIF_Type * p_reg,
112 bool enable);
113
114 /**
115 * @brief Function for configuring mapping of the memory device to EXMIF peripheral.
116 *
117 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
118 * @param[in] device_idx Device number to configure.
119 * @param[in] p_device Pointer to the configuration structure of the memory device.
120 */
121 NRF_STATIC_INLINE void nrf_exmif_device_config(NRF_EXMIF_Type * p_reg,
122 uint8_t device_idx,
123 nrf_exmif_config_t const * p_device);
124
125 /**
126 * @brief Function for enabling the EXMIF memory device.
127 *
128 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
129 * @param[in] device_idx Device number to enable.
130 */
131 NRF_STATIC_INLINE void nrf_exmif_device_enable(NRF_EXMIF_Type * p_reg,
132 uint8_t device_idx);
133
134 /**
135 * @brief Function for disabling the EXMIF memory device.
136 *
137 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
138 * @param[in] device_idx Device number to disable.
139 */
140 NRF_STATIC_INLINE void nrf_exmif_device_disable(NRF_EXMIF_Type * p_reg,
141 uint8_t device_idx);
142
143 #ifndef NRF_DECLARE_ONLY
144
nrf_exmif_task_trigger(NRF_EXMIF_Type * p_reg,nrf_exmif_task_t task)145 NRF_STATIC_INLINE void nrf_exmif_task_trigger(NRF_EXMIF_Type * p_reg,
146 nrf_exmif_task_t task)
147 {
148 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
149 }
150
nrf_exmif_task_address_get(NRF_EXMIF_Type const * p_reg,nrf_exmif_task_t task)151 NRF_STATIC_INLINE uint32_t nrf_exmif_task_address_get(NRF_EXMIF_Type const * p_reg,
152 nrf_exmif_task_t task)
153 {
154 return nrf_task_event_address_get(p_reg, task);
155 }
156
nrf_exmif_reset_set(NRF_EXMIF_Type * p_reg,bool enable)157 NRF_STATIC_INLINE void nrf_exmif_reset_set(NRF_EXMIF_Type * p_reg,
158 bool enable)
159 {
160 p_reg->RESET = (enable ? (EXMIF_RESET_RESET_Set << EXMIF_RESET_RESET_Pos) :
161 (EXMIF_RESET_RESET_Clear << EXMIF_RESET_RESET_Pos));
162 }
163
nrf_exmif_locked_access_set(NRF_EXMIF_Type * p_reg,bool enable)164 NRF_STATIC_INLINE void nrf_exmif_locked_access_set(NRF_EXMIF_Type * p_reg,
165 bool enable)
166 {
167 p_reg->LOCKEDACCESS =
168 (enable ? (EXMIF_LOCKEDACCESS_ENABLE_Enabled << EXMIF_LOCKEDACCESS_ENABLE_Pos) :
169 (EXMIF_LOCKEDACCESS_ENABLE_Disabled << EXMIF_LOCKEDACCESS_ENABLE_Pos));
170 }
171
nrf_exmif_device_config(NRF_EXMIF_Type * p_reg,uint8_t device_idx,nrf_exmif_config_t const * p_device)172 NRF_STATIC_INLINE void nrf_exmif_device_config(NRF_EXMIF_Type * p_reg,
173 uint8_t device_idx,
174 nrf_exmif_config_t const * p_device)
175 {
176 NRFX_ASSERT(p_device->size <= NRF_EXMIF_MAX_MEMORY_DEVICE_SIZE);
177 NRFX_ASSERT(device_idx < NRF_EXMIF_MAX_NUMBER_OF_DEVICES);
178 switch (device_idx)
179 {
180 case 0:
181 p_reg->EXTCONF1.OFFSET = p_device->offset;
182 p_reg->EXTCONF1.SIZE = p_device->size;
183 break;
184 case 1:
185 p_reg->EXTCONF2.OFFSET = p_device->offset;
186 p_reg->EXTCONF2.SIZE = p_device->size;
187 break;
188 default:
189 NRFX_ASSERT(false);
190 break;
191 }
192 }
193
nrf_exmif_device_enable(NRF_EXMIF_Type * p_reg,uint8_t device_idx)194 NRF_STATIC_INLINE void nrf_exmif_device_enable(NRF_EXMIF_Type * p_reg,
195 uint8_t device_idx)
196 {
197 NRFX_ASSERT(device_idx < NRF_EXMIF_MAX_NUMBER_OF_DEVICES);
198 switch (device_idx)
199 {
200 case 0:
201 p_reg->EXTCONF1.ENABLE = (EXMIF_EXTCONF1_ENABLE_ENABLE_Enabled << EXMIF_EXTCONF1_ENABLE_ENABLE_Pos);
202 break;
203 case 1:
204 p_reg->EXTCONF2.ENABLE = (EXMIF_EXTCONF2_ENABLE_ENABLE_Enabled << EXMIF_EXTCONF2_ENABLE_ENABLE_Pos);
205 break;
206 default:
207 NRFX_ASSERT(false);
208 break;
209 }
210 }
211
nrf_exmif_device_disable(NRF_EXMIF_Type * p_reg,uint8_t device_idx)212 NRF_STATIC_INLINE void nrf_exmif_device_disable(NRF_EXMIF_Type * p_reg,
213 uint8_t device_idx)
214 {
215 NRFX_ASSERT(device_idx < NRF_EXMIF_MAX_NUMBER_OF_DEVICES);
216 switch (device_idx)
217 {
218 case 0:
219 p_reg->EXTCONF1.ENABLE = (EXMIF_EXTCONF1_ENABLE_ENABLE_Disabled << EXMIF_EXTCONF1_ENABLE_ENABLE_Pos);
220 break;
221 case 1:
222 p_reg->EXTCONF2.ENABLE = (EXMIF_EXTCONF2_ENABLE_ENABLE_Disabled << EXMIF_EXTCONF2_ENABLE_ENABLE_Pos);
223 break;
224 default:
225 NRFX_ASSERT(false);
226 break;
227 }
228 }
229
230 #endif // NRF_DECLARE_ONLY
231
232 /** @} */
233
234 #ifdef __cplusplus
235 }
236 #endif
237
238 #endif // NRF_EXMIF_H__
239