gd32f3x0_gpio.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*!
  2. \file gd32f3x0_gpio.c
  3. \brief GPIO driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-06-06, V1.0.0, firmware for GD32F3x0
  8. */
  9. #include "gd32f3x0_gpio.h"
  10. /*!
  11. \brief reset GPIO port
  12. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  13. \param[out] none
  14. \retval none
  15. */
  16. void gpio_deinit(uint32_t gpio_periph)
  17. {
  18. switch(gpio_periph){
  19. case GPIOA:
  20. /* reset GPIOA */
  21. rcu_periph_reset_enable(RCU_GPIOARST);
  22. rcu_periph_reset_disable(RCU_GPIOARST);
  23. break;
  24. case GPIOB:
  25. /* reset GPIOB */
  26. rcu_periph_reset_enable(RCU_GPIOBRST);
  27. rcu_periph_reset_disable(RCU_GPIOBRST);
  28. break;
  29. case GPIOC:
  30. /* reset GPIOC */
  31. rcu_periph_reset_enable(RCU_GPIOCRST);
  32. rcu_periph_reset_disable(RCU_GPIOCRST);
  33. break;
  34. case GPIOD:
  35. /* reset GPIOD */
  36. rcu_periph_reset_enable(RCU_GPIODRST);
  37. rcu_periph_reset_disable(RCU_GPIODRST);
  38. break;
  39. case GPIOF:
  40. /* reset GPIOF */
  41. rcu_periph_reset_enable(RCU_GPIOFRST);
  42. rcu_periph_reset_disable(RCU_GPIOFRST);
  43. break;
  44. default:
  45. break;
  46. }
  47. }
  48. /*!
  49. \brief set GPIO output mode
  50. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  51. \param[in] mode: gpio pin mode
  52. \arg GPIO_MODE_INPUT: input mode
  53. \arg GPIO_MODE_OUTPUT: output mode
  54. \arg GPIO_MODE_AF: alternate function mode
  55. \arg GPIO_MODE_ANALOG: analog mode
  56. \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor
  57. \arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors
  58. \arg GPIO_PUPD_PULLUP: with pull-up resistor
  59. \arg GPIO_PUPD_PULLDOWN:with pull-down resistor
  60. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  61. \param[out] none
  62. \retval none
  63. */
  64. void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)
  65. {
  66. uint16_t i;
  67. uint32_t ctl, pupd;
  68. ctl = GPIO_CTL(gpio_periph);
  69. pupd = GPIO_PUD(gpio_periph);
  70. for(i = 0U;i < 16U;i++){
  71. if((1U << i) & pin){
  72. /* clear the specified pin mode bits */
  73. ctl &= ~GPIO_MODE_MASK(i);
  74. /* set the specified pin mode bits */
  75. ctl |= GPIO_MODE_SET(i, mode);
  76. /* clear the specified pin pupd bits */
  77. pupd &= ~GPIO_PUPD_MASK(i);
  78. /* set the specified pin pupd bits */
  79. pupd |= GPIO_PUPD_SET(i, pull_up_down);
  80. }
  81. }
  82. GPIO_CTL(gpio_periph) = ctl;
  83. GPIO_PUD(gpio_periph) = pupd;
  84. }
  85. /*!
  86. \brief set GPIO output type and speed
  87. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  88. \param[in] otype: gpio pin output mode
  89. \arg GPIO_OTYPE_PP: push pull mode
  90. \arg GPIO_OTYPE_OD: open drain mode
  91. \param[in] speed: gpio pin output max speed
  92. \arg GPIO_OSPEED_2MHZ: output max speed 2MHz
  93. \arg GPIO_OSPEED_10MHZ: output max speed 10MHz
  94. \arg GPIO_OSPEED_50MHZ: output max speed 50MHz
  95. \arg GPIO_OSPEED_MAX: GPIO very high output speed, max speed more than 50MHz
  96. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  97. \param[out] none
  98. \retval none
  99. */
  100. void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin)
  101. {
  102. uint16_t i;
  103. uint32_t ospeed0,ospeed1;
  104. if(GPIO_OTYPE_OD == otype){
  105. GPIO_OMODE(gpio_periph) |= (uint32_t)pin;
  106. }else{
  107. GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin);
  108. }
  109. /* get the specified pin output speed bits value */
  110. ospeed0 = GPIO_OSPD0(gpio_periph);
  111. if(GPIO_OSPEED_MAX == speed){
  112. ospeed1 = GPIO_OSPD1(gpio_periph);
  113. for(i = 0U;i < 16U;i++){
  114. if((1U << i) & pin){
  115. /* enable very high output speed function of the pin when the corresponding OSPDy(y=0..15)
  116. is "11" (output max speed 50MHz) */
  117. ospeed0 |= GPIO_OSPEED_SET(i,0x03);
  118. ospeed1 |= (1U << i);
  119. }
  120. }
  121. GPIO_OSPD0(gpio_periph) = ospeed0;
  122. GPIO_OSPD1(gpio_periph) = ospeed1;
  123. }else{
  124. for(i = 0U;i < 16U;i++){
  125. if((1U << i) & pin){
  126. /* clear the specified pin output speed bits */
  127. ospeed0 &= ~GPIO_OSPEED_MASK(i);
  128. /* set the specified pin output speed bits */
  129. ospeed0 |= GPIO_OSPEED_SET(i,speed);
  130. }
  131. }
  132. GPIO_OSPD0(gpio_periph) = ospeed0;
  133. }
  134. }
  135. /*!
  136. \brief set GPIO pin bit
  137. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  138. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  139. \param[out] none
  140. \retval none
  141. */
  142. void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
  143. {
  144. GPIO_BOP(gpio_periph) = (uint32_t)pin;
  145. }
  146. /*!
  147. \brief reset GPIO pin bit
  148. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  149. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  150. \param[out] none
  151. \retval none
  152. */
  153. void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin)
  154. {
  155. GPIO_BC(gpio_periph) = (uint32_t)pin;
  156. }
  157. /*!
  158. \brief write data to the specified GPIO pin
  159. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  160. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  161. \param[in] bit_value: SET or RESET
  162. \arg RESET: clear the port pin
  163. \arg SET: set the port pin
  164. \param[out] none
  165. \retval none
  166. */
  167. void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value)
  168. {
  169. if(RESET != bit_value){
  170. GPIO_BOP(gpio_periph) = (uint32_t)pin;
  171. }else{
  172. GPIO_BC(gpio_periph) = (uint32_t)pin;
  173. }
  174. }
  175. /*!
  176. \brief write data to the specified GPIO port
  177. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  178. \param[in] data: specify the value to be written to the port output control register
  179. \param[out] none
  180. \retval none
  181. */
  182. void gpio_port_write(uint32_t gpio_periph, uint16_t data)
  183. {
  184. GPIO_OCTL(gpio_periph) = (uint32_t)data;
  185. }
  186. /*!
  187. \brief get GPIO pin input status
  188. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  189. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  190. \param[out] none
  191. \retval SET or RESET
  192. */
  193. FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin)
  194. {
  195. if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
  196. return SET;
  197. }else{
  198. return RESET;
  199. }
  200. }
  201. /*!
  202. \brief get GPIO all pins input status
  203. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  204. \param[out] none
  205. \retval state of GPIO all pins
  206. */
  207. uint16_t gpio_input_port_get(uint32_t gpio_periph)
  208. {
  209. return (uint16_t)GPIO_ISTAT(gpio_periph);
  210. }
  211. /*!
  212. \brief get GPIO pin output status
  213. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  214. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  215. \param[out] none
  216. \retval SET or RESET
  217. */
  218. FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin)
  219. {
  220. if((uint32_t)RESET != (GPIO_OCTL(gpio_periph)&(pin))){
  221. return SET;
  222. }else{
  223. return RESET;
  224. }
  225. }
  226. /*!
  227. \brief get GPIO all pins output status
  228. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  229. \param[out] none
  230. \retval state of GPIO all pins
  231. */
  232. uint16_t gpio_output_port_get(uint32_t gpio_periph)
  233. {
  234. return (uint16_t)GPIO_OCTL(gpio_periph);
  235. }
  236. /*!
  237. \brief set GPIO alternate function
  238. \param[in] gpio_periph: GPIOx(x = A,B,C)
  239. \param[in] alt_func_num: GPIO pin af function, please refer to specific device datasheet
  240. \arg GPIO_AF_0: TIMER2, TIMER13, TIMER14, TIMER16, SPI0, SPI1, I2S0, CK_OUT, USART0, CEC,
  241. IFRP, TSI, CTC, I2C0, I2C1, SWDIO, SWCLK
  242. \arg GPIO_AF_1: USART0, USART1, TIMER2, TIMER14, I2C0, I2C1, IFRP, CEC
  243. \arg GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, I2S0
  244. \arg GPIO_AF_3: TSI, I2C0, TIMER14
  245. \arg GPIO_AF_4(port A,B only): USART1, I2C0, I2C1, TIMER13
  246. \arg GPIO_AF_5(port A,B only): TIMER15, TIMER16, USBFS, I2S0
  247. \arg GPIO_AF_6(port A,B only): CTC, SPI1
  248. \arg GPIO_AF_7(port A,B only): CMP0, CMP1
  249. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  250. \param[out] none
  251. \retval none
  252. */
  253. void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin)
  254. {
  255. uint16_t i;
  256. uint32_t afrl, afrh;
  257. afrl = GPIO_AFSEL0(gpio_periph);
  258. afrh = GPIO_AFSEL1(gpio_periph);
  259. for(i = 0U;i < 8U;i++){
  260. if((1U << i) & pin){
  261. /* clear the specified pin alternate function bits */
  262. afrl &= ~GPIO_AFR_MASK(i);
  263. afrl |= GPIO_AFR_SET(i,alt_func_num);
  264. }
  265. }
  266. for(i = 8U;i < 16U;i++){
  267. if((1U << i) & pin){
  268. /* clear the specified pin alternate function bits */
  269. afrh &= ~GPIO_AFR_MASK(i - 8U);
  270. afrh |= GPIO_AFR_SET(i - 8U,alt_func_num);
  271. }
  272. }
  273. GPIO_AFSEL0(gpio_periph) = afrl;
  274. GPIO_AFSEL1(gpio_periph) = afrh;
  275. }
  276. /*!
  277. \brief lock GPIO pin bit
  278. \param[in] gpio_periph: GPIOx(x = A,B)
  279. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  280. \param[out] none
  281. \retval none
  282. */
  283. void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin)
  284. {
  285. uint32_t lock = 0x00010000U;
  286. lock |= pin;
  287. /* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */
  288. GPIO_LOCK(gpio_periph) = (uint32_t)lock;
  289. GPIO_LOCK(gpio_periph) = (uint32_t)pin;
  290. GPIO_LOCK(gpio_periph) = (uint32_t)lock;
  291. lock = GPIO_LOCK(gpio_periph);
  292. lock = GPIO_LOCK(gpio_periph);
  293. }
  294. /*!
  295. \brief toggle GPIO pin status
  296. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  297. \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
  298. \param[out] none
  299. \retval none
  300. */
  301. void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin)
  302. {
  303. GPIO_TG(gpio_periph) = (uint32_t)pin;
  304. }
  305. /*!
  306. \brief toggle GPIO port status
  307. \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
  308. \param[out] none
  309. \retval none
  310. */
  311. void gpio_port_toggle(uint32_t gpio_periph)
  312. {
  313. GPIO_TG(gpio_periph) = 0x0000FFFFU;
  314. }