nrf_drv_gpiote.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. #include "nrf_drv_gpiote.h"
  13. #include "nrf_drv_common.h"
  14. #include "nrf_drv_config.h"
  15. #include "app_util_platform.h"
  16. #include "nrf_assert.h"
  17. #define FORBIDDEN_HANDLER_ADDRESS ((nrf_drv_gpiote_evt_handler_t)UINT32_MAX)
  18. #define PIN_NOT_USED (-1)
  19. #define PIN_USED (-2)
  20. #define NO_CHANNELS (-1)
  21. #define SENSE_FIELD_POS (6)
  22. #define SENSE_FIELD_MASK (0xC0)
  23. /**
  24. * @brief Macro for conveting task-event index to an address of an event register.
  25. *
  26. * Macro utilizes the fact that registers are grouped together in ascending order.
  27. */
  28. #define TE_IDX_TO_EVENT_ADDR(idx) (nrf_gpiote_events_t)((uint32_t)NRF_GPIOTE_EVENTS_IN_0+(sizeof(uint32_t)*(idx)))
  29. /**
  30. * @brief Macro for conveting task-event index to an address of a task register.
  31. *
  32. * Macro utilizes the fact that registers are grouped together in ascending order.
  33. */
  34. #define TE_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_OUT_0+(sizeof(uint32_t)*(idx)))
  35. //lint -save -e661
  36. typedef struct
  37. {
  38. nrf_drv_gpiote_evt_handler_t handlers[NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];
  39. int8_t pin_assignments[NUMBER_OF_PINS];
  40. int8_t port_handlers_pins[GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];
  41. nrf_drv_state_t state;
  42. } gpiote_control_block_t;
  43. static gpiote_control_block_t m_cb;
  44. __STATIC_INLINE bool pin_in_use(uint32_t pin)
  45. {
  46. return (m_cb.pin_assignments[pin] != PIN_NOT_USED);
  47. }
  48. __STATIC_INLINE bool pin_in_use_as_non_task_out(uint32_t pin)
  49. {
  50. return (m_cb.pin_assignments[pin] == PIN_USED);
  51. }
  52. __STATIC_INLINE bool pin_in_use_by_te(uint32_t pin)
  53. {
  54. return (m_cb.pin_assignments[pin] >= 0 && m_cb.pin_assignments[pin] < NUMBER_OF_GPIO_TE) ? true : false;
  55. }
  56. __STATIC_INLINE bool pin_in_use_by_port(uint32_t pin)
  57. {
  58. return (m_cb.pin_assignments[pin] >= NUMBER_OF_GPIO_TE);
  59. }
  60. __STATIC_INLINE bool pin_in_use_by_gpiote(uint32_t pin)
  61. {
  62. return (m_cb.pin_assignments[pin] >= 0);
  63. }
  64. __STATIC_INLINE void pin_in_use_by_te_set(uint32_t pin,
  65. uint32_t channel_id,
  66. nrf_drv_gpiote_evt_handler_t handler,
  67. bool is_channel)
  68. {
  69. m_cb.pin_assignments[pin] = channel_id;
  70. m_cb.handlers[channel_id] = handler;
  71. if (!is_channel)
  72. {
  73. m_cb.port_handlers_pins[channel_id-NUMBER_OF_GPIO_TE] = (int8_t)pin;
  74. }
  75. }
  76. __STATIC_INLINE void pin_in_use_set(uint32_t pin)
  77. {
  78. m_cb.pin_assignments[pin] = PIN_USED;
  79. }
  80. __STATIC_INLINE void pin_in_use_clear(uint32_t pin)
  81. {
  82. m_cb.pin_assignments[pin] = PIN_NOT_USED;
  83. }
  84. __STATIC_INLINE int8_t channel_port_get(uint32_t pin)
  85. {
  86. return m_cb.pin_assignments[pin];
  87. }
  88. __STATIC_INLINE nrf_drv_gpiote_evt_handler_t channel_handler_get(uint32_t channel)
  89. {
  90. return m_cb.handlers[channel];
  91. }
  92. static int8_t channel_port_alloc(uint32_t pin,nrf_drv_gpiote_evt_handler_t handler, bool channel)
  93. {
  94. int8_t channel_id = NO_CHANNELS;
  95. uint32_t i;
  96. uint32_t start_idx = channel ? 0 : NUMBER_OF_GPIO_TE;
  97. uint32_t end_idx = channel ? NUMBER_OF_GPIO_TE : (NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS);
  98. //critical section
  99. for (i = start_idx; i < end_idx; i++)
  100. {
  101. if (m_cb.handlers[i] == FORBIDDEN_HANDLER_ADDRESS)
  102. {
  103. pin_in_use_by_te_set(pin, i, handler, channel);
  104. channel_id = i;
  105. break;
  106. }
  107. }
  108. //critical section
  109. return channel_id;
  110. }
  111. static void channel_free(uint8_t channel_id)
  112. {
  113. m_cb.handlers[channel_id] = FORBIDDEN_HANDLER_ADDRESS;
  114. if (channel_id >= NUMBER_OF_GPIO_TE)
  115. {
  116. m_cb.port_handlers_pins[channel_id-NUMBER_OF_GPIO_TE] = (int8_t)PIN_NOT_USED;
  117. }
  118. }
  119. ret_code_t nrf_drv_gpiote_init(void)
  120. {
  121. if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
  122. {
  123. return NRF_ERROR_INVALID_STATE;
  124. }
  125. uint8_t i;
  126. for (i = 0; i < NUMBER_OF_PINS; i++)
  127. {
  128. pin_in_use_clear(i);
  129. }
  130. for (i = 0; i < (NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); i++)
  131. {
  132. channel_free(i);
  133. }
  134. nrf_drv_common_irq_enable(GPIOTE_IRQn, GPIOTE_CONFIG_IRQ_PRIORITY);
  135. nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk);
  136. m_cb.state = NRF_DRV_STATE_INITIALIZED;
  137. return NRF_SUCCESS;
  138. }
  139. bool nrf_drv_gpiote_is_init(void)
  140. {
  141. return (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) ? true : false;
  142. }
  143. void nrf_drv_gpiote_uninit(void)
  144. {
  145. ASSERT(m_cb.state!=NRF_DRV_STATE_UNINITIALIZED);
  146. uint32_t i;
  147. for (i = 0; i < NUMBER_OF_PINS; i++)
  148. {
  149. if (pin_in_use_as_non_task_out(i))
  150. {
  151. nrf_drv_gpiote_out_uninit(i);
  152. }
  153. else if( pin_in_use_by_gpiote(i))
  154. {
  155. /* Disable gpiote_in is having the same effect on out pin as gpiote_out_uninit on
  156. * so it can be called on all pins used by GPIOTE.
  157. */
  158. nrf_drv_gpiote_in_uninit(i);
  159. }
  160. }
  161. m_cb.state = NRF_DRV_STATE_UNINITIALIZED;
  162. }
  163. ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin,
  164. nrf_drv_gpiote_out_config_t const * p_config)
  165. {
  166. ASSERT(pin < NUMBER_OF_PINS);
  167. ASSERT(m_cb.state == NRF_DRV_STATE_INITIALIZED);
  168. ASSERT(p_config);
  169. ret_code_t result = NRF_SUCCESS;
  170. if (pin_in_use(pin))
  171. {
  172. result = NRF_ERROR_INVALID_STATE;
  173. }
  174. else
  175. {
  176. if (p_config->task_pin)
  177. {
  178. int8_t channel = channel_port_alloc(pin, NULL, true);
  179. if (channel != NO_CHANNELS)
  180. {
  181. nrf_gpiote_task_configure(channel, pin, p_config->action, p_config->init_state);
  182. }
  183. else
  184. {
  185. result = NRF_ERROR_NO_MEM;
  186. }
  187. }
  188. else
  189. {
  190. pin_in_use_set(pin);
  191. }
  192. if (result == NRF_SUCCESS)
  193. {
  194. if (p_config->init_state == NRF_GPIOTE_INITIAL_VALUE_HIGH)
  195. {
  196. nrf_gpio_pin_set(pin);
  197. }
  198. else
  199. {
  200. nrf_gpio_pin_clear(pin);
  201. }
  202. nrf_gpio_cfg_output(pin);
  203. }
  204. }
  205. return result;
  206. }
  207. void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin)
  208. {
  209. ASSERT(pin < NUMBER_OF_PINS);
  210. ASSERT(pin_in_use(pin));
  211. if (pin_in_use_by_te(pin))
  212. {
  213. channel_free((uint8_t)channel_port_get(pin));
  214. nrf_gpiote_te_default(channel_port_get(pin));
  215. }
  216. pin_in_use_clear(pin);
  217. nrf_gpio_cfg_default(pin);
  218. }
  219. void nrf_drv_gpiote_out_set(nrf_drv_gpiote_pin_t pin)
  220. {
  221. ASSERT(pin < NUMBER_OF_PINS);
  222. ASSERT(pin_in_use(pin));
  223. ASSERT(!pin_in_use_by_te(pin))
  224. nrf_gpio_pin_set(pin);
  225. }
  226. void nrf_drv_gpiote_out_clear(nrf_drv_gpiote_pin_t pin)
  227. {
  228. ASSERT(pin < NUMBER_OF_PINS);
  229. ASSERT(pin_in_use(pin));
  230. ASSERT(!pin_in_use_by_te(pin))
  231. nrf_gpio_pin_clear(pin);
  232. }
  233. void nrf_drv_gpiote_out_toggle(nrf_drv_gpiote_pin_t pin)
  234. {
  235. ASSERT(pin < NUMBER_OF_PINS);
  236. ASSERT(pin_in_use(pin));
  237. ASSERT(!pin_in_use_by_te(pin))
  238. nrf_gpio_pin_toggle(pin);
  239. }
  240. void nrf_drv_gpiote_out_task_enable(nrf_drv_gpiote_pin_t pin)
  241. {
  242. ASSERT(pin < NUMBER_OF_PINS);
  243. ASSERT(pin_in_use(pin));
  244. ASSERT(pin_in_use_by_te(pin))
  245. nrf_gpiote_task_enable(m_cb.pin_assignments[pin]);
  246. }
  247. void nrf_drv_gpiote_out_task_disable(nrf_drv_gpiote_pin_t pin)
  248. {
  249. ASSERT(pin < NUMBER_OF_PINS);
  250. ASSERT(pin_in_use(pin));
  251. ASSERT(pin_in_use_by_te(pin))
  252. nrf_gpiote_task_disable(m_cb.pin_assignments[pin]);
  253. }
  254. uint32_t nrf_drv_gpiote_out_task_addr_get(nrf_drv_gpiote_pin_t pin)
  255. {
  256. ASSERT(pin < NUMBER_OF_PINS);
  257. ASSERT(pin_in_use_by_te(pin));
  258. nrf_gpiote_tasks_t task = TE_IDX_TO_TASK_ADDR(channel_port_get(pin));
  259. return nrf_gpiote_task_addr_get(task);
  260. }
  261. void nrf_drv_gpiote_out_task_force(nrf_drv_gpiote_pin_t pin, uint8_t state)
  262. {
  263. ASSERT(pin < NUMBER_OF_PINS);
  264. ASSERT(pin_in_use(pin));
  265. ASSERT(pin_in_use_by_te(pin));
  266. nrf_gpiote_outinit_t init_val = state ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW;
  267. nrf_gpiote_task_force(m_cb.pin_assignments[pin], init_val);
  268. }
  269. void nrf_drv_gpiote_out_task_trigger(nrf_drv_gpiote_pin_t pin)
  270. {
  271. ASSERT(pin < NUMBER_OF_PINS);
  272. ASSERT(pin_in_use(pin));
  273. ASSERT(pin_in_use_by_te(pin));
  274. nrf_gpiote_tasks_t task = TE_IDX_TO_TASK_ADDR(channel_port_get(pin));;
  275. nrf_gpiote_task_set(task);
  276. }
  277. ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin,
  278. nrf_drv_gpiote_in_config_t const * p_config,
  279. nrf_drv_gpiote_evt_handler_t evt_handler)
  280. {
  281. ASSERT(pin < NUMBER_OF_PINS);
  282. ret_code_t result = NRF_SUCCESS;
  283. /* Only one GPIOTE channel can be assigned to one physical pin. */
  284. if (pin_in_use_by_gpiote(pin))
  285. {
  286. result = NRF_ERROR_INVALID_STATE;
  287. }
  288. else
  289. {
  290. int8_t channel = channel_port_alloc(pin, evt_handler, p_config->hi_accuracy);
  291. if (channel != NO_CHANNELS)
  292. {
  293. if (p_config->is_watcher)
  294. {
  295. nrf_gpio_cfg_watcher(pin);
  296. }
  297. else
  298. {
  299. nrf_gpio_cfg_input(pin,p_config->pull);
  300. }
  301. if (p_config->hi_accuracy)
  302. {
  303. nrf_gpiote_event_configure(channel, pin,p_config->sense);
  304. }
  305. else
  306. {
  307. m_cb.port_handlers_pins[channel-NUMBER_OF_GPIO_TE] |= (p_config->sense)<< SENSE_FIELD_POS;
  308. }
  309. }
  310. else
  311. {
  312. result = NRF_ERROR_NO_MEM;
  313. }
  314. }
  315. return result;
  316. }
  317. void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable)
  318. {
  319. ASSERT(pin < NUMBER_OF_PINS);
  320. ASSERT(pin_in_use_by_gpiote(pin));
  321. if (pin_in_use_by_port(pin))
  322. {
  323. uint8_t pin_and_sense = m_cb.port_handlers_pins[channel_port_get(pin)-NUMBER_OF_GPIO_TE];
  324. nrf_gpiote_polarity_t polarity = (nrf_gpiote_polarity_t)(pin_and_sense >> SENSE_FIELD_POS);
  325. nrf_gpio_pin_sense_t sense;
  326. if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
  327. {
  328. /* read current pin state and set for next sense to oposit */
  329. sense = (nrf_gpio_pins_read() & (1 << pin)) ?
  330. NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;
  331. }
  332. else
  333. {
  334. sense = (polarity == NRF_GPIOTE_POLARITY_LOTOHI) ?
  335. NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW;
  336. }
  337. nrf_gpio_cfg_sense_set(pin,sense);
  338. }
  339. else if(pin_in_use_by_te(pin))
  340. {
  341. int32_t channel = (int32_t)channel_port_get(pin);
  342. nrf_gpiote_events_t event = TE_IDX_TO_EVENT_ADDR(channel);
  343. nrf_gpiote_event_enable(channel);
  344. nrf_gpiote_event_clear(event);
  345. if (int_enable)
  346. {
  347. nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(channel_port_get(pin));
  348. // Enable the interrupt only if event handler was provided.
  349. if (handler)
  350. {
  351. nrf_gpiote_int_enable(1 << channel);
  352. }
  353. }
  354. }
  355. }
  356. void nrf_drv_gpiote_in_event_disable(nrf_drv_gpiote_pin_t pin)
  357. {
  358. ASSERT(pin < NUMBER_OF_PINS);
  359. ASSERT(pin_in_use_by_gpiote(pin));
  360. if (pin_in_use_by_port(pin))
  361. {
  362. nrf_gpio_cfg_sense_set(pin,NRF_GPIO_PIN_NOSENSE);
  363. }
  364. else if(pin_in_use_by_te(pin))
  365. {
  366. int32_t channel = (int32_t)channel_port_get(pin);
  367. nrf_gpiote_event_disable(channel);
  368. nrf_gpiote_int_disable(1 << channel);
  369. }
  370. }
  371. void nrf_drv_gpiote_in_uninit(nrf_drv_gpiote_pin_t pin)
  372. {
  373. ASSERT(pin < NUMBER_OF_PINS);
  374. ASSERT(pin_in_use_by_gpiote(pin));
  375. nrf_drv_gpiote_in_event_disable(pin);
  376. if(pin_in_use_by_te(pin))
  377. {
  378. nrf_gpiote_te_default(channel_port_get(pin));
  379. }
  380. nrf_gpio_cfg_default(pin);
  381. channel_free((uint8_t)channel_port_get(pin));
  382. pin_in_use_clear(pin);
  383. }
  384. bool nrf_drv_gpiote_in_is_set(nrf_drv_gpiote_pin_t pin)
  385. {
  386. ASSERT(pin < NUMBER_OF_PINS);
  387. return nrf_gpio_pin_read(pin) ? true : false;
  388. }
  389. uint32_t nrf_drv_gpiote_in_event_addr_get(nrf_drv_gpiote_pin_t pin)
  390. {
  391. ASSERT(pin < NUMBER_OF_PINS);
  392. ASSERT(pin_in_use_by_te(pin));
  393. nrf_gpiote_events_t event = TE_IDX_TO_EVENT_ADDR(channel_port_get(pin));
  394. return nrf_gpiote_event_addr_get(event);
  395. }
  396. void GPIOTE_IRQHandler(void)
  397. {
  398. uint32_t status = 0;
  399. uint32_t input = 0;
  400. /* collect status of all GPIOTE pin events. Processing is done once all are collected and cleared.*/
  401. uint32_t i;
  402. nrf_gpiote_events_t event = NRF_GPIOTE_EVENTS_IN_0;
  403. uint32_t mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK;
  404. for (i = 0; i < NUMBER_OF_GPIO_TE; i++)
  405. {
  406. if (nrf_gpiote_event_is_set(event) && nrf_gpiote_int_is_enabled(mask))
  407. {
  408. nrf_gpiote_event_clear(event);
  409. status |= mask;
  410. }
  411. mask <<= 1;
  412. /* Incrementing to next event, utilizing the fact that events are grouped together
  413. * in ascending order. */
  414. event = (nrf_gpiote_events_t)((uint32_t)event + sizeof(uint32_t));
  415. }
  416. /* collect PORT status event, if event is set read pins state. Processing is postponed to the
  417. * end of interrupt. */
  418. if (nrf_gpiote_event_is_set(NRF_GPIOTE_EVENTS_PORT))
  419. {
  420. nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT);
  421. status |= (uint32_t)NRF_GPIOTE_INT_PORT_MASK;
  422. input = nrf_gpio_pins_read();
  423. }
  424. /* Process pin events. */
  425. if (status & NRF_GPIOTE_INT_IN_MASK)
  426. {
  427. mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK;
  428. for (i = 0; i < NUMBER_OF_GPIO_TE; i++)
  429. {
  430. if (mask & status)
  431. {
  432. nrf_drv_gpiote_pin_t pin = nrf_gpiote_event_pin_get(i);
  433. nrf_gpiote_polarity_t polarity = nrf_gpiote_event_polarity_get(i);
  434. nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(i);
  435. handler(pin,polarity);
  436. }
  437. mask <<= 1;
  438. }
  439. }
  440. if (status & (uint32_t)NRF_GPIOTE_INT_PORT_MASK)
  441. {
  442. /* Process port event. */
  443. uint8_t repeat = 0;
  444. uint32_t toggle_mask = 0;
  445. uint32_t pins_to_check = 0xFFFFFFFFuL;
  446. do
  447. {
  448. repeat = 0;
  449. for (i = 0; i < GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++)
  450. {
  451. uint8_t pin_and_sense = m_cb.port_handlers_pins[i];
  452. nrf_drv_gpiote_pin_t pin = (pin_and_sense & ~SENSE_FIELD_MASK);
  453. if ((m_cb.port_handlers_pins[i] != PIN_NOT_USED)
  454. && ((1UL << pin) & pins_to_check))
  455. {
  456. nrf_gpiote_polarity_t polarity =
  457. (nrf_gpiote_polarity_t)((pin_and_sense & SENSE_FIELD_MASK) >> SENSE_FIELD_POS);
  458. nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(channel_port_get(pin));
  459. if (handler || polarity == NRF_GPIOTE_POLARITY_TOGGLE)
  460. {
  461. mask = 1 << pin;
  462. if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
  463. {
  464. toggle_mask |= mask;
  465. }
  466. nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
  467. if (((mask & input) && (sense==NRF_GPIO_PIN_SENSE_HIGH)) ||
  468. (!(mask & input) && (sense==NRF_GPIO_PIN_SENSE_LOW)) )
  469. {
  470. if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
  471. {
  472. nrf_gpio_pin_sense_t next_sense = (sense == NRF_GPIO_PIN_SENSE_HIGH) ?
  473. NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;
  474. nrf_gpio_cfg_sense_set(pin, next_sense);
  475. ++repeat;
  476. }
  477. if (handler)
  478. {
  479. handler(pin, polarity);
  480. }
  481. }
  482. }
  483. }
  484. }
  485. if (repeat)
  486. {
  487. // When one of the pins in low-accuracy and toggle mode becomes active,
  488. // it's sense mode is inverted to clear the internal SENSE signal.
  489. // State of any other enabled low-accuracy input in toggle mode must be checked
  490. // explicitly, because it does not trigger the interrput when SENSE signal is active.
  491. // For more information about SENSE functionality, refer to Product Specification.
  492. uint32_t new_input = nrf_gpio_pins_read();
  493. if (new_input == input)
  494. {
  495. //No change.
  496. repeat = 0;
  497. }
  498. else
  499. {
  500. input = new_input;
  501. pins_to_check = toggle_mask;
  502. }
  503. }
  504. }
  505. while (repeat);
  506. }
  507. }
  508. //lint -restore