ls1b_gpio.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2017-09-06 勤为本 first version
  9. * 2021-02-02 michael5hzg@gmail.com adapt to ls1b
  10. */
  11. #include "ls1b_public.h"
  12. #include "ls1b_regs.h"
  13. #include "ls1b_gpio.h"
  14. #include "ls1b_pin.h"
  15. /*
  16. * 获取指定gpio的CFG寄存器
  17. * @gpio gpio编号
  18. * @ret CFG寄存器
  19. */
  20. volatile unsigned int *gpio_get_cfg_reg(unsigned int gpio)
  21. {
  22. volatile unsigned int *gpio_cfgx = NULL; // GPIO_CFGx寄存器
  23. unsigned int port = GPIO_GET_PORT(gpio);
  24. switch (port)
  25. {
  26. case 0:
  27. gpio_cfgx = (volatile unsigned int *)LS1B_GPIO_CFG0;
  28. break;
  29. case 1:
  30. gpio_cfgx = (volatile unsigned int *)LS1B_GPIO_CFG1;
  31. break;
  32. default:
  33. gpio_cfgx = NULL;
  34. break;
  35. }
  36. return gpio_cfgx;
  37. }
  38. /*
  39. * 获取指定gpio的EN寄存器
  40. * @gpio gpio编号
  41. * @ret EN寄存器
  42. */
  43. volatile unsigned int *gpio_get_en_reg(unsigned int gpio)
  44. {
  45. volatile unsigned int *gpio_enx = NULL; // GPIO_ENx寄存器
  46. unsigned int port = GPIO_GET_PORT(gpio);
  47. switch (port)
  48. {
  49. case 0:
  50. gpio_enx = (volatile unsigned int *)LS1B_GPIO_EN0;
  51. break;
  52. case 1:
  53. gpio_enx = (volatile unsigned int *)LS1B_GPIO_EN1;
  54. break;
  55. default:
  56. gpio_enx = NULL;
  57. return gpio_enx;
  58. }
  59. return gpio_enx;
  60. }
  61. /*
  62. * gpio初始化
  63. * @gpio gpio引脚,取值范围[0, 127]
  64. * @mode gpio的工作模式(输入、输出)
  65. *
  66. * 例: 将gpio50初始化为输出
  67. * gpio_init(50, gpio_mode_output);
  68. */
  69. void gpio_init(unsigned int gpio, gpio_mode_t mode)
  70. {
  71. volatile unsigned int *gpio_enx = NULL; // GPIO_ENx寄存器
  72. unsigned int pin = GPIO_GET_PIN(gpio);
  73. // 将pin设为普通GPIO
  74. pin_set_purpose(gpio, PIN_PURPOSE_GPIO);
  75. // 设置gpio工作模式(输入、输出)
  76. gpio_enx = gpio_get_en_reg(gpio);
  77. if (gpio_mode_output == mode) // 输出
  78. {
  79. reg_clr_one_bit(gpio_enx, pin);
  80. }
  81. else // 输入
  82. {
  83. reg_set_one_bit(gpio_enx, pin);
  84. }
  85. return ;
  86. }
  87. /*
  88. * 在指定gpio输出高电平或低电平
  89. * @gpio gpio引脚,取值范围[0, 127]
  90. * @level 电平值
  91. *
  92. * 例: 在gpio50上输出低电平
  93. * gpio_set(50, gpio_level_low);
  94. */
  95. void gpio_set(unsigned int gpio, gpio_level_t level)
  96. {
  97. volatile unsigned int *gpio_outx = NULL; // GPIO_OUTx寄存器
  98. unsigned int port = GPIO_GET_PORT(gpio);
  99. unsigned int pin = GPIO_GET_PIN(gpio);
  100. // 获取寄存器地址
  101. switch (port)
  102. {
  103. case 0:
  104. gpio_outx = (volatile unsigned int *)LS1B_GPIO_OUT0;
  105. break;
  106. case 1:
  107. gpio_outx = (volatile unsigned int *)LS1B_GPIO_OUT1;
  108. break;
  109. default: // 正确的程序不应该走到这里,直接返回
  110. return ;
  111. }
  112. // 输出
  113. if (gpio_level_low == level)
  114. {
  115. reg_clr_one_bit(gpio_outx, pin);
  116. }
  117. else
  118. {
  119. reg_set_one_bit(gpio_outx, pin);
  120. }
  121. return ;
  122. }
  123. /*
  124. * 读取指定gpio引脚的值
  125. * @gpio gpio引脚,取值范围[0,127]
  126. *
  127. * 例: 读取gpio50引脚上的值
  128. * gpio_level_t level;
  129. * level = gpio_get(50);
  130. */
  131. unsigned int gpio_get(unsigned int gpio)
  132. {
  133. volatile unsigned int *gpio_inx = NULL; // GPIO_INx寄存器
  134. unsigned int port = GPIO_GET_PORT(gpio);
  135. unsigned int pin = GPIO_GET_PIN(gpio);
  136. // 获取寄存器地址
  137. switch (port)
  138. {
  139. case 0:
  140. gpio_inx = (volatile unsigned int *)LS1B_GPIO_IN0;
  141. break;
  142. case 1:
  143. gpio_inx = (volatile unsigned int *)LS1B_GPIO_IN1;
  144. break;
  145. default: // 正常的流程不应该走到这里,直接返回
  146. return 0;
  147. }
  148. // 读取
  149. return reg_get_bit(gpio_inx, pin);
  150. }
  151. /**
  152. * 设置中断类型
  153. * @gpio gpio引脚
  154. * @type 触发中断的条件。高电平触发、低电平触发、上升沿触发 or 下降沿触发
  155. */
  156. void gpio_set_irq_type(unsigned int gpio, gpio_irq_type_t type)
  157. {
  158. volatile unsigned int *int_pol = NULL; // 中断极性选择寄存器
  159. volatile unsigned int *int_edge = NULL; // 中断边沿选择寄存器
  160. unsigned int port = GPIO_GET_PORT(gpio);
  161. unsigned int pin = GPIO_GET_PIN(gpio);
  162. // 获取寄存器地址
  163. switch (port)
  164. {
  165. case 0: // GPIO[31:0]
  166. int_pol = (volatile unsigned int *)LS1B_INT2_POL;
  167. int_edge = (volatile unsigned int *)LS1B_INT2_EDGE;
  168. break;
  169. case 1: // GPIO[63:32]
  170. int_pol = (volatile unsigned int *)LS1B_INT3_POL;
  171. int_edge = (volatile unsigned int *)LS1B_INT3_EDGE;
  172. break;
  173. }
  174. // 设置中断类型
  175. switch (type)
  176. {
  177. case IRQ_TYPE_EDGE_RISING:
  178. *int_pol |= (1 << pin);
  179. *int_edge |= (1 << pin);
  180. break;
  181. case IRQ_TYPE_EDGE_FALLING:
  182. *int_pol &= ~(1 << pin);
  183. *int_edge |= (1 << pin);
  184. break;
  185. case IRQ_TYPE_LEVEL_HIGH:
  186. *int_pol |= (1 << pin);
  187. *int_edge &= ~(1 << pin);
  188. break;
  189. case IRQ_TYPE_LEVEL_LOW:
  190. *int_pol &= ~(1 << pin);
  191. *int_edge &= ~(1 << pin);
  192. break;
  193. default:
  194. break;
  195. }
  196. return ;
  197. }