Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mbed-os/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_SDK11/drivers_nrf/gpiote/nrf_drv_gpiote.c@0:9fca2b23d0ba, 2019-02-23 (annotated)
- Committer:
- marcozecchini
- Date:
- Sat Feb 23 12:13:36 2019 +0000
- Revision:
- 0:9fca2b23d0ba
final commit
Who changed what in which revision?
| User | Revision | Line number | New 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 |