HAL_GPIO.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /*
  2. ******************************************************************************
  3. * @file HAL_GPIO.c
  4. * @version V1.0.0
  5. * @date 2020
  6. * @brief GPIO HAL module driver.
  7. * This file provides firmware functions to manage the following
  8. * functionalities of the General Purpose Input/Output (GPIO) peripheral:
  9. * @ Initialization functions
  10. * @ IO operation functions
  11. ******************************************************************************
  12. */
  13. #include "ACM32Fxx_HAL.h"
  14. /*********************************************************************************
  15. * Function : HAL_GPIO_IRQHandler
  16. * Description : GPIO interrupt Handler
  17. * Input :
  18. * Outpu :
  19. * Author : Chris_Kyle Date : 2020年
  20. **********************************************************************************/
  21. void HAL_GPIO_IRQHandler(enum_GPIOx_t fe_GPIO, uint32_t fu32_GPIO_Pin)
  22. {
  23. GPIO_TypeDef *GPIOx;
  24. switch (fe_GPIO)
  25. {
  26. case GPIOA:
  27. case GPIOB:
  28. {
  29. GPIOx = GPIOAB;
  30. }break;
  31. case GPIOC:
  32. case GPIOD:
  33. {
  34. GPIOx = GPIOCD;
  35. }break;
  36. default: break;
  37. }
  38. if (fe_GPIO == GPIOB || fe_GPIO == GPIOD )
  39. {
  40. fu32_GPIO_Pin <<= 16;
  41. }
  42. if (GPIOx->RIS & fu32_GPIO_Pin)
  43. {
  44. GPIOx->IC = fu32_GPIO_Pin;
  45. /* user can call your application process function here */
  46. /* ...... */
  47. }
  48. }
  49. /*********************************************************************************
  50. * Function : HAL_GPIO_Init
  51. * Description : Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init
  52. * Input : fe_GPIO: to select the GPIO peripheral.
  53. * Input : GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
  54. the configuration information for the specified GPIO peripheral.
  55. * Outpu :
  56. * Author : Chris_Kyle Date : 2020年
  57. **********************************************************************************/
  58. void HAL_GPIO_Init(enum_GPIOx_t fe_GPIO, GPIO_InitTypeDef *GPIO_Init)
  59. {
  60. uint32_t lu32_Position = 0;
  61. uint32_t lu32_Current_Pin;
  62. uint32_t lu32_Position_Mask;
  63. volatile uint32_t *lu32_SEL1 = NULL; // 指向 -> 管脚复用寄存器1
  64. volatile uint32_t *lu32_SEL2 = NULL; // 指向 -> 管脚复用寄存器2
  65. volatile uint32_t *lu32_PollUP = NULL; // 指向 -> 上拉选择寄存器
  66. volatile uint32_t *lu32_PollDown = NULL; // 指向 -> 下拉选择寄存器
  67. volatile uint32_t *lu32_ODEnable = NULL; // 指向 -> 开漏使能寄存器
  68. volatile uint32_t *lu32_ADS = NULL; // 指向 -> 数字、模拟选择寄存器
  69. GPIO_TypeDef *GPIOx;
  70. #if (USE_FULL_ASSERT == 1)
  71. /* Check the parameters */
  72. if (!IS_GPIO_ALL_INSTANCE(fe_GPIO)) return;
  73. if (!IS_GPIO_PIN(GPIO_Init->Pin)) return;
  74. if (!IS_GPIO_MODE(GPIO_Init->Mode)) return;
  75. if (!IS_GPIO_PULL(GPIO_Init->Pull)) return;
  76. #endif
  77. switch (fe_GPIO)
  78. {
  79. case GPIOA:
  80. case GPIOB:
  81. {
  82. GPIOx = GPIOAB;
  83. System_Module_Enable(EN_GPIOAB);
  84. lu32_PollUP = &(SCU->PABPUR);
  85. lu32_PollDown = &(SCU->PABPDR);
  86. lu32_ODEnable = &(SCU->PABODR);
  87. lu32_ADS = &(SCU->PABADS);
  88. if (fe_GPIO == GPIOB)
  89. {
  90. GPIO_Init->Pin <<= 16;
  91. lu32_SEL1 = &(SCU->PBSEL1);
  92. lu32_SEL2 = &(SCU->PBSEL2);
  93. }
  94. else
  95. {
  96. lu32_SEL1 = &(SCU->PASEL1);
  97. lu32_SEL2 = &(SCU->PASEL2);
  98. }
  99. }break;
  100. case GPIOC:
  101. case GPIOD:
  102. {
  103. GPIOx = GPIOCD;
  104. System_Module_Enable(EN_GPIOCD);
  105. lu32_PollUP = &(SCU->PCDPUR);
  106. lu32_PollDown = &(SCU->PCDPDR);
  107. lu32_ODEnable = &(SCU->PCDODR);
  108. lu32_ADS = &(SCU->PCDADS);
  109. if (fe_GPIO == GPIOD)
  110. {
  111. GPIO_Init->Pin <<= 16;
  112. lu32_SEL1 = &(SCU->PDSEL1);
  113. }
  114. else
  115. {
  116. lu32_SEL1 = &(SCU->PCSEL1);
  117. lu32_SEL2 = &(SCU->PCSEL2);
  118. }
  119. }break;
  120. default: break;
  121. }
  122. /* Configure Select pins */
  123. while ((GPIO_Init->Pin) >> lu32_Position != 0)
  124. {
  125. /* Get current pin position */
  126. lu32_Current_Pin = (GPIO_Init->Pin) & (1uL << lu32_Position);
  127. if (lu32_Current_Pin)
  128. {
  129. switch (GPIO_Init->Mode)
  130. {
  131. /* GPIO IN Function */
  132. case GPIO_MODE_INPUT:
  133. {
  134. GPIOx->DIR &= ~lu32_Current_Pin;
  135. }break;
  136. /* GPIO OUT Function */
  137. case GPIO_MODE_OUTPUT_PP:
  138. case GPIO_MODE_OUTPUT_OD:
  139. {
  140. GPIOx->DIR |= lu32_Current_Pin;
  141. }break;
  142. /* Alternate Function */
  143. case GPIO_MODE_AF_PP:
  144. case GPIO_MODE_AF_OD:
  145. {
  146. /* Get Position Mask */
  147. if (lu32_Position < 16)
  148. { /* GOIOA、GPIOC、GPIOE */
  149. lu32_Position_Mask = lu32_Position;
  150. }
  151. else
  152. { /* GPIOB、GPIOD、GPIOF */
  153. lu32_Position_Mask = lu32_Position - 16;
  154. }
  155. /* SET GPIO Function */
  156. if (lu32_Position_Mask < 8)
  157. {
  158. *lu32_SEL1 = (*lu32_SEL1 & ~(0xF << (lu32_Position_Mask * 4))) | (GPIO_Init->Alternate << (lu32_Position_Mask * 4));
  159. }
  160. else
  161. {
  162. *lu32_SEL2 = (*lu32_SEL2 & ~(0xF << ((lu32_Position_Mask - 8) * 4))) | (GPIO_Init->Alternate << ((lu32_Position_Mask - 8) * 4));
  163. }
  164. }break;
  165. /* GPIO INT Function */
  166. case GPIO_MODE_IT_RISING:
  167. case GPIO_MODE_IT_FALLING:
  168. case GPIO_MODE_IT_RISING_FALLING:
  169. case GPIO_MODE_IT_HIGH_LEVEL:
  170. case GPIO_MODE_IT_LOW_LEVEL:
  171. {
  172. /* Set direction Input、Enable INT */
  173. GPIOx->DIR &= ~lu32_Current_Pin;
  174. GPIOx->IEN |= lu32_Current_Pin;
  175. /* Single edge */
  176. if (GPIO_Init->Mode == GPIO_MODE_IT_RISING || GPIO_Init->Mode == GPIO_MODE_IT_FALLING)
  177. {
  178. /* edge trigger */
  179. GPIOx->IS &= ~lu32_Current_Pin;
  180. /* Single trigger */
  181. GPIOx->IBE &= ~lu32_Current_Pin;
  182. if (GPIO_Init->Mode == GPIO_MODE_IT_RISING)
  183. {
  184. GPIOx->IEV |= lu32_Current_Pin;
  185. }
  186. else
  187. {
  188. GPIOx->IEV &= ~lu32_Current_Pin;
  189. }
  190. }
  191. /* Double edge */
  192. if (GPIO_Init->Mode == GPIO_MODE_IT_RISING_FALLING)
  193. {
  194. /* edge trigger */
  195. GPIOx->IS &= ~lu32_Current_Pin;
  196. /* Double trigger */
  197. GPIOx->IBE |= lu32_Current_Pin;
  198. }
  199. /* LEVEL trigger */
  200. if (GPIO_Init->Mode == GPIO_MODE_IT_HIGH_LEVEL || GPIO_Init->Mode == GPIO_MODE_IT_LOW_LEVEL)
  201. {
  202. /* LEVEL trigger */
  203. GPIOx->IS |= lu32_Current_Pin;
  204. if (GPIO_Init->Mode == GPIO_MODE_IT_HIGH_LEVEL)
  205. {
  206. GPIOx->IEV |= lu32_Current_Pin;
  207. }
  208. else
  209. {
  210. GPIOx->IEV &= ~lu32_Current_Pin;
  211. }
  212. }
  213. }break;
  214. default: break;
  215. }
  216. /* Set Pull UP or DOWN or NO */
  217. if (GPIO_Init->Pull == GPIO_NOPULL)
  218. {
  219. *lu32_PollUP &= ~lu32_Current_Pin;
  220. *lu32_PollDown &= ~lu32_Current_Pin;
  221. }
  222. else if (GPIO_Init->Pull == GPIO_PULLUP)
  223. {
  224. *lu32_PollUP |= lu32_Current_Pin;
  225. *lu32_PollDown &= ~lu32_Current_Pin;
  226. }
  227. else if (GPIO_Init->Pull == GPIO_PULLDOWN)
  228. {
  229. *lu32_PollUP &= ~lu32_Current_Pin;
  230. *lu32_PollDown |= lu32_Current_Pin;
  231. }
  232. /* Set Open Drain Mode */
  233. if (GPIO_Init->Mode & GPIO_MODE_OD_MASK)
  234. {
  235. *lu32_ODEnable |= lu32_Current_Pin;
  236. }
  237. else
  238. {
  239. *lu32_ODEnable &= ~lu32_Current_Pin;
  240. }
  241. /* GPIO Function */
  242. if (GPIO_Init->Mode & GPIO_MODE_IO_MASK)
  243. {
  244. /* Get Position Mask */
  245. if (lu32_Position < 16)
  246. { /* GOIOA、GPIOC、GPIOE */
  247. lu32_Position_Mask = lu32_Position;
  248. }
  249. else
  250. { /* GPIOB、GPIOD、GPIOF */
  251. lu32_Position_Mask = lu32_Position - 16;
  252. }
  253. /* SET GPIO Function */
  254. if (lu32_Position_Mask < 8)
  255. {
  256. *lu32_SEL1 = (*lu32_SEL1 & ~(0xF << (lu32_Position_Mask * 4))) | (GPIO_FUNCTION_0 << (lu32_Position_Mask * 4));
  257. }
  258. else
  259. {
  260. *lu32_SEL2 = (*lu32_SEL2 & ~(0xF << ((lu32_Position_Mask - 8) * 4))) | (GPIO_FUNCTION_0 << ((lu32_Position_Mask - 8) * 4));
  261. }
  262. }
  263. /* SET Digital or Analog */
  264. if (GPIO_Init->Mode == GPIO_MODE_ANALOG)
  265. {
  266. *lu32_ADS |= lu32_Current_Pin;
  267. }
  268. else
  269. {
  270. *lu32_ADS &= ~lu32_Current_Pin;
  271. }
  272. }
  273. lu32_Position++;
  274. }
  275. }
  276. /*********************************************************************************
  277. * Function : HAL_GPIO_DeInit
  278. * Description : De-initializes the GPIOx peripheral registers to their default reset values.
  279. * Input : fe_GPIO:to select the GPIO peripheral.
  280. * Input : fu32_Pin:specifies the port bit to be written.
  281. This parameter can be one of GPIO_PIN_x where x can be (0..15).
  282. * Outpu :
  283. * Author : Chris_Kyle Date : 2020
  284. **********************************************************************************/
  285. void HAL_GPIO_DeInit(enum_GPIOx_t fe_GPIO, uint32_t fu32_Pin)
  286. {
  287. uint32_t lu32_Position = 0;
  288. uint32_t lu32_Current_Pin;
  289. uint32_t lu32_Position_Mask;
  290. volatile uint32_t *lu32_SEL1 = NULL; // 指向 -> 管脚复用寄存器1
  291. volatile uint32_t *lu32_SEL2 = NULL; // 指向 -> 管脚复用寄存器2
  292. volatile uint32_t *lu32_PollUP = NULL; // 指向 -> 上拉选择寄存器
  293. volatile uint32_t *lu32_PollDown = NULL; // 指向 -> 下拉选择寄存器
  294. volatile uint32_t *lu32_ODEnable = NULL; // 指向 -> 开漏使能寄存器
  295. volatile uint32_t *lu32_ADS = NULL; // 指向 -> 数字、模拟选择寄存器
  296. GPIO_TypeDef *GPIOx;
  297. #if (USE_FULL_ASSERT == 1)
  298. /* Check the parameters */
  299. if (!IS_GPIO_ALL_INSTANCE(fe_GPIO)) return;
  300. if (!IS_GPIO_PIN(fu32_Pin)) return;
  301. #endif
  302. switch (fe_GPIO)
  303. {
  304. case GPIOA:
  305. case GPIOB:
  306. {
  307. GPIOx = GPIOAB;
  308. System_Module_Enable(EN_GPIOAB);
  309. lu32_PollUP = &(SCU->PABPUR);
  310. lu32_PollDown = &(SCU->PABPDR);
  311. lu32_ODEnable = &(SCU->PABODR);
  312. lu32_ADS = &(SCU->PABADS);
  313. if (fe_GPIO == GPIOB)
  314. {
  315. fu32_Pin <<= 16;
  316. lu32_SEL1 = &(SCU->PBSEL1);
  317. lu32_SEL2 = &(SCU->PBSEL2);
  318. }
  319. else
  320. {
  321. lu32_SEL1 = &(SCU->PASEL1);
  322. lu32_SEL2 = &(SCU->PASEL2);
  323. }
  324. }break;
  325. case GPIOC:
  326. case GPIOD:
  327. {
  328. GPIOx = GPIOCD;
  329. System_Module_Enable(EN_GPIOCD);
  330. lu32_PollUP = &(SCU->PCDPUR);
  331. lu32_PollDown = &(SCU->PCDPDR);
  332. lu32_ODEnable = &(SCU->PCDODR);
  333. lu32_ADS = &(SCU->PCDADS);
  334. if (fe_GPIO == GPIOD)
  335. {
  336. fu32_Pin <<= 16;
  337. lu32_SEL1 = &(SCU->PDSEL1);
  338. }
  339. else
  340. {
  341. lu32_SEL1 = &(SCU->PCSEL1);
  342. lu32_SEL2 = &(SCU->PCSEL2);
  343. }
  344. }break;
  345. default: break;
  346. }
  347. /* Configure Select pins */
  348. while (fu32_Pin >> lu32_Position != 0)
  349. {
  350. /* Get current pin position */
  351. lu32_Current_Pin = fu32_Pin & (1uL << lu32_Position);
  352. if (lu32_Current_Pin)
  353. {
  354. /* GPIO IN Function */
  355. GPIOx->DIR &= ~lu32_Current_Pin;
  356. GPIOx->CLR |= lu32_Current_Pin;
  357. /* Disable Enable INT */
  358. GPIOx->IEN &= ~lu32_Current_Pin;
  359. /* Clear trigger config */
  360. GPIOx->IS &= ~lu32_Current_Pin;
  361. GPIOx->IBE &= ~lu32_Current_Pin;
  362. GPIOx->IEV &= ~lu32_Current_Pin;
  363. /* Get Position Mask */
  364. if (lu32_Position < 16)
  365. { /* GOIOA、GPIOC、GPIOE */
  366. lu32_Position_Mask = lu32_Position;
  367. }
  368. else
  369. { /* GPIOB、GPIOD、GPIOF */
  370. lu32_Position_Mask = lu32_Position - 16;
  371. }
  372. /* SET GPIO Function */
  373. if (lu32_Position_Mask < 8)
  374. {
  375. *lu32_SEL1 &= ~(0xF << (lu32_Position_Mask * 4));
  376. }
  377. else
  378. {
  379. *lu32_SEL2 &= ~(0xF << ((lu32_Position_Mask - 8) * 4));
  380. }
  381. /* NO Pull */
  382. *lu32_PollUP &= ~lu32_Current_Pin;
  383. *lu32_PollDown &= ~lu32_Current_Pin;
  384. /* Not Open Drain */
  385. *lu32_ODEnable &= ~lu32_Current_Pin;
  386. /* Analog Mode */
  387. *lu32_ADS |= lu32_Current_Pin;
  388. }
  389. lu32_Position++;
  390. }
  391. }
  392. /*********************************************************************************
  393. * Function : HAL_GPIO_AnalogEnable
  394. * Description : Quickly Configure to analog function
  395. * Input : fe_GPIO:to select the GPIO peripheral.
  396. * Input : fu32_Pin:specifies the port bit to be written.
  397. This parameter can be one of GPIO_PIN_x where x can be (0..15).
  398. * Outpu :
  399. * Author : Chris_Kyle Date : 2020年
  400. **********************************************************************************/
  401. void HAL_GPIO_AnalogEnable(enum_GPIOx_t fe_GPIO, uint32_t fu32_Pin)
  402. {
  403. uint32_t lu32_Position = 0;
  404. uint32_t lu32_Current_Pin;
  405. volatile uint32_t *lp32_ADS = NULL; // 指向 -> 数字、模拟选择寄存器
  406. #if (USE_FULL_ASSERT == 1)
  407. /* Check the parameters */
  408. if (!IS_GPIO_ALL_INSTANCE(fe_GPIO)) return;
  409. if (!IS_GPIO_PIN(fu32_Pin)) return;
  410. #endif
  411. switch (fe_GPIO)
  412. {
  413. case GPIOA:
  414. case GPIOB:
  415. {
  416. System_Module_Enable(EN_GPIOAB);
  417. lp32_ADS = &(SCU->PABADS);
  418. if (fe_GPIO == GPIOB)
  419. {
  420. fu32_Pin <<= 16;
  421. }
  422. }break;
  423. case GPIOC:
  424. case GPIOD:
  425. {
  426. System_Module_Enable(EN_GPIOCD);
  427. lp32_ADS = &(SCU->PCDADS);
  428. if (fe_GPIO == GPIOD)
  429. {
  430. fu32_Pin <<= 16;
  431. }
  432. }break;
  433. default: break;
  434. }
  435. /* Configure Select pins */
  436. while ((fu32_Pin) >> lu32_Position != 0)
  437. {
  438. /* Get current pin position */
  439. lu32_Current_Pin = (fu32_Pin) & (1uL << lu32_Position);
  440. if (lu32_Current_Pin)
  441. {
  442. *lp32_ADS |= lu32_Current_Pin;
  443. }
  444. lu32_Position++;
  445. }
  446. }
  447. /*********************************************************************************
  448. * Function : HAL_GPIO_WritePin
  449. * Description : Set or clear the selected data port bit.
  450. * Input :
  451. * Outpu :
  452. * Author : Chris_Kyle Date : 2020年
  453. **********************************************************************************/
  454. void HAL_GPIO_WritePin(enum_GPIOx_t fe_GPIO, uint32_t fu32_GPIO_Pin, enum_PinState_t fe_PinState)
  455. {
  456. GPIO_TypeDef *GPIOx;
  457. #if (USE_FULL_ASSERT == 1)
  458. /* Check the parameters */
  459. if (!IS_GPIO_ALL_INSTANCE(fe_GPIO)) return;
  460. if (!IS_GPIO_PIN(fu32_GPIO_Pin)) return;
  461. if (!IS_GPIO_PIN_ACTION(fe_PinState)) return;
  462. #endif
  463. switch (fe_GPIO)
  464. {
  465. case GPIOA:
  466. case GPIOB:
  467. {
  468. GPIOx = GPIOAB;
  469. }break;
  470. case GPIOC:
  471. case GPIOD:
  472. {
  473. GPIOx = GPIOCD;
  474. }break;
  475. default: break;
  476. }
  477. if (fe_GPIO == GPIOB || fe_GPIO == GPIOD )
  478. {
  479. fu32_GPIO_Pin <<= 16;
  480. }
  481. if (GPIO_PIN_SET == fe_PinState)
  482. {
  483. GPIOx->ODATA |= fu32_GPIO_Pin;
  484. }
  485. else
  486. {
  487. GPIOx->ODATA &= ~fu32_GPIO_Pin;
  488. }
  489. }
  490. /*********************************************************************************
  491. * Function : HAL_GPIO_ReadPin
  492. * Description : Read the specified input port pin.
  493. * Input :
  494. * Outpu :
  495. * Author : Chris_Kyle Date : 2020年
  496. **********************************************************************************/
  497. enum_PinState_t HAL_GPIO_ReadPin(enum_GPIOx_t fe_GPIO, uint32_t fu32_GPIO_Pin)
  498. {
  499. GPIO_TypeDef *GPIOx;
  500. switch (fe_GPIO)
  501. {
  502. case GPIOA:
  503. case GPIOB:
  504. {
  505. GPIOx = GPIOAB;
  506. }break;
  507. case GPIOC:
  508. case GPIOD:
  509. {
  510. GPIOx = GPIOCD;
  511. }break;
  512. default: break;
  513. }
  514. if (fe_GPIO == GPIOB || fe_GPIO == GPIOD )
  515. {
  516. fu32_GPIO_Pin <<= 16;
  517. }
  518. if (GPIOx->IDATA & fu32_GPIO_Pin)
  519. {
  520. return GPIO_PIN_SET;
  521. }
  522. else
  523. {
  524. return GPIO_PIN_CLEAR;
  525. }
  526. }