ctl_gpio.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <sys/mman.h>
  6. #include <stdint.h> // 添加这个头文件来支持 uint32_t
  7. #define MAP_SIZE 0x1000 // 4KB 页大小
  8. #define GPIO1_CTL 0xFD6D0B50
  9. #define GPIO1_STATUS 0xFD6D0940
  10. #define GPIO2_CTL 0xFD6D0B60
  11. #define GPIO2_STATUS 0xFD6D0950
  12. int write_mem_bit(off_t target, int bit, int value)
  13. {
  14. volatile uint32_t *map_base = NULL;
  15. volatile uint32_t *addr = NULL;
  16. int fd;
  17. fd = open("/dev/mem", O_RDWR | O_SYNC);
  18. if (fd < 0)
  19. {
  20. perror("open /dev/mem");
  21. return -1;
  22. }
  23. // 页边界对齐映射
  24. map_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~(MAP_SIZE - 1));
  25. if (map_base == MAP_FAILED)
  26. {
  27. perror("mmap");
  28. close(fd);
  29. return -1;
  30. }
  31. addr = map_base + ((target & (MAP_SIZE - 1)) / sizeof(uint32_t));
  32. uint32_t reg = *addr;
  33. if (value)
  34. reg |= (1 << bit);
  35. else
  36. reg &= ~(1 << bit);
  37. *addr = reg;
  38. return 0;
  39. }
  40. int read_mem_bit(off_t target, int bit)
  41. {
  42. volatile uint32_t *map_base = NULL;
  43. volatile uint32_t *addr = NULL;
  44. int fd;
  45. fd = open("/dev/mem", O_RDWR | O_SYNC);
  46. if (fd < 0)
  47. {
  48. perror("open /dev/mem");
  49. return -1;
  50. }
  51. // 页边界对齐映射
  52. map_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~(MAP_SIZE - 1));
  53. if (map_base == MAP_FAILED)
  54. {
  55. perror("mmap");
  56. close(fd);
  57. return -1;
  58. }
  59. addr = map_base + ((target & (MAP_SIZE - 1)) / sizeof(uint32_t));
  60. return (*addr >> bit) & 1;
  61. }
  62. void usage()
  63. {
  64. printf("opt info:\n");
  65. printf(" 1-set gpio 1 output 0\n");
  66. printf(" 2-set gpio 1 output 1\n");
  67. printf(" 3-set gpio 2 output 0\n");
  68. printf(" 4-set gpio 2 output 1\n");
  69. printf(" 5-get gpio 1 status\n");
  70. printf(" 6-get gpio 2 status\n");
  71. printf(" 0-exit\n");
  72. printf("please input select:\n");
  73. }
  74. /*
  75. ./a.out <opt> <GPIO_num> <value>
  76. opt: w-write, r-read
  77. GPIO_num: 1, 2
  78. value: 0, 1
  79. for example:
  80. ./a.out w 1 0 GPIO-1 output 0
  81. ./a.out r 1 Get GPIO1 status
  82. */
  83. int main(int argc, char *argv[])
  84. {
  85. int cmd = -1;
  86. int ret = 0;
  87. while(cmd)
  88. {
  89. usage();
  90. scanf("%d", &cmd);
  91. switch(cmd)
  92. {
  93. case 1:
  94. ret = write_mem_bit(GPIO1_CTL, 0, 0);
  95. if(ret != 0)
  96. {
  97. printf("write gpio1 error\n");
  98. }
  99. break;
  100. case 2:
  101. ret = write_mem_bit(GPIO1_CTL, 0, 1);
  102. if(ret != 0)
  103. {
  104. printf("write gpio1 error\n");
  105. }
  106. break;
  107. case 3:
  108. ret = write_mem_bit(GPIO2_CTL, 0, 0);
  109. if(ret != 0)
  110. {
  111. printf("write gpio2 error\n");
  112. }
  113. break;
  114. case 4:
  115. ret = write_mem_bit(GPIO2_CTL, 0, 1);
  116. if(ret != 0)
  117. {
  118. printf("write gpio2 error\n");
  119. }
  120. break;
  121. case 5:
  122. printf("GPIO1 status = %d\n", read_mem_bit(GPIO1_STATUS, 1));
  123. break;
  124. case 6:
  125. printf("GPIO2 status = %d\n", read_mem_bit(GPIO2_STATUS, 1));
  126. break;
  127. case 0:
  128. printf("exit\n");
  129. return 0;
  130. }
  131. }
  132. return 0;
  133. }
  134. #if 0
  135. volatile uint32_t *map_base;
  136. int fd;
  137. void gpio_init(off_t target) {
  138. fd = open("/dev/mem", O_RDWR | O_SYNC);
  139. if (fd < 0) {
  140. perror("open /dev/mem");
  141. exit(1);
  142. }
  143. map_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~(MAP_SIZE - 1));
  144. if (map_base == MAP_FAILED) {
  145. perror("mmap");
  146. close(fd);
  147. exit(1);
  148. }
  149. }
  150. void gpio_write(off_t target, int bit, int value) {
  151. volatile uint32_t *addr = map_base + ((target & (MAP_SIZE - 1)) / sizeof(uint32_t));
  152. uint32_t reg = *addr;
  153. if (value)
  154. reg |= (1 << bit);
  155. else
  156. reg &= ~(1 << bit);
  157. *addr = reg;
  158. }
  159. int gpio_read(off_t target, int bit) {
  160. volatile uint32_t *addr = map_base + ((target & (MAP_SIZE - 1)) / sizeof(uint32_t));
  161. return (*addr >> bit) & 1;
  162. }
  163. void gpio_close() {
  164. munmap((void *)map_base, MAP_SIZE);
  165. close(fd);
  166. }
  167. int main() {
  168. // 示例:控制 GPIO1 输出高电平
  169. printf("设置 GPIO1 输出高电平...\n");
  170. gpio_init(0xFD6D0B50);
  171. gpio_write(0xFD6D0B50, 0, 1);
  172. gpio_close();
  173. // 读取 GPIO1 的状态
  174. printf("读取 GPIO1 状态...\n");
  175. gpio_init(0xFD6D0940);
  176. int val1 = gpio_read(0xFD6D0940, 1);
  177. printf("GPIO1 状态 = %d\n", val1);
  178. gpio_close();
  179. // 控制 GPIO2 输出低电平
  180. printf("设置 GPIO2 输出低电平...\n");
  181. gpio_init(0xFD6D0B60);
  182. gpio_write(0xFD6D0B60, 0, 0);
  183. gpio_close();
  184. // 读取 GPIO2 的状态
  185. printf("读取 GPIO2 状态...\n");
  186. gpio_init(0xFD6D0950);
  187. int val2 = gpio_read(0xFD6D0950, 1);
  188. printf("GPIO2 状态 = %d\n", val2);
  189. gpio_close();
  190. return 0;
  191. }
  192. #endif