ls1c_gpio.c 5.9 KB

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