1 /*
2 * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef NRFX_PPI_H__
33 #define NRFX_PPI_H__
34
35 #include <nrfx.h>
36 #include <hal/nrf_ppi.h>
37
38 /**
39 * @defgroup nrfx_ppi PPI allocator
40 * @{
41 * @ingroup nrf_ppi
42 * @brief Programmable Peripheral Interconnect (PPI) allocator.
43 */
44
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48
49 #ifndef NRFX_PPI_CHANNELS_USED
50 #define NRFX_PPI_CHANNELS_USED 0
51 #endif
52
53 #ifndef NRFX_PPI_GROUPS_USED
54 #define NRFX_PPI_GROUPS_USED 0
55 #endif
56
57 #if PPI_CH_NUM > 16
58 #define NRFX_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFFFFFFFuL & ~(NRFX_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */
59 #define NRFX_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x000FFFFFuL & ~(NRFX_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */
60 #else
61 #define NRFX_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFF0FFFFuL & ~(NRFX_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */
62 #define NRFX_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x0000FFFFuL & ~(NRFX_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */
63 #endif
64
65 #define NRFX_PPI_ALL_APP_GROUPS_MASK (((1uL << PPI_GROUP_NUM) - 1) & ~(NRFX_PPI_GROUPS_USED)) /**< All PPI groups available to the application. */
66
67 /**
68 * @brief Function for uninitializing the PPI module.
69 *
70 * This function disables all channels and clears the channel groups.
71 */
72 void nrfx_ppi_free_all(void);
73
74 /**
75 * @brief Function for allocating a PPI channel.
76 * @details This function allocates the first unused PPI channel.
77 *
78 * @param[out] p_channel Pointer to the PPI channel that has been allocated.
79 *
80 * @retval NRFX_SUCCESS If the channel was successfully allocated.
81 * @retval NRFX_ERROR_NO_MEM If there is no available channel to be used.
82 */
83 nrfx_err_t nrfx_ppi_channel_alloc(nrf_ppi_channel_t * p_channel);
84
85 /**
86 * @brief Function for freeing a PPI channel.
87 * @details This function also disables the chosen channel.
88 *
89 * @param[in] channel PPI channel to be freed.
90 *
91 * @retval NRFX_SUCCESS If the channel was successfully freed.
92 * @retval NRFX_ERROR_INVALID_PARAM If the channel is not user-configurable.
93 */
94 nrfx_err_t nrfx_ppi_channel_free(nrf_ppi_channel_t channel);
95
96 /**
97 * @brief Function for assigning task and event endpoints to the PPI channel.
98 *
99 * @param[in] channel PPI channel to be assigned endpoints.
100 * @param[in] eep Event endpoint address.
101 * @param[in] tep Task endpoint address.
102 *
103 * @retval NRFX_SUCCESS If the channel was successfully assigned.
104 * @retval NRFX_ERROR_INVALID_STATE If the channel is not allocated for the user.
105 * @retval NRFX_ERROR_INVALID_PARAM If the channel is not user-configurable.
106 */
107 nrfx_err_t nrfx_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep);
108
109 /**
110 * @brief Function for assigning or clearing fork endpoint to the PPI channel.
111 *
112 * @param[in] channel PPI channel to be assigned endpoints.
113 * @param[in] fork_tep Fork task endpoint address or 0 to clear.
114 *
115 * @retval NRFX_SUCCESS If the channel was successfully assigned.
116 * @retval NRFX_ERROR_INVALID_STATE If the channel is not allocated for the user.
117 * @retval NRFX_ERROR_NOT_SUPPORTED If function is not supported.
118 */
119 nrfx_err_t nrfx_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep);
120
121 /**
122 * @brief Function for enabling a PPI channel.
123 *
124 * @param[in] channel PPI channel to be enabled.
125 *
126 * @retval NRFX_SUCCESS If the channel was successfully enabled.
127 * @retval NRFX_ERROR_INVALID_STATE If the user-configurable channel is not allocated.
128 * @retval NRFX_ERROR_INVALID_PARAM If the channel cannot be enabled by the user.
129 */
130 nrfx_err_t nrfx_ppi_channel_enable(nrf_ppi_channel_t channel);
131
132 /**
133 * @brief Function for disabling a PPI channel.
134 *
135 * @param[in] channel PPI channel to be disabled.
136 *
137 * @retval NRFX_SUCCESS If the channel was successfully disabled.
138 * @retval NRFX_ERROR_INVALID_STATE If the user-configurable channel is not allocated.
139 * @retval NRFX_ERROR_INVALID_PARAM If the channel cannot be disabled by the user.
140 */
141 nrfx_err_t nrfx_ppi_channel_disable(nrf_ppi_channel_t channel);
142
143 /**
144 * @brief Function for allocating a PPI channel group.
145 * @details This function allocates the first unused PPI group.
146 *
147 * @param[out] p_group Pointer to the PPI channel group that has been allocated.
148 *
149 * @retval NRFX_SUCCESS If the channel group was successfully allocated.
150 * @retval NRFX_ERROR_NO_MEM If there is no available channel group to be used.
151 */
152 nrfx_err_t nrfx_ppi_group_alloc(nrf_ppi_channel_group_t * p_group);
153
154 /**
155 * @brief Function for freeing a PPI channel group.
156 * @details This function also disables the chosen group.
157 *
158 * @param[in] group PPI channel group to be freed.
159 *
160 * @retval NRFX_SUCCESS If the channel group was successfully freed.
161 * @retval NRFX_ERROR_INVALID_PARAM If the channel group is not user-configurable.
162 */
163 nrfx_err_t nrfx_ppi_group_free(nrf_ppi_channel_group_t group);
164
165 /**
166 * @brief Compute a channel mask for NRF_PPI registers.
167 *
168 * @param[in] channel Channel number to transform to a mask.
169 *
170 * @retval Channel mask.
171 */
nrfx_ppi_channel_to_mask(nrf_ppi_channel_t channel)172 __STATIC_INLINE uint32_t nrfx_ppi_channel_to_mask(nrf_ppi_channel_t channel)
173 {
174 return (1uL << (uint32_t) channel);
175 }
176
177 /**
178 * @brief Function for including multiple PPI channels in a channel group.
179 *
180 * @param[in] channel_mask PPI channels to be added.
181 * @param[in] group Channel group in which to include the channels.
182 *
183 * @retval NRFX_SUCCESS If the channels was successfully included.
184 * @retval NRFX_ERROR_INVALID_PARAM If group is not an application group or channels are not an
185 * application channels.
186 * @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
187 */
188 nrfx_err_t nrfx_ppi_channels_include_in_group(uint32_t channel_mask,
189 nrf_ppi_channel_group_t group);
190
191 /**
192 * @brief Function for including a PPI channel in a channel group.
193 *
194 * @param[in] channel PPI channel to be added.
195 * @param[in] group Channel group in which to include the channel.
196 *
197 * @retval NRFX_SUCCESS If the channel was successfully included.
198 * @retval NRFX_ERROR_INVALID_PARAM If group is not an application group or channel is not an
199 * application channel.
200 * @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
201 */
nrfx_ppi_channel_include_in_group(nrf_ppi_channel_t channel,nrf_ppi_channel_group_t group)202 __STATIC_INLINE nrfx_err_t nrfx_ppi_channel_include_in_group(nrf_ppi_channel_t channel,
203 nrf_ppi_channel_group_t group)
204 {
205 return nrfx_ppi_channels_include_in_group(nrfx_ppi_channel_to_mask(channel), group);
206 }
207
208 /**
209 * @brief Function for removing multiple PPI channels from a channel group.
210 *
211 * @param[in] channel_mask PPI channels to be removed.
212 * @param[in] group Channel group from which to remove the channels.
213 *
214 * @retval NRFX_SUCCESS If the channel was successfully removed.
215 * @retval NRFX_ERROR_INVALID_PARAM If group is not an application group or channels are not an
216 * application channels.
217 * @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
218 */
219 nrfx_err_t nrfx_ppi_channels_remove_from_group(uint32_t channel_mask,
220 nrf_ppi_channel_group_t group);
221
222 /**
223 * @brief Function for removing a PPI channel from a channel group.
224 *
225 * @param[in] channel PPI channel to be removed.
226 * @param[in] group Channel group from which to remove the channel.
227 *
228 * @retval NRFX_SUCCESS If the channel was successfully removed.
229 * @retval NRFX_ERROR_INVALID_PARAM If group is not an application group or channel is not an
230 * application channel.
231 * @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
232 */
nrfx_ppi_channel_remove_from_group(nrf_ppi_channel_t channel,nrf_ppi_channel_group_t group)233 __STATIC_INLINE nrfx_err_t nrfx_ppi_channel_remove_from_group(nrf_ppi_channel_t channel,
234 nrf_ppi_channel_group_t group)
235 {
236 return nrfx_ppi_channels_remove_from_group(nrfx_ppi_channel_to_mask(channel), group);
237 }
238
239 /**
240 * @brief Function for clearing a PPI channel group.
241 *
242 * @param[in] group Channel group to be cleared.
243 *
244 * @retval NRFX_SUCCESS If the group was successfully cleared.
245 * @retval NRFX_ERROR_INVALID_PARAM If group is not an application group.
246 * @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
247 */
nrfx_ppi_group_clear(nrf_ppi_channel_group_t group)248 __STATIC_INLINE nrfx_err_t nrfx_ppi_group_clear(nrf_ppi_channel_group_t group)
249 {
250 return nrfx_ppi_channels_remove_from_group(NRFX_PPI_ALL_APP_CHANNELS_MASK, group);
251 }
252
253 /**
254 * @brief Function for enabling a PPI channel group.
255 *
256 * @param[in] group Channel group to be enabled.
257 *
258 * @retval NRFX_SUCCESS If the group was successfully enabled.
259 * @retval NRFX_ERROR_INVALID_PARAM If group is not an application group.
260 * @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
261 */
262 nrfx_err_t nrfx_ppi_group_enable(nrf_ppi_channel_group_t group);
263
264 /**
265 * @brief Function for disabling a PPI channel group.
266 *
267 * @param[in] group Channel group to be disabled.
268 *
269 * @retval NRFX_SUCCESS If the group was successfully disabled.
270 * @retval NRFX_ERROR_INVALID_PARAM If group is not an application group.
271 * @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
272 */
273 nrfx_err_t nrfx_ppi_group_disable(nrf_ppi_channel_group_t group);
274
275 /**
276 * @brief Function for getting the address of a PPI task.
277 *
278 * @param[in] task Task.
279 *
280 * @retval Task address.
281 */
nrfx_ppi_task_addr_get(nrf_ppi_task_t task)282 __STATIC_INLINE uint32_t nrfx_ppi_task_addr_get(nrf_ppi_task_t task)
283 {
284 return (uint32_t) nrf_ppi_task_address_get(task);
285 }
286
287 /**
288 * @brief Function for getting the address of a PPI group enable task.
289 *
290 * @param[in] group PPI channel group
291 *
292 * @retval Task address.
293 */
nrfx_ppi_task_addr_group_enable_get(nrf_ppi_channel_group_t group)294 __STATIC_INLINE uint32_t nrfx_ppi_task_addr_group_enable_get(nrf_ppi_channel_group_t group)
295 {
296 return (uint32_t) nrf_ppi_task_group_enable_address_get(group);
297 }
298
299 /**
300 * @brief Function for getting the address of a PPI group enable task.
301 *
302 * @param[in] group PPI channel group
303 *
304 * @retval Task address.
305 */
nrfx_ppi_task_addr_group_disable_get(nrf_ppi_channel_group_t group)306 __STATIC_INLINE uint32_t nrfx_ppi_task_addr_group_disable_get(nrf_ppi_channel_group_t group)
307 {
308 return (uint32_t) nrf_ppi_task_group_disable_address_get(group);
309 }
310
311 /** @} */
312
313 #ifdef __cplusplus
314 }
315 #endif
316
317 #endif // NRFX_PPI_H__
318