1 /*
2  * Copyright (c) 2019 - 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 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              NRF_DPPI_GROUP_NUM_MAX
117 #define NRFX_GPPI_GROUPS_USED            NRFX_DPPI_GROUPS_USED
118 #define NRFX_GPPI_ALL_APP_GROUPS_MASK    (NRFX_BIT_MASK(NRF_DPPI_GROUP_NUM_MAX) & \
119                                          ~NRFX_DPPI_GROUPS_USED)
120 #define NRFX_GPPI_ALL_APP_CHANNELS_MASK  (NRFX_BIT_MASK(NRF_DPPI_CH_NUM_MAX) & \
121                                          ~NRFX_DPPI_CHANNELS_USED)
122 #if defined(HALTIUM_XXAA) || defined(LUMOS_XXAA)
123 #define NRFX_GPPI_PROG_APP_CHANNELS_NUM  NRFX_BIT_SIZE(sizeof(uint32_t))
124 #define NRFX_GPPI_PROG_APP_CHANNELS_MASK NRFX_BIT_MASK(NRFX_GPPI_PROG_APP_CHANNELS_NUM)
125 #else
126 #define NRFX_GPPI_PROG_APP_CHANNELS_MASK NRFX_GPPI_ALL_APP_CHANNELS_MASK
127 #endif
128 
129 typedef enum
130 {
131     NRFX_GPPI_CHANNEL_GROUP0 = NRF_DPPI_CHANNEL_GROUP0,
132     NRFX_GPPI_CHANNEL_GROUP1 = NRF_DPPI_CHANNEL_GROUP1,
133 #if NRFX_GPPI_GROUP_NUM > 2
134     NRFX_GPPI_CHANNEL_GROUP2 = NRF_DPPI_CHANNEL_GROUP2,
135     NRFX_GPPI_CHANNEL_GROUP3 = NRF_DPPI_CHANNEL_GROUP3,
136 #endif
137 #if NRFX_GPPI_GROUP_NUM > 4
138     NRFX_GPPI_CHANNEL_GROUP4 = NRF_DPPI_CHANNEL_GROUP4,
139     NRFX_GPPI_CHANNEL_GROUP5 = NRF_DPPI_CHANNEL_GROUP5,
140 #endif
141 } nrfx_gppi_channel_group_t;
142 
143 typedef enum
144 {
145     NRFX_GPPI_TASK_CHG0_EN  = NRF_DPPI_TASK_CHG0_EN,
146     NRFX_GPPI_TASK_CHG0_DIS = NRF_DPPI_TASK_CHG0_DIS,
147     NRFX_GPPI_TASK_CHG1_EN  = NRF_DPPI_TASK_CHG1_EN,
148     NRFX_GPPI_TASK_CHG1_DIS = NRF_DPPI_TASK_CHG1_DIS,
149 #if NRFX_GPPI_GROUP_NUM > 2
150     NRFX_GPPI_TASK_CHG2_EN  = NRF_DPPI_TASK_CHG2_EN,
151     NRFX_GPPI_TASK_CHG2_DIS = NRF_DPPI_TASK_CHG2_DIS,
152     NRFX_GPPI_TASK_CHG3_EN  = NRF_DPPI_TASK_CHG3_EN,
153     NRFX_GPPI_TASK_CHG3_DIS = NRF_DPPI_TASK_CHG3_DIS,
154 #endif
155 #if NRFX_GPPI_GROUP_NUM > 4
156     NRFX_GPPI_TASK_CHG4_EN  = NRF_DPPI_TASK_CHG4_EN,
157     NRFX_GPPI_TASK_CHG4_DIS = NRF_DPPI_TASK_CHG4_DIS,
158     NRFX_GPPI_TASK_CHG5_EN  = NRF_DPPI_TASK_CHG5_EN,
159     NRFX_GPPI_TASK_CHG5_DIS = NRF_DPPI_TASK_CHG5_DIS
160 #endif
161 } nrfx_gppi_task_t;
162 
163 #elif defined(__NRFX_DOXYGEN__)
164 
165 /** @brief Generic PPI channel groups. */
166 typedef enum
167 {
168     NRFX_GPPI_CHANNEL_GROUP0, /**< Channel group 0.*/
169     NRFX_GPPI_CHANNEL_GROUP1, /**< Channel group 1.*/
170     NRFX_GPPI_CHANNEL_GROUP2, /**< Channel group 2.*/
171     NRFX_GPPI_CHANNEL_GROUP3, /**< Channel group 3.*/
172     NRFX_GPPI_CHANNEL_GROUP4, /**< Channel group 4.*/
173     NRFX_GPPI_CHANNEL_GROUP5, /**< Channel group 5.*/
174 } nrfx_gppi_channel_group_t;
175 
176 /** @brief Generic PPI tasks. */
177 typedef enum
178 {
179     NRFX_GPPI_TASK_CHG0_EN,  /**< Task for enabling channel group 0 */
180     NRFX_GPPI_TASK_CHG0_DIS, /**< Task for disabling channel group 0 */
181     NRFX_GPPI_TASK_CHG1_EN,  /**< Task for enabling channel group 1 */
182     NRFX_GPPI_TASK_CHG1_DIS, /**< Task for disabling channel group 1 */
183     NRFX_GPPI_TASK_CHG2_EN,  /**< Task for enabling channel group 2 */
184     NRFX_GPPI_TASK_CHG2_DIS, /**< Task for disabling channel group 2 */
185     NRFX_GPPI_TASK_CHG3_EN,  /**< Task for enabling channel group 3 */
186     NRFX_GPPI_TASK_CHG3_DIS, /**< Task for disabling channel group 3 */
187     NRFX_GPPI_TASK_CHG4_EN,  /**< Task for enabling channel group 4 */
188     NRFX_GPPI_TASK_CHG4_DIS, /**< Task for disabling channel group 4 */
189     NRFX_GPPI_TASK_CHG5_EN,  /**< Task for enabling channel group 5 */
190     NRFX_GPPI_TASK_CHG5_DIS, /**< Task for disabling channel group 5 */
191 } nrfx_gppi_task_t;
192 #endif // defined(__NRFX_DOXYGEN__)
193 
194 /**
195  * @brief Function for checking if a given channel is enabled.
196  *
197  * @param[in] channel Channel to check.
198  *
199  * @retval true  The channel is enabled.
200  * @retval false The channel is not enabled.
201  */
202 bool nrfx_gppi_channel_check(uint8_t channel);
203 
204 /** @brief Function for disabling all channels. */
205 void nrfx_gppi_channels_disable_all(void);
206 
207 /**
208  * @brief Function for enabling multiple channels.
209  *
210  * The bits in @c mask value correspond to particular channels. This means that
211  * writing 1 to bit 0 enables channel 0, writing 1 to bit 1 enables channel 1, etc.
212  *
213  * @param[in] mask Channel mask.
214  */
215 void nrfx_gppi_channels_enable(uint32_t mask);
216 
217 /**
218  * @brief Function for disabling multiple channels.
219  *
220  * The bits in @c mask value correspond to particular channels. This means that
221  * writing 1 to bit 0 disables channel 0, writing 1 to bit 1 disables channel 1, etc.
222  *
223  * @param[in] mask Channel mask.
224  */
225 void nrfx_gppi_channels_disable(uint32_t mask);
226 
227 /**
228  * @brief Function for associating a given channel with the specified event register.
229  *
230  * This function sets the DPPI publish configuration for a given event
231  * or sets the PPI event endpoint register.
232  *
233  * @param[in] channel Channel to which to assign the event.
234  * @param[in] eep     Address of the event register.
235  */
236 void nrfx_gppi_event_endpoint_setup(uint8_t channel, uint32_t eep);
237 
238 /**
239  * @brief Function for associating a given channel with the specified task register.
240  *
241  * This function sets the DPPI subscribe configuration for a given task
242  * or sets the PPI task endpoint register.
243  *
244  * @param[in] channel Channel to which to assign the task.
245  * @param[in] tep     Address of the task register.
246  */
247 void nrfx_gppi_task_endpoint_setup(uint8_t channel, uint32_t tep);
248 
249 /**
250  * @brief Function for setting up the event and task endpoints for a given channel.
251  *
252  * @param[in] channel Channel to which the given endpoints are assigned.
253  * @param[in] eep     Address of the event register.
254  * @param[in] tep     Address of the task register.
255  */
256 void nrfx_gppi_channel_endpoints_setup(uint8_t channel, uint32_t eep, uint32_t tep);
257 
258 /**
259  * @brief Function for clearing the event and task endpoints for a given channel.
260  *
261  * @param[in] channel Channel to which the given endpoints are assigned.
262  * @param[in] eep     Address of the event register.
263  * @param[in] tep     Address of the task register.
264  */
265 void nrfx_gppi_channel_endpoints_clear(uint8_t  channel, uint32_t eep, uint32_t tep);
266 
267 /**
268  * @brief Function for clearing the DPPI publish configuration for a given event
269  * register or for clearing the PPI event endpoint register.
270  *
271  * @param[in] channel Channel for which to clear the event endpoint. Not used in DPPI.
272  * @param[in] eep     Address of the event register. Not used in PPI.
273  */
274 void nrfx_gppi_event_endpoint_clear(uint8_t channel, uint32_t eep);
275 
276 /**
277  * @brief Function for clearing the DPPI subscribe configuration for a given task
278  * register or for clearing the PPI task endpoint register.
279  *
280  * @param[in] channel Channel from which to disconnect the task enpoint. Not used in DPPI.
281  * @param[in] tep     Address of the task register. Not used in PPI.
282  */
283 void nrfx_gppi_task_endpoint_clear(uint8_t channel, uint32_t tep);
284 
285 #if defined(PPI_FEATURE_FORKS_PRESENT) || defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
286 /**
287  * @brief Function for setting up the task endpoint for a given PPI fork or for
288  * associating the DPPI channel with an additional task register.
289  *
290  * @param[in] channel  Channel to which the given fork endpoint is assigned.
291  * @param[in] fork_tep Address of the task register.
292  */
293 void nrfx_gppi_fork_endpoint_setup(uint8_t channel, uint32_t fork_tep);
294 
295 /**
296  * @brief Function for clearing the task endpoint for a given PPI fork or for clearing
297  * the DPPI subscribe register.
298  *
299  * @param[in] channel  Channel for which to clear the fork endpoint. Not used in DPPI.
300  * @param[in] fork_tep Address of the task register. Not used in PPI.
301  */
302 void nrfx_gppi_fork_endpoint_clear(uint8_t channel, uint32_t fork_tep);
303 #endif // defined(PPI_FEATURE_FORKS_PRESENT) || defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
304 
305 /**
306  * @brief Function for setting multiple channels in a channel group.
307  *
308  * @param[in] channel_mask  Channels to be set in the group.
309  * @param[in] channel_group Channel group.
310  */
311 void nrfx_gppi_channels_group_set(uint32_t                  channel_mask,
312                                   nrfx_gppi_channel_group_t channel_group);
313 
314 /**
315  * @brief Function for including multiple channels in a channel group.
316  *
317  * @param[in] channel_mask  Channels to be included in the group.
318  * @param[in] channel_group Channel group.
319  */
320 void nrfx_gppi_channels_include_in_group(uint32_t                  channel_mask,
321                                          nrfx_gppi_channel_group_t channel_group);
322 
323 /**
324  * @brief Function for removing multiple channels from a channel group.
325  *
326  * @param[in] channel_mask  Channels to be removed from the group.
327  * @param[in] channel_group Channel group.
328  */
329 void nrfx_gppi_channels_remove_from_group(uint32_t                  channel_mask,
330                                           nrfx_gppi_channel_group_t channel_group);
331 
332 /**
333  * @brief Function for removing all channels from a channel group.
334  *
335  * @param[in] channel_group Channel group.
336  */
337 void nrfx_gppi_group_clear(nrfx_gppi_channel_group_t channel_group);
338 
339 /**
340  * @brief Function for enabling a channel group.
341  *
342  * @param[in] channel_group Channel group.
343  */
344 void nrfx_gppi_group_enable(nrfx_gppi_channel_group_t channel_group);
345 
346 /**
347  * @brief Function for disabling a group.
348  *
349  * @param[in] channel_group Channel group.
350  */
351 void nrfx_gppi_group_disable(nrfx_gppi_channel_group_t channel_group);
352 
353 /**
354  * @brief Function for activating a task.
355  *
356  * @param[in] task Task to be activated.
357  */
358 void nrfx_gppi_task_trigger(nrfx_gppi_task_t task);
359 
360 /**
361  * @brief Function for returning the address of a specific task register.
362  *
363  * @param[in] task PPI or DPPI task.
364  *
365  * @return Address of the requested task register.
366  */
367 uint32_t nrfx_gppi_task_address_get(nrfx_gppi_task_t task);
368 
369 /**
370  * @brief Function for returning the address of a channel group disable task.
371  *
372  * @param[in] group Channel group.
373  *
374  * @return Disable task address of the specified group.
375  */
376 nrfx_gppi_task_t nrfx_gppi_group_disable_task_get(nrfx_gppi_channel_group_t group);
377 
378 /**
379  * @brief Function for returning the address of a channel group enable task.
380  *
381  * @param[in] group Channel group.
382  *
383  * @return Enable task address of the specified group.
384  */
385 nrfx_gppi_task_t nrfx_gppi_group_enable_task_get(nrfx_gppi_channel_group_t group);
386 
387 /**
388  * @brief Function for allocating a channel.
389  *
390  * @param[out] p_channel After successful allocation, index of the allocated channel.
391  *
392  * @retval NRFX_SUCCESS             Channel was successfully allocated.
393  * @retval NRFX_ERROR_NO_MEM        There is no available channel to be used.
394  * @retval NRFX_ERROR_NOT_SUPPORTED Driver is not enabled.
395  */
396 nrfx_err_t nrfx_gppi_channel_alloc(uint8_t * p_channel);
397 
398 /**
399  * @brief Function for freeing a channel.
400  *
401  * @param[in] channel (D)PPI channel to be freed.
402  *
403  * @retval NRFX_SUCCESS             The channel was successfully freed.
404  * @retval NRFX_ERROR_INVALID_PARAM The specified channel is not allocated or
405  *                                  is not user-configurable.
406  * @retval NRFX_ERROR_NOT_SUPPORTED Driver is not enabled.
407  */
408 nrfx_err_t nrfx_gppi_channel_free(uint8_t channel);
409 
410 /**
411  * @brief Function for allocating a channel group.
412  *
413  * @param[out] p_group Pointer to the (D)PPI channel group that has been allocated.
414  *
415  * @retval NRFX_SUCCESS             The channel group was successfully allocated.
416  * @retval NRFX_ERROR_NO_MEM        There is no available channel group to be used.
417  * @retval NRFX_ERROR_NOT_SUPPORTED Driver is not enabled.
418  */
419 nrfx_err_t nrfx_gppi_group_alloc(nrfx_gppi_channel_group_t * p_group);
420 
421 /**
422  * @brief Function for freeing a channel group.
423  *
424  * @param[in] group (D)PPI channel group to be freed.
425  *
426  * @retval NRFX_SUCCESS             The channel was successfully freed.
427  * @retval NRFX_ERROR_INVALID_PARAM The specified channel is not allocated or
428  *                                  is not user-configurable.
429  * @retval NRFX_ERROR_NOT_SUPPORTED Driver is not enabled.
430  */
431 nrfx_err_t nrfx_gppi_group_free(nrfx_gppi_channel_group_t group);
432 /** @} */
433 
434 #ifdef __cplusplus
435 }
436 #endif
437 
438 #endif // NRFX_GPPI_H
439