gpio_lib.c 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * gpio_lib.c
  3. *
  4. * Copyright 2013 Stefan Mavrodiev <support@olimex.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  19. * MA 02110-1301, USA.
  20. */
  21. /******************************************************************************/
  22. #include <ctype.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <math.h>
  27. #include <time.h>
  28. #include <signal.h>
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <fcntl.h>
  32. #include <sys/mman.h>
  33. #include <sys/select.h>
  34. #include <pthread.h>
  35. #include <unistd.h>
  36. #include <sched.h>
  37. #include "gpio_lib.h"
  38. /******************************************************************************/
  39. unsigned int SUNXI_PIO_BASE = 0;
  40. static volatile long int *gpio_map = NULL;
  41. /******************************************************************************/
  42. int sunxi_gpio_init(void)
  43. {
  44. int fd;
  45. unsigned int addr_start, addr_offset;
  46. unsigned int PageSize, PageMask;
  47. fd = open("/dev/mem", O_RDWR);
  48. if (fd < 0) {
  49. return SETUP_DEVMEM_FAIL;
  50. }
  51. PageSize = sysconf(_SC_PAGESIZE);
  52. PageMask = (~(PageSize-1));
  53. addr_start = SW_PORTC_IO_BASE & PageMask;
  54. addr_offset = SW_PORTC_IO_BASE & ~PageMask;
  55. gpio_map = (void *)mmap(0, PageSize*2, PROT_READ|PROT_WRITE,
  56. MAP_SHARED, fd, addr_start);
  57. if (gpio_map == MAP_FAILED)
  58. {
  59. return SETUP_MMAP_FAIL;
  60. }
  61. SUNXI_PIO_BASE = (unsigned int)gpio_map;
  62. SUNXI_PIO_BASE += addr_offset;
  63. close(fd);
  64. return SETUP_OK;
  65. }
  66. /******************************************************************************/
  67. int sunxi_gpio_set_cfgpin(unsigned int pin, unsigned int val)
  68. {
  69. unsigned int cfg;
  70. unsigned int bank = GPIO_BANK(pin);
  71. unsigned int index = GPIO_CFG_INDEX(pin);
  72. unsigned int offset = GPIO_CFG_OFFSET(pin);
  73. if (SUNXI_PIO_BASE == 0) {
  74. return -1;
  75. }
  76. struct sunxi_gpio *pio =
  77. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  78. cfg = *(&pio->cfg[0] + index);
  79. cfg &= ~(0xf << offset);
  80. cfg |= val << offset;
  81. *(&pio->cfg[0] + index) = cfg;
  82. return 0;
  83. }
  84. /******************************************************************************/
  85. int sunxi_gpio_get_cfgpin(unsigned int pin)
  86. {
  87. unsigned int cfg;
  88. unsigned int bank = GPIO_BANK(pin);
  89. unsigned int index = GPIO_CFG_INDEX(pin);
  90. unsigned int offset = GPIO_CFG_OFFSET(pin);
  91. if (SUNXI_PIO_BASE == 0)
  92. {
  93. return -1;
  94. }
  95. struct sunxi_gpio *pio =
  96. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  97. cfg = *(&pio->cfg[0] + index);
  98. cfg >>= offset;
  99. return (cfg & 0xf);
  100. }
  101. /******************************************************************************/
  102. int sunxi_gpio_output(unsigned int pin, unsigned int val)
  103. {
  104. unsigned int bank = GPIO_BANK(pin);
  105. unsigned int num = GPIO_NUM(pin);
  106. if (SUNXI_PIO_BASE == 0)
  107. {
  108. return -1;
  109. }
  110. struct sunxi_gpio *pio =
  111. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  112. if(val)
  113. *(&pio->dat) |= 1 << num;
  114. else
  115. *(&pio->dat) &= ~(1 << num);
  116. return 0;
  117. }
  118. /******************************************************************************/
  119. int sunxi_gpio_getoutput(unsigned int pin)
  120. {
  121. unsigned int bank = GPIO_BANK(pin);
  122. unsigned int num = GPIO_NUM(pin);
  123. if (SUNXI_PIO_BASE == 0)
  124. {
  125. return -1;
  126. }
  127. struct sunxi_gpio *pio =
  128. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  129. return *(&pio->dat) & (1 << num);
  130. }
  131. /******************************************************************************/
  132. int sunxi_gpio_input(unsigned int pin)
  133. {
  134. unsigned int dat;
  135. unsigned int bank = GPIO_BANK(pin);
  136. unsigned int num = GPIO_NUM(pin);
  137. if (SUNXI_PIO_BASE == 0)
  138. {
  139. return -1;
  140. }
  141. struct sunxi_gpio *pio =
  142. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  143. dat = *(&pio->dat);
  144. dat >>= num;
  145. return (dat & 0x1);
  146. }
  147. /******************************************************************************/
  148. void sunxi_gpio_cleanup(void)
  149. {
  150. unsigned int PageSize;
  151. if (gpio_map == NULL)
  152. return;
  153. PageSize = sysconf(_SC_PAGESIZE);
  154. munmap((void*)gpio_map, PageSize*2);
  155. }
  156. /******************************************************************************/