LCOV - code coverage report
Current view: top level - home/jason/ncs-2.0.0/modules/hal/nordic/nrfx/drivers/src - nrfx_gpiote.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 17 425 4.0 %
Date: 2022-08-18 11:36:24 Functions: 3 60 5.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 290 0.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2015 - 2022, 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                 :            : #include <nrfx.h>
      34                 :            : 
      35                 :            : #if NRFX_CHECK(NRFX_GPIOTE_ENABLED)
      36                 :            : 
      37                 :            : #include <nrfx_gpiote.h>
      38                 :            : #include <helpers/nrfx_flag32_allocator.h>
      39                 :            : #include "nrf_bitmask.h"
      40                 :            : #include <string.h>
      41                 :            : 
      42                 :            : #define NRFX_LOG_MODULE GPIOTE
      43                 :            : #include <nrfx_log.h>
      44                 :            : 
      45                 :            : #if (GPIO_COUNT == 1)
      46                 :            : #define MAX_PIN_NUMBER 32
      47                 :            : #elif (GPIO_COUNT == 2)
      48                 :            : #define MAX_PIN_NUMBER (32 + P1_PIN_NUM)
      49                 :            : #else
      50                 :            : #error "Not supported."
      51                 :            : #endif
      52                 :            : 
      53                 :            : /* Use legacy configuration if new is not present. That will lead to slight
      54                 :            :  * increase of RAM usage since number of slots will exceed application need.
      55                 :            :  */
      56                 :            : #ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS
      57                 :            : #define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS \
      58                 :            :         (GPIOTE_CH_NUM + NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS)
      59                 :            : #endif
      60                 :            : 
      61                 :            : /* Verify that trigger matches gpiote enum. */
      62                 :            : NRFX_STATIC_ASSERT(NRFX_GPIOTE_TRIGGER_LOTOHI == GPIOTE_CONFIG_POLARITY_LoToHi);
      63                 :            : NRFX_STATIC_ASSERT(NRFX_GPIOTE_TRIGGER_HITOLO == GPIOTE_CONFIG_POLARITY_HiToLo);
      64                 :            : NRFX_STATIC_ASSERT(NRFX_GPIOTE_TRIGGER_TOGGLE == GPIOTE_CONFIG_POLARITY_Toggle);
      65                 :            : 
      66                 :            : /*
      67                 :            :  * 2 bytes are dedicated for each pin to store it's current state.
      68                 :            :  *
      69                 :            :  * +--------+-------+-----------------------+-----+--------+--------+---------+-------+
      70                 :            :  * | 0      | 1     | 2-4                   | 5   | 6      | 7      | 8-12    | 13-15 |
      71                 :            :  * +--------+-------+-----------------------+-----+--------+--------+---------+-------+
      72                 :            :  * | in use | dir   | nrfx_gpiote_trigger_t | te  | skip   | legacy |8:       | TE    |
      73                 :            :  * | 0: no  | 0:in  |                       | used| config | api    | present | index |
      74                 :            :  * | 1: yes | 1:out |                       |     |        |        |9-12:    | (when |
      75                 :            :  * |        |       |                       |     |        |        | handler |  used)|
      76                 :            :  * |        |       |                       |     |        |        | index   |       |
      77                 :            :  * +--------+-------+-----------------------+-----+--------+--------+---------+-------+
      78                 :            :  *
      79                 :            :  */
      80                 :            : 
      81                 :            : /* Flags content when pin is not used by the driver. */
      82                 :            : #define PIN_FLAG_NOT_USED 0
      83                 :            : 
      84                 :            : #define PIN_FLAG_IN_USE NRFX_BIT(0)
      85                 :            : 
      86                 :            : #define PIN_FLAG_DIR_MASK NRFX_BIT(1)
      87                 :            : 
      88                 :            : /* Flag indicating output direction. */
      89                 :            : #define PIN_FLAG_OUTPUT PIN_FLAG_DIR_MASK
      90                 :            : 
      91                 :            : /* Macro checks if pin is output. */
      92                 :            : #define PIN_FLAG_IS_OUTPUT(flags) ((flags & PIN_FLAG_DIR_MASK) == PIN_FLAG_OUTPUT)
      93                 :            : 
      94                 :            : /* Trigger mode field. It stores the information about a trigger type. If trigger
      95                 :            :  * is not enabled, it holds information about task usage and pin direction. */
      96                 :            : #define PIN_FLAG_TRIG_MODE_OFFSET 2
      97                 :            : #define PIN_FLAG_TRIG_MODE_BITS 3
      98                 :            : #define PIN_FLAG_TRIG_MODE_MASK \
      99                 :            :         (NRFX_BIT_MASK(PIN_FLAG_TRIG_MODE_BITS) << PIN_FLAG_TRIG_MODE_OFFSET)
     100                 :            : NRFX_STATIC_ASSERT(NRFX_GPIOTE_TRIGGER_MAX <= NRFX_BIT(PIN_FLAG_TRIG_MODE_BITS));
     101                 :            : 
     102                 :            : /* Macro sets trigger mode field. */
     103                 :            : #define PIN_FLAG_TRIG_MODE_SET(trigger) (trigger << PIN_FLAG_TRIG_MODE_OFFSET)
     104                 :            : 
     105                 :            : /* Macro gets trigger mode from pin flags. */
     106                 :            : #define PIN_FLAG_TRIG_MODE_GET(flags) \
     107                 :            :         (nrfx_gpiote_trigger_t)((flags & PIN_FLAG_TRIG_MODE_MASK) >> PIN_FLAG_TRIG_MODE_OFFSET)
     108                 :            : 
     109                 :            : #define PIN_FLAG_TE_USED        NRFX_BIT(5)
     110                 :            : #define PIN_FLAG_SKIP_CONFIG    NRFX_BIT(6)
     111                 :            : #define PIN_FLAG_LEGACY_API_PIN NRFX_BIT(7)
     112                 :            : 
     113                 :            : #define PIN_FLAG_HANDLER_PRESENT NRFX_BIT(8)
     114                 :            : 
     115                 :            : #define PIN_HANDLER_ID_SHIFT 9
     116                 :            : #define PIN_HANDLER_ID_BITS 4
     117                 :            : #define PIN_HANDLER_ID_MASK (NRFX_BIT_MASK(PIN_HANDLER_ID_BITS) << PIN_HANDLER_ID_SHIFT)
     118                 :            : #define PIN_HANDLER_MASK (PIN_FLAG_HANDLER_PRESENT | PIN_HANDLER_ID_MASK)
     119                 :            : 
     120                 :            : /* Macro for encoding handler index into the flags. */
     121                 :            : #define PIN_FLAG_HANDLER(x) \
     122                 :            :         (PIN_FLAG_HANDLER_PRESENT | ((x) << PIN_HANDLER_ID_SHIFT))
     123                 :            : 
     124                 :            : /* Pin in use but no handler attached. */
     125                 :            : #define PIN_FLAG_NO_HANDLER -1
     126                 :            : 
     127                 :            : /* Macro for getting handler index from flags. -1 is returned when no handler */
     128                 :            : #define PIN_GET_HANDLER_ID(flags) \
     129                 :            :         ((flags & PIN_FLAG_HANDLER_PRESENT) \
     130                 :            :          ? (int32_t)((flags & PIN_HANDLER_ID_MASK) >> PIN_HANDLER_ID_SHIFT) \
     131                 :            :          : PIN_FLAG_NO_HANDLER)
     132                 :            : 
     133                 :            : #define PIN_HANDLER_MAX_COUNT NRFX_BIT_MASK(PIN_HANDLER_ID_BITS)
     134                 :            : NRFX_STATIC_ASSERT(NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS <= PIN_HANDLER_MAX_COUNT);
     135                 :            : 
     136                 :            : #define PIN_TE_ID_SHIFT 13
     137                 :            : #define PIN_TE_ID_BITS 3
     138                 :            : #define PIN_TE_ID_MASK (NRFX_BIT_MASK(PIN_TE_ID_BITS) << PIN_TE_ID_SHIFT)
     139                 :            : 
     140                 :            : /* Validate that field is big enough for number of channels. */
     141                 :            : NRFX_STATIC_ASSERT((NRFX_BIT(PIN_TE_ID_BITS)) >= GPIOTE_CH_NUM);
     142                 :            : 
     143                 :            : /* Macro for encoding Task/Event index into the flags. */
     144                 :            : #define PIN_FLAG_TE_ID(x) \
     145                 :            :         (PIN_FLAG_TE_USED | (((x) << PIN_TE_ID_SHIFT) & PIN_TE_ID_MASK))
     146                 :            : 
     147                 :            : /* Macro for getting Task/Event index from flags. */
     148                 :            : #define PIN_GET_TE_ID(flags) ((flags & PIN_TE_ID_MASK) >> PIN_TE_ID_SHIFT)
     149                 :            : 
     150                 :            : /* Structure holding state of the pins */
     151                 :            : typedef struct
     152                 :            : {
     153                 :            :     /* Pin specific handlers. */
     154                 :            :     nrfx_gpiote_handler_config_t handlers[NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS];
     155                 :            : 
     156                 :            :     /* Global handler called on each event */
     157                 :            :     nrfx_gpiote_handler_config_t global_handler;
     158                 :            : 
     159                 :            :     /* Each pin state */
     160                 :            :     uint16_t                     pin_flags[MAX_PIN_NUMBER];
     161                 :            : 
     162                 :            :     /* Mask for tracking gpiote channel allocation. */
     163                 :            :     nrfx_atomic_t                available_channels_mask;
     164                 :            : 
     165                 :            :     /* Mask for tracking event handler entries allocation. */
     166                 :            :     nrfx_atomic_t                available_evt_handlers;
     167                 :            : 
     168                 :            : #if !defined(NRF_GPIO_LATCH_PRESENT)
     169                 :            :     uint32_t                     port_pins[GPIO_COUNT];
     170                 :            : #endif
     171                 :            :     nrfx_drv_state_t             state;
     172                 :            : } gpiote_control_block_t;
     173                 :            : 
     174                 :            : static gpiote_control_block_t m_cb = {
     175                 :            :     .available_channels_mask = NRFX_GPIOTE_APP_CHANNELS_MASK
     176                 :            : };
     177                 :            : 
     178                 :            : /** @brief Checks if pin is in use by the driver.
     179                 :            :  *
     180                 :            :  * @param[in] pin Absolute pin.
     181                 :            :  *
     182                 :            :  * @return True if pin is in use.
     183                 :            :  */
     184                 :          0 : static bool pin_in_use(uint32_t pin)
     185                 :            : {
     186                 :          0 :     return m_cb.pin_flags[pin] & PIN_FLAG_IN_USE;
     187                 :            : }
     188                 :            : 
     189                 :            : /** @brief Check if Task/Event is used.
     190                 :            :  *
     191                 :            :  * Assuming that pin is in use.
     192                 :            :  *
     193                 :            :  * @param[in] pin Absolute pin.
     194                 :            :  *
     195                 :            :  * @return True if pin uses GPIOTE task/event.
     196                 :            :  */
     197                 :          0 : static bool pin_in_use_by_te(uint32_t pin)
     198                 :            : {
     199                 :          0 :     return m_cb.pin_flags[pin] & PIN_FLAG_TE_USED;
     200                 :            : }
     201                 :            : 
     202                 :            : /** @brief Check if pin has trigger.
     203                 :            :  *
     204                 :            :  * @param[in] pin Absolute pin.
     205                 :            :  *
     206                 :            :  * @return True if pin has trigger.
     207                 :            :  */
     208                 :          0 : static bool pin_has_trigger(uint32_t pin)
     209                 :            : {
     210                 :          0 :     return PIN_FLAG_TRIG_MODE_GET(m_cb.pin_flags[pin]) != NRFX_GPIOTE_TRIGGER_NONE;
     211                 :            : }
     212                 :            : 
     213                 :            : /** @brief Check if pin is output.
     214                 :            :  *
     215                 :            :  * Assuming that pin is in use.
     216                 :            :  *
     217                 :            :  * @param[in] pin Absolute pin.
     218                 :            :  *
     219                 :            :  * @return True if pin is output.
     220                 :            :  */
     221                 :          0 : static bool pin_is_output(uint32_t pin)
     222                 :            : {
     223                 :          0 :     return PIN_FLAG_IS_OUTPUT(m_cb.pin_flags[pin]);
     224                 :            : }
     225                 :            : 
     226                 :            : /** @brief Check if pin is output controlled by GPIOTE task.
     227                 :            :  *
     228                 :            :  * @param[in] pin Absolute pin.
     229                 :            :  *
     230                 :            :  * @return True if pin is task output.
     231                 :            :  */
     232                 :          0 : static bool pin_is_task_output(uint32_t pin)
     233                 :            : {
     234   [ #  #  #  # ]:          0 :     return pin_is_output(pin) && pin_in_use_by_te(pin);
     235                 :            : }
     236                 :            : 
     237                 :            : /** @brief Check if pin is used by the driver and configured as input.
     238                 :            :  *
     239                 :            :  * @param[in] pin Absolute pin.
     240                 :            :  *
     241                 :            :  * @return True if pin is configured as input.
     242                 :            :  */
     243                 :          0 : static bool pin_is_input(uint32_t pin)
     244                 :            : {
     245                 :          0 :     return !pin_is_output(pin);
     246                 :            : }
     247                 :            : 
     248                 :            : /* Convert polarity enum (HAL) to trigger enum. */
     249                 :          0 : static nrfx_gpiote_trigger_t gpiote_polarity_to_trigger(nrf_gpiote_polarity_t polarity)
     250                 :            : {
     251                 :          0 :    return (nrfx_gpiote_trigger_t)polarity;
     252                 :            : }
     253                 :            : 
     254                 :            : /* Convert trigger enum to polarity enum (HAL). */
     255                 :          0 : static nrf_gpiote_polarity_t gpiote_trigger_to_polarity(nrfx_gpiote_trigger_t trigger)
     256                 :            : {
     257                 :          0 :     return (nrf_gpiote_polarity_t)trigger;
     258                 :            : }
     259                 :            : 
     260                 :            : /* Returns gpiote TE channel associated with the pin */
     261                 :          0 : static uint8_t pin_te_get(nrfx_gpiote_pin_t pin)
     262                 :            : {
     263                 :          0 :     return PIN_GET_TE_ID(m_cb.pin_flags[pin]);
     264                 :            : }
     265                 :            : 
     266                 :          0 : static bool is_level(nrfx_gpiote_trigger_t trigger)
     267                 :            : {
     268                 :          0 :         return trigger >= NRFX_GPIOTE_TRIGGER_LOW;
     269                 :            : }
     270                 :            : 
     271                 :          0 : static bool handler_in_use(int32_t handler_id)
     272                 :            : {
     273                 :            : 
     274         [ #  # ]:          0 :     for (uint32_t i = 0; i < MAX_PIN_NUMBER; i++)
     275                 :            :     {
     276   [ #  #  #  # ]:          0 :         if (PIN_GET_HANDLER_ID(m_cb.pin_flags[i]) == handler_id)
     277                 :            :         {
     278                 :          0 :             return true;
     279                 :            :         }
     280                 :            :     }
     281                 :            : 
     282                 :          0 :     return false;
     283                 :            : }
     284                 :            : 
     285                 :            : /* Function clears pin handler flag and releases handler slot if handler+context
     286                 :            :  * pair is not used by other pin. */
     287                 :          0 : static void release_handler(nrfx_gpiote_pin_t pin)
     288                 :            : {
     289         [ #  # ]:          0 :     int32_t handler_id = PIN_GET_HANDLER_ID(m_cb.pin_flags[pin]);
     290                 :            : 
     291         [ #  # ]:          0 :     if (handler_id == PIN_FLAG_NO_HANDLER)
     292                 :            :     {
     293                 :          0 :         return;
     294                 :            :     }
     295                 :            : 
     296                 :          0 :     m_cb.pin_flags[pin] &= ~PIN_HANDLER_MASK;
     297                 :            : 
     298                 :            :     /* Check if other pin is using same handler and release handler only if handler
     299                 :            :      * is not used by others.
     300                 :            :      */
     301         [ #  # ]:          0 :     if (!handler_in_use(handler_id))
     302                 :            :     {
     303                 :          0 :         m_cb.handlers[handler_id].handler = NULL;
     304                 :          0 :         nrfx_err_t err = nrfx_flag32_free(&m_cb.available_evt_handlers, handler_id);
     305                 :            :         (void)err;
     306         [ #  # ]:          0 :         NRFX_ASSERT(err == NRFX_SUCCESS);
     307                 :            :     }
     308                 :            : }
     309                 :            : 
     310                 :            : /* Function releases the handler associated with the pin and sets GPIOTE channel
     311                 :            :  * configuration to default if it was used with the pin.
     312                 :            :  */
     313                 :          0 : static void pin_handler_trigger_uninit(nrfx_gpiote_pin_t pin)
     314                 :            : {
     315         [ #  # ]:          0 :     if (pin_in_use_by_te(pin))
     316                 :            :     {
     317                 :            :         /* te to default */
     318                 :          0 :         nrf_gpiote_te_default(NRF_GPIOTE, pin_te_get(pin));
     319                 :            :     }
     320                 :            :     else
     321                 :            :     {
     322                 :            : #if !defined(NRF_GPIO_LATCH_PRESENT)
     323                 :            :         nrf_bitmask_bit_clear(pin, (uint8_t *)m_cb.port_pins);
     324                 :            : #endif
     325                 :            :     }
     326                 :            : 
     327                 :          0 :     release_handler(pin);
     328                 :          0 :     m_cb.pin_flags[pin] = PIN_FLAG_NOT_USED;
     329                 :          0 : }
     330                 :            : 
     331                 :          0 : nrfx_err_t nrfx_gpiote_pin_uninit(nrfx_gpiote_pin_t pin)
     332                 :            : {
     333         [ #  # ]:          0 :     if (!pin_in_use(pin))
     334                 :            :     {
     335                 :          0 :         return NRFX_ERROR_INVALID_PARAM;
     336                 :            :     }
     337                 :            : 
     338                 :          0 :     nrfx_gpiote_trigger_disable(pin);
     339                 :          0 :     pin_handler_trigger_uninit(pin);
     340                 :          0 :     nrf_gpio_cfg_default(pin);
     341                 :            : 
     342                 :          0 :     return NRFX_SUCCESS;
     343                 :            : }
     344                 :            : 
     345                 :          0 : static int32_t find_handler(nrfx_gpiote_interrupt_handler_t handler, void * p_context)
     346                 :            : {
     347         [ #  # ]:          0 :     for (uint32_t i = 0; i < NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS; i++)
     348                 :            :     {
     349   [ #  #  #  # ]:          0 :         if ((m_cb.handlers[i].handler == handler) && (m_cb.handlers[i].p_context == p_context))
     350                 :            :         {
     351                 :          0 :             return i;
     352                 :            :         }
     353                 :            :     }
     354                 :            : 
     355                 :          0 :     return -1;
     356                 :            : }
     357                 :            : 
     358                 :            : /** @brief Set new handler, if handler was not previously set allocate it. */
     359                 :          0 : static nrfx_err_t pin_handler_set(nrfx_gpiote_pin_t               pin,
     360                 :            :                                   nrfx_gpiote_interrupt_handler_t handler,
     361                 :            :                                   void *                          p_context)
     362                 :            : {
     363                 :            :     nrfx_err_t err;
     364                 :            :     int32_t handler_id;
     365                 :            : 
     366                 :          0 :     release_handler(pin);
     367         [ #  # ]:          0 :     if (!handler)
     368                 :            :     {
     369                 :          0 :         return NRFX_SUCCESS;
     370                 :            :     }
     371                 :            : 
     372                 :          0 :     handler_id = find_handler(handler, p_context);
     373                 :            :     /* Handler not found, new must be allocated. */
     374         [ #  # ]:          0 :     if (handler_id < 0)
     375                 :            :     {
     376                 :            :         uint8_t id;
     377                 :            : 
     378                 :          0 :         err = nrfx_flag32_alloc(&m_cb.available_evt_handlers, &id);
     379         [ #  # ]:          0 :         if (err != NRFX_SUCCESS)
     380                 :            :         {
     381                 :          0 :             return err;
     382                 :            :         }
     383                 :          0 :         handler_id = (int32_t)id;
     384                 :            :     }
     385                 :            : 
     386                 :          0 :     m_cb.handlers[handler_id].handler = handler;
     387                 :          0 :     m_cb.handlers[handler_id].p_context = p_context;
     388                 :          0 :     m_cb.pin_flags[pin] |= PIN_FLAG_HANDLER(handler_id);
     389                 :            : 
     390                 :          0 :     return NRFX_SUCCESS;
     391                 :            : }
     392                 :            : 
     393                 :          0 : static inline nrf_gpio_pin_sense_t get_initial_sense(nrfx_gpiote_pin_t pin)
     394                 :            : {
     395                 :          0 :     nrfx_gpiote_trigger_t trigger = PIN_FLAG_TRIG_MODE_GET(m_cb.pin_flags[pin]);
     396                 :            :     nrf_gpio_pin_sense_t sense;
     397                 :            : 
     398         [ #  # ]:          0 :     if (trigger == NRFX_GPIOTE_TRIGGER_LOW)
     399                 :            :     {
     400                 :          0 :         sense = NRF_GPIO_PIN_SENSE_LOW;
     401                 :            :     }
     402         [ #  # ]:          0 :     else if (trigger == NRFX_GPIOTE_TRIGGER_HIGH)
     403                 :            :     {
     404                 :          0 :         sense = NRF_GPIO_PIN_SENSE_HIGH;
     405                 :            :     }
     406                 :            :     else
     407                 :            :     {
     408                 :            :         /* If edge detection start with sensing opposite state. */
     409         [ #  # ]:          0 :         sense = nrf_gpio_pin_read(pin) ? NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;
     410                 :            :     }
     411                 :            : 
     412                 :          0 :     return sense;
     413                 :            : }
     414                 :            : 
     415                 :          0 : nrfx_err_t nrfx_gpiote_input_configure(nrfx_gpiote_pin_t                    pin,
     416                 :            :                                        nrfx_gpiote_input_config_t const *   p_input_config,
     417                 :            :                                        nrfx_gpiote_trigger_config_t const * p_trigger_config,
     418                 :            :                                        nrfx_gpiote_handler_config_t const * p_handler_config)
     419                 :            : {
     420                 :            :     nrfx_err_t err;
     421                 :            : 
     422         [ #  # ]:          0 :     if (p_input_config)
     423                 :            :     {
     424         [ #  # ]:          0 :         if (pin_is_task_output(pin))
     425                 :            :         {
     426                 :          0 :             return NRFX_ERROR_INVALID_PARAM;
     427                 :            :         }
     428                 :            : 
     429                 :          0 :         nrf_gpio_pin_dir_t dir = NRF_GPIO_PIN_DIR_INPUT;
     430                 :          0 :         nrf_gpio_pin_input_t input_connect = NRF_GPIO_PIN_INPUT_CONNECT;
     431                 :            : 
     432                 :          0 :         nrf_gpio_reconfigure(pin, &dir, &input_connect, &p_input_config->pull, NULL, NULL);
     433                 :            : 
     434                 :          0 :         m_cb.pin_flags[pin] &= ~PIN_FLAG_OUTPUT;
     435                 :          0 :         m_cb.pin_flags[pin] |= PIN_FLAG_IN_USE;
     436                 :            :     }
     437                 :            : 
     438         [ #  # ]:          0 :     if (p_trigger_config)
     439                 :            :     {
     440                 :          0 :         nrfx_gpiote_trigger_t trigger = p_trigger_config->trigger;
     441                 :          0 :         bool use_evt = p_trigger_config->p_in_channel ? true : false;
     442                 :            : 
     443         [ #  # ]:          0 :         if (pin_is_output(pin))
     444                 :            :         {
     445         [ #  # ]:          0 :             if (use_evt)
     446                 :            :             {
     447                 :          0 :                 return NRFX_ERROR_INVALID_PARAM;
     448                 :            :             }
     449                 :            :         }
     450                 :            :         else
     451                 :            :         {
     452                 :          0 :             m_cb.pin_flags[pin] &= ~(PIN_TE_ID_MASK | PIN_FLAG_TE_USED);
     453         [ #  # ]:          0 :             if (use_evt)
     454                 :            :             {
     455                 :          0 :                 bool edge = trigger <= NRFX_GPIOTE_TRIGGER_TOGGLE;
     456                 :            : 
     457                 :            :                 /* IN event used. */
     458         [ #  # ]:          0 :                 if (!edge)
     459                 :            :                 {
     460                 :            :                     /* IN event supports only edge trigger. */
     461                 :          0 :                     return NRFX_ERROR_INVALID_PARAM;
     462                 :            :                 }
     463                 :            : 
     464                 :          0 :                 uint8_t ch = *p_trigger_config->p_in_channel;
     465                 :            : 
     466         [ #  # ]:          0 :                 if (trigger == NRFX_GPIOTE_TRIGGER_NONE)
     467                 :            :                 {
     468                 :          0 :                     nrf_gpiote_te_default(NRF_GPIOTE, ch);
     469                 :            :                 }
     470                 :            :                 else
     471                 :            :                 {
     472                 :          0 :                     nrf_gpiote_polarity_t polarity = gpiote_trigger_to_polarity(trigger);
     473                 :            : 
     474                 :          0 :                     nrf_gpiote_event_disable(NRF_GPIOTE, ch);
     475                 :          0 :                     nrf_gpiote_event_configure(NRF_GPIOTE, ch, pin, polarity);
     476                 :            : 
     477                 :          0 :                     m_cb.pin_flags[pin] |= PIN_FLAG_TE_ID(ch);
     478                 :            :                 }
     479                 :            :             }
     480                 :            :         }
     481                 :            : #if !defined(NRF_GPIO_LATCH_PRESENT)
     482                 :            :         if (use_evt || trigger == NRFX_GPIOTE_TRIGGER_NONE)
     483                 :            :         {
     484                 :            :             nrf_bitmask_bit_clear(pin, (uint8_t *)m_cb.port_pins);
     485                 :            :         }
     486                 :            :         else
     487                 :            :         {
     488                 :            :             nrf_bitmask_bit_set(pin, (uint8_t *)m_cb.port_pins);
     489                 :            :         }
     490                 :            : #endif
     491                 :          0 :         m_cb.pin_flags[pin] &= ~PIN_FLAG_TRIG_MODE_MASK;
     492                 :          0 :         m_cb.pin_flags[pin] |= PIN_FLAG_TRIG_MODE_SET(trigger);
     493                 :            :     }
     494                 :            : 
     495         [ #  # ]:          0 :     if (p_handler_config)
     496                 :            :     {
     497                 :          0 :         err = pin_handler_set(pin, p_handler_config->handler, p_handler_config->p_context);
     498                 :            :     }
     499                 :            :     else
     500                 :            :     {
     501                 :          0 :         err = NRFX_SUCCESS;
     502                 :            :     }
     503                 :            : 
     504                 :          0 :     return err;
     505                 :            : }
     506                 :            : 
     507                 :          0 : nrfx_err_t nrfx_gpiote_output_configure(nrfx_gpiote_pin_t                   pin,
     508                 :            :                                         nrfx_gpiote_output_config_t const * p_config,
     509                 :            :                                         nrfx_gpiote_task_config_t const *   p_task_config)
     510                 :            : {
     511         [ #  # ]:          0 :     if (p_config)
     512                 :            :     {
     513                 :            :         /* Cannot configure pin to output if pin was using TE event. */
     514   [ #  #  #  # ]:          0 :         if (pin_is_input(pin) && pin_in_use_by_te(pin))
     515                 :            :         {
     516                 :          0 :             return NRFX_ERROR_INVALID_PARAM;
     517                 :            :         }
     518                 :            : 
     519                 :            :         /* If reconfiguring to output pin that has trigger configured then accept
     520                 :            :          * only when input is still connected. */
     521   [ #  #  #  # ]:          0 :         if (pin_has_trigger(pin) && (p_config->input_connect == NRF_GPIO_PIN_INPUT_DISCONNECT))
     522                 :            :         {
     523                 :          0 :             return NRFX_ERROR_INVALID_PARAM;
     524                 :            :         }
     525                 :            : 
     526                 :          0 :         nrf_gpio_pin_dir_t dir = NRF_GPIO_PIN_DIR_OUTPUT;
     527                 :            : 
     528                 :          0 :         nrf_gpio_reconfigure(pin, &dir, &p_config->input_connect, &p_config->pull,
     529                 :            :                              &p_config->drive, NULL);
     530                 :            : 
     531                 :          0 :         m_cb.pin_flags[pin] |= PIN_FLAG_IN_USE | PIN_FLAG_OUTPUT;
     532                 :            :     }
     533                 :            : 
     534         [ #  # ]:          0 :     if (p_task_config)
     535                 :            :     {
     536         [ #  # ]:          0 :         if (pin_is_input(pin))
     537                 :            :         {
     538                 :          0 :             return NRFX_ERROR_INVALID_PARAM;
     539                 :            :         }
     540                 :            : 
     541                 :          0 :         uint32_t ch = p_task_config->task_ch;
     542                 :            : 
     543                 :          0 :         nrf_gpiote_te_default(NRF_GPIOTE, ch);
     544                 :          0 :         m_cb.pin_flags[pin] &= ~(PIN_FLAG_TE_USED | PIN_TE_ID_MASK);
     545         [ #  # ]:          0 :         if (p_task_config->polarity != NRF_GPIOTE_POLARITY_NONE)
     546                 :            :         {
     547                 :          0 :             nrf_gpiote_task_configure(NRF_GPIOTE, ch, pin,
     548                 :            :                                       p_task_config->polarity,
     549                 :            :                                       p_task_config->init_val);
     550                 :          0 :             m_cb.pin_flags[pin] |= PIN_FLAG_TE_ID(ch);
     551                 :            :         }
     552                 :            :     }
     553                 :            : 
     554                 :          0 :     return NRFX_SUCCESS;
     555                 :            : }
     556                 :            : 
     557                 :          1 : void nrfx_gpiote_global_callback_set(nrfx_gpiote_interrupt_handler_t handler, void * p_context)
     558                 :            : {
     559                 :          1 :     m_cb.global_handler.handler = handler;
     560                 :          1 :     m_cb.global_handler.p_context = p_context;
     561                 :          1 : }
     562                 :            : 
     563                 :          0 : nrfx_err_t nrfx_gpiote_channel_get(nrfx_gpiote_pin_t pin, uint8_t *p_channel)
     564                 :            : {
     565         [ #  # ]:          0 :     NRFX_ASSERT(p_channel);
     566                 :            : 
     567         [ #  # ]:          0 :     if (pin_in_use_by_te(pin))
     568                 :            :     {
     569                 :          0 :         *p_channel = PIN_GET_TE_ID(m_cb.pin_flags[pin]);
     570                 :          0 :         return NRFX_SUCCESS;
     571                 :            :     }
     572                 :            :     else
     573                 :            :     {
     574                 :          0 :         return NRFX_ERROR_INVALID_PARAM;
     575                 :            :     }
     576                 :            : }
     577                 :            : 
     578                 :            : /* Return handler associated with given pin or null. */
     579                 :          0 : static nrfx_gpiote_handler_config_t const * channel_handler_get(nrfx_gpiote_pin_t pin)
     580                 :            : {
     581         [ #  # ]:          0 :     int32_t handler_id = PIN_GET_HANDLER_ID(m_cb.pin_flags[pin]);
     582                 :            : 
     583         [ #  # ]:          0 :     if (handler_id == PIN_FLAG_NO_HANDLER)
     584                 :            :     {
     585                 :          0 :         return NULL;
     586                 :            :     }
     587                 :            : 
     588                 :          0 :     return &m_cb.handlers[handler_id];
     589                 :            : }
     590                 :            : 
     591                 :          1 : nrfx_err_t nrfx_gpiote_init(uint8_t interrupt_priority)
     592                 :            : {
     593                 :            :     nrfx_err_t err_code;
     594                 :            : 
     595         [ -  + ]:          1 :     if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
     596                 :            :     {
     597                 :          0 :         err_code = NRFX_ERROR_INVALID_STATE;
     598         [ #  # ]:          0 :         NRFX_LOG_WARNING("Function: %s, error code: %s.",
     599                 :            :                          __func__,
     600                 :            :                          NRFX_LOG_ERROR_STRING_GET(err_code));
     601                 :          0 :         return err_code;
     602                 :            :     }
     603                 :            : 
     604                 :          1 :     memset(m_cb.pin_flags, 0, sizeof(m_cb.pin_flags));
     605                 :            : 
     606                 :            :     NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(NRF_GPIOTE), interrupt_priority);
     607                 :          1 :     NRFX_IRQ_ENABLE(nrfx_get_irq_number(NRF_GPIOTE));
     608                 :            : 
     609                 :          1 :     nrf_gpiote_event_clear(NRF_GPIOTE, NRF_GPIOTE_EVENT_PORT);
     610                 :          1 :     nrf_gpiote_int_enable(NRF_GPIOTE, (uint32_t)NRF_GPIOTE_INT_PORT_MASK);
     611                 :          1 :     m_cb.state = NRFX_DRV_STATE_INITIALIZED;
     612                 :          1 :     m_cb.available_evt_handlers = NRFX_BIT_MASK(NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS);
     613                 :            : 
     614                 :          1 :     err_code = NRFX_SUCCESS;
     615         [ +  - ]:          1 :     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
     616                 :          1 :     return err_code;
     617                 :            : }
     618                 :            : 
     619                 :            : 
     620                 :          2 : bool nrfx_gpiote_is_init(void)
     621                 :            : {
     622                 :          2 :     return (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED) ? true : false;
     623                 :            : }
     624                 :            : 
     625                 :            : 
     626                 :          0 : void nrfx_gpiote_uninit(void)
     627                 :            : {
     628         [ #  # ]:          0 :     NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
     629                 :            : 
     630                 :            :     uint32_t i;
     631                 :            : 
     632         [ #  # ]:          0 :     for (i = 0; i < MAX_PIN_NUMBER; i++)
     633                 :            :     {
     634   [ #  #  #  # ]:          0 :         if (nrf_gpio_pin_present_check(i) && pin_in_use(i))
     635                 :            :         {
     636         [ #  # ]:          0 :             if (m_cb.pin_flags[i] & PIN_FLAG_LEGACY_API_PIN)
     637                 :            :             {
     638                 :          0 :                 m_cb.pin_flags[i] &= ~PIN_FLAG_LEGACY_API_PIN;
     639         [ #  # ]:          0 :                 if (pin_has_trigger(i))
     640                 :            :                 {
     641                 :          0 :                     nrfx_gpiote_in_uninit(i);
     642                 :            :                 }
     643                 :            :                 else
     644                 :            :                 {
     645                 :          0 :                     nrfx_gpiote_out_uninit(i);
     646                 :            :                 }
     647                 :            :             }
     648                 :            :             else
     649                 :            :             {
     650                 :          0 :                 nrfx_gpiote_pin_uninit(i);
     651                 :            :             }
     652                 :            :         }
     653                 :            :     }
     654                 :          0 :     m_cb.state = NRFX_DRV_STATE_UNINITIALIZED;
     655         [ #  # ]:          0 :     NRFX_LOG_INFO("Uninitialized.");
     656                 :          0 : }
     657                 :            : 
     658                 :          0 : nrfx_err_t nrfx_gpiote_channel_free(uint8_t channel)
     659                 :            : {
     660                 :          0 :     return nrfx_flag32_free(&m_cb.available_channels_mask, channel);
     661                 :            : }
     662                 :            : 
     663                 :          0 : nrfx_err_t nrfx_gpiote_channel_alloc(uint8_t * p_channel)
     664                 :            : {
     665                 :          0 :     return nrfx_flag32_alloc(&m_cb.available_channels_mask, p_channel);
     666                 :            : }
     667                 :            : 
     668                 :          0 : nrfx_err_t nrfx_gpiote_out_init(nrfx_gpiote_pin_t                pin,
     669                 :            :                                 nrfx_gpiote_out_config_t const * p_config)
     670                 :            : {
     671                 :            :     uint8_t ch;
     672                 :            :     nrfx_err_t err;
     673                 :            : 
     674         [ #  # ]:          0 :     if (p_config->task_pin)
     675                 :            :     {
     676                 :          0 :         err = nrfx_gpiote_channel_alloc(&ch);
     677         [ #  # ]:          0 :         if (err != NRFX_SUCCESS)
     678                 :            :         {
     679                 :          0 :             return err;
     680                 :            :         }
     681                 :            :     }
     682                 :            :     else
     683                 :            :     {
     684                 :            :         /* Value will not be used. */
     685                 :          0 :         ch = 0xFF;
     686                 :            :     }
     687                 :            : 
     688                 :          0 :     err = nrfx_gpiote_out_prealloc_init(pin, p_config, ch);
     689   [ #  #  #  # ]:          0 :     if (err == NRFX_ERROR_BUSY && p_config->task_pin)
     690                 :            :     {
     691                 :          0 :         nrfx_gpiote_channel_free(ch);
     692                 :            :     }
     693                 :            : 
     694                 :          0 :     return err;
     695                 :            : }
     696                 :            : 
     697                 :          0 : nrfx_err_t nrfx_gpiote_out_prealloc_init(nrfx_gpiote_pin_t                pin,
     698                 :            :                                          nrfx_gpiote_out_config_t const * p_config,
     699                 :            :                                          uint8_t                          channel)
     700                 :            : {
     701                 :          0 :     nrfx_gpiote_output_config_t config = NRFX_GPIOTE_DEFAULT_OUTPUT_CONFIG;
     702                 :            :     nrfx_gpiote_task_config_t task_config;
     703                 :          0 :     bool use_task = p_config->task_pin;
     704                 :            :     nrfx_err_t err;
     705                 :            : 
     706         [ #  # ]:          0 :     if (pin_in_use(pin))
     707                 :            :     {
     708                 :          0 :         return NRFX_ERROR_BUSY;
     709                 :            :     }
     710                 :            : 
     711         [ #  # ]:          0 :     if (p_config->init_state == NRF_GPIOTE_INITIAL_VALUE_HIGH)
     712                 :            :     {
     713                 :          0 :         nrf_gpio_pin_set(pin);
     714                 :            :     }
     715                 :            : 
     716         [ #  # ]:          0 :     if (use_task)
     717                 :            :     {
     718                 :            : 
     719                 :          0 :         task_config.task_ch = channel;
     720                 :          0 :         task_config.init_val = p_config->init_state;
     721                 :          0 :         task_config.polarity = p_config->action;
     722                 :            :     }
     723                 :            : 
     724         [ #  # ]:          0 :     err = nrfx_gpiote_output_configure(pin, &config, use_task ? &task_config : NULL);
     725         [ #  # ]:          0 :     if (err == NRFX_SUCCESS)
     726                 :            :     {
     727                 :          0 :         m_cb.pin_flags[pin] |= PIN_FLAG_LEGACY_API_PIN;
     728                 :            :     }
     729                 :            : 
     730                 :          0 :     return err;
     731                 :            : }
     732                 :            : 
     733                 :          0 : void nrfx_gpiote_out_uninit(nrfx_gpiote_pin_t pin)
     734                 :            : {
     735         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     736         [ #  # ]:          0 :     NRFX_ASSERT(pin_in_use(pin));
     737                 :            : 
     738         [ #  # ]:          0 :     uint8_t ch = pin_in_use_by_te(pin) ? pin_te_get(pin) : 0xFF;
     739                 :            : 
     740                 :          0 :     nrfx_err_t err = nrfx_gpiote_pin_uninit(pin);
     741         [ #  # ]:          0 :     NRFX_ASSERT(err == NRFX_SUCCESS);
     742                 :            : 
     743         [ #  # ]:          0 :     if (ch != 0xFF)
     744                 :            :     {
     745                 :          0 :         nrfx_gpiote_channel_free(ch);
     746                 :            :     }
     747                 :            : 
     748                 :            :     (void)err;
     749                 :          0 : }
     750                 :            : 
     751                 :            : 
     752                 :          0 : void nrfx_gpiote_out_set(nrfx_gpiote_pin_t pin)
     753                 :            : {
     754         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     755   [ #  #  #  # ]:          0 :     NRFX_ASSERT(pin_is_output(pin) && !pin_in_use_by_te(pin));
     756                 :            : 
     757                 :          0 :     nrf_gpio_pin_set(pin);
     758                 :          0 : }
     759                 :            : 
     760                 :            : 
     761                 :          0 : void nrfx_gpiote_out_clear(nrfx_gpiote_pin_t pin)
     762                 :            : {
     763         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     764   [ #  #  #  # ]:          0 :     NRFX_ASSERT(pin_is_output(pin) && !pin_in_use_by_te(pin));
     765                 :            : 
     766                 :          0 :     nrf_gpio_pin_clear(pin);
     767                 :          0 : }
     768                 :            : 
     769                 :            : 
     770                 :          0 : void nrfx_gpiote_out_toggle(nrfx_gpiote_pin_t pin)
     771                 :            : {
     772         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     773   [ #  #  #  # ]:          0 :     NRFX_ASSERT(pin_is_output(pin) && !pin_in_use_by_te(pin));
     774                 :            : 
     775                 :          0 :     nrf_gpio_pin_toggle(pin);
     776                 :          0 : }
     777                 :            : 
     778                 :          0 : void nrfx_gpiote_out_task_enable(nrfx_gpiote_pin_t pin)
     779                 :            : {
     780                 :            :     (void)pin_is_task_output; /* Add to avoid compiler warnings when asserts disabled.*/
     781         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     782         [ #  # ]:          0 :     NRFX_ASSERT(pin_is_task_output(pin));
     783                 :            : 
     784                 :          0 :     nrf_gpiote_task_enable(NRF_GPIOTE, (uint32_t)pin_te_get(pin));
     785                 :          0 : }
     786                 :            : 
     787                 :            : 
     788                 :          0 : void nrfx_gpiote_out_task_disable(nrfx_gpiote_pin_t pin)
     789                 :            : {
     790         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     791         [ #  # ]:          0 :     NRFX_ASSERT(pin_is_task_output(pin));
     792                 :            : 
     793                 :          0 :     nrf_gpiote_task_disable(NRF_GPIOTE, (uint32_t)pin_te_get(pin));
     794                 :          0 : }
     795                 :            : 
     796                 :            : 
     797                 :          0 : nrf_gpiote_task_t nrfx_gpiote_out_task_get(nrfx_gpiote_pin_t pin)
     798                 :            : {
     799         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     800         [ #  # ]:          0 :     NRFX_ASSERT(pin_is_task_output(pin));
     801                 :            : 
     802                 :          0 :     return nrf_gpiote_out_task_get((uint8_t)pin_te_get(pin));
     803                 :            : }
     804                 :            : 
     805                 :            : 
     806                 :          0 : uint32_t nrfx_gpiote_out_task_addr_get(nrfx_gpiote_pin_t pin)
     807                 :            : {
     808                 :          0 :     nrf_gpiote_task_t task = nrfx_gpiote_out_task_get(pin);
     809                 :          0 :     return nrf_gpiote_task_address_get(NRF_GPIOTE, task);
     810                 :            : }
     811                 :            : 
     812                 :            : 
     813                 :            : #if defined(GPIOTE_FEATURE_SET_PRESENT)
     814                 :          0 : nrf_gpiote_task_t nrfx_gpiote_set_task_get(nrfx_gpiote_pin_t pin)
     815                 :            : {
     816         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     817         [ #  # ]:          0 :     NRFX_ASSERT(pin_is_task_output(pin));
     818                 :            : 
     819                 :          0 :     return nrf_gpiote_set_task_get((uint8_t)pin_te_get(pin));
     820                 :            : }
     821                 :            : 
     822                 :            : 
     823                 :          0 : uint32_t nrfx_gpiote_set_task_addr_get(nrfx_gpiote_pin_t pin)
     824                 :            : {
     825                 :          0 :     nrf_gpiote_task_t task = nrfx_gpiote_set_task_get(pin);
     826                 :          0 :     return nrf_gpiote_task_address_get(NRF_GPIOTE, task);
     827                 :            : }
     828                 :            : #endif // defined(GPIOTE_FEATURE_SET_PRESENT)
     829                 :            : 
     830                 :            : 
     831                 :            : #if defined(GPIOTE_FEATURE_CLR_PRESENT)
     832                 :          0 : nrf_gpiote_task_t nrfx_gpiote_clr_task_get(nrfx_gpiote_pin_t pin)
     833                 :            : {
     834         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     835         [ #  # ]:          0 :     NRFX_ASSERT(pin_is_task_output(pin));
     836                 :            : 
     837                 :          0 :     return nrf_gpiote_clr_task_get((uint8_t)pin_te_get(pin));
     838                 :            : }
     839                 :            : 
     840                 :            : 
     841                 :          0 : uint32_t nrfx_gpiote_clr_task_addr_get(nrfx_gpiote_pin_t pin)
     842                 :            : {
     843                 :          0 :     nrf_gpiote_task_t task = nrfx_gpiote_clr_task_get(pin);
     844                 :          0 :     return nrf_gpiote_task_address_get(NRF_GPIOTE, task);
     845                 :            : }
     846                 :            : #endif // defined(GPIOTE_FEATURE_CLR_PRESENT)
     847                 :            : 
     848                 :            : 
     849                 :          0 : void nrfx_gpiote_out_task_force(nrfx_gpiote_pin_t pin, uint8_t state)
     850                 :            : {
     851         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     852         [ #  # ]:          0 :     NRFX_ASSERT(pin_is_task_output(pin));
     853                 :            : 
     854                 :          0 :     nrf_gpiote_outinit_t init_val =
     855                 :          0 :         state ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW;
     856                 :          0 :     nrf_gpiote_task_force(NRF_GPIOTE, (uint32_t)pin_te_get(pin), init_val);
     857                 :          0 : }
     858                 :            : 
     859                 :            : 
     860                 :          0 : void nrfx_gpiote_out_task_trigger(nrfx_gpiote_pin_t pin)
     861                 :            : {
     862         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     863         [ #  # ]:          0 :     NRFX_ASSERT(pin_is_task_output(pin));
     864                 :            : 
     865                 :          0 :     nrf_gpiote_task_t task = nrf_gpiote_out_task_get((uint8_t)pin_te_get(pin));
     866                 :          0 :     nrf_gpiote_task_trigger(NRF_GPIOTE, task);
     867                 :          0 : }
     868                 :            : 
     869                 :            : 
     870                 :            : #if defined(GPIOTE_FEATURE_SET_PRESENT)
     871                 :          0 : void nrfx_gpiote_set_task_trigger(nrfx_gpiote_pin_t pin)
     872                 :            : {
     873         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     874         [ #  # ]:          0 :     NRFX_ASSERT(pin_in_use(pin));
     875         [ #  # ]:          0 :     NRFX_ASSERT(pin_in_use_by_te(pin));
     876                 :            : 
     877                 :          0 :     nrf_gpiote_task_t task = nrf_gpiote_set_task_get((uint8_t)pin_te_get(pin));
     878                 :          0 :     nrf_gpiote_task_trigger(NRF_GPIOTE, task);
     879                 :          0 : }
     880                 :            : 
     881                 :            : 
     882                 :            : #endif // defined(GPIOTE_FEATURE_SET_PRESENT)
     883                 :            : 
     884                 :            : #if  defined(GPIOTE_FEATURE_CLR_PRESENT)
     885                 :          0 : void nrfx_gpiote_clr_task_trigger(nrfx_gpiote_pin_t pin)
     886                 :            : {
     887         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
     888         [ #  # ]:          0 :     NRFX_ASSERT(pin_in_use(pin));
     889         [ #  # ]:          0 :     NRFX_ASSERT(pin_in_use_by_te(pin));
     890                 :            : 
     891                 :          0 :     nrf_gpiote_task_t task = nrf_gpiote_clr_task_get((uint8_t)pin_te_get(pin));
     892                 :          0 :     nrf_gpiote_task_trigger(NRF_GPIOTE, task);
     893                 :          0 : }
     894                 :            : 
     895                 :            : 
     896                 :            : #endif // defined(GPIOTE_FEATURE_CLR_PRESENT)
     897                 :            : 
     898                 :            : 
     899                 :          0 : nrfx_err_t nrfx_gpiote_in_init(nrfx_gpiote_pin_t               pin,
     900                 :            :                                nrfx_gpiote_in_config_t const * p_config,
     901                 :            :                                nrfx_gpiote_evt_handler_t       evt_handler)
     902                 :            : {
     903                 :            :     uint8_t ch;
     904                 :            :     nrfx_err_t err;
     905                 :            : 
     906         [ #  # ]:          0 :     if (p_config->hi_accuracy)
     907                 :            :     {
     908                 :          0 :         err = nrfx_gpiote_channel_alloc(&ch);
     909         [ #  # ]:          0 :         if (err != NRFX_SUCCESS)
     910                 :            :         {
     911                 :          0 :             return err;
     912                 :            :         }
     913                 :            :     }
     914                 :            :     else
     915                 :            :     {
     916                 :            :         /* Value will not be used. */
     917                 :          0 :         ch = 0xFF;
     918                 :            :     }
     919                 :            : 
     920                 :          0 :     err = nrfx_gpiote_in_prealloc_init(pin, p_config, ch, evt_handler);
     921   [ #  #  #  # ]:          0 :     if ((err == NRFX_ERROR_NO_MEM) && p_config->hi_accuracy)
     922                 :            :     {
     923                 :          0 :         nrfx_gpiote_channel_free(ch);
     924                 :            :     }
     925                 :            : 
     926                 :          0 :     return err;
     927                 :            : }
     928                 :            : 
     929                 :          0 : static void legacy_handler(nrfx_gpiote_pin_t pin, nrfx_gpiote_trigger_t trigger, void * p_context)
     930                 :            : {
     931         [ #  # ]:          0 :     NRFX_ASSERT(trigger <= NRFX_GPIOTE_TRIGGER_TOGGLE);
     932                 :            : 
     933                 :          0 :     ((nrfx_gpiote_evt_handler_t)p_context)(pin, gpiote_trigger_to_polarity(trigger));
     934                 :          0 : }
     935                 :            : 
     936                 :          0 : nrfx_err_t nrfx_gpiote_in_prealloc_init(nrfx_gpiote_pin_t               pin,
     937                 :            :                                         nrfx_gpiote_in_config_t const * p_config,
     938                 :            :                                         uint8_t                         channel,
     939                 :            :                                         nrfx_gpiote_evt_handler_t       evt_handler)
     940                 :            : {
     941                 :            :     nrfx_err_t err;
     942                 :          0 :     bool skip_in_config = false;
     943                 :            :     nrfx_gpiote_input_config_t input_config;
     944                 :          0 :     nrfx_gpiote_trigger_config_t trigger_config = {
     945                 :          0 :         .trigger = gpiote_polarity_to_trigger(p_config->sense),
     946         [ #  # ]:          0 :         .p_in_channel = p_config->hi_accuracy ? &channel : NULL
     947                 :            :     };
     948                 :          0 :     nrfx_gpiote_handler_config_t handler_config = {
     949                 :            :         .handler = legacy_handler,
     950                 :            :         .p_context = (void *)evt_handler
     951                 :            :     };
     952                 :            : 
     953         [ #  # ]:          0 :     if (p_config->is_watcher)
     954                 :            :     {
     955                 :          0 :         nrfx_gpiote_output_config_t output_config = {
     956                 :            :             .input_connect = NRF_GPIO_PIN_INPUT_CONNECT
     957                 :            :         };
     958                 :            : 
     959                 :          0 :         skip_in_config = true;
     960                 :          0 :         err = nrfx_gpiote_output_configure(pin, &output_config, NULL);
     961         [ #  # ]:          0 :         if (err != NRFX_SUCCESS)
     962                 :            :         {
     963                 :          0 :             return err;
     964                 :            :         }
     965                 :            :     }
     966                 :            :     else
     967                 :            :     {
     968                 :          0 :         input_config.pull = p_config->pull;
     969                 :            :     }
     970                 :            : 
     971         [ #  # ]:          0 :     if (p_config->skip_gpio_setup)
     972                 :            :     {
     973                 :          0 :         m_cb.pin_flags[pin] |= PIN_FLAG_SKIP_CONFIG;
     974                 :          0 :         skip_in_config = true;
     975                 :            :     }
     976                 :            : 
     977         [ #  # ]:          0 :     err = nrfx_gpiote_input_configure(pin,
     978                 :            :                                       skip_in_config ? NULL : &input_config,
     979                 :            :                                       &trigger_config,
     980                 :            :                                       &handler_config);
     981         [ #  # ]:          0 :     if (err == NRFX_SUCCESS)
     982                 :            :     {
     983                 :          0 :         m_cb.pin_flags[pin] |= PIN_FLAG_LEGACY_API_PIN;
     984                 :            :     }
     985                 :            : 
     986                 :          0 :     return err;
     987                 :            : }
     988                 :            : 
     989                 :          0 : void nrfx_gpiote_trigger_enable(nrfx_gpiote_pin_t pin, bool int_enable)
     990                 :            : {
     991         [ #  # ]:          0 :     NRFX_ASSERT(pin_has_trigger(pin));
     992                 :            : 
     993   [ #  #  #  # ]:          0 :     if (pin_in_use_by_te(pin) && pin_is_input(pin))
     994                 :          0 :     {
     995                 :          0 :         uint8_t ch = pin_te_get(pin);
     996                 :            : 
     997                 :          0 :         nrf_gpiote_event_clear(NRF_GPIOTE, nrf_gpiote_in_event_get(ch));
     998                 :          0 :         nrf_gpiote_event_enable(NRF_GPIOTE, ch);
     999         [ #  # ]:          0 :         if (int_enable)
    1000                 :            :         {
    1001                 :          0 :             nrf_gpiote_int_enable(NRF_GPIOTE, NRFX_BIT(ch));
    1002                 :            :         }
    1003                 :            :     }
    1004                 :            :     else
    1005                 :            :     {
    1006         [ #  # ]:          0 :         NRFX_ASSERT(int_enable);
    1007                 :          0 :         nrf_gpio_cfg_sense_set(pin, get_initial_sense(pin));
    1008                 :            :     }
    1009                 :          0 : }
    1010                 :            : 
    1011                 :          0 : void nrfx_gpiote_trigger_disable(nrfx_gpiote_pin_t pin)
    1012                 :            : {
    1013   [ #  #  #  # ]:          0 :     if (pin_in_use_by_te(pin) && pin_is_input(pin))
    1014                 :          0 :     {
    1015                 :          0 :         uint8_t ch = pin_te_get(pin);
    1016                 :            : 
    1017                 :          0 :         nrf_gpiote_int_disable(NRF_GPIOTE, NRFX_BIT(ch));
    1018                 :          0 :         nrf_gpiote_event_disable(NRF_GPIOTE, ch);
    1019                 :            :     }
    1020                 :            :     else
    1021                 :            :     {
    1022                 :          0 :         nrf_gpio_cfg_sense_set(pin, NRF_GPIO_PIN_NOSENSE);
    1023                 :            :     }
    1024                 :          0 : }
    1025                 :            : 
    1026                 :          0 : void nrfx_gpiote_in_uninit(nrfx_gpiote_pin_t pin)
    1027                 :            : {
    1028         [ #  # ]:          0 :     NRFX_ASSERT(pin_in_use(pin));
    1029   [ #  #  #  # ]:          0 :     NRFX_ASSERT(pin_is_input(pin) || pin_has_trigger(pin));
    1030                 :            :     nrfx_err_t err;
    1031                 :            :     uint8_t ch;
    1032                 :            : 
    1033         [ #  # ]:          0 :     if (!pin_in_use(pin))
    1034                 :            :     {
    1035                 :          0 :         return;
    1036                 :            :     }
    1037                 :            : 
    1038         [ #  # ]:          0 :     ch = pin_in_use_by_te(pin) ? pin_te_get(pin) : 0xFF;
    1039                 :            : 
    1040         [ #  # ]:          0 :     if (m_cb.pin_flags[pin] & PIN_FLAG_SKIP_CONFIG)
    1041                 :            :     {
    1042                 :          0 :         pin_handler_trigger_uninit(pin);
    1043                 :          0 :         m_cb.pin_flags[pin] &= ~PIN_FLAG_SKIP_CONFIG;
    1044                 :            :     }
    1045                 :            :     else
    1046                 :            :     {
    1047                 :          0 :         err = nrfx_gpiote_pin_uninit(pin);
    1048         [ #  # ]:          0 :         NRFX_ASSERT(err == NRFX_SUCCESS);
    1049                 :            :     }
    1050                 :            : 
    1051         [ #  # ]:          0 :     if (ch != 0xFF)
    1052                 :            :     {
    1053                 :          0 :         nrfx_gpiote_channel_free(ch);
    1054                 :            :     }
    1055                 :            : 
    1056                 :            :     (void)err;
    1057                 :            : }
    1058                 :            : 
    1059                 :            : 
    1060                 :          0 : bool nrfx_gpiote_in_is_set(nrfx_gpiote_pin_t pin)
    1061                 :            : {
    1062         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
    1063                 :          0 :     return nrf_gpio_pin_read(pin) ? true : false;
    1064                 :            : }
    1065                 :            : 
    1066                 :            : 
    1067                 :          0 : nrf_gpiote_event_t nrfx_gpiote_in_event_get(nrfx_gpiote_pin_t pin)
    1068                 :            : {
    1069         [ #  # ]:          0 :     NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
    1070         [ #  # ]:          0 :     NRFX_ASSERT(pin_is_input(pin));
    1071         [ #  # ]:          0 :     NRFX_ASSERT(pin_has_trigger(pin));
    1072                 :            : 
    1073         [ #  # ]:          0 :     if (pin_in_use_by_te(pin))
    1074                 :            :     {
    1075                 :          0 :         return nrf_gpiote_in_event_get((uint8_t)pin_te_get(pin));
    1076                 :            :     }
    1077                 :            : 
    1078                 :          0 :     return NRF_GPIOTE_EVENT_PORT;
    1079                 :            : }
    1080                 :            : 
    1081                 :            : 
    1082                 :          0 : uint32_t nrfx_gpiote_in_event_addr_get(nrfx_gpiote_pin_t pin)
    1083                 :            : {
    1084                 :          0 :     nrf_gpiote_event_t event = nrfx_gpiote_in_event_get(pin);
    1085                 :          0 :     return nrf_gpiote_event_address_get(NRF_GPIOTE, event);
    1086                 :            : }
    1087                 :            : 
    1088                 :          0 : static void call_handler(nrfx_gpiote_pin_t pin, nrfx_gpiote_trigger_t trigger)
    1089                 :            : {
    1090                 :          0 :     nrfx_gpiote_handler_config_t const * handler = channel_handler_get(pin);
    1091                 :            : 
    1092         [ #  # ]:          0 :     if (handler)
    1093                 :            :     {
    1094                 :          0 :         handler->handler(pin, trigger, handler->p_context);
    1095                 :            :     }
    1096         [ #  # ]:          0 :     if (m_cb.global_handler.handler)
    1097                 :            :     {
    1098                 :          0 :         m_cb.global_handler.handler(pin, trigger, m_cb.global_handler.p_context);
    1099                 :            :     }
    1100                 :          0 : }
    1101                 :            : 
    1102                 :          0 : static void next_sense_cond_call_handler(nrfx_gpiote_pin_t     pin,
    1103                 :            :                                          nrfx_gpiote_trigger_t trigger,
    1104                 :            :                                          nrf_gpio_pin_sense_t  sense)
    1105                 :            : {
    1106         [ #  # ]:          0 :     if (is_level(trigger))
    1107                 :            :     {
    1108                 :          0 :         call_handler(pin, trigger);
    1109         [ #  # ]:          0 :         if (nrf_gpio_pin_sense_get(pin) == sense)
    1110                 :            :         {
    1111                 :            :             /* The sensing mechanism needs to be reenabled here so that the PORT event
    1112                 :            :              * is generated again for the pin if it stays at the sensed level. */
    1113                 :          0 :             nrf_gpio_cfg_sense_set(pin, NRF_GPIO_PIN_NOSENSE);
    1114                 :          0 :             nrf_gpio_cfg_sense_set(pin, sense);
    1115                 :            :         }
    1116                 :            :     }
    1117                 :            :     else
    1118                 :            :     {
    1119                 :            :         /* Reconfigure sense to the opposite level, so the internal PINx.DETECT signal
    1120                 :            :          * can be deasserted. Therefore PORT event can be generated again,
    1121                 :            :          * unless some other PINx.DETECT signal is still active. */
    1122                 :          0 :         nrf_gpio_pin_sense_t next_sense = (sense == NRF_GPIO_PIN_SENSE_HIGH) ?
    1123         [ #  # ]:          0 :                 NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;
    1124                 :            : 
    1125                 :          0 :         nrf_gpio_cfg_sense_set(pin, next_sense);
    1126                 :            : 
    1127                 :            :         /* Invoke user handler only if the sensed pin level matches its polarity
    1128                 :            :          * configuration. Call handler unconditionally in case of toggle trigger or
    1129                 :            :          * level trigger. */
    1130   [ #  #  #  # ]:          0 :         if ((trigger == NRFX_GPIOTE_TRIGGER_TOGGLE) ||
    1131   [ #  #  #  # ]:          0 :             (sense == NRF_GPIO_PIN_SENSE_HIGH && trigger == NRFX_GPIOTE_TRIGGER_LOTOHI) ||
    1132         [ #  # ]:          0 :             (sense == NRF_GPIO_PIN_SENSE_LOW && trigger == NRFX_GPIOTE_TRIGGER_HITOLO))
    1133                 :            :         {
    1134                 :          0 :             call_handler(pin, trigger);
    1135                 :            :         }
    1136                 :            :     }
    1137                 :          0 : }
    1138                 :            : 
    1139                 :            : #if defined(NRF_GPIO_LATCH_PRESENT)
    1140                 :          0 : static bool latch_pending_read_and_check(uint32_t * latch)
    1141                 :            : {
    1142                 :          0 :     nrf_gpio_latches_read_and_clear(0, GPIO_COUNT, latch);
    1143                 :            : 
    1144         [ #  # ]:          0 :     for (uint32_t port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
    1145                 :            :     {
    1146         [ #  # ]:          0 :         if (latch[port_idx])
    1147                 :            :         {
    1148                 :            :             /* If any of the latch bits is still set, it means another edge has been captured
    1149                 :            :              * before or during the interrupt processing. Therefore event-processing loop
    1150                 :            :              * should be executed again. */
    1151                 :          0 :             return true;
    1152                 :            :         }
    1153                 :            :     }
    1154                 :          0 :     return false;
    1155                 :            : }
    1156                 :            : 
    1157                 :          0 : static void port_event_handle(void)
    1158                 :            : {
    1159                 :            :     uint32_t latch[GPIO_COUNT];
    1160                 :            : 
    1161                 :          0 :     nrf_gpio_latches_read_and_clear(0, GPIO_COUNT, latch);
    1162                 :            : 
    1163                 :            :     do {
    1164         [ #  # ]:          0 :         for (uint32_t i = 0; i < GPIO_COUNT; i++)
    1165                 :            :         {
    1166         [ #  # ]:          0 :             while (latch[i])
    1167                 :            :             {
    1168                 :          0 :                 uint32_t pin = NRF_CTZ(latch[i]);
    1169                 :            : 
    1170                 :            :                 /* Convert to absolute value. */
    1171                 :          0 :                 pin += 32 * i;
    1172                 :            :                 nrf_gpio_pin_sense_t sense;
    1173                 :          0 :                 nrfx_gpiote_trigger_t trigger = PIN_FLAG_TRIG_MODE_GET(m_cb.pin_flags[pin]);
    1174                 :            : 
    1175                 :          0 :                 nrf_bitmask_bit_clear(pin, latch);
    1176                 :          0 :                 sense = nrf_gpio_pin_sense_get(pin);
    1177                 :            : 
    1178                 :          0 :                 next_sense_cond_call_handler(pin, trigger, sense);
    1179                 :            :                 /* Try to clear LATCH bit corresponding to currently processed pin.
    1180                 :            :                  * This may not succeed if the pin's state changed during the interrupt processing
    1181                 :            :                  * and now it matches the new sense configuration. In such case,
    1182                 :            :                  * the pin will be processed again in another iteration of the outer loop. */
    1183                 :          0 :                 nrf_gpio_pin_latch_clear(pin);
    1184                 :            :            }
    1185                 :            :         }
    1186                 :            : 
    1187                 :            :         /* All pins have been handled, clear PORT, check latch again in case
    1188                 :            :          * something came between deciding to exit and clearing PORT event. */
    1189                 :          0 :         nrf_gpiote_event_clear(NRF_GPIOTE, NRF_GPIOTE_EVENT_PORT);
    1190         [ #  # ]:          0 :     } while (latch_pending_read_and_check(latch));
    1191                 :          0 : }
    1192                 :            : 
    1193                 :            : #else
    1194                 :            : 
    1195                 :            : static bool input_read_and_check(uint32_t * input, uint32_t * pins_to_check)
    1196                 :            : {
    1197                 :            :     bool process_inputs_again;
    1198                 :            :     uint32_t new_input[GPIO_COUNT];
    1199                 :            : 
    1200                 :            :     nrf_gpio_ports_read(0, GPIO_COUNT, new_input);
    1201                 :            : 
    1202                 :            :     process_inputs_again = false;
    1203                 :            :     for (uint32_t port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
    1204                 :            :     {
    1205                 :            :         /* Execute XOR to find out which inputs have changed. */
    1206                 :            :         uint32_t input_diff = input[port_idx] ^ new_input[port_idx];
    1207                 :            :         input[port_idx] = new_input[port_idx];
    1208                 :            :         if (input_diff)
    1209                 :            :         {
    1210                 :            :             /* If any differences among inputs were found, mark those pins
    1211                 :            :              * to be processed again. */
    1212                 :            :             pins_to_check[port_idx] &= input_diff;
    1213                 :            :             process_inputs_again = true;
    1214                 :            :         }
    1215                 :            :         else
    1216                 :            :         {
    1217                 :            :             pins_to_check[port_idx] = 0;
    1218                 :            :         }
    1219                 :            :     }
    1220                 :            :     return process_inputs_again;
    1221                 :            : }
    1222                 :            : 
    1223                 :            : static void port_event_handle(void)
    1224                 :            : {
    1225                 :            :     uint32_t pins_to_check[GPIO_COUNT];
    1226                 :            :     uint32_t input[GPIO_COUNT] = {0};
    1227                 :            :     uint8_t rel_pin;
    1228                 :            :     uint8_t pin;
    1229                 :            :     nrfx_gpiote_trigger_t trigger;
    1230                 :            : 
    1231                 :            :     nrf_gpio_ports_read(0, GPIO_COUNT, input);
    1232                 :            : 
    1233                 :            :     for (uint32_t port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
    1234                 :            :     {
    1235                 :            :         pins_to_check[port_idx] = m_cb.port_pins[port_idx];
    1236                 :            :     }
    1237                 :            : 
    1238                 :            :     do {
    1239                 :            :         for (uint32_t i = 0; i < GPIO_COUNT; i++)
    1240                 :            :         {
    1241                 :            :             while (pins_to_check[i])
    1242                 :            :             {
    1243                 :            :                 nrf_gpio_pin_sense_t sense;
    1244                 :            :                 bool pin_state;
    1245                 :            : 
    1246                 :            :                 rel_pin = NRF_CTZ(pins_to_check[i]);
    1247                 :            :                 pins_to_check[i] &= ~NRFX_BIT(rel_pin);
    1248                 :            :                 /* Absolute */
    1249                 :            :                 pin = rel_pin + 32 * i;
    1250                 :            : 
    1251                 :            :                 trigger = PIN_FLAG_TRIG_MODE_GET(m_cb.pin_flags[pin]);
    1252                 :            :                 sense = nrf_gpio_pin_sense_get(pin);
    1253                 :            :                 pin_state = nrf_bitmask_bit_is_set(pin, input);
    1254                 :            : 
    1255                 :            :                 /* Process pin further only if its state matches its sense level. */
    1256                 :            :                 if ((pin_state && (sense == NRF_GPIO_PIN_SENSE_HIGH)) ||
    1257                 :            :                     (!pin_state && (sense == NRF_GPIO_PIN_SENSE_LOW)) )
    1258                 :            :                 {
    1259                 :            :                     next_sense_cond_call_handler(pin, trigger, sense);
    1260                 :            :                 }
    1261                 :            :             }
    1262                 :            :         }
    1263                 :            : 
    1264                 :            :         /* All pins used with PORT must be rechecked because it's content and
    1265                 :            :          * number of port pins may have changed during handler execution. */
    1266                 :            :         for (uint32_t port_idx = 0; port_idx < GPIO_COUNT; port_idx++)
    1267                 :            :         {
    1268                 :            :             pins_to_check[port_idx] = m_cb.port_pins[port_idx];
    1269                 :            :         }
    1270                 :            : 
    1271                 :            :         /* Small trick to continue check if input level is equal to the trigger:
    1272                 :            :          * Set input to the opposite level. If input equals trigger level that
    1273                 :            :          * it will be set in pins_to_check. */
    1274                 :            :         for (uint32_t i = 0; i < GPIO_COUNT; i++)
    1275                 :            :         {
    1276                 :            :             uint32_t pin_mask = pins_to_check[i];
    1277                 :            : 
    1278                 :            :             while (pin_mask)
    1279                 :            :             {
    1280                 :            :                 rel_pin = NRF_CTZ(pin_mask);
    1281                 :            :                 pin_mask &= ~NRFX_BIT(rel_pin);
    1282                 :            :                 pin = rel_pin + 32 * i;
    1283                 :            :                 if (nrf_gpio_pin_sense_get(pin) != NRF_GPIO_PIN_NOSENSE)
    1284                 :            :                 {
    1285                 :            :                     trigger = PIN_FLAG_TRIG_MODE_GET(m_cb.pin_flags[pin]);
    1286                 :            :                     if (trigger == NRFX_GPIOTE_TRIGGER_HIGH)
    1287                 :            :                     {
    1288                 :            :                         input[i] &= ~NRFX_BIT(rel_pin);
    1289                 :            :                     }
    1290                 :            :                     else if (trigger == NRFX_GPIOTE_TRIGGER_LOW)
    1291                 :            :                     {
    1292                 :            :                         input[i] |= NRFX_BIT(rel_pin);
    1293                 :            :                     }
    1294                 :            :                 }
    1295                 :            :             }
    1296                 :            :         }
    1297                 :            : 
    1298                 :            :         nrf_gpiote_event_clear(NRF_GPIOTE, NRF_GPIOTE_EVENT_PORT);
    1299                 :            :     } while (input_read_and_check(input, pins_to_check));
    1300                 :            : }
    1301                 :            : #endif // defined(NRF_GPIO_LATCH_PRESENT)
    1302                 :            : 
    1303                 :          0 : static void gpiote_evt_handle(uint32_t mask)
    1304                 :            : {
    1305         [ #  # ]:          0 :     while (mask)
    1306                 :            :     {
    1307                 :          0 :         uint32_t ch = NRF_CTZ(mask);
    1308                 :          0 :         mask &= ~NRFX_BIT(ch);
    1309                 :          0 :         nrfx_gpiote_pin_t pin = nrf_gpiote_event_pin_get(NRF_GPIOTE, ch);
    1310                 :          0 :         nrf_gpiote_polarity_t polarity = nrf_gpiote_event_polarity_get(NRF_GPIOTE, ch);
    1311                 :            : 
    1312                 :          0 :         call_handler(pin, gpiote_polarity_to_trigger(polarity));
    1313                 :            :     }
    1314                 :          0 : }
    1315                 :            : 
    1316                 :          0 : void nrfx_gpiote_irq_handler(void)
    1317                 :            : {
    1318                 :          0 :     uint32_t status = 0;
    1319                 :            :     uint32_t i;
    1320                 :          0 :     nrf_gpiote_event_t event = NRF_GPIOTE_EVENT_IN_0;
    1321                 :          0 :     uint32_t mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK;
    1322                 :            : 
    1323                 :            :     /* collect status of all GPIOTE pin events. Processing is done once all are collected and cleared.*/
    1324         [ #  # ]:          0 :     for (i = 0; i < GPIOTE_CH_NUM; i++)
    1325                 :            :     {
    1326   [ #  #  #  # ]:          0 :         if (nrf_gpiote_event_check(NRF_GPIOTE, event) &&
    1327                 :          0 :             nrf_gpiote_int_enable_check(NRF_GPIOTE, mask))
    1328                 :            :         {
    1329                 :          0 :             nrf_gpiote_event_clear(NRF_GPIOTE, event);
    1330                 :          0 :             status |= mask;
    1331                 :            :         }
    1332                 :          0 :         mask <<= 1;
    1333                 :            :         /* Incrementing to next event, utilizing the fact that events are grouped together
    1334                 :            :          * in ascending order. */
    1335                 :          0 :         event = (nrf_gpiote_event_t)((uint32_t)event + sizeof(uint32_t));
    1336                 :            :     }
    1337                 :            : 
    1338                 :            :     /* handle PORT event */
    1339         [ #  # ]:          0 :     if (nrf_gpiote_event_check(NRF_GPIOTE, NRF_GPIOTE_EVENT_PORT))
    1340                 :            :     {
    1341                 :          0 :         port_event_handle();
    1342                 :            :     }
    1343                 :            : 
    1344                 :            :     /* Process pin events. */
    1345                 :          0 :     gpiote_evt_handle(status);
    1346                 :          0 : }
    1347                 :            : 
    1348                 :            : #endif // NRFX_CHECK(NRFX_GPIOTE_ENABLED)

Generated by: LCOV version 1.14