gd32f1x0_gpio.c 14 KB

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