gd32f3x0_gpio.c 15 KB

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