1
0

ls1c_gpio.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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. */
  10. #include "ls1c_public.h"
  11. #include "ls1c_regs.h"
  12. #include "ls1c_gpio.h"
  13. #include "ls1c_pin.h"
  14. /*
  15. * 获取指定gpio的CFG寄存器
  16. * @gpio gpio编号
  17. * @ret CFG寄存器
  18. */
  19. volatile unsigned int *gpio_get_cfg_reg(unsigned int gpio)
  20. {
  21. volatile unsigned int *gpio_cfgx = NULL; // GPIO_CFGx寄存器
  22. unsigned int port = GPIO_GET_PORT(gpio);
  23. switch (port)
  24. {
  25. case 0:
  26. gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG0;
  27. break;
  28. case 1:
  29. gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG1;
  30. break;
  31. case 2:
  32. gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG2;
  33. break;
  34. case 3:
  35. gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG3;
  36. break;
  37. default:
  38. gpio_cfgx = NULL;
  39. break;
  40. }
  41. return gpio_cfgx;
  42. }
  43. /*
  44. * 获取指定gpio的EN寄存器
  45. * @gpio gpio编号
  46. * @ret EN寄存器
  47. */
  48. volatile unsigned int *gpio_get_en_reg(unsigned int gpio)
  49. {
  50. volatile unsigned int *gpio_enx = NULL; // GPIO_ENx寄存器
  51. unsigned int port = GPIO_GET_PORT(gpio);
  52. switch (port)
  53. {
  54. case 0:
  55. gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN0;
  56. break;
  57. case 1:
  58. gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN1;
  59. break;
  60. case 2:
  61. gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN2;
  62. break;
  63. case 3:
  64. gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN3;
  65. break;
  66. default:
  67. gpio_enx = NULL;
  68. return gpio_enx;
  69. }
  70. return gpio_enx;
  71. }
  72. /*
  73. * gpio初始化
  74. * @gpio gpio引脚,取值范围[0, 127]
  75. * @mode gpio的工作模式(输入、输出)
  76. *
  77. * 例: 将gpio50初始化为输出
  78. * gpio_init(50, gpio_mode_output);
  79. */
  80. void gpio_init(unsigned int gpio, gpio_mode_t mode)
  81. {
  82. volatile unsigned int *gpio_enx = NULL; // GPIO_ENx寄存器
  83. unsigned int pin = GPIO_GET_PIN(gpio);
  84. // 将pin设为普通GPIO
  85. pin_set_purpose(gpio, PIN_PURPOSE_GPIO);
  86. // 设置gpio工作模式(输入、输出)
  87. gpio_enx = gpio_get_en_reg(gpio);
  88. if (gpio_mode_output == mode) // 输出
  89. {
  90. reg_clr_one_bit(gpio_enx, pin);
  91. }
  92. else // 输入
  93. {
  94. reg_set_one_bit(gpio_enx, pin);
  95. }
  96. return ;
  97. }
  98. /*
  99. * 在指定gpio输出高电平或低电平
  100. * @gpio gpio引脚,取值范围[0, 127]
  101. * @level 电平值
  102. *
  103. * 例: 在gpio50上输出低电平
  104. * gpio_set(50, gpio_level_low);
  105. */
  106. void gpio_set(unsigned int gpio, gpio_level_t level)
  107. {
  108. volatile unsigned int *gpio_outx = NULL; // GPIO_OUTx寄存器
  109. unsigned int port = GPIO_GET_PORT(gpio);
  110. unsigned int pin = GPIO_GET_PIN(gpio);
  111. // 获取寄存器地址
  112. switch (port)
  113. {
  114. case 0:
  115. gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT0;
  116. break;
  117. case 1:
  118. gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT1;
  119. break;
  120. case 2:
  121. gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT2;
  122. break;
  123. case 3:
  124. gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT3;
  125. break;
  126. default: // 正确的程序不应该走到这里,直接返回
  127. return ;
  128. }
  129. // 输出
  130. if (gpio_level_low == level)
  131. {
  132. reg_clr_one_bit(gpio_outx, pin);
  133. }
  134. else
  135. {
  136. reg_set_one_bit(gpio_outx, pin);
  137. }
  138. return ;
  139. }
  140. /*
  141. * 读取指定gpio引脚的值
  142. * @gpio gpio引脚,取值范围[0,127]
  143. *
  144. * 例: 读取gpio50引脚上的值
  145. * gpio_level_t level;
  146. * level = gpio_get(50);
  147. */
  148. unsigned int gpio_get(unsigned int gpio)
  149. {
  150. volatile unsigned int *gpio_inx = NULL; // GPIO_INx寄存器
  151. unsigned int port = GPIO_GET_PORT(gpio);
  152. unsigned int pin = GPIO_GET_PIN(gpio);
  153. // 获取寄存器地址
  154. switch (port)
  155. {
  156. case 0:
  157. gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN0;
  158. break;
  159. case 1:
  160. gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN1;
  161. break;
  162. case 2:
  163. gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN2;
  164. break;
  165. case 3:
  166. gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN3;
  167. break;
  168. default: // 正常的流程不应该走到这里,直接返回
  169. return 0;
  170. }
  171. // 读取
  172. return reg_get_bit(gpio_inx, pin);
  173. }
  174. /**
  175. * 设置中断类型
  176. * @gpio gpio引脚
  177. * @type 触发中断的条件。高电平触发、低电平触发、上升沿触发 or 下降沿触发
  178. */
  179. void gpio_set_irq_type(unsigned int gpio, gpio_irq_type_t type)
  180. {
  181. volatile unsigned int *int_pol = NULL; // 中断极性选择寄存器
  182. volatile unsigned int *int_edge = NULL; // 中断边沿选择寄存器
  183. unsigned int port = GPIO_GET_PORT(gpio);
  184. unsigned int pin = GPIO_GET_PIN(gpio);
  185. // 获取寄存器地址
  186. switch (port)
  187. {
  188. case 0: // GPIO[31:0]
  189. int_pol = (volatile unsigned int *)LS1C_INT2_POL;
  190. int_edge = (volatile unsigned int *)LS1C_INT2_EDGE;
  191. break;
  192. case 1: // GPIO[63:32]
  193. int_pol = (volatile unsigned int *)LS1C_INT3_POL;
  194. int_edge = (volatile unsigned int *)LS1C_INT3_EDGE;
  195. break;
  196. case 2: // GPIO[95:64]
  197. int_pol = (volatile unsigned int *)LS1C_INT4_POL;
  198. int_edge = (volatile unsigned int *)LS1C_INT4_EDGE;
  199. break;
  200. }
  201. // 设置中断类型
  202. switch (type)
  203. {
  204. case IRQ_TYPE_EDGE_RISING:
  205. *int_pol |= (1 << pin);
  206. *int_edge |= (1 << pin);
  207. break;
  208. case IRQ_TYPE_EDGE_FALLING:
  209. *int_pol &= ~(1 << pin);
  210. *int_edge |= (1 << pin);
  211. break;
  212. case IRQ_TYPE_LEVEL_HIGH:
  213. *int_pol |= (1 << pin);
  214. *int_edge &= ~(1 << pin);
  215. break;
  216. case IRQ_TYPE_LEVEL_LOW:
  217. *int_pol &= ~(1 << pin);
  218. *int_edge &= ~(1 << pin);
  219. break;
  220. default:
  221. break;
  222. }
  223. return ;
  224. }