nrfx_gpiote.c 25 KB

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