gd32f4xx_gpio.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*!
  2. \file gd32f4xx_gpio.c
  3. \brief GPIO driver
  4. \version 2016-08-15, V1.0.0, firmware for GD32F4xx
  5. \version 2018-12-12, V2.0.0, firmware for GD32F4xx
  6. \version 2020-09-30, V2.1.0, firmware for GD32F4xx
  7. */
  8. /*
  9. Copyright (c) 2020, GigaDevice Semiconductor Inc.
  10. Redistribution and use in source and binary forms, with or without modification,
  11. are permitted provided that the following conditions are met:
  12. 1. Redistributions of source code must retain the above copyright notice, this
  13. list of conditions and the following disclaimer.
  14. 2. Redistributions in binary form must reproduce the above copyright notice,
  15. this list of conditions and the following disclaimer in the documentation
  16. and/or other materials provided with the distribution.
  17. 3. Neither the name of the copyright holder nor the names of its contributors
  18. may be used to endorse or promote products derived from this software without
  19. specific prior written permission.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  24. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  27. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  29. OF SUCH DAMAGE.
  30. */
  31. #include "gd32f4xx_gpio.h"
  32. /*!
  33. \brief reset GPIO port
  34. \param[in] gpio_periph: GPIO port
  35. only one parameter can be selected which is shown as below:
  36. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  37. \param[out] none
  38. \retval none
  39. */
  40. void gpio_deinit(uint32_t gpio_periph)
  41. {
  42. switch(gpio_periph){
  43. case GPIOA:
  44. /* reset GPIOA */
  45. rcu_periph_reset_enable(RCU_GPIOARST);
  46. rcu_periph_reset_disable(RCU_GPIOARST);
  47. break;
  48. case GPIOB:
  49. /* reset GPIOB */
  50. rcu_periph_reset_enable(RCU_GPIOBRST);
  51. rcu_periph_reset_disable(RCU_GPIOBRST);
  52. break;
  53. case GPIOC:
  54. /* reset GPIOC */
  55. rcu_periph_reset_enable(RCU_GPIOCRST);
  56. rcu_periph_reset_disable(RCU_GPIOCRST);
  57. break;
  58. case GPIOD:
  59. /* reset GPIOD */
  60. rcu_periph_reset_enable(RCU_GPIODRST);
  61. rcu_periph_reset_disable(RCU_GPIODRST);
  62. break;
  63. case GPIOE:
  64. /* reset GPIOE */
  65. rcu_periph_reset_enable(RCU_GPIOERST);
  66. rcu_periph_reset_disable(RCU_GPIOERST);
  67. break;
  68. case GPIOF:
  69. /* reset GPIOF */
  70. rcu_periph_reset_enable(RCU_GPIOFRST);
  71. rcu_periph_reset_disable(RCU_GPIOFRST);
  72. break;
  73. case GPIOG:
  74. /* reset GPIOG */
  75. rcu_periph_reset_enable(RCU_GPIOGRST);
  76. rcu_periph_reset_disable(RCU_GPIOGRST);
  77. break;
  78. case GPIOH:
  79. /* reset GPIOH */
  80. rcu_periph_reset_enable(RCU_GPIOHRST);
  81. rcu_periph_reset_disable(RCU_GPIOHRST);
  82. break;
  83. case GPIOI:
  84. /* reset GPIOI */
  85. rcu_periph_reset_enable(RCU_GPIOIRST);
  86. rcu_periph_reset_disable(RCU_GPIOIRST);
  87. break;
  88. default:
  89. break;
  90. }
  91. }
  92. /*!
  93. \brief set GPIO mode
  94. \param[in] gpio_periph: GPIO port
  95. only one parameter can be selected which is shown as below:
  96. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  97. \param[in] mode: GPIO pin mode
  98. \arg GPIO_MODE_INPUT: input mode
  99. \arg GPIO_MODE_OUTPUT: output mode
  100. \arg GPIO_MODE_AF: alternate function mode
  101. \arg GPIO_MODE_ANALOG: analog mode
  102. \param[in] pull_up_down: GPIO pin with pull-up or pull-down resistor
  103. \arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors
  104. \arg GPIO_PUPD_PULLUP: with pull-up resistor
  105. \arg GPIO_PUPD_PULLDOWN:with pull-down resistor
  106. \param[in] pin: GPIO pin
  107. one or more parameters can be selected which are shown as below:
  108. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  109. \param[out] none
  110. \retval none
  111. */
  112. void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)
  113. {
  114. uint16_t i;
  115. uint32_t ctl, pupd;
  116. ctl = GPIO_CTL(gpio_periph);
  117. pupd = GPIO_PUD(gpio_periph);
  118. for(i = 0U;i < 16U;i++){
  119. if((1U << i) & pin){
  120. /* clear the specified pin mode bits */
  121. ctl &= ~GPIO_MODE_MASK(i);
  122. /* set the specified pin mode bits */
  123. ctl |= GPIO_MODE_SET(i, mode);
  124. /* clear the specified pin pupd bits */
  125. pupd &= ~GPIO_PUPD_MASK(i);
  126. /* set the specified pin pupd bits */
  127. pupd |= GPIO_PUPD_SET(i, pull_up_down);
  128. }
  129. }
  130. GPIO_CTL(gpio_periph) = ctl;
  131. GPIO_PUD(gpio_periph) = pupd;
  132. }
  133. /*!
  134. \brief set GPIO output type and speed
  135. \param[in] gpio_periph: GPIO port
  136. only one parameter can be selected which is shown as below:
  137. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  138. \param[in] otype: GPIO pin output mode
  139. \arg GPIO_OTYPE_PP: push pull mode
  140. \arg GPIO_OTYPE_OD: open drain mode
  141. \param[in] speed: GPIO pin output max speed
  142. \arg GPIO_OSPEED_2MHZ: output max speed 2MHz
  143. \arg GPIO_OSPEED_25MHZ: output max speed 25MHz
  144. \arg GPIO_OSPEED_50MHZ: output max speed 50MHz
  145. \arg GPIO_OSPEED_200MHZ: output max speed 200MHz
  146. \param[in] pin: GPIO pin
  147. one or more parameters can be selected which are shown as below:
  148. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  149. \param[out] none
  150. \retval none
  151. */
  152. void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin)
  153. {
  154. uint16_t i;
  155. uint32_t ospeedr;
  156. if(GPIO_OTYPE_OD == otype){
  157. GPIO_OMODE(gpio_periph) |= (uint32_t)pin;
  158. }else{
  159. GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin);
  160. }
  161. /* get the specified pin output speed bits value */
  162. ospeedr = GPIO_OSPD(gpio_periph);
  163. for(i = 0U;i < 16U;i++){
  164. if((1U << i) & pin){
  165. /* clear the specified pin output speed bits */
  166. ospeedr &= ~GPIO_OSPEED_MASK(i);
  167. /* set the specified pin output speed bits */
  168. ospeedr |= GPIO_OSPEED_SET(i,speed);
  169. }
  170. }
  171. GPIO_OSPD(gpio_periph) = ospeedr;
  172. }
  173. /*!
  174. \brief set GPIO pin bit
  175. \param[in] gpio_periph: GPIO port
  176. only one parameter can be selected which is shown as below:
  177. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  178. \param[in] pin: GPIO pin
  179. one or more parameters can be selected which are shown as below:
  180. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  181. \param[out] none
  182. \retval none
  183. */
  184. void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
  185. {
  186. GPIO_BOP(gpio_periph) = (uint32_t)pin;
  187. }
  188. /*!
  189. \brief reset GPIO pin bit
  190. \param[in] gpio_periph: GPIO port
  191. only one parameter can be selected which is shown as below:
  192. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  193. \param[in] pin: GPIO pin
  194. one or more parameters can be selected which are shown as below:
  195. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  196. \param[out] none
  197. \retval none
  198. */
  199. void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin)
  200. {
  201. GPIO_BC(gpio_periph) = (uint32_t)pin;
  202. }
  203. /*!
  204. \brief write data to the specified GPIO pin
  205. \param[in] gpio_periph: GPIO port
  206. only one parameter can be selected which is shown as below:
  207. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  208. \param[in] pin: GPIO pin
  209. one or more parameters can be selected which are shown as below:
  210. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  211. \param[in] bit_value: SET or RESET
  212. \arg RESET: clear the port pin
  213. \arg SET: set the port pin
  214. \param[out] none
  215. \retval none
  216. */
  217. void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value)
  218. {
  219. if(RESET != bit_value){
  220. GPIO_BOP(gpio_periph) = (uint32_t)pin;
  221. }else{
  222. GPIO_BC(gpio_periph) = (uint32_t)pin;
  223. }
  224. }
  225. /*!
  226. \brief write data to the specified GPIO port
  227. \param[in] gpio_periph: GPIO port
  228. only one parameter can be selected which is shown as below:
  229. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  230. \param[in] data: specify the value to be written to the port output control register
  231. \param[out] none
  232. \retval none
  233. */
  234. void gpio_port_write(uint32_t gpio_periph, uint16_t data)
  235. {
  236. GPIO_OCTL(gpio_periph) = (uint32_t)data;
  237. }
  238. /*!
  239. \brief get GPIO pin input status
  240. \param[in] gpio_periph: GPIO port
  241. only one parameter can be selected which is shown as below:
  242. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  243. \param[in] pin: GPIO pin
  244. one or more parameters can be selected which are shown as below:
  245. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  246. \param[out] none
  247. \retval input status of GPIO pin: SET or RESET
  248. */
  249. FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin)
  250. {
  251. if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
  252. return SET;
  253. }else{
  254. return RESET;
  255. }
  256. }
  257. /*!
  258. \brief get GPIO all pins input status
  259. \param[in] gpio_periph: GPIO port
  260. only one parameter can be selected which is shown as below:
  261. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  262. \param[out] none
  263. \retval input status of GPIO all pins
  264. */
  265. uint16_t gpio_input_port_get(uint32_t gpio_periph)
  266. {
  267. return ((uint16_t)GPIO_ISTAT(gpio_periph));
  268. }
  269. /*!
  270. \brief get GPIO pin output status
  271. \param[in] gpio_periph: GPIO port
  272. only one parameter can be selected which is shown as below:
  273. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  274. \param[in] pin: GPIO pin
  275. one or more parameters can be selected which are shown as below:
  276. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  277. \param[out] none
  278. \retval output status of GPIO pin: SET or RESET
  279. */
  280. FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin)
  281. {
  282. if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){
  283. return SET;
  284. }else{
  285. return RESET;
  286. }
  287. }
  288. /*!
  289. \brief get GPIO all pins output status
  290. \param[in] gpio_periph: GPIO port
  291. only one parameter can be selected which is shown as below:
  292. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  293. \param[out] none
  294. \retval output status of GPIO all pins
  295. */
  296. uint16_t gpio_output_port_get(uint32_t gpio_periph)
  297. {
  298. return ((uint16_t)GPIO_OCTL(gpio_periph));
  299. }
  300. /*!
  301. \brief set GPIO alternate function
  302. \param[in] gpio_periph: GPIO port
  303. only one parameter can be selected which is shown as below:
  304. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  305. \param[in] alt_func_num: GPIO pin af function
  306. \arg GPIO_AF_0: SYSTEM
  307. \arg GPIO_AF_1: TIMER0, TIMER1
  308. \arg GPIO_AF_2: TIMER2, TIMER3, TIMER4
  309. \arg GPIO_AF_3: TIMER7, TIMER8, TIMER9, TIMER10
  310. \arg GPIO_AF_4: I2C0, I2C1, I2C2
  311. \arg GPIO_AF_5: SPI0, SPI1, SPI2, SPI3, SPI4, SPI5
  312. \arg GPIO_AF_6: SPI1, SPI2, SAI0
  313. \arg GPIO_AF_7: USART0, USART1, USART2
  314. \arg GPIO_AF_8: UART3, UART4, USART5, UART6, UART7
  315. \arg GPIO_AF_9: CAN0, CAN1, TLI, TIMER11, TIMER12, TIMER13
  316. \arg GPIO_AF_10: USB_FS, USB_HS
  317. \arg GPIO_AF_11: ENET
  318. \arg GPIO_AF_12: EXMC, SDIO, USB_HS
  319. \arg GPIO_AF_13: DCI
  320. \arg GPIO_AF_14: TLI
  321. \arg GPIO_AF_15: EVENTOUT
  322. \param[in] pin: GPIO pin
  323. one or more parameters can be selected which are shown as below:
  324. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  325. \param[out] none
  326. \retval none
  327. */
  328. void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin)
  329. {
  330. uint16_t i;
  331. uint32_t afrl, afrh;
  332. afrl = GPIO_AFSEL0(gpio_periph);
  333. afrh = GPIO_AFSEL1(gpio_periph);
  334. for(i = 0U;i < 8U;i++){
  335. if((1U << i) & pin){
  336. /* clear the specified pin alternate function bits */
  337. afrl &= ~GPIO_AFR_MASK(i);
  338. afrl |= GPIO_AFR_SET(i,alt_func_num);
  339. }
  340. }
  341. for(i = 8U;i < 16U;i++){
  342. if((1U << i) & pin){
  343. /* clear the specified pin alternate function bits */
  344. afrh &= ~GPIO_AFR_MASK(i - 8U);
  345. afrh |= GPIO_AFR_SET(i - 8U,alt_func_num);
  346. }
  347. }
  348. GPIO_AFSEL0(gpio_periph) = afrl;
  349. GPIO_AFSEL1(gpio_periph) = afrh;
  350. }
  351. /*!
  352. \brief lock GPIO pin bit
  353. \param[in] gpio_periph: GPIO port
  354. only one parameter can be selected which is shown as below:
  355. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  356. \param[in] pin: GPIO pin
  357. one or more parameters can be selected which are shown as below:
  358. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  359. \param[out] none
  360. \retval none
  361. */
  362. void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin)
  363. {
  364. uint32_t lock = 0x00010000U;
  365. lock |= pin;
  366. /* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */
  367. GPIO_LOCK(gpio_periph) = (uint32_t)lock;
  368. GPIO_LOCK(gpio_periph) = (uint32_t)pin;
  369. GPIO_LOCK(gpio_periph) = (uint32_t)lock;
  370. lock = GPIO_LOCK(gpio_periph);
  371. lock = GPIO_LOCK(gpio_periph);
  372. }
  373. /*!
  374. \brief toggle GPIO pin status
  375. \param[in] gpio_periph: GPIO port
  376. only one parameter can be selected which is shown as below:
  377. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  378. \param[in] pin: GPIO pin
  379. one or more parameters can be selected which are shown as below:
  380. \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  381. \param[out] none
  382. \retval none
  383. */
  384. void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin)
  385. {
  386. GPIO_TG(gpio_periph) = (uint32_t)pin;
  387. }
  388. /*!
  389. \brief toggle GPIO port status
  390. \param[in] gpio_periph: GPIO port
  391. only one parameter can be selected which is shown as below:
  392. \arg GPIOx(x = A,B,C,D,E,F,G,H,I)
  393. \param[out] none
  394. \retval none
  395. */
  396. void gpio_port_toggle(uint32_t gpio_periph)
  397. {
  398. GPIO_TG(gpio_periph) = 0x0000FFFFU;
  399. }