1 /*
2  * Copyright (c) 2019 - 2023, 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 NRFX_GPPI_H
35 #define NRFX_GPPI_H
36 
37 #include <nrfx.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * @defgroup nrfx_gppi Generic PPI layer
45  * @{
46  * @ingroup nrfx
47  * @ingroup nrf_dppi
48  * @ingroup nrf_ppi
49  *
50  * @brief Helper layer that provides the common functionality of PPI and DPPI drivers.
51  *
52  * Use PPI and DPPI drivers directly.
53  * This layer is provided only to help create generic code that can be built
54  * for SoCs equipped with either of these peripherals. When using this layer,
55  * take into account that there are significant differences between the PPI and DPPI
56  * interfaces that affect the behavior of this layer.
57  *
58  * One difference is that PPI allows associating of one task or event with
59  * more than one channel, whereas DPPI does not allow this. In DPPI, the second
60  * association overwrites the first one. Consequently, this helper layer cannot
61  * be used in applications that need to connect a task or event to multiple
62  * channels.
63  *
64  * Another difference is that in DPPI one channel can be associated with
65  * multiple tasks and multiple events, while in PPI this is not possible (with
66  * the exception of the association of a second task as a fork). Because of
67  * this difference, it is important to clear the previous endpoints of the channel that
68  * is to be reused with some different ones. Otherwise, the behavior of this
69  * helper layer will be different, depending on the actual interface used:
70  * in DPPI the channel configuration will be extended with the new endpoints, and
71  * in PPI the new endpoints will replace the previous ones.
72  */
73 
74 #if defined(PPI_PRESENT)
75 #include <nrfx_ppi.h>
76 
77 #define NRFX_GPPI_GROUP_NUM              PPI_GROUP_NUM
78 #define NRFX_GPPI_GROUPS_USED            NRFX_PPI_GROUPS_USED
79 #define NRFX_GPPI_ALL_APP_GROUPS_MASK    (((1uL << PPI_GROUP_NUM) - 1) & ~(NRFX_PPI_GROUPS_USED))
80 #define NRFX_GPPI_ALL_APP_CHANNELS_MASK  NRFX_PPI_ALL_APP_CHANNELS_MASK
81 #define NRFX_GPPI_PROG_APP_CHANNELS_MASK NRFX_PPI_PROG_APP_CHANNELS_MASK
82 
83 typedef enum
84 {
85     NRFX_GPPI_CHANNEL_GROUP0 = NRF_PPI_CHANNEL_GROUP0,
86     NRFX_GPPI_CHANNEL_GROUP1 = NRF_PPI_CHANNEL_GROUP1,
87     NRFX_GPPI_CHANNEL_GROUP2 = NRF_PPI_CHANNEL_GROUP2,
88     NRFX_GPPI_CHANNEL_GROUP3 = NRF_PPI_CHANNEL_GROUP3,
89 #if (PPI_GROUP_NUM > 4)
90     NRFX_GPPI_CHANNEL_GROUP4 = NRF_PPI_CHANNEL_GROUP4,
91     NRFX_GPPI_CHANNEL_GROUP5 = NRF_PPI_CHANNEL_GROUP5,
92 #endif
93 } nrfx_gppi_channel_group_t;
94 
95 typedef enum
96 {
97     NRFX_GPPI_TASK_CHG0_EN  = NRF_PPI_TASK_CHG0_EN,
98     NRFX_GPPI_TASK_CHG0_DIS = NRF_PPI_TASK_CHG0_DIS,
99     NRFX_GPPI_TASK_CHG1_EN  = NRF_PPI_TASK_CHG1_EN,
100     NRFX_GPPI_TASK_CHG1_DIS = NRF_PPI_TASK_CHG1_DIS,
101     NRFX_GPPI_TASK_CHG2_EN  = NRF_PPI_TASK_CHG2_EN,
102     NRFX_GPPI_TASK_CHG2_DIS = NRF_PPI_TASK_CHG2_DIS,
103     NRFX_GPPI_TASK_CHG3_EN  = NRF_PPI_TASK_CHG3_EN,
104     NRFX_GPPI_TASK_CHG3_DIS = NRF_PPI_TASK_CHG3_DIS,
105 #if (PPI_GROUP_NUM > 4)
106     NRFX_GPPI_TASK_CHG4_EN  = NRF_PPI_TASK_CHG4_EN,
107     NRFX_GPPI_TASK_CHG4_DIS = NRF_PPI_TASK_CHG4_DIS,
108     NRFX_GPPI_TASK_CHG5_EN  = NRF_PPI_TASK_CHG5_EN,
109     NRFX_GPPI_TASK_CHG5_DIS = NRF_PPI_TASK_CHG5_DIS
110 #endif
111 } nrfx_gppi_task_t;
112 
113 #elif defined(DPPI_PRESENT)
114 #include <haly/nrfy_dppi.h>
115 
116 #define NRFX_GPPI_GROUP_NUM              DPPI_GROUP_NUM
117 #define NRFX_GPPI_GROUPS_USED            NRFX_DPPI_GROUPS_USED
118 #define NRFX_GPPI_ALL_APP_GROUPS_MASK    (NRFX_BIT_MASK(DPPI_GROUP_NUM) & ~NRFX_DPPI_GROUPS_USED)
119 #define NRFX_GPPI_ALL_APP_CHANNELS_MASK  (NRFX_BIT_MASK(DPPI_CH_NUM) & ~NRFX_DPPI_CHANNELS_USED)
120 #if !defined(NRFX_GPPI_PROG_APP_CHANNELS_MASK)
121 #define NRFX_GPPI_PROG_APP_CHANNELS_MASK NRFX_GPPI_ALL_APP_CHANNELS_MASK
122 #endif
123 
124 typedef enum
125 {
126     NRFX_GPPI_CHANNEL_GROUP0 = NRF_DPPI_CHANNEL_GROUP0,
127     NRFX_GPPI_CHANNEL_GROUP1 = NRF_DPPI_CHANNEL_GROUP1,
128 #if DPPI_GROUP_NUM > 2
129     NRFX_GPPI_CHANNEL_GROUP2 = NRF_DPPI_CHANNEL_GROUP2,
130     NRFX_GPPI_CHANNEL_GROUP3 = NRF_DPPI_CHANNEL_GROUP3,
131     NRFX_GPPI_CHANNEL_GROUP4 = NRF_DPPI_CHANNEL_GROUP4,
132     NRFX_GPPI_CHANNEL_GROUP5 = NRF_DPPI_CHANNEL_GROUP5,
133 #endif
134 } nrfx_gppi_channel_group_t;
135 
136 typedef enum
137 {
138     NRFX_GPPI_TASK_CHG0_EN  = NRF_DPPI_TASK_CHG0_EN,
139     NRFX_GPPI_TASK_CHG0_DIS = NRF_DPPI_TASK_CHG0_DIS,
140     NRFX_GPPI_TASK_CHG1_EN  = NRF_DPPI_TASK_CHG1_EN,
141     NRFX_GPPI_TASK_CHG1_DIS = NRF_DPPI_TASK_CHG1_DIS,
142 #if DPPI_GROUP_NUM > 2
143     NRFX_GPPI_TASK_CHG2_EN  = NRF_DPPI_TASK_CHG2_EN,
144     NRFX_GPPI_TASK_CHG2_DIS = NRF_DPPI_TASK_CHG2_DIS,
145     NRFX_GPPI_TASK_CHG3_EN  = NRF_DPPI_TASK_CHG3_EN,
146     NRFX_GPPI_TASK_CHG3_DIS = NRF_DPPI_TASK_CHG3_DIS,
147     NRFX_GPPI_TASK_CHG4_EN  = NRF_DPPI_TASK_CHG4_EN,
148     NRFX_GPPI_TASK_CHG4_DIS = NRF_DPPI_TASK_CHG4_DIS,
149     NRFX_GPPI_TASK_CHG5_EN  = NRF_DPPI_TASK_CHG5_EN,
150     NRFX_GPPI_TASK_CHG5_DIS = NRF_DPPI_TASK_CHG5_DIS
151 #endif
152 } nrfx_gppi_task_t;
153 
154 #elif defined(__NRFX_DOXYGEN__)
155 
156 /** @brief Generic PPI channel groups. */
157 typedef enum
158 {
159     NRFX_GPPI_CHANNEL_GROUP0, /**< Channel group 0.*/
160     NRFX_GPPI_CHANNEL_GROUP1, /**< Channel group 1.*/
161 #if NRFX_GPPI_GROUP_NUM > 2 || defined(__NRFX_DOXYGEN__)
162     NRFX_GPPI_CHANNEL_GROUP2, /**< Channel group 2.*/
163     NRFX_GPPI_CHANNEL_GROUP3, /**< Channel group 3.*/
164     NRFX_GPPI_CHANNEL_GROUP4, /**< Channel group 4.*/
165     NRFX_GPPI_CHANNEL_GROUP5, /**< Channel group 5.*/
166 #endif
167 } nrfx_gppi_channel_group_t;
168 
169 /** @brief Generic PPI tasks. */
170 typedef enum
171 {
172     NRFX_GPPI_TASK_CHG0_EN,  /**< Task for enabling channel group 0 */
173     NRFX_GPPI_TASK_CHG0_DIS, /**< Task for disabling channel group 0 */
174     NRFX_GPPI_TASK_CHG1_EN,  /**< Task for enabling channel group 1 */
175     NRFX_GPPI_TASK_CHG1_DIS, /**< Task for disabling channel group 1 */
176 #if NRFX_GPPI_GROUP_NUM > 2 || defined(__NRFX_DOXYGEN__)
177     NRFX_GPPI_TASK_CHG2_EN,  /**< Task for enabling channel group 2 */
178     NRFX_GPPI_TASK_CHG2_DIS, /**< Task for disabling channel group 2 */
179     NRFX_GPPI_TASK_CHG3_EN,  /**< Task for enabling channel group 3 */
180     NRFX_GPPI_TASK_CHG3_DIS, /**< Task for disabling channel group 3 */
181     NRFX_GPPI_TASK_CHG4_EN,  /**< Task for enabling channel group 4 */
182     NRFX_GPPI_TASK_CHG4_DIS, /**< Task for disabling channel group 4 */
183     NRFX_GPPI_TASK_CHG5_EN,  /**< Task for enabling channel group 5 */
184     NRFX_GPPI_TASK_CHG5_DIS, /**< Task for disabling channel group 5 */
185 #endif
186 } nrfx_gppi_task_t;
187 #endif // defined(__NRFX_DOXYGEN__)
188 
189 /**
190  * @brief Function for checking if a given channel is enabled.
191  *
192  * @param[in] channel Channel to check.
193  *
194  * @retval true  The channel is enabled.
195  * @retval false The channel is not enabled.
196  */
197 bool nrfx_gppi_channel_check(uint8_t channel);
198 
199 /** @brief Function for disabling all channels. */
200 void nrfx_gppi_channels_disable_all(void);
201 
202 /**
203  * @brief Function for enabling multiple channels.
204  *
205  * The bits in @c mask value correspond to particular channels. This means that
206  * writing 1 to bit 0 enables channel 0, writing 1 to bit 1 enables channel 1, etc.
207  *
208  * @param[in] mask Channel mask.
209  */
210 void nrfx_gppi_channels_enable(uint32_t mask);
211 
212 /**
213  * @brief Function for disabling multiple channels.
214  *
215  * The bits in @c mask value correspond to particular channels. This means that
216  * writing 1 to bit 0 disables channel 0, writing 1 to bit 1 disables channel 1, etc.
217  *
218  * @param[in] mask Channel mask.
219  */
220 void nrfx_gppi_channels_disable(uint32_t mask);
221 
222 /**
223  * @brief Function for associating a given channel with the specified event register.
224  *
225  * This function sets the DPPI publish configuration for a given event
226  * or sets the PPI event endpoint register.
227  *
228  * @param[in] channel Channel to which to assign the event.
229  * @param[in] eep     Address of the event register.
230  */
231 void nrfx_gppi_event_endpoint_setup(uint8_t channel, uint32_t eep);
232 
233 /**
234  * @brief Function for associating a given channel with the specified task register.
235  *
236  * This function sets the DPPI subscribe configuration for a given task
237  * or sets the PPI task endpoint register.
238  *
239  * @param[in] channel Channel to which to assign the task.
240  * @param[in] tep     Address of the task register.
241  */
242 void nrfx_gppi_task_endpoint_setup(uint8_t channel, uint32_t tep);
243 
244 /**
245  * @brief Function for setting up the event and task endpoints for a given channel.
246  *
247  * @param[in] channel Channel to which the given endpoints are assigned.
248  * @param[in] eep     Address of the event register.
249  * @param[in] tep     Address of the task register.
250  */
251 void nrfx_gppi_channel_endpoints_setup(uint8_t channel, uint32_t eep, uint32_t tep);
252 
253 /**
254  * @brief Function for clearing the event and task endpoints for a given channel.
255  *
256  * @param[in] channel Channel to which the given endpoints are assigned.
257  * @param[in] eep     Address of the event register.
258  * @param[in] tep     Address of the task register.
259  */
260 void nrfx_gppi_channel_endpoints_clear(uint8_t  channel, uint32_t eep, uint32_t tep);
261 
262 /**
263  * @brief Function for clearing the DPPI publish configuration for a given event
264  * register or for clearing the PPI event endpoint register.
265  *
266  * @param[in] channel Channel for which to clear the event endpoint. Not used in DPPI.
267  * @param[in] eep     Address of the event register. Not used in PPI.
268  */
269 void nrfx_gppi_event_endpoint_clear(uint8_t channel, uint32_t eep);
270 
271 /**
272  * @brief Function for clearing the DPPI subscribe configuration for a given task
273  * register or for clearing the PPI task endpoint register.
274  *
275  * @param[in] channel Channel from which to disconnect the task enpoint. Not used in DPPI.
276  * @param[in] tep     Address of the task register. Not used in PPI.
277  */
278 void nrfx_gppi_task_endpoint_clear(uint8_t channel, uint32_t tep);
279 
280 #if defined(PPI_FEATURE_FORKS_PRESENT) || defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
281 /**
282  * @brief Function for setting up the task endpoint for a given PPI fork or for
283  * associating the DPPI channel with an additional task register.
284  *
285  * @param[in] channel  Channel to which the given fork endpoint is assigned.
286  * @param[in] fork_tep Address of the task register.
287  */
288 void nrfx_gppi_fork_endpoint_setup(uint8_t channel, uint32_t fork_tep);
289 
290 /**
291  * @brief Function for clearing the task endpoint for a given PPI fork or for clearing
292  * the DPPI subscribe register.
293  *
294  * @param[in] channel  Channel for which to clear the fork endpoint. Not used in DPPI.
295  * @param[in] fork_tep Address of the task register. Not used in PPI.
296  */
297 void nrfx_gppi_fork_endpoint_clear(uint8_t channel, uint32_t fork_tep);
298 #endif // defined(PPI_FEATURE_FORKS_PRESENT) || defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
299 
300 /**
301  * @brief Function for including multiple channels in a channel group.
302  *
303  * @param[in] channel_mask  Channels to be included in the group.
304  * @param[in] channel_group Channel group.
305  */
306 void nrfx_gppi_channels_include_in_group(uint32_t                  channel_mask,
307                                          nrfx_gppi_channel_group_t channel_group);
308 
309 /**
310  * @brief Function for removing multiple channels from a channel group.
311  *
312  * @param[in] channel_mask  Channels to be removed from the group.
313  * @param[in] channel_group Channel group.
314  */
315 void nrfx_gppi_channels_remove_from_group(uint32_t                  channel_mask,
316                                           nrfx_gppi_channel_group_t channel_group);
317 
318 /**
319  * @brief Function for removing all channels from a channel group.
320  *
321  * @param[in] channel_group Channel group.
322  */
323 void nrfx_gppi_group_clear(nrfx_gppi_channel_group_t channel_group);
324 
325 /**
326  * @brief Function for enabling a channel group.
327  *
328  * @param[in] channel_group Channel group.
329  */
330 void nrfx_gppi_group_enable(nrfx_gppi_channel_group_t channel_group);
331 
332 /**
333  * @brief Function for disabling a group.
334  *
335  * @param[in] channel_group Channel group.
336  */
337 void nrfx_gppi_group_disable(nrfx_gppi_channel_group_t channel_group);
338 
339 /**
340  * @brief Function for activating a task.
341  *
342  * @param[in] task Task to be activated.
343  */
344 void nrfx_gppi_task_trigger(nrfx_gppi_task_t task);
345 
346 /**
347  * @brief Function for returning the address of a specific task register.
348  *
349  * @param[in] task PPI or DPPI task.
350  *
351  * @return Address of the requested task register.
352  */
353 uint32_t nrfx_gppi_task_address_get(nrfx_gppi_task_t task);
354 
355 /**
356  * @brief Function for returning the address of a channel group disable task.
357  *
358  * @param[in] group Channel group.
359  *
360  * @return Disable task address of the specified group.
361  */
362 nrfx_gppi_task_t nrfx_gppi_group_disable_task_get(nrfx_gppi_channel_group_t group);
363 
364 /**
365  * @brief Function for returning the address of a channel group enable task.
366  *
367  * @param[in] group Channel group.
368  *
369  * @return Enable task address of the specified group.
370  */
371 nrfx_gppi_task_t nrfx_gppi_group_enable_task_get(nrfx_gppi_channel_group_t group);
372 
373 /**
374  * @brief Function for allocating a channel.
375  *
376  * @param[out] p_channel After successful allocation, index of the allocated channel.
377  *
378  * @retval NRFX_SUCCESS             Channel was successfully allocated.
379  * @retval NRFX_ERROR_NO_MEM        There is no available channel to be used.
380  * @retval NRFX_ERROR_NOT_SUPPORTED Driver is not enabled.
381  */
382 nrfx_err_t nrfx_gppi_channel_alloc(uint8_t * p_channel);
383 
384 /**
385  * @brief Function for freeing a channel.
386  *
387  * @param[in] channel (D)PPI channel to be freed.
388  *
389  * @retval NRFX_SUCCESS             The channel was successfully freed.
390  * @retval NRFX_ERROR_INVALID_PARAM The specified channel is not allocated or
391  *                                  is not user-configurable.
392  * @retval NRFX_ERROR_NOT_SUPPORTED Driver is not enabled.
393  */
394 nrfx_err_t nrfx_gppi_channel_free(uint8_t channel);
395 
396 /**
397  * @brief Function for allocating a channel group.
398  *
399  * @param[out] p_group Pointer to the (D)PPI channel group that has been allocated.
400  *
401  * @retval NRFX_SUCCESS             The channel group was successfully allocated.
402  * @retval NRFX_ERROR_NO_MEM        There is no available channel group to be used.
403  * @retval NRFX_ERROR_NOT_SUPPORTED Driver is not enabled.
404  */
405 nrfx_err_t nrfx_gppi_group_alloc(nrfx_gppi_channel_group_t * p_group);
406 
407 /**
408  * @brief Function for freeing a channel group.
409  *
410  * @param[in] group (D)PPI channel group to be freed.
411  *
412  * @retval NRFX_SUCCESS             The channel was successfully freed.
413  * @retval NRFX_ERROR_INVALID_PARAM The specified channel is not allocated or
414  *                                  is not user-configurable.
415  * @retval NRFX_ERROR_NOT_SUPPORTED Driver is not enabled.
416  */
417 nrfx_err_t nrfx_gppi_group_free(nrfx_gppi_channel_group_t group);
418 /** @} */
419 
420 #ifdef __cplusplus
421 }
422 #endif
423 
424 #endif // NRFX_GPPI_H
425