gpio.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /**************************************************************************************************
  2. Phyplus Microelectronics Limited confidential and proprietary.
  3. All rights reserved.
  4. IMPORTANT: All rights of this software belong to Phyplus Microelectronics
  5. Limited ("Phyplus"). Your use of this Software is limited to those
  6. specific rights granted under the terms of the business contract, the
  7. confidential agreement, the non-disclosure agreement and any other forms
  8. of agreements as a customer or a partner of Phyplus. You may not use this
  9. Software unless you agree to abide by the terms of these agreements.
  10. You acknowledge that the Software may not be modified, copied,
  11. distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
  12. (BLE) integrated circuit, either as a product or is integrated into your
  13. products. Other than for the aforementioned purposes, you may not use,
  14. reproduce, copy, prepare derivative works of, modify, distribute, perform,
  15. display or sell this Software and/or its documentation for any purposes.
  16. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  17. PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  18. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  19. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  20. PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
  21. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  22. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  23. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  24. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  25. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  26. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  27. **************************************************************************************************/
  28. /*******************************************************************************
  29. * @file gpio.c
  30. * @brief Contains all functions support for gpio and iomux driver
  31. * @version 0.0
  32. * @date 19. Oct. 2017
  33. * @author qing.han
  34. *
  35. * Copyright(C) 2016, PhyPlus Semiconductor
  36. * All rights reserved.
  37. *
  38. *******************************************************************************/
  39. #include "types.h"
  40. #include "string.h"
  41. #include "ap_cp.h"
  42. #include "clock.h"
  43. #include "pwrmgr.h"
  44. #include "gpio.h"
  45. #include "error.h"
  46. #include "log.h"
  47. enum {
  48. GPIO_PIN_ASSI_NONE = 0,
  49. GPIO_PIN_ASSI_OUT,
  50. GPIO_PIN_ASSI_IN_IRQ,
  51. GPIO_PIN_ASSI_IN_WAKEUP,
  52. GPIO_PIN_ASSI_IN_IRQ_AND_WAKEUP,
  53. };
  54. typedef struct {
  55. bool enable;
  56. uint8_t pin_state;
  57. gpioin_Hdl_t posedgeHdl;
  58. gpioin_Hdl_t negedgeHdl;
  59. }gpioin_Ctx_t;
  60. typedef struct {
  61. bool state;
  62. uint8_t pin_assignments[NUMBER_OF_PINS];
  63. gpioin_Ctx_t irq_ctx[NUMBER_OF_PINS];
  64. }gpio_Ctx_t;
  65. static gpio_Ctx_t m_gpioCtx = {
  66. .state = FALSE,
  67. .pin_assignments = {0,},
  68. };
  69. static void pad_pe_control(GPIO_Pin_e pin, BitAction_e value) {
  70. uint32_t bit = BIT(pin & 0x1f);
  71. if (value) {
  72. BM_SET(REG_PAD_EN(pin), bit); //set bit
  73. }
  74. else {
  75. BM_CLR(REG_PAD_EN(pin), bit); //clear bit
  76. }
  77. }
  78. //static void pad_ds_control(GPIO_Pin_e pin, BitAction_e value) {
  79. // uint32_t bit = BIT(pin & 0x1f);
  80. // if (value) {
  81. // BM_SET(REG_PAD_DS(pin), bit); //set bit
  82. // }
  83. // else {
  84. // BM_CLR(REG_PAD_DS(pin), bit); //clear bit
  85. // }
  86. //}
  87. static void io_wakeup_control(GPIO_Pin_e pin, BitAction_e value) {
  88. uint32_t bit = BIT(pin & 0x1f);
  89. if (value) {
  90. BM_SET(REG_IO_WAKEUP_EN(pin), bit); //set bit
  91. }
  92. else {
  93. BM_CLR(REG_IO_WAKEUP_EN(pin), bit); //clear bit
  94. }
  95. }
  96. static int gpio_interrupt_enable(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
  97. {
  98. uint32_t gpio_tmp;
  99. if (pin >= NUMBER_OF_IRQ_PINS)
  100. return PPlus_ERR_NOT_SUPPORTED;
  101. gpio_tmp = *(volatile uint32_t *)0x40008038;
  102. gpio_tmp |= (1 << pin); //edge sensitive
  103. *(volatile uint32_t *)0x40008038 = gpio_tmp;
  104. gpio_tmp = *(volatile uint32_t *)0x40008034;
  105. gpio_tmp &= ~(1 << pin); //unmask interrupt
  106. *(volatile uint32_t *)0x40008034 = gpio_tmp;
  107. gpio_tmp = *(volatile uint32_t *)0x4000803c;
  108. if (type == POSEDGE)
  109. gpio_tmp |= (1 << pin);
  110. else
  111. gpio_tmp &= ~(1 << pin);
  112. *(volatile uint32_t *)0x4000803c = gpio_tmp;
  113. gpio_tmp = *(volatile uint32_t *)0x40008030;
  114. gpio_tmp |= (1 << pin); //enable interrupt
  115. *(volatile uint32_t *)0x40008030 = gpio_tmp;
  116. return PPlus_SUCCESS;
  117. }
  118. static int gpio_interrupt_disable(GPIO_Pin_e pin)
  119. {
  120. //enable gpio 15 gpio falling edge intteruput
  121. uint32_t gpio_tmp = *(volatile uint32_t *)0x40008038;
  122. if (pin >= NUMBER_OF_IRQ_PINS)
  123. return PPlus_ERR_NOT_SUPPORTED;
  124. gpio_tmp = *(volatile uint32_t *)0x40008034;
  125. gpio_tmp |= (1 << pin); //mask interrupt
  126. *(volatile uint32_t *)0x40008034 = gpio_tmp;
  127. gpio_tmp = *(volatile uint32_t *)0x40008030;
  128. gpio_tmp &= ~(1 << pin); //disable interrupt
  129. *(volatile uint32_t *)0x40008030 = gpio_tmp;
  130. return PPlus_SUCCESS;
  131. }
  132. static void gpioin_event_pin(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
  133. {
  134. gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
  135. if (p_irq_ctx[pin].posedgeHdl && (type == POSEDGE)) {
  136. //LOG("POS\n");
  137. p_irq_ctx[pin].posedgeHdl(pin,POSEDGE);
  138. }
  139. else if (p_irq_ctx[pin].negedgeHdl && (type == NEGEDGE)) {
  140. //LOG("NEG\n");
  141. p_irq_ctx[pin].negedgeHdl(pin,NEGEDGE);
  142. }
  143. }
  144. static void gpioin_wakeup_trigger(GPIO_Pin_e pin)
  145. {
  146. uint8_t pin_state = (uint8_t)hal_gpio_read(pin);
  147. IO_Wakeup_Pol_e type = pin_state ? POSEDGE : NEGEDGE;
  148. if (m_gpioCtx.irq_ctx[pin].pin_state != pin_state)
  149. gpioin_event_pin(pin, type);
  150. }
  151. static void gpioin_event(uint32 int_status, uint32 polarity)
  152. {
  153. int i;
  154. gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
  155. //LOG("GI:%x,%x\n",int_status,polarity);
  156. for (i = 0; i < NUMBER_OF_IRQ_PINS; i++) {
  157. if (int_status & (1ul << i)) {
  158. IO_Wakeup_Pol_e type = (polarity & BIT(i)) ? POSEDGE : NEGEDGE;
  159. gpioin_event_pin((GPIO_Pin_e)i, type);
  160. //reconfig interrupt
  161. if (p_irq_ctx[i].posedgeHdl && p_irq_ctx[i].negedgeHdl) //both raise and fall
  162. {
  163. type = (type == POSEDGE) ? NEGEDGE : POSEDGE;
  164. gpio_interrupt_enable((GPIO_Pin_e)i, type);
  165. }
  166. else if (p_irq_ctx[i].posedgeHdl) //raise
  167. {
  168. gpio_interrupt_enable((GPIO_Pin_e)i, POSEDGE);
  169. }
  170. else if (p_irq_ctx[i].negedgeHdl) //fall
  171. {
  172. gpio_interrupt_enable((GPIO_Pin_e)i, NEGEDGE);
  173. }
  174. }
  175. }
  176. }
  177. static void gpio_sleep_handler(void)
  178. {
  179. int i;
  180. IO_Wakeup_Pol_e pol;
  181. for (i = 0; i < NUMBER_OF_PINS; i++) {
  182. //config wakeup
  183. if (m_gpioCtx.pin_assignments[i] > GPIO_PIN_ASSI_IN_IRQ)
  184. {
  185. pol = hal_gpio_read((GPIO_Pin_e)i) ? NEGEDGE : POSEDGE;
  186. hal_gpio_wakeup_set((GPIO_Pin_e)i, pol);
  187. }
  188. //prepare interrupt
  189. if (i < NUMBER_OF_PINS &&
  190. (m_gpioCtx.pin_assignments[i] > GPIO_PIN_ASSI_IN_IRQ)
  191. )
  192. {
  193. m_gpioCtx.irq_ctx[i].pin_state = hal_gpio_read((GPIO_Pin_e)i);
  194. }
  195. }
  196. }
  197. static void gpio_wakeup_handler(void)
  198. {
  199. int i;
  200. NVIC_SetPriority((IRQn_Type)GPIO_IRQ, IRQ_PRIO_HAL);
  201. NVIC_EnableIRQ((IRQn_Type)GPIO_IRQ);
  202. for (i = 0; i < NUMBER_OF_PINS; i++) {
  203. if (m_gpioCtx.irq_ctx[i].enable) {
  204. //resume gpio irq
  205. hal_gpioin_enable((GPIO_Pin_e)i);
  206. //trigger gpio irq manually
  207. gpioin_wakeup_trigger((GPIO_Pin_e)i);
  208. }
  209. }
  210. }
  211. /*static*/ int gpio_pin0to3_pin31to34_control(GPIO_Pin_e pin, uint8_t en) {
  212. if (pin < 4) {
  213. if (en) {
  214. write_reg(0x40003814, read_reg(0x40003814) | BIT(pin));
  215. }
  216. else {
  217. write_reg(0x40003814, read_reg(0x40003814)&(~BIT(pin)));
  218. }
  219. }
  220. else {
  221. if (en) {
  222. write_reg(0x40003814, read_reg(0x40003814) | BIT(pin - 18));
  223. }
  224. else {
  225. write_reg(0x40003814, read_reg(0x40003814)&(~BIT(pin - 18)));
  226. }
  227. }
  228. return PPlus_SUCCESS;
  229. }
  230. void __attribute__((used)) hal_GPIO_IRQHandler(void)
  231. {
  232. uint32 polarity = AP_GPIOA->int_polarity;
  233. uint32 st = AP_GPIOA->int_status;
  234. //clear interrupt
  235. AP_GPIOA->porta_eoi = st;
  236. gpioin_event(st, polarity);
  237. }
  238. int hal_gpio_write(GPIO_Pin_e pin, uint8_t en) {
  239. hal_gpio_pin_init(pin, OEN); //set output enable
  240. uint32_t bit;
  241. if (pin < 18) {
  242. bit = BIT(pin);
  243. if (en) {
  244. BM_SET(reg_gpio_swporta_dr, bit); //set pin output(set bit)
  245. }
  246. else {
  247. BM_CLR(reg_gpio_swporta_dr, bit); //set pin input(clear bit)
  248. }
  249. }
  250. else {
  251. bit = BIT(pin - 18);
  252. if (en) {
  253. BM_SET(reg_gpio_swportb_dr, bit); //set pin output(set bit)
  254. }
  255. else {
  256. BM_CLR(reg_gpio_swportb_dr, bit); //set pin input(clear bit)
  257. }
  258. }
  259. return PPlus_SUCCESS;
  260. }
  261. void hal_gpio_fast_write(GPIO_Pin_e pin, uint8_t en) {
  262. uint32_t bit;
  263. if (pin < 18) {
  264. bit = BIT(pin);
  265. if (en) {
  266. BM_SET(reg_gpio_swporta_dr, bit); //set pin output(set bit)
  267. }
  268. else {
  269. BM_CLR(reg_gpio_swporta_dr, bit); //set pin input(clear bit)
  270. }
  271. }
  272. else {
  273. bit = BIT(pin - 18);
  274. if (en) {
  275. BM_SET(reg_gpio_swportb_dr, bit); //set pin output(set bit)
  276. }
  277. else {
  278. BM_CLR(reg_gpio_swportb_dr, bit); //set pin input(clear bit)
  279. }
  280. }
  281. }
  282. int hal_gpio_toggle(GPIO_Pin_e pin) {
  283. hal_gpio_pin_init(pin, OEN); //set output enable
  284. uint32_t bit;
  285. if (pin < 18) {
  286. bit = BIT(pin);
  287. BM_SET(reg_gpio_swporta_dr, bit); //set pin output(set bit)
  288. BM_CLR(reg_gpio_swporta_dr, bit); //set pin input(clear bit)
  289. }
  290. else {
  291. bit = BIT(pin - 18);
  292. BM_SET(reg_gpio_swportb_dr, bit); //set pin output(set bit)
  293. BM_CLR(reg_gpio_swportb_dr, bit); //set pin input(clear bit)
  294. }
  295. return PPlus_SUCCESS;
  296. }
  297. bool hal_gpio_read(GPIO_Pin_e pin)
  298. {
  299. uint32_t r;
  300. uint32_t bit;
  301. uint32_t en;
  302. if (pin < 18) {
  303. bit = BIT(pin);
  304. en = BM_IS_SET(reg_gpio_ioe_porta, bit);
  305. if (en) {
  306. r = read_reg(reg_gpio_swporta_dr);
  307. }
  308. else {
  309. r = read_reg(reg_gpio_ext_porta);
  310. }
  311. r = (r & bit);
  312. }
  313. else {
  314. bit = BIT(pin - 18);
  315. en = BM_IS_SET(reg_gpio_ioe_portb, bit);
  316. if (en) {
  317. r = read_reg(reg_gpio_swportb_dr);
  318. }
  319. else {
  320. r = read_reg(reg_gpio_ext_portb);
  321. }
  322. r = (r & bit);
  323. }
  324. return r ? TRUE : FALSE;
  325. }
  326. int hal_gpio_pin_init(GPIO_Pin_e pin, GPIO_ioe type) {
  327. uint32_t bit;
  328. if ((pin < P4) || ((pin <= P34) && (pin >= P31)))
  329. gpio_pin0to3_pin31to34_control(pin, 1);
  330. hal_gpio_fmux(pin, Bit_DISABLE); //disable fullmux function
  331. if (pin < 18) {
  332. bit = BIT(pin);
  333. if (type) {
  334. BM_SET(reg_gpio_ioe_porta, bit); //set pin output(set bit)
  335. }
  336. else {
  337. BM_CLR(reg_gpio_ioe_porta, bit); //set pin input(clear bit)
  338. }
  339. }
  340. else {
  341. bit = BIT(pin - 18);
  342. if (type) {
  343. BM_SET(reg_gpio_ioe_portb, bit); //set pin output(set bit)
  344. }
  345. else {
  346. BM_CLR(reg_gpio_ioe_portb, bit); //set pin input(clear bit)
  347. }
  348. }
  349. return PPlus_SUCCESS;
  350. }
  351. int hal_gpio_cfg_analog_io(GPIO_Pin_e pin, BitAction_e value) {
  352. uint32_t bit = BIT(pin - 11);
  353. if (value) {
  354. pad_pe_control(pin, Bit_DISABLE); //pad en disable
  355. hal_gpio_pull_set(pin, FLOATING); //set pin pull up/down floating
  356. BM_SET(REG_ANALOG_IO, bit); //set bit
  357. }
  358. else {
  359. BM_CLR(REG_ANALOG_IO, bit); //clear bit
  360. }
  361. return PPlus_SUCCESS;
  362. }
  363. /**************************************************************************************
  364. * @fn hal_gpio_DS_control
  365. *
  366. * @brief This function process for enable or disable pad driver strenth
  367. *
  368. * input parameters
  369. *
  370. * @param GPIO_Pin_e pin: gpio pin number
  371. * BitAction_e value: enable(Bit_ENABLE) or disable(Bit_DISABLE)
  372. *
  373. * output parameters
  374. *
  375. * @param None.
  376. *
  377. * @return None.
  378. **************************************************************************************/
  379. int hal_gpio_DS_control(GPIO_Pin_e pin, BitAction_e value){
  380. uint32_t bit = BIT(pin & 0x1f);
  381. if(value){
  382. BM_SET(REG_PAD_DS(pin), bit); //set bit
  383. }else{
  384. BM_CLR(REG_PAD_DS(pin), bit); //clear bit
  385. }
  386. return PPlus_SUCCESS;
  387. }
  388. int hal_gpio_fmux(GPIO_Pin_e pin, BitAction_e value)
  389. {
  390. uint32_t bit = BIT(pin & 0x1f);
  391. if (value) {
  392. BM_SET(REG_FMUX_EN_FUC(pin), bit);
  393. }
  394. else {
  395. BM_CLR(REG_FMUX_EN_FUC(pin), bit);
  396. }
  397. return PPlus_SUCCESS;
  398. }
  399. int hal_gpio_fmux_set(GPIO_Pin_e pin, Fmux_Type_e type) {
  400. hal_gpio_fmux(pin, Bit_ENABLE); //enable fullmux fuction; enable or disable
  401. FMUX_FUNIO_SELECT(pin, type); //select fmux pin function,the type is spi/uart/iic and so on
  402. return PPlus_SUCCESS;
  403. }
  404. int hal_gpio_pull_set(GPIO_Pin_e pin, IO_Pull_Type_e type) {
  405. uint32_t itype = (uint32_t)type;
  406. uint8_t index = (pin % 10) * 3 + 1;
  407. uint32_t bit = ~(BIT(index) | BIT(index + 1));
  408. bit = (*REG_IOPULL_IO(pin)) & bit;
  409. itype = (itype << index) | bit;
  410. *REG_IOPULL_IO(pin) = itype;
  411. return PPlus_SUCCESS;
  412. }
  413. int hal_gpio_wakeup_set(GPIO_Pin_e pin, IO_Wakeup_Pol_e type) {
  414. uint8_t index = (pin % 10) * 3;
  415. io_wakeup_control(pin, Bit_ENABLE); //enable wakeup function
  416. uint32_t bit = BIT(index);
  417. if (type) {
  418. BM_SET(REG_IO_Wakeuo_Pol(pin), bit); //set bit
  419. }
  420. else {
  421. BM_CLR(REG_IO_Wakeuo_Pol(pin), bit); //clear bit
  422. }
  423. return PPlus_SUCCESS;
  424. }
  425. int hal_gpioin_enable(GPIO_Pin_e pin)
  426. {
  427. gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
  428. IO_Wakeup_Pol_e type = NEGEDGE;
  429. uint32 pinVal = 0;
  430. if (p_irq_ctx[pin].posedgeHdl == NULL && p_irq_ctx[pin].negedgeHdl == NULL)
  431. return PPlus_ERR_NOT_REGISTED;
  432. if (pin >= NUMBER_OF_IRQ_PINS)
  433. m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_IN_WAKEUP;
  434. else
  435. m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_IN_IRQ_AND_WAKEUP;
  436. p_irq_ctx[pin].enable = TRUE;
  437. hal_gpio_pin_init(pin, IE);
  438. //hal_gpio_pull_set(pin, PULL_DOWN); //??need disccuss
  439. if (p_irq_ctx[pin].posedgeHdl && p_irq_ctx[pin].negedgeHdl) //both raise and fall
  440. {
  441. pinVal = hal_gpio_read(pin);
  442. type = pinVal ? NEGEDGE : POSEDGE;
  443. gpio_interrupt_enable(pin, type);
  444. return PPlus_SUCCESS;
  445. }
  446. else if (p_irq_ctx[pin].posedgeHdl) //raise
  447. {
  448. type = POSEDGE;
  449. }
  450. else if (p_irq_ctx[pin].negedgeHdl) //fall
  451. {
  452. type = NEGEDGE;
  453. }
  454. gpio_interrupt_enable(pin, type);
  455. return PPlus_SUCCESS;
  456. }
  457. int hal_gpioin_disable(GPIO_Pin_e pin)
  458. {
  459. gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
  460. if (pin > 17)
  461. return PPlus_ERR_NOT_SUPPORTED;
  462. p_irq_ctx[pin].enable = FALSE;
  463. m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_NONE;
  464. hal_gpio_pin_init(pin, IE);
  465. return gpio_interrupt_disable(pin);
  466. }
  467. int hal_gpioin_register(GPIO_Pin_e pin, gpioin_Hdl_t posedgeHdl, gpioin_Hdl_t negedgeHdl)
  468. {
  469. int ret;
  470. gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
  471. hal_gpioin_disable(pin);
  472. p_irq_ctx[pin].posedgeHdl = posedgeHdl;
  473. p_irq_ctx[pin].negedgeHdl = negedgeHdl;
  474. ret = hal_gpioin_enable(pin);
  475. if (ret != PPlus_SUCCESS)
  476. hal_gpioin_disable(pin);
  477. return ret;
  478. }
  479. int hal_gpioin_unregister(GPIO_Pin_e pin)
  480. {
  481. gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
  482. if (pin > 17)
  483. return PPlus_ERR_NOT_SUPPORTED;
  484. hal_gpioin_disable(pin);
  485. p_irq_ctx[pin].negedgeHdl = NULL;
  486. p_irq_ctx[pin].posedgeHdl = NULL;
  487. return PPlus_SUCCESS;
  488. }
  489. int hal_gpio_init(void)
  490. {
  491. if (m_gpioCtx.state)
  492. return PPlus_ERR_INVALID_STATE;
  493. memset(&m_gpioCtx, 0, sizeof(m_gpioCtx));
  494. m_gpioCtx.state = TRUE;
  495. //disable all channel irq,unmask all channel
  496. AP_GPIOA->inten = 0;
  497. AP_GPIOA->intmask = 0;
  498. //disable all wakeup pin
  499. AP_WAKEUP->io_wu_mask_31_0 = 0;
  500. AP_WAKEUP->io_wu_mask_34_32 = 0;
  501. NVIC_SetPriority((IRQn_Type)GPIO_IRQ, IRQ_PRIO_HAL);
  502. NVIC_EnableIRQ((IRQn_Type)GPIO_IRQ);
  503. hal_pwrmgr_register(MOD_GPIO, gpio_sleep_handler, gpio_wakeup_handler);
  504. return PPlus_SUCCESS;
  505. }
  506. void hal_gpio_p00_to_hclk_div8_enable(void)
  507. {
  508. REG_DMUX_EN_FUC |= (1<<0);
  509. }
  510. void hal_gpio_p00_to_hclk_div8_disable(void)
  511. {
  512. REG_DMUX_EN_FUC &= ~(1<<0);
  513. }
  514. void hal_gpio_p01_to_pclk_div4_enable(void)
  515. {
  516. REG_DMUX_EN_FUC |= (1<<1);
  517. }
  518. void hal_gpio_p01_to_pclk_div4_disable(void)
  519. {
  520. REG_DMUX_EN_FUC &= ~(1<<1);
  521. }
  522. void hal_gpio_p24_to_rc32k_enable(void)
  523. {
  524. REG_DMUX_EN_FUC |= (1<<6);
  525. }
  526. void hal_gpio_p24_to_rc32k_disable(void)
  527. {
  528. REG_DMUX_EN_FUC &= ~(1<<6);
  529. }
  530. void hal_gpio_p25_to_xtal_clk32k_enable(void)
  531. {
  532. REG_DMUX_EN_FUC |= (1<<7);
  533. }
  534. void hal_gpio_p25_to_xtal_clk32k_disable(void)
  535. {
  536. REG_DMUX_EN_FUC &= ~(1<<7);
  537. }