Marco Zecchini / Mbed OS Example_RTOS
Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /*
marcozecchini 0:9fca2b23d0ba 2 * Copyright (c) 2015 Nordic Semiconductor ASA
marcozecchini 0:9fca2b23d0ba 3 * All rights reserved.
marcozecchini 0:9fca2b23d0ba 4 *
marcozecchini 0:9fca2b23d0ba 5 * Redistribution and use in source and binary forms, with or without modification,
marcozecchini 0:9fca2b23d0ba 6 * are permitted provided that the following conditions are met:
marcozecchini 0:9fca2b23d0ba 7 *
marcozecchini 0:9fca2b23d0ba 8 * 1. Redistributions of source code must retain the above copyright notice, this list
marcozecchini 0:9fca2b23d0ba 9 * of conditions and the following disclaimer.
marcozecchini 0:9fca2b23d0ba 10 *
marcozecchini 0:9fca2b23d0ba 11 * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
marcozecchini 0:9fca2b23d0ba 12 * integrated circuit in a product or a software update for such product, must reproduce
marcozecchini 0:9fca2b23d0ba 13 * the above copyright notice, this list of conditions and the following disclaimer in
marcozecchini 0:9fca2b23d0ba 14 * the documentation and/or other materials provided with the distribution.
marcozecchini 0:9fca2b23d0ba 15 *
marcozecchini 0:9fca2b23d0ba 16 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
marcozecchini 0:9fca2b23d0ba 17 * used to endorse or promote products derived from this software without specific prior
marcozecchini 0:9fca2b23d0ba 18 * written permission.
marcozecchini 0:9fca2b23d0ba 19 *
marcozecchini 0:9fca2b23d0ba 20 * 4. This software, with or without modification, must only be used with a
marcozecchini 0:9fca2b23d0ba 21 * Nordic Semiconductor ASA integrated circuit.
marcozecchini 0:9fca2b23d0ba 22 *
marcozecchini 0:9fca2b23d0ba 23 * 5. Any software provided in binary or object form under this license must not be reverse
marcozecchini 0:9fca2b23d0ba 24 * engineered, decompiled, modified and/or disassembled.
marcozecchini 0:9fca2b23d0ba 25 *
marcozecchini 0:9fca2b23d0ba 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
marcozecchini 0:9fca2b23d0ba 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
marcozecchini 0:9fca2b23d0ba 28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
marcozecchini 0:9fca2b23d0ba 29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
marcozecchini 0:9fca2b23d0ba 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
marcozecchini 0:9fca2b23d0ba 31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
marcozecchini 0:9fca2b23d0ba 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
marcozecchini 0:9fca2b23d0ba 33 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
marcozecchini 0:9fca2b23d0ba 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
marcozecchini 0:9fca2b23d0ba 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
marcozecchini 0:9fca2b23d0ba 36 *
marcozecchini 0:9fca2b23d0ba 37 */
marcozecchini 0:9fca2b23d0ba 38
marcozecchini 0:9fca2b23d0ba 39
marcozecchini 0:9fca2b23d0ba 40 #include "nrf_drv_gpiote.h"
marcozecchini 0:9fca2b23d0ba 41 #include "nrf_drv_common.h"
marcozecchini 0:9fca2b23d0ba 42 #include "nrf_drv_config.h"
marcozecchini 0:9fca2b23d0ba 43 #include "app_util_platform.h"
marcozecchini 0:9fca2b23d0ba 44 #include "nrf_assert.h"
marcozecchini 0:9fca2b23d0ba 45
marcozecchini 0:9fca2b23d0ba 46 #define FORBIDDEN_HANDLER_ADDRESS ((nrf_drv_gpiote_evt_handler_t)UINT32_MAX)
marcozecchini 0:9fca2b23d0ba 47 #define PIN_NOT_USED (-1)
marcozecchini 0:9fca2b23d0ba 48 #define PIN_USED (-2)
marcozecchini 0:9fca2b23d0ba 49 #define NO_CHANNELS (-1)
marcozecchini 0:9fca2b23d0ba 50 #define SENSE_FIELD_POS (6)
marcozecchini 0:9fca2b23d0ba 51 #define SENSE_FIELD_MASK (0xC0)
marcozecchini 0:9fca2b23d0ba 52
marcozecchini 0:9fca2b23d0ba 53 /**
marcozecchini 0:9fca2b23d0ba 54 * @brief Macro for conveting task-event index to an address of an event register.
marcozecchini 0:9fca2b23d0ba 55 *
marcozecchini 0:9fca2b23d0ba 56 * Macro utilizes the fact that registers are grouped together in ascending order.
marcozecchini 0:9fca2b23d0ba 57 */
marcozecchini 0:9fca2b23d0ba 58 #define TE_IDX_TO_EVENT_ADDR(idx) (nrf_gpiote_events_t)((uint32_t)NRF_GPIOTE_EVENTS_IN_0+(sizeof(uint32_t)*(idx)))
marcozecchini 0:9fca2b23d0ba 59
marcozecchini 0:9fca2b23d0ba 60 /**
marcozecchini 0:9fca2b23d0ba 61 * @brief Macro for conveting task-event index to an address of a task register.
marcozecchini 0:9fca2b23d0ba 62 *
marcozecchini 0:9fca2b23d0ba 63 * Macro utilizes the fact that registers are grouped together in ascending order.
marcozecchini 0:9fca2b23d0ba 64 */
marcozecchini 0:9fca2b23d0ba 65 #define TE_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_OUT_0+(sizeof(uint32_t)*(idx)))
marcozecchini 0:9fca2b23d0ba 66
marcozecchini 0:9fca2b23d0ba 67 //lint -save -e661
marcozecchini 0:9fca2b23d0ba 68 typedef struct
marcozecchini 0:9fca2b23d0ba 69 {
marcozecchini 0:9fca2b23d0ba 70 nrf_drv_gpiote_evt_handler_t handlers[NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];
marcozecchini 0:9fca2b23d0ba 71 int8_t pin_assignments[NUMBER_OF_PINS];
marcozecchini 0:9fca2b23d0ba 72 int8_t port_handlers_pins[GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];
marcozecchini 0:9fca2b23d0ba 73 nrf_drv_state_t state;
marcozecchini 0:9fca2b23d0ba 74 } gpiote_control_block_t;
marcozecchini 0:9fca2b23d0ba 75
marcozecchini 0:9fca2b23d0ba 76 static gpiote_control_block_t m_cb;
marcozecchini 0:9fca2b23d0ba 77
marcozecchini 0:9fca2b23d0ba 78 __STATIC_INLINE bool pin_in_use(uint32_t pin)
marcozecchini 0:9fca2b23d0ba 79 {
marcozecchini 0:9fca2b23d0ba 80 return (m_cb.pin_assignments[pin] != PIN_NOT_USED);
marcozecchini 0:9fca2b23d0ba 81 }
marcozecchini 0:9fca2b23d0ba 82
marcozecchini 0:9fca2b23d0ba 83 __STATIC_INLINE bool pin_in_use_as_non_task_out(uint32_t pin)
marcozecchini 0:9fca2b23d0ba 84 {
marcozecchini 0:9fca2b23d0ba 85 return (m_cb.pin_assignments[pin] == PIN_USED);
marcozecchini 0:9fca2b23d0ba 86 }
marcozecchini 0:9fca2b23d0ba 87
marcozecchini 0:9fca2b23d0ba 88 __STATIC_INLINE bool pin_in_use_by_te(uint32_t pin)
marcozecchini 0:9fca2b23d0ba 89 {
marcozecchini 0:9fca2b23d0ba 90 return (m_cb.pin_assignments[pin] >= 0 && m_cb.pin_assignments[pin] < NUMBER_OF_GPIO_TE) ? true : false;
marcozecchini 0:9fca2b23d0ba 91 }
marcozecchini 0:9fca2b23d0ba 92
marcozecchini 0:9fca2b23d0ba 93 __STATIC_INLINE bool pin_in_use_by_port(uint32_t pin)
marcozecchini 0:9fca2b23d0ba 94 {
marcozecchini 0:9fca2b23d0ba 95 return (m_cb.pin_assignments[pin] >= NUMBER_OF_GPIO_TE);
marcozecchini 0:9fca2b23d0ba 96 }
marcozecchini 0:9fca2b23d0ba 97
marcozecchini 0:9fca2b23d0ba 98 __STATIC_INLINE bool pin_in_use_by_gpiote(uint32_t pin)
marcozecchini 0:9fca2b23d0ba 99 {
marcozecchini 0:9fca2b23d0ba 100 return (m_cb.pin_assignments[pin] >= 0);
marcozecchini 0:9fca2b23d0ba 101 }
marcozecchini 0:9fca2b23d0ba 102
marcozecchini 0:9fca2b23d0ba 103 __STATIC_INLINE void pin_in_use_by_te_set(uint32_t pin,
marcozecchini 0:9fca2b23d0ba 104 uint32_t channel_id,
marcozecchini 0:9fca2b23d0ba 105 nrf_drv_gpiote_evt_handler_t handler,
marcozecchini 0:9fca2b23d0ba 106 bool is_channel)
marcozecchini 0:9fca2b23d0ba 107 {
marcozecchini 0:9fca2b23d0ba 108 m_cb.pin_assignments[pin] = channel_id;
marcozecchini 0:9fca2b23d0ba 109 m_cb.handlers[channel_id] = handler;
marcozecchini 0:9fca2b23d0ba 110 if (!is_channel)
marcozecchini 0:9fca2b23d0ba 111 {
marcozecchini 0:9fca2b23d0ba 112 m_cb.port_handlers_pins[channel_id-NUMBER_OF_GPIO_TE] = (int8_t)pin;
marcozecchini 0:9fca2b23d0ba 113 }
marcozecchini 0:9fca2b23d0ba 114 }
marcozecchini 0:9fca2b23d0ba 115
marcozecchini 0:9fca2b23d0ba 116 __STATIC_INLINE void pin_in_use_set(uint32_t pin)
marcozecchini 0:9fca2b23d0ba 117 {
marcozecchini 0:9fca2b23d0ba 118 m_cb.pin_assignments[pin] = PIN_USED;
marcozecchini 0:9fca2b23d0ba 119 }
marcozecchini 0:9fca2b23d0ba 120
marcozecchini 0:9fca2b23d0ba 121 __STATIC_INLINE void pin_in_use_clear(uint32_t pin)
marcozecchini 0:9fca2b23d0ba 122 {
marcozecchini 0:9fca2b23d0ba 123 m_cb.pin_assignments[pin] = PIN_NOT_USED;
marcozecchini 0:9fca2b23d0ba 124 }
marcozecchini 0:9fca2b23d0ba 125
marcozecchini 0:9fca2b23d0ba 126 __STATIC_INLINE int8_t channel_port_get(uint32_t pin)
marcozecchini 0:9fca2b23d0ba 127 {
marcozecchini 0:9fca2b23d0ba 128 return m_cb.pin_assignments[pin];
marcozecchini 0:9fca2b23d0ba 129 }
marcozecchini 0:9fca2b23d0ba 130
marcozecchini 0:9fca2b23d0ba 131 __STATIC_INLINE nrf_drv_gpiote_evt_handler_t channel_handler_get(uint32_t channel)
marcozecchini 0:9fca2b23d0ba 132 {
marcozecchini 0:9fca2b23d0ba 133 return m_cb.handlers[channel];
marcozecchini 0:9fca2b23d0ba 134 }
marcozecchini 0:9fca2b23d0ba 135
marcozecchini 0:9fca2b23d0ba 136 static int8_t channel_port_alloc(uint32_t pin,nrf_drv_gpiote_evt_handler_t handler, bool channel)
marcozecchini 0:9fca2b23d0ba 137 {
marcozecchini 0:9fca2b23d0ba 138 int8_t channel_id = NO_CHANNELS;
marcozecchini 0:9fca2b23d0ba 139 uint32_t i;
marcozecchini 0:9fca2b23d0ba 140
marcozecchini 0:9fca2b23d0ba 141 uint32_t start_idx = channel ? 0 : NUMBER_OF_GPIO_TE;
marcozecchini 0:9fca2b23d0ba 142 uint32_t end_idx = channel ? NUMBER_OF_GPIO_TE : (NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS);
marcozecchini 0:9fca2b23d0ba 143 //critical section
marcozecchini 0:9fca2b23d0ba 144
marcozecchini 0:9fca2b23d0ba 145 for (i = start_idx; i < end_idx; i++)
marcozecchini 0:9fca2b23d0ba 146 {
marcozecchini 0:9fca2b23d0ba 147 if (m_cb.handlers[i] == FORBIDDEN_HANDLER_ADDRESS)
marcozecchini 0:9fca2b23d0ba 148 {
marcozecchini 0:9fca2b23d0ba 149 pin_in_use_by_te_set(pin, i, handler, channel);
marcozecchini 0:9fca2b23d0ba 150 channel_id = i;
marcozecchini 0:9fca2b23d0ba 151 break;
marcozecchini 0:9fca2b23d0ba 152 }
marcozecchini 0:9fca2b23d0ba 153 }
marcozecchini 0:9fca2b23d0ba 154 //critical section
marcozecchini 0:9fca2b23d0ba 155 return channel_id;
marcozecchini 0:9fca2b23d0ba 156 }
marcozecchini 0:9fca2b23d0ba 157
marcozecchini 0:9fca2b23d0ba 158 static void channel_free(uint8_t channel_id)
marcozecchini 0:9fca2b23d0ba 159 {
marcozecchini 0:9fca2b23d0ba 160 m_cb.handlers[channel_id] = FORBIDDEN_HANDLER_ADDRESS;
marcozecchini 0:9fca2b23d0ba 161 if (channel_id >= NUMBER_OF_GPIO_TE)
marcozecchini 0:9fca2b23d0ba 162 {
marcozecchini 0:9fca2b23d0ba 163 m_cb.port_handlers_pins[channel_id-NUMBER_OF_GPIO_TE] = (int8_t)PIN_NOT_USED;
marcozecchini 0:9fca2b23d0ba 164 }
marcozecchini 0:9fca2b23d0ba 165 }
marcozecchini 0:9fca2b23d0ba 166
marcozecchini 0:9fca2b23d0ba 167 ret_code_t nrf_drv_gpiote_init(void)
marcozecchini 0:9fca2b23d0ba 168 {
marcozecchini 0:9fca2b23d0ba 169 if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
marcozecchini 0:9fca2b23d0ba 170 {
marcozecchini 0:9fca2b23d0ba 171 return NRF_ERROR_INVALID_STATE;
marcozecchini 0:9fca2b23d0ba 172 }
marcozecchini 0:9fca2b23d0ba 173
marcozecchini 0:9fca2b23d0ba 174 uint8_t i;
marcozecchini 0:9fca2b23d0ba 175 for (i = 0; i < NUMBER_OF_PINS; i++)
marcozecchini 0:9fca2b23d0ba 176 {
marcozecchini 0:9fca2b23d0ba 177 pin_in_use_clear(i);
marcozecchini 0:9fca2b23d0ba 178 }
marcozecchini 0:9fca2b23d0ba 179 for (i = 0; i < (NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); i++)
marcozecchini 0:9fca2b23d0ba 180 {
marcozecchini 0:9fca2b23d0ba 181 channel_free(i);
marcozecchini 0:9fca2b23d0ba 182 }
marcozecchini 0:9fca2b23d0ba 183
marcozecchini 0:9fca2b23d0ba 184 nrf_drv_common_irq_enable(GPIOTE_IRQn, GPIOTE_CONFIG_IRQ_PRIORITY);
marcozecchini 0:9fca2b23d0ba 185 nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk);
marcozecchini 0:9fca2b23d0ba 186 m_cb.state = NRF_DRV_STATE_INITIALIZED;
marcozecchini 0:9fca2b23d0ba 187
marcozecchini 0:9fca2b23d0ba 188 return NRF_SUCCESS;
marcozecchini 0:9fca2b23d0ba 189 }
marcozecchini 0:9fca2b23d0ba 190
marcozecchini 0:9fca2b23d0ba 191 bool nrf_drv_gpiote_is_init(void)
marcozecchini 0:9fca2b23d0ba 192 {
marcozecchini 0:9fca2b23d0ba 193 return (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) ? true : false;
marcozecchini 0:9fca2b23d0ba 194 }
marcozecchini 0:9fca2b23d0ba 195
marcozecchini 0:9fca2b23d0ba 196 void nrf_drv_gpiote_uninit(void)
marcozecchini 0:9fca2b23d0ba 197 {
marcozecchini 0:9fca2b23d0ba 198 ASSERT(m_cb.state!=NRF_DRV_STATE_UNINITIALIZED);
marcozecchini 0:9fca2b23d0ba 199
marcozecchini 0:9fca2b23d0ba 200 uint32_t i;
marcozecchini 0:9fca2b23d0ba 201 for (i = 0; i < NUMBER_OF_PINS; i++)
marcozecchini 0:9fca2b23d0ba 202 {
marcozecchini 0:9fca2b23d0ba 203 if (pin_in_use_as_non_task_out(i))
marcozecchini 0:9fca2b23d0ba 204 {
marcozecchini 0:9fca2b23d0ba 205 nrf_drv_gpiote_out_uninit(i);
marcozecchini 0:9fca2b23d0ba 206 }
marcozecchini 0:9fca2b23d0ba 207 else if( pin_in_use_by_gpiote(i))
marcozecchini 0:9fca2b23d0ba 208 {
marcozecchini 0:9fca2b23d0ba 209 /* Disable gpiote_in is having the same effect on out pin as gpiote_out_uninit on
marcozecchini 0:9fca2b23d0ba 210 * so it can be called on all pins used by GPIOTE.
marcozecchini 0:9fca2b23d0ba 211 */
marcozecchini 0:9fca2b23d0ba 212 nrf_drv_gpiote_in_uninit(i);
marcozecchini 0:9fca2b23d0ba 213 }
marcozecchini 0:9fca2b23d0ba 214 }
marcozecchini 0:9fca2b23d0ba 215 m_cb.state = NRF_DRV_STATE_UNINITIALIZED;
marcozecchini 0:9fca2b23d0ba 216 }
marcozecchini 0:9fca2b23d0ba 217
marcozecchini 0:9fca2b23d0ba 218 ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin,
marcozecchini 0:9fca2b23d0ba 219 nrf_drv_gpiote_out_config_t const * p_config)
marcozecchini 0:9fca2b23d0ba 220 {
marcozecchini 0:9fca2b23d0ba 221 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 222 ASSERT(m_cb.state == NRF_DRV_STATE_INITIALIZED);
marcozecchini 0:9fca2b23d0ba 223 ASSERT(p_config);
marcozecchini 0:9fca2b23d0ba 224
marcozecchini 0:9fca2b23d0ba 225 ret_code_t result = NRF_SUCCESS;
marcozecchini 0:9fca2b23d0ba 226
marcozecchini 0:9fca2b23d0ba 227 if (pin_in_use(pin))
marcozecchini 0:9fca2b23d0ba 228 {
marcozecchini 0:9fca2b23d0ba 229 result = NRF_ERROR_INVALID_STATE;
marcozecchini 0:9fca2b23d0ba 230 }
marcozecchini 0:9fca2b23d0ba 231 else
marcozecchini 0:9fca2b23d0ba 232 {
marcozecchini 0:9fca2b23d0ba 233 if (p_config->task_pin)
marcozecchini 0:9fca2b23d0ba 234 {
marcozecchini 0:9fca2b23d0ba 235 int8_t channel = channel_port_alloc(pin, NULL, true);
marcozecchini 0:9fca2b23d0ba 236
marcozecchini 0:9fca2b23d0ba 237 if (channel != NO_CHANNELS)
marcozecchini 0:9fca2b23d0ba 238 {
marcozecchini 0:9fca2b23d0ba 239 nrf_gpiote_task_configure(channel, pin, p_config->action, p_config->init_state);
marcozecchini 0:9fca2b23d0ba 240 }
marcozecchini 0:9fca2b23d0ba 241 else
marcozecchini 0:9fca2b23d0ba 242 {
marcozecchini 0:9fca2b23d0ba 243 result = NRF_ERROR_NO_MEM;
marcozecchini 0:9fca2b23d0ba 244 }
marcozecchini 0:9fca2b23d0ba 245 }
marcozecchini 0:9fca2b23d0ba 246 else
marcozecchini 0:9fca2b23d0ba 247 {
marcozecchini 0:9fca2b23d0ba 248 pin_in_use_set(pin);
marcozecchini 0:9fca2b23d0ba 249 }
marcozecchini 0:9fca2b23d0ba 250
marcozecchini 0:9fca2b23d0ba 251 if (result == NRF_SUCCESS)
marcozecchini 0:9fca2b23d0ba 252 {
marcozecchini 0:9fca2b23d0ba 253 if (p_config->init_state == NRF_GPIOTE_INITIAL_VALUE_HIGH)
marcozecchini 0:9fca2b23d0ba 254 {
marcozecchini 0:9fca2b23d0ba 255 nrf_gpio_pin_set(pin);
marcozecchini 0:9fca2b23d0ba 256 }
marcozecchini 0:9fca2b23d0ba 257 else
marcozecchini 0:9fca2b23d0ba 258 {
marcozecchini 0:9fca2b23d0ba 259 nrf_gpio_pin_clear(pin);
marcozecchini 0:9fca2b23d0ba 260 }
marcozecchini 0:9fca2b23d0ba 261
marcozecchini 0:9fca2b23d0ba 262 nrf_gpio_cfg_output(pin);
marcozecchini 0:9fca2b23d0ba 263 }
marcozecchini 0:9fca2b23d0ba 264 }
marcozecchini 0:9fca2b23d0ba 265
marcozecchini 0:9fca2b23d0ba 266 return result;
marcozecchini 0:9fca2b23d0ba 267 }
marcozecchini 0:9fca2b23d0ba 268
marcozecchini 0:9fca2b23d0ba 269 void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 270 {
marcozecchini 0:9fca2b23d0ba 271 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 272 ASSERT(pin_in_use(pin));
marcozecchini 0:9fca2b23d0ba 273
marcozecchini 0:9fca2b23d0ba 274 if (pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 275 {
marcozecchini 0:9fca2b23d0ba 276 channel_free((uint8_t)channel_port_get(pin));
marcozecchini 0:9fca2b23d0ba 277 nrf_gpiote_te_default(channel_port_get(pin));
marcozecchini 0:9fca2b23d0ba 278 }
marcozecchini 0:9fca2b23d0ba 279 pin_in_use_clear(pin);
marcozecchini 0:9fca2b23d0ba 280
marcozecchini 0:9fca2b23d0ba 281 nrf_gpio_cfg_default(pin);
marcozecchini 0:9fca2b23d0ba 282 }
marcozecchini 0:9fca2b23d0ba 283
marcozecchini 0:9fca2b23d0ba 284 void nrf_drv_gpiote_out_set(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 285 {
marcozecchini 0:9fca2b23d0ba 286 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 287 ASSERT(pin_in_use(pin));
marcozecchini 0:9fca2b23d0ba 288 ASSERT(!pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 289
marcozecchini 0:9fca2b23d0ba 290 nrf_gpio_pin_set(pin);
marcozecchini 0:9fca2b23d0ba 291 }
marcozecchini 0:9fca2b23d0ba 292
marcozecchini 0:9fca2b23d0ba 293 void nrf_drv_gpiote_out_clear(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 294 {
marcozecchini 0:9fca2b23d0ba 295 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 296 ASSERT(pin_in_use(pin));
marcozecchini 0:9fca2b23d0ba 297 ASSERT(!pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 298
marcozecchini 0:9fca2b23d0ba 299 nrf_gpio_pin_clear(pin);
marcozecchini 0:9fca2b23d0ba 300 }
marcozecchini 0:9fca2b23d0ba 301
marcozecchini 0:9fca2b23d0ba 302 void nrf_drv_gpiote_out_toggle(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 303 {
marcozecchini 0:9fca2b23d0ba 304 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 305 ASSERT(pin_in_use(pin));
marcozecchini 0:9fca2b23d0ba 306 ASSERT(!pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 307
marcozecchini 0:9fca2b23d0ba 308 nrf_gpio_pin_toggle(pin);
marcozecchini 0:9fca2b23d0ba 309 }
marcozecchini 0:9fca2b23d0ba 310
marcozecchini 0:9fca2b23d0ba 311 void nrf_drv_gpiote_out_task_enable(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 312 {
marcozecchini 0:9fca2b23d0ba 313 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 314 ASSERT(pin_in_use(pin));
marcozecchini 0:9fca2b23d0ba 315 ASSERT(pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 316
marcozecchini 0:9fca2b23d0ba 317 nrf_gpiote_task_enable(m_cb.pin_assignments[pin]);
marcozecchini 0:9fca2b23d0ba 318 }
marcozecchini 0:9fca2b23d0ba 319
marcozecchini 0:9fca2b23d0ba 320 void nrf_drv_gpiote_out_task_disable(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 321 {
marcozecchini 0:9fca2b23d0ba 322 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 323 ASSERT(pin_in_use(pin));
marcozecchini 0:9fca2b23d0ba 324 ASSERT(pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 325
marcozecchini 0:9fca2b23d0ba 326 nrf_gpiote_task_disable(m_cb.pin_assignments[pin]);
marcozecchini 0:9fca2b23d0ba 327 }
marcozecchini 0:9fca2b23d0ba 328
marcozecchini 0:9fca2b23d0ba 329 uint32_t nrf_drv_gpiote_out_task_addr_get(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 330 {
marcozecchini 0:9fca2b23d0ba 331 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 332 ASSERT(pin_in_use_by_te(pin));
marcozecchini 0:9fca2b23d0ba 333
marcozecchini 0:9fca2b23d0ba 334 nrf_gpiote_tasks_t task = TE_IDX_TO_TASK_ADDR(channel_port_get(pin));
marcozecchini 0:9fca2b23d0ba 335 return nrf_gpiote_task_addr_get(task);
marcozecchini 0:9fca2b23d0ba 336 }
marcozecchini 0:9fca2b23d0ba 337
marcozecchini 0:9fca2b23d0ba 338 void nrf_drv_gpiote_out_task_force(nrf_drv_gpiote_pin_t pin, uint8_t state)
marcozecchini 0:9fca2b23d0ba 339 {
marcozecchini 0:9fca2b23d0ba 340 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 341 ASSERT(pin_in_use(pin));
marcozecchini 0:9fca2b23d0ba 342 ASSERT(pin_in_use_by_te(pin));
marcozecchini 0:9fca2b23d0ba 343
marcozecchini 0:9fca2b23d0ba 344 nrf_gpiote_outinit_t init_val = state ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW;
marcozecchini 0:9fca2b23d0ba 345 nrf_gpiote_task_force(m_cb.pin_assignments[pin], init_val);
marcozecchini 0:9fca2b23d0ba 346 }
marcozecchini 0:9fca2b23d0ba 347
marcozecchini 0:9fca2b23d0ba 348 void nrf_drv_gpiote_out_task_trigger(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 349 {
marcozecchini 0:9fca2b23d0ba 350 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 351 ASSERT(pin_in_use(pin));
marcozecchini 0:9fca2b23d0ba 352 ASSERT(pin_in_use_by_te(pin));
marcozecchini 0:9fca2b23d0ba 353
marcozecchini 0:9fca2b23d0ba 354 nrf_gpiote_tasks_t task = TE_IDX_TO_TASK_ADDR(channel_port_get(pin));;
marcozecchini 0:9fca2b23d0ba 355 nrf_gpiote_task_set(task);
marcozecchini 0:9fca2b23d0ba 356 }
marcozecchini 0:9fca2b23d0ba 357
marcozecchini 0:9fca2b23d0ba 358 ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin,
marcozecchini 0:9fca2b23d0ba 359 nrf_drv_gpiote_in_config_t const * p_config,
marcozecchini 0:9fca2b23d0ba 360 nrf_drv_gpiote_evt_handler_t evt_handler)
marcozecchini 0:9fca2b23d0ba 361 {
marcozecchini 0:9fca2b23d0ba 362 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 363 ret_code_t result = NRF_SUCCESS;
marcozecchini 0:9fca2b23d0ba 364 /* Only one GPIOTE channel can be assigned to one physical pin. */
marcozecchini 0:9fca2b23d0ba 365 if (pin_in_use_by_gpiote(pin))
marcozecchini 0:9fca2b23d0ba 366 {
marcozecchini 0:9fca2b23d0ba 367 result = NRF_ERROR_INVALID_STATE;
marcozecchini 0:9fca2b23d0ba 368 }
marcozecchini 0:9fca2b23d0ba 369 else
marcozecchini 0:9fca2b23d0ba 370 {
marcozecchini 0:9fca2b23d0ba 371 int8_t channel = channel_port_alloc(pin, evt_handler, p_config->hi_accuracy);
marcozecchini 0:9fca2b23d0ba 372 if (channel != NO_CHANNELS)
marcozecchini 0:9fca2b23d0ba 373 {
marcozecchini 0:9fca2b23d0ba 374 if (p_config->is_watcher)
marcozecchini 0:9fca2b23d0ba 375 {
marcozecchini 0:9fca2b23d0ba 376 nrf_gpio_cfg_watcher(pin);
marcozecchini 0:9fca2b23d0ba 377 }
marcozecchini 0:9fca2b23d0ba 378 else
marcozecchini 0:9fca2b23d0ba 379 {
marcozecchini 0:9fca2b23d0ba 380 nrf_gpio_cfg_input(pin,p_config->pull);
marcozecchini 0:9fca2b23d0ba 381 }
marcozecchini 0:9fca2b23d0ba 382
marcozecchini 0:9fca2b23d0ba 383 if (p_config->hi_accuracy)
marcozecchini 0:9fca2b23d0ba 384 {
marcozecchini 0:9fca2b23d0ba 385 nrf_gpiote_event_configure(channel, pin,p_config->sense);
marcozecchini 0:9fca2b23d0ba 386 }
marcozecchini 0:9fca2b23d0ba 387 else
marcozecchini 0:9fca2b23d0ba 388 {
marcozecchini 0:9fca2b23d0ba 389 m_cb.port_handlers_pins[channel-NUMBER_OF_GPIO_TE] |= (p_config->sense)<< SENSE_FIELD_POS;
marcozecchini 0:9fca2b23d0ba 390 }
marcozecchini 0:9fca2b23d0ba 391 }
marcozecchini 0:9fca2b23d0ba 392 else
marcozecchini 0:9fca2b23d0ba 393 {
marcozecchini 0:9fca2b23d0ba 394 result = NRF_ERROR_NO_MEM;
marcozecchini 0:9fca2b23d0ba 395 }
marcozecchini 0:9fca2b23d0ba 396 }
marcozecchini 0:9fca2b23d0ba 397 return result;
marcozecchini 0:9fca2b23d0ba 398 }
marcozecchini 0:9fca2b23d0ba 399
marcozecchini 0:9fca2b23d0ba 400 void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable)
marcozecchini 0:9fca2b23d0ba 401 {
marcozecchini 0:9fca2b23d0ba 402 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 403 ASSERT(pin_in_use_by_gpiote(pin));
marcozecchini 0:9fca2b23d0ba 404 if (pin_in_use_by_port(pin))
marcozecchini 0:9fca2b23d0ba 405 {
marcozecchini 0:9fca2b23d0ba 406 uint8_t pin_and_sense = m_cb.port_handlers_pins[channel_port_get(pin)-NUMBER_OF_GPIO_TE];
marcozecchini 0:9fca2b23d0ba 407 nrf_gpiote_polarity_t polarity = (nrf_gpiote_polarity_t)(pin_and_sense >> SENSE_FIELD_POS);
marcozecchini 0:9fca2b23d0ba 408 nrf_gpio_pin_sense_t sense;
marcozecchini 0:9fca2b23d0ba 409 if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
marcozecchini 0:9fca2b23d0ba 410 {
marcozecchini 0:9fca2b23d0ba 411 /* read current pin state and set for next sense to oposit */
marcozecchini 0:9fca2b23d0ba 412 sense = (nrf_gpio_pins_read() & (1 << pin)) ?
marcozecchini 0:9fca2b23d0ba 413 NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;
marcozecchini 0:9fca2b23d0ba 414 }
marcozecchini 0:9fca2b23d0ba 415 else
marcozecchini 0:9fca2b23d0ba 416 {
marcozecchini 0:9fca2b23d0ba 417 sense = (polarity == NRF_GPIOTE_POLARITY_LOTOHI) ?
marcozecchini 0:9fca2b23d0ba 418 NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW;
marcozecchini 0:9fca2b23d0ba 419 }
marcozecchini 0:9fca2b23d0ba 420 nrf_gpio_cfg_sense_set(pin,sense);
marcozecchini 0:9fca2b23d0ba 421 }
marcozecchini 0:9fca2b23d0ba 422 else if(pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 423 {
marcozecchini 0:9fca2b23d0ba 424 int32_t channel = (int32_t)channel_port_get(pin);
marcozecchini 0:9fca2b23d0ba 425 nrf_gpiote_events_t event = TE_IDX_TO_EVENT_ADDR(channel);
marcozecchini 0:9fca2b23d0ba 426
marcozecchini 0:9fca2b23d0ba 427 nrf_gpiote_event_enable(channel);
marcozecchini 0:9fca2b23d0ba 428
marcozecchini 0:9fca2b23d0ba 429 nrf_gpiote_event_clear(event);
marcozecchini 0:9fca2b23d0ba 430 if (int_enable)
marcozecchini 0:9fca2b23d0ba 431 {
marcozecchini 0:9fca2b23d0ba 432 nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(channel_port_get(pin));
marcozecchini 0:9fca2b23d0ba 433 // Enable the interrupt only if event handler was provided.
marcozecchini 0:9fca2b23d0ba 434 if (handler)
marcozecchini 0:9fca2b23d0ba 435 {
marcozecchini 0:9fca2b23d0ba 436 nrf_gpiote_int_enable(1 << channel);
marcozecchini 0:9fca2b23d0ba 437 }
marcozecchini 0:9fca2b23d0ba 438 }
marcozecchini 0:9fca2b23d0ba 439 }
marcozecchini 0:9fca2b23d0ba 440 }
marcozecchini 0:9fca2b23d0ba 441
marcozecchini 0:9fca2b23d0ba 442 void nrf_drv_gpiote_in_event_disable(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 443 {
marcozecchini 0:9fca2b23d0ba 444 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 445 ASSERT(pin_in_use_by_gpiote(pin));
marcozecchini 0:9fca2b23d0ba 446 if (pin_in_use_by_port(pin))
marcozecchini 0:9fca2b23d0ba 447 {
marcozecchini 0:9fca2b23d0ba 448 nrf_gpio_cfg_sense_set(pin,NRF_GPIO_PIN_NOSENSE);
marcozecchini 0:9fca2b23d0ba 449 }
marcozecchini 0:9fca2b23d0ba 450 else if(pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 451 {
marcozecchini 0:9fca2b23d0ba 452 int32_t channel = (int32_t)channel_port_get(pin);
marcozecchini 0:9fca2b23d0ba 453 nrf_gpiote_event_disable(channel);
marcozecchini 0:9fca2b23d0ba 454 nrf_gpiote_int_disable(1 << channel);
marcozecchini 0:9fca2b23d0ba 455 }
marcozecchini 0:9fca2b23d0ba 456 }
marcozecchini 0:9fca2b23d0ba 457
marcozecchini 0:9fca2b23d0ba 458 void nrf_drv_gpiote_in_uninit(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 459 {
marcozecchini 0:9fca2b23d0ba 460 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 461 ASSERT(pin_in_use_by_gpiote(pin));
marcozecchini 0:9fca2b23d0ba 462 nrf_drv_gpiote_in_event_disable(pin);
marcozecchini 0:9fca2b23d0ba 463 if(pin_in_use_by_te(pin))
marcozecchini 0:9fca2b23d0ba 464 {
marcozecchini 0:9fca2b23d0ba 465 nrf_gpiote_te_default(channel_port_get(pin));
marcozecchini 0:9fca2b23d0ba 466 }
marcozecchini 0:9fca2b23d0ba 467 nrf_gpio_cfg_default(pin);
marcozecchini 0:9fca2b23d0ba 468 channel_free((uint8_t)channel_port_get(pin));
marcozecchini 0:9fca2b23d0ba 469 pin_in_use_clear(pin);
marcozecchini 0:9fca2b23d0ba 470 }
marcozecchini 0:9fca2b23d0ba 471
marcozecchini 0:9fca2b23d0ba 472 bool nrf_drv_gpiote_in_is_set(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 473 {
marcozecchini 0:9fca2b23d0ba 474 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 475 return nrf_gpio_pin_read(pin) ? true : false;
marcozecchini 0:9fca2b23d0ba 476 }
marcozecchini 0:9fca2b23d0ba 477
marcozecchini 0:9fca2b23d0ba 478 uint32_t nrf_drv_gpiote_in_event_addr_get(nrf_drv_gpiote_pin_t pin)
marcozecchini 0:9fca2b23d0ba 479 {
marcozecchini 0:9fca2b23d0ba 480 ASSERT(pin < NUMBER_OF_PINS);
marcozecchini 0:9fca2b23d0ba 481 ASSERT(pin_in_use_by_te(pin));
marcozecchini 0:9fca2b23d0ba 482
marcozecchini 0:9fca2b23d0ba 483 nrf_gpiote_events_t event = TE_IDX_TO_EVENT_ADDR(channel_port_get(pin));
marcozecchini 0:9fca2b23d0ba 484 return nrf_gpiote_event_addr_get(event);
marcozecchini 0:9fca2b23d0ba 485 }
marcozecchini 0:9fca2b23d0ba 486
marcozecchini 0:9fca2b23d0ba 487 void GPIOTE_IRQHandler(void)
marcozecchini 0:9fca2b23d0ba 488 {
marcozecchini 0:9fca2b23d0ba 489 uint32_t status = 0;
marcozecchini 0:9fca2b23d0ba 490 uint32_t input = 0;
marcozecchini 0:9fca2b23d0ba 491
marcozecchini 0:9fca2b23d0ba 492 /* collect status of all GPIOTE pin events. Processing is done once all are collected and cleared.*/
marcozecchini 0:9fca2b23d0ba 493 uint32_t i;
marcozecchini 0:9fca2b23d0ba 494 nrf_gpiote_events_t event = NRF_GPIOTE_EVENTS_IN_0;
marcozecchini 0:9fca2b23d0ba 495 uint32_t mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK;
marcozecchini 0:9fca2b23d0ba 496 for (i = 0; i < NUMBER_OF_GPIO_TE; i++)
marcozecchini 0:9fca2b23d0ba 497 {
marcozecchini 0:9fca2b23d0ba 498 if (nrf_gpiote_event_is_set(event) && nrf_gpiote_int_is_enabled(mask))
marcozecchini 0:9fca2b23d0ba 499 {
marcozecchini 0:9fca2b23d0ba 500 nrf_gpiote_event_clear(event);
marcozecchini 0:9fca2b23d0ba 501 status |= mask;
marcozecchini 0:9fca2b23d0ba 502 }
marcozecchini 0:9fca2b23d0ba 503 mask <<= 1;
marcozecchini 0:9fca2b23d0ba 504 /* Incrementing to next event, utilizing the fact that events are grouped together
marcozecchini 0:9fca2b23d0ba 505 * in ascending order. */
marcozecchini 0:9fca2b23d0ba 506 event = (nrf_gpiote_events_t)((uint32_t)event + sizeof(uint32_t));
marcozecchini 0:9fca2b23d0ba 507 }
marcozecchini 0:9fca2b23d0ba 508
marcozecchini 0:9fca2b23d0ba 509 /* collect PORT status event, if event is set read pins state. Processing is postponed to the
marcozecchini 0:9fca2b23d0ba 510 * end of interrupt. */
marcozecchini 0:9fca2b23d0ba 511 if (nrf_gpiote_event_is_set(NRF_GPIOTE_EVENTS_PORT))
marcozecchini 0:9fca2b23d0ba 512 {
marcozecchini 0:9fca2b23d0ba 513 nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT);
marcozecchini 0:9fca2b23d0ba 514 status |= (uint32_t)NRF_GPIOTE_INT_PORT_MASK;
marcozecchini 0:9fca2b23d0ba 515 input = nrf_gpio_pins_read();
marcozecchini 0:9fca2b23d0ba 516 }
marcozecchini 0:9fca2b23d0ba 517
marcozecchini 0:9fca2b23d0ba 518 /* Process pin events. */
marcozecchini 0:9fca2b23d0ba 519 if (status & NRF_GPIOTE_INT_IN_MASK)
marcozecchini 0:9fca2b23d0ba 520 {
marcozecchini 0:9fca2b23d0ba 521 mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK;
marcozecchini 0:9fca2b23d0ba 522 for (i = 0; i < NUMBER_OF_GPIO_TE; i++)
marcozecchini 0:9fca2b23d0ba 523 {
marcozecchini 0:9fca2b23d0ba 524 if (mask & status)
marcozecchini 0:9fca2b23d0ba 525 {
marcozecchini 0:9fca2b23d0ba 526 nrf_drv_gpiote_pin_t pin = nrf_gpiote_event_pin_get(i);
marcozecchini 0:9fca2b23d0ba 527 nrf_gpiote_polarity_t polarity = nrf_gpiote_event_polarity_get(i);
marcozecchini 0:9fca2b23d0ba 528 nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(i);
marcozecchini 0:9fca2b23d0ba 529 handler(pin,polarity);
marcozecchini 0:9fca2b23d0ba 530 }
marcozecchini 0:9fca2b23d0ba 531 mask <<= 1;
marcozecchini 0:9fca2b23d0ba 532 }
marcozecchini 0:9fca2b23d0ba 533 }
marcozecchini 0:9fca2b23d0ba 534
marcozecchini 0:9fca2b23d0ba 535 if (status & (uint32_t)NRF_GPIOTE_INT_PORT_MASK)
marcozecchini 0:9fca2b23d0ba 536 {
marcozecchini 0:9fca2b23d0ba 537 /* Process port event. */
marcozecchini 0:9fca2b23d0ba 538 uint8_t repeat = 0;
marcozecchini 0:9fca2b23d0ba 539 uint32_t toggle_mask = 0;
marcozecchini 0:9fca2b23d0ba 540 uint32_t pins_to_check = 0xFFFFFFFFuL;
marcozecchini 0:9fca2b23d0ba 541
marcozecchini 0:9fca2b23d0ba 542 do
marcozecchini 0:9fca2b23d0ba 543 {
marcozecchini 0:9fca2b23d0ba 544 repeat = 0;
marcozecchini 0:9fca2b23d0ba 545 for (i = 0; i < GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++)
marcozecchini 0:9fca2b23d0ba 546 {
marcozecchini 0:9fca2b23d0ba 547 uint8_t pin_and_sense = m_cb.port_handlers_pins[i];
marcozecchini 0:9fca2b23d0ba 548 nrf_drv_gpiote_pin_t pin = (pin_and_sense & ~SENSE_FIELD_MASK);
marcozecchini 0:9fca2b23d0ba 549
marcozecchini 0:9fca2b23d0ba 550 if ((m_cb.port_handlers_pins[i] != PIN_NOT_USED)
marcozecchini 0:9fca2b23d0ba 551 && ((1UL << pin) & pins_to_check))
marcozecchini 0:9fca2b23d0ba 552 {
marcozecchini 0:9fca2b23d0ba 553 nrf_gpiote_polarity_t polarity =
marcozecchini 0:9fca2b23d0ba 554 (nrf_gpiote_polarity_t)((pin_and_sense & SENSE_FIELD_MASK) >> SENSE_FIELD_POS);
marcozecchini 0:9fca2b23d0ba 555 nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(channel_port_get(pin));
marcozecchini 0:9fca2b23d0ba 556 if (handler || polarity == NRF_GPIOTE_POLARITY_TOGGLE)
marcozecchini 0:9fca2b23d0ba 557 {
marcozecchini 0:9fca2b23d0ba 558 mask = 1 << pin;
marcozecchini 0:9fca2b23d0ba 559 if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
marcozecchini 0:9fca2b23d0ba 560 {
marcozecchini 0:9fca2b23d0ba 561 toggle_mask |= mask;
marcozecchini 0:9fca2b23d0ba 562 }
marcozecchini 0:9fca2b23d0ba 563 nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
marcozecchini 0:9fca2b23d0ba 564
marcozecchini 0:9fca2b23d0ba 565 if (((mask & input) && (sense==NRF_GPIO_PIN_SENSE_HIGH)) ||
marcozecchini 0:9fca2b23d0ba 566 (!(mask & input) && (sense==NRF_GPIO_PIN_SENSE_LOW)) )
marcozecchini 0:9fca2b23d0ba 567 {
marcozecchini 0:9fca2b23d0ba 568 if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
marcozecchini 0:9fca2b23d0ba 569 {
marcozecchini 0:9fca2b23d0ba 570 nrf_gpio_pin_sense_t next_sense = (sense == NRF_GPIO_PIN_SENSE_HIGH) ?
marcozecchini 0:9fca2b23d0ba 571 NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;
marcozecchini 0:9fca2b23d0ba 572 nrf_gpio_cfg_sense_set(pin, next_sense);
marcozecchini 0:9fca2b23d0ba 573 ++repeat;
marcozecchini 0:9fca2b23d0ba 574 }
marcozecchini 0:9fca2b23d0ba 575 if (handler)
marcozecchini 0:9fca2b23d0ba 576 {
marcozecchini 0:9fca2b23d0ba 577 handler(pin, polarity);
marcozecchini 0:9fca2b23d0ba 578 }
marcozecchini 0:9fca2b23d0ba 579 }
marcozecchini 0:9fca2b23d0ba 580 }
marcozecchini 0:9fca2b23d0ba 581 }
marcozecchini 0:9fca2b23d0ba 582 }
marcozecchini 0:9fca2b23d0ba 583
marcozecchini 0:9fca2b23d0ba 584 if (repeat)
marcozecchini 0:9fca2b23d0ba 585 {
marcozecchini 0:9fca2b23d0ba 586 // When one of the pins in low-accuracy and toggle mode becomes active,
marcozecchini 0:9fca2b23d0ba 587 // it's sense mode is inverted to clear the internal SENSE signal.
marcozecchini 0:9fca2b23d0ba 588 // State of any other enabled low-accuracy input in toggle mode must be checked
marcozecchini 0:9fca2b23d0ba 589 // explicitly, because it does not trigger the interrput when SENSE signal is active.
marcozecchini 0:9fca2b23d0ba 590 // For more information about SENSE functionality, refer to Product Specification.
marcozecchini 0:9fca2b23d0ba 591 uint32_t new_input = nrf_gpio_pins_read();
marcozecchini 0:9fca2b23d0ba 592 if (new_input == input)
marcozecchini 0:9fca2b23d0ba 593 {
marcozecchini 0:9fca2b23d0ba 594 //No change.
marcozecchini 0:9fca2b23d0ba 595 repeat = 0;
marcozecchini 0:9fca2b23d0ba 596 }
marcozecchini 0:9fca2b23d0ba 597 else
marcozecchini 0:9fca2b23d0ba 598 {
marcozecchini 0:9fca2b23d0ba 599 input = new_input;
marcozecchini 0:9fca2b23d0ba 600 pins_to_check = toggle_mask;
marcozecchini 0:9fca2b23d0ba 601 }
marcozecchini 0:9fca2b23d0ba 602 }
marcozecchini 0:9fca2b23d0ba 603 }
marcozecchini 0:9fca2b23d0ba 604 while (repeat);
marcozecchini 0:9fca2b23d0ba 605 }
marcozecchini 0:9fca2b23d0ba 606 }
marcozecchini 0:9fca2b23d0ba 607 //lint -restore