gpio.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. /**
  2. * \file
  3. *
  4. * \brief SAM GPIO Driver for SAMB11
  5. *
  6. * Copyright (C) 2015-2016 Atmel Corporation. All rights reserved.
  7. *
  8. * \asf_license_start
  9. *
  10. * \page License
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright notice,
  16. * this list of conditions and the following disclaimer.
  17. *
  18. * 2. Redistributions in binary form must reproduce the above copyright notice,
  19. * this list of conditions and the following disclaimer in the documentation
  20. * and/or other materials provided with the distribution.
  21. *
  22. * 3. The name of Atmel may not be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * 4. This software may only be redistributed and used in connection with an
  26. * Atmel microcontroller product.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  29. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  30. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  31. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  32. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  36. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * \asf_license_stop
  41. *
  42. */
  43. /*
  44. * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
  45. */
  46. #include <gpio.h>
  47. /**
  48. * \internal
  49. * Internal driver device instance struct.
  50. */
  51. struct gpio_module _gpio_instances[3];
  52. static void (*aon_handle_ext_wakeup_isr)(void) = (void (*)(void))0x1bc51;
  53. /**
  54. * \brief Initializes a gpio pin/group configuration structure to defaults.
  55. *
  56. * Initializes a given gpio pin/group configuration structure to a set of
  57. * known default values. This function should be called on all new
  58. * instances of these configuration structures before being modified by the
  59. * user application.
  60. *
  61. * The default configuration is as follows:
  62. * \li Input mode with internal pullup enabled
  63. *
  64. * \param[out] config Configuration structure to initialize to default values.
  65. */
  66. void gpio_get_config_defaults(struct gpio_config *const config)
  67. {
  68. /* Default configuration values */
  69. config->direction = GPIO_PIN_DIR_INPUT;
  70. config->input_pull = GPIO_PIN_PULL_UP;
  71. config->powersave = false;
  72. config->aon_wakeup = false;
  73. }
  74. /**
  75. * \brief Writes a gpio pin configuration to the hardware module.
  76. *
  77. * Writes out a given configuration of a gpio pin configuration to the hardware
  78. * module. If the configuration is NULL then it releases the gpio pin.
  79. *
  80. * \note If the pin direction is set as an output, the pull-up/pull-down input
  81. * configuration setting is ignored. Also certain gpio pin is used by
  82. * FW and not available for user application. Please \ref gpio_pin
  83. * for list of gpio_pin available.
  84. *
  85. * \param[in] gpio_pin Index of the GPIO pin to configure.
  86. * \param[in] config Configuration settings for the pin.
  87. *
  88. * \return Status of initialization.
  89. * \retval STATUS_OK gpio configured correctly
  90. * \retval STATUS_ERR_INVALID_ARG Invalid gpio number, Certain gpios
  91. * are used by FW and not allowed to change.
  92. * \retval STATUS_RESOURCE_NOT_AVAILABLE Requested gpio is already in use.
  93. *
  94. */
  95. enum status_code gpio_pin_set_config(const uint8_t gpio_pin,
  96. const struct gpio_config *config)
  97. {
  98. enum status_code status = STATUS_OK;
  99. /* Following GPIO's should never be modified by user.
  100. * GPIO_0 & GPIO_1 are used for SWD.
  101. */
  102. if ((gpio_pin == PIN_LP_GPIO_0) || \
  103. (gpio_pin == PIN_LP_GPIO_1))
  104. {
  105. status = STATUS_ERR_INVALID_ARG;
  106. } else {
  107. if (gpio_pin <= 7) {
  108. LPMCU_MISC_REGS0->PINMUX_SEL_0.reg &= ~(7 << ((gpio_pin % 8) * 4));
  109. } else if (gpio_pin <= 15) {
  110. LPMCU_MISC_REGS0->PINMUX_SEL_1.reg &= ~(7 << ((gpio_pin % 8) * 4));
  111. } else if (gpio_pin <= 23) {
  112. LPMCU_MISC_REGS0->PINMUX_SEL_2.reg &= ~(7 << ((gpio_pin % 8) * 4));
  113. } else if (44 <= gpio_pin && gpio_pin < 48) {
  114. /* Set GPIO_MSx as digital mode */
  115. AON_GP_REGS0->MS_GPIO_MODE.vec.ANALOG_ENABLE_ &= ~(1 << (gpio_pin - PIN_GPIO_MS4));
  116. }
  117. if ((gpio_pin == PIN_AO_GPIO_0) || (gpio_pin == PIN_AO_GPIO_1) ||
  118. (gpio_pin == PIN_AO_GPIO_2)) {
  119. /* Active Low, Always On Pull Enable Control */
  120. if (config->input_pull == GPIO_PIN_PULL_UP) {
  121. AON_GP_REGS0->AON_PULL_ENABLE.reg &= ~(1 << (31 - gpio_pin));
  122. } else {
  123. AON_GP_REGS0->AON_PULL_ENABLE.reg |= 1 << (31 - gpio_pin);
  124. }
  125. if (config->aon_wakeup) {
  126. /* Enable AON_GPIO_x to be a wakeup MCU from sleep mode */
  127. AON_GP_REGS0->AON_PINMUX_SEL.reg |= 1 << (4 * (31 - gpio_pin));
  128. /* Enable AON_GPIO_x to wake up the BLE domain from sleep mode */
  129. AON_PWR_SEQ0->GPIO_WAKEUP_CTRL.bit.BLE_ENABLE = 1;
  130. }
  131. } else {
  132. if(config->direction == GPIO_PIN_DIR_INPUT) {
  133. if(gpio_pin < 16) {
  134. GPIO0->OUTENCLR.reg = (1 << gpio_pin);
  135. } else if (gpio_pin < 32){
  136. GPIO1->OUTENCLR.reg = (1 << (gpio_pin % 16));
  137. } else {
  138. GPIO2->OUTENCLR.reg = (1 << (gpio_pin % 16));
  139. }
  140. /* pull_enable. */
  141. if (gpio_pin < 32) {
  142. switch(config->input_pull) {
  143. case GPIO_PIN_PULL_NONE:
  144. LPMCU_MISC_REGS0->PULL_ENABLE.reg |= (1 << gpio_pin);
  145. break;
  146. case GPIO_PIN_PULL_UP:
  147. LPMCU_MISC_REGS0->PULL_ENABLE.reg &= ~(1 << gpio_pin);
  148. break;
  149. case GPIO_PIN_PULL_DOWN:
  150. /* Set R-Type */
  151. LPMCU_MISC_REGS0->RTYPE_PAD_0.reg |= (1 << gpio_pin);
  152. /* Set REN */
  153. LPMCU_MISC_REGS0->PULL_ENABLE.reg &= ~(1 << gpio_pin);
  154. break;
  155. default:
  156. status = STATUS_ERR_INVALID_ARG;
  157. break;
  158. }
  159. }
  160. } else if(config->direction == GPIO_PIN_DIR_OUTPUT) {
  161. if (gpio_pin < 16) {
  162. GPIO0->OUTENSET.reg = (1 << gpio_pin);
  163. } else if (gpio_pin < 32) {
  164. GPIO1->OUTENSET.reg = (1 << (gpio_pin % 16));
  165. } else {
  166. GPIO2->OUTENSET.reg = (1 << (gpio_pin % 16));
  167. }
  168. }
  169. }
  170. }
  171. return status;
  172. }
  173. /**
  174. * \brief Retrieves the state of a gpio pin that is configured as an input.
  175. *
  176. * Reads the current logic level of a gpio pin and returns the current
  177. * level as a boolean value.
  178. *
  179. * \param[in] gpio_pin Index of the GPIO pin to read.
  180. *
  181. * \return Status of the gpio pin's input buffer.
  182. */
  183. bool gpio_pin_get_input_level(const uint8_t gpio_pin)
  184. {
  185. uint32_t regval = 0;
  186. if (gpio_pin < 16) {
  187. regval = GPIO0->DATA.reg;
  188. regval &= (1 << gpio_pin);
  189. } else if (gpio_pin < 32) {
  190. regval = GPIO1->DATA.reg;
  191. regval &= (1 << (gpio_pin % 16));
  192. } else {
  193. regval = GPIO2->DATA.reg;
  194. regval &= (1 << (gpio_pin % 16));
  195. }
  196. return regval;
  197. }
  198. /**
  199. * \brief Retrieves the state of a gpio pin that is configured as an output.
  200. *
  201. * Reads the current logical output level of a gpio pin and returns the current
  202. * level as a boolean value.
  203. *
  204. * \param[in] gpio_pin Index of the GPIO pin to read.
  205. *
  206. * \return Status of the gpio pin's output buffer.
  207. */
  208. bool gpio_pin_get_output_level(const uint8_t gpio_pin)
  209. {
  210. uint32_t regval = 0;
  211. if (gpio_pin < 16) {
  212. regval = GPIO0->DATAOUT.reg;
  213. regval &= (1 << gpio_pin);
  214. } else if (gpio_pin < 32) {
  215. regval = GPIO1->DATAOUT.reg;
  216. regval &= (1 << (gpio_pin % 16));
  217. } else {
  218. regval = GPIO2->DATAOUT.reg;
  219. regval &= (1 << (gpio_pin % 16));
  220. }
  221. return regval;
  222. }
  223. /**
  224. * \brief Sets the state of a gpio pin that is configured as an output.
  225. *
  226. * Sets the current output level of a gpio pin to a given logic level.
  227. *
  228. * \param[in] gpio_pin Index of the GPIO pin to write to.
  229. * \param[in] level Logical level to set the given pin to.
  230. */
  231. void gpio_pin_set_output_level(const uint8_t gpio_pin, const bool level)
  232. {
  233. if (gpio_pin < 16) {
  234. if(level) {
  235. GPIO0->DATAOUT.reg |= (1 << gpio_pin);
  236. } else {
  237. GPIO0->DATAOUT.reg &= ~(1 << gpio_pin);
  238. }
  239. } else if (gpio_pin < 32) {
  240. if(level) {
  241. GPIO1->DATAOUT.reg |= (1 << (gpio_pin % 16));
  242. } else {
  243. GPIO1->DATAOUT.reg &= ~(1 << (gpio_pin % 16));
  244. }
  245. } else {
  246. if(level) {
  247. GPIO2->DATAOUT.reg |= (1 << (gpio_pin % 16));
  248. } else {
  249. GPIO2->DATAOUT.reg &= ~(1 << (gpio_pin % 16));
  250. }
  251. }
  252. }
  253. /**
  254. * \brief Toggles the state of a gpio pin that is configured as an output.
  255. *
  256. * Toggles the current output level of a gpio pin.
  257. *
  258. * \param[in] gpio_pin Index of the GPIO pin to toggle.
  259. */
  260. void gpio_pin_toggle_output_level(const uint8_t gpio_pin)
  261. {
  262. if (gpio_pin < 16) {
  263. GPIO0->DATAOUT.reg ^= (1 << gpio_pin);
  264. } else if (gpio_pin < 32) {
  265. GPIO1->DATAOUT.reg ^= (1 << (gpio_pin % 16));
  266. } else {
  267. GPIO2->DATAOUT.reg ^= (1 << (gpio_pin % 16));
  268. }
  269. }
  270. /**
  271. * \brief Writes a GPIO pin configuration to the hardware module.
  272. *
  273. * Writes out a given configuration of a GPIO pin configuration to the hardware
  274. * module.
  275. *
  276. * \param[in] gpio_pin Index of the GPIO pin to toggle.
  277. * \param[in] pinmux_sel PINMUX selection.
  278. */
  279. void gpio_pinmux_cofiguration(const uint8_t gpio_pin, uint16_t pinmux_sel)
  280. {
  281. uint8_t megamux_sel = (pinmux_sel >> 8) & 0xFF;
  282. pinmux_sel &= 0xFF;
  283. if (gpio_pin <= 7) {
  284. LPMCU_MISC_REGS0->PINMUX_SEL_0.reg &= ~(7 << ((gpio_pin % 8) * 4));
  285. LPMCU_MISC_REGS0->PINMUX_SEL_0.reg |= (pinmux_sel << ((gpio_pin % 8)*4));
  286. if (pinmux_sel == 0x01) {
  287. if (gpio_pin <= 3) {
  288. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_0.reg &= ~(0x3F << ((gpio_pin % 4) * 8));
  289. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_0.reg |= (megamux_sel << ((gpio_pin % 4) * 8));
  290. } else if (gpio_pin <= 7) {
  291. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_1.reg &= ~(0x3F << ((gpio_pin % 4) * 8));
  292. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_1.reg |= (megamux_sel << ((gpio_pin % 4) * 8));
  293. }
  294. }
  295. } else if (gpio_pin <= 15) {
  296. LPMCU_MISC_REGS0->PINMUX_SEL_1.reg &= ~(7 << ((gpio_pin % 8) * 4));
  297. LPMCU_MISC_REGS0->PINMUX_SEL_1.reg |= (pinmux_sel << ((gpio_pin % 8)*4));
  298. if (pinmux_sel == 0x01) {
  299. if (gpio_pin <= 11) {
  300. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_2.reg &= ~(0x3F << ((gpio_pin % 4) * 8));
  301. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_2.reg |= (megamux_sel << ((gpio_pin % 4) * 8));
  302. } else if (gpio_pin <= 15) {
  303. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_3.reg &= ~(0x3F << ((gpio_pin % 4) * 8));
  304. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_3.reg |= (megamux_sel << ((gpio_pin % 4) * 8));
  305. }
  306. }
  307. } else if (gpio_pin <= 23) {
  308. LPMCU_MISC_REGS0->PINMUX_SEL_2.reg &= ~(7 << ((gpio_pin % 8) * 4));
  309. LPMCU_MISC_REGS0->PINMUX_SEL_2.reg |= (pinmux_sel << ((gpio_pin % 8)*4));
  310. if (pinmux_sel == 0x01) {
  311. if (gpio_pin <= 19) {
  312. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_4.reg &= ~(0x3F << ((gpio_pin % 4) * 8));
  313. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_4.reg |= (megamux_sel << ((gpio_pin % 4) * 8));
  314. } else if (gpio_pin <= 23) {
  315. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_5.reg &= ~(0x3F << ((gpio_pin % 4) * 8));
  316. LPMCU_MISC_REGS0->MEGA_MUX_IO_SEL_5.reg |= (megamux_sel << ((gpio_pin % 4) * 8));
  317. }
  318. }
  319. }
  320. }
  321. /**
  322. * \brief Registers a callback
  323. *
  324. * Registers a callback function which is implemented by the user.
  325. *
  326. * \note The callback must be enabled by \ref gpio_enable_callback,
  327. * in order for the interrupt handler to call it when the conditions for
  328. * the callback type are met.
  329. *
  330. * \param[in] gpio_pin GPIO pin number
  331. * \param[in] callback_func Pointer to callback function
  332. * \param[in] callback_type Callback type given by an enum
  333. *
  334. */
  335. void gpio_register_callback(uint8_t gpio_pin, gpio_callback_t callback_func,
  336. enum gpio_callback callback_type)
  337. {
  338. /* Sanity check arguments */
  339. Assert(callback_func);
  340. Assert(gpio_pin < 48);
  341. uint8_t gpio_port = 0;
  342. if (gpio_pin < 16) {
  343. gpio_port = 0;
  344. } else if (gpio_pin < 32) {
  345. gpio_port = 1;
  346. } else {
  347. gpio_port = 2;
  348. }
  349. switch (callback_type) {
  350. case GPIO_CALLBACK_LOW:
  351. _gpio_instances[gpio_port].hw->INTTYPECLR.reg = 1 << (gpio_pin % 16);
  352. _gpio_instances[gpio_port].hw->INTPOLCLR.reg = 1 << (gpio_pin % 16);
  353. break;
  354. case GPIO_CALLBACK_HIGH:
  355. _gpio_instances[gpio_port].hw->INTTYPECLR.reg = 1 << (gpio_pin % 16);
  356. _gpio_instances[gpio_port].hw->INTPOLSET.reg = 1 << (gpio_pin % 16);
  357. break;
  358. case GPIO_CALLBACK_RISING:
  359. _gpio_instances[gpio_port].hw->INTTYPESET.reg = 1 << (gpio_pin % 16);
  360. _gpio_instances[gpio_port].hw->INTPOLSET.reg = 1 << (gpio_pin % 16);
  361. break;
  362. case GPIO_CALLBACK_FALLING:
  363. _gpio_instances[gpio_port].hw->INTTYPESET.reg = 1 << (gpio_pin % 16);
  364. _gpio_instances[gpio_port].hw->INTPOLCLR.reg = (1 << (gpio_pin % 16));
  365. break;
  366. case GPIO_CALLBACK_N:
  367. break;
  368. }
  369. /* Register callback function */
  370. _gpio_instances[gpio_port].callback[gpio_pin % 16] = callback_func;
  371. /* Set the bit corresponding to the gpio pin */
  372. _gpio_instances[gpio_port].callback_reg_mask |= (1 << (gpio_pin % 16));
  373. }
  374. /**
  375. * \brief Unregisters a callback
  376. *
  377. * Unregisters a callback function which is implemented by the user.
  378. *
  379. *
  380. * \param[in] gpio_pin GPIO pin number
  381. * \param[in] callback_type Callback type given by an enum
  382. *
  383. */
  384. void gpio_unregister_callback(uint8_t gpio_pin,
  385. enum gpio_callback callback_type)
  386. {
  387. /* Sanity check arguments */
  388. Assert(callback_func);
  389. Assert(gpio_pin < 48);
  390. uint8_t gpio_port = 0;
  391. if (gpio_pin < 16) {
  392. gpio_port = 0;
  393. } else if (gpio_pin < 32) {
  394. gpio_port = 1;
  395. } else {
  396. gpio_port = 2;
  397. }
  398. /* Unregister callback function */
  399. _gpio_instances[gpio_port].callback[gpio_pin % 16] = NULL;
  400. /* Set the bit corresponding to the gpio pin */
  401. _gpio_instances[gpio_port].callback_reg_mask &= ~(1 << (gpio_pin % 16));
  402. }
  403. /**
  404. * \brief Enables callback
  405. *
  406. * Enables the callback function registered by the \ref gpio_register_callback.
  407. * The callback function will be called from the interrupt handler when the
  408. * conditions for the callback type are met.
  409. *
  410. * \param[in] gpio_pin GPIO pin
  411. */
  412. void gpio_enable_callback(uint8_t gpio_pin)
  413. {
  414. Assert(gpio_pin < 48);
  415. uint8_t gpio_port = 0;
  416. if (gpio_pin < 16) {
  417. gpio_port = 0;
  418. NVIC_EnableIRQ(GPIO0_IRQn);
  419. } else if (gpio_pin < 32) {
  420. gpio_port = 1;
  421. NVIC_EnableIRQ(GPIO1_IRQn);
  422. } else {
  423. gpio_port = 2;
  424. NVIC_EnableIRQ(GPIO2_IRQn);
  425. }
  426. /* Enable callback */
  427. _gpio_instances[gpio_port].callback_enable_mask |= (1 << (gpio_pin % 16));
  428. _gpio_instances[gpio_port].hw->INTENSET.reg = (1 << (gpio_pin % 16));
  429. }
  430. /**
  431. * \brief Disables callback
  432. *
  433. * Disables the callback function registered by the \ref usart_register_callback.
  434. * The callback function will not be called from the interrupt handler.
  435. *
  436. * \param[in] gpio_pin GPIO pin
  437. */
  438. void gpio_disable_callback(uint8_t gpio_pin)
  439. {
  440. Assert(gpio_pin < 48);
  441. uint8_t gpio_port = 0;
  442. if (gpio_pin < 16) {
  443. gpio_port = 0;
  444. } else if (gpio_pin < 32) {
  445. gpio_port = 1;
  446. } else {
  447. gpio_port = 2;
  448. }
  449. /* Enable callback */
  450. _gpio_instances[gpio_port].callback_enable_mask &= ~(1 << (gpio_pin % 16));
  451. _gpio_instances[gpio_port].hw->INTENCLR.reg = (1 << (gpio_pin % 16));
  452. }
  453. /**
  454. * \internal GPIO port0 isr handler.
  455. *
  456. * This function will enter interrupt.
  457. *
  458. */
  459. static void gpio_port0_isr_handler(void)
  460. {
  461. uint32_t flag = _gpio_instances[0].hw->INTSTATUSCLEAR.reg;
  462. for (uint8_t i = 0; i < 16; i++){
  463. if (flag & (1 << i)) {
  464. /* Clear interrupt flag */
  465. _gpio_instances[0].hw->INTSTATUSCLEAR.reg = (1 << i);
  466. if ((_gpio_instances[0].callback_enable_mask & (1 << i)) && \
  467. (_gpio_instances[0].callback_reg_mask & (1 << i)))
  468. _gpio_instances[0].callback[i]();
  469. break;
  470. }
  471. }
  472. NVIC_ClearPendingIRQ(GPIO0_IRQn);
  473. }
  474. /**
  475. * \internal GPIO port1 isr handler.
  476. *
  477. * This function will enter interrupt.
  478. *
  479. */
  480. static void gpio_port1_isr_handler(void)
  481. {
  482. uint32_t flag = _gpio_instances[1].hw->INTSTATUSCLEAR.reg;
  483. for (uint8_t i = 0; i < 16; i++){
  484. /* For AON wakeup pin clear interrupt */
  485. if (flag & ((1<<15) | (1<<14) | (1<<13))) {
  486. aon_handle_ext_wakeup_isr();
  487. }
  488. if (flag & (1 << i)) {
  489. /* Clear interrupt flag */
  490. _gpio_instances[1].hw->INTSTATUSCLEAR.reg = (1 << i);
  491. if ((_gpio_instances[1].callback_enable_mask & (1 << i)) && \
  492. (_gpio_instances[1].callback_reg_mask & (1 << i))) {
  493. _gpio_instances[1].callback[i]();
  494. break;
  495. }
  496. }
  497. }
  498. NVIC_ClearPendingIRQ(GPIO1_IRQn);
  499. }
  500. /**
  501. * \internal GPIO port2 isr handler.
  502. *
  503. * This function will enter interrupt.
  504. *
  505. */
  506. static void gpio_port2_isr_handler(void)
  507. {
  508. uint32_t flag = _gpio_instances[2].hw->INTSTATUSCLEAR.reg;
  509. for (uint8_t i = 12; i < 16; i++){
  510. if (flag & (1 << i)) {
  511. /* Clear interrupt flag */
  512. _gpio_instances[2].hw->INTSTATUSCLEAR.reg = (1 << i);
  513. if ((_gpio_instances[2].callback_enable_mask & (1 << i)) && \
  514. (_gpio_instances[2].callback_reg_mask & (1 << i)))
  515. _gpio_instances[2].callback[i]();
  516. break;
  517. }
  518. }
  519. NVIC_ClearPendingIRQ(GPIO2_IRQn);
  520. }
  521. /**
  522. * \internal GPIO callback init.
  523. *
  524. * This function will init GPIO callback.
  525. *
  526. */
  527. void gpio_init(void)
  528. {
  529. uint8_t i, j;
  530. for(i = 0; i < 3; i++) {
  531. for(j = 0; j < 16; j++) {
  532. _gpio_instances[i].callback[j] = NULL;
  533. }
  534. _gpio_instances[i].callback_enable_mask = 0;
  535. _gpio_instances[i].callback_reg_mask = 0;
  536. }
  537. _gpio_instances[0].hw = (void *)GPIO0;
  538. _gpio_instances[1].hw = (void *)GPIO1;
  539. _gpio_instances[2].hw = (void *)GPIO2;
  540. system_register_isr(RAM_ISR_TABLE_PORT0_COMB_INDEX, (uint32_t)gpio_port0_isr_handler);
  541. system_register_isr(RAM_ISR_TABLE_PORT1_COMB_INDEX, (uint32_t)gpio_port1_isr_handler);
  542. system_register_isr(RAM_ISR_TABLE_PORT2_COMB_INDEX, (uint32_t)gpio_port2_isr_handler);
  543. }