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