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