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