Драйверы программы Machinekit для работы c RISC сопроцессором внутри процессоров Allwinner H2+, H3 и H5
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

arisc.gpio.c 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. #include <stdint.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include "rtapi.h"
  5. #include "rtapi_app.h"
  6. #include "hal.h"
  7. #include "msg_api.h"
  8. #include "gpio_api.h"
  9. #include "arisc.gpio.h"
  10. #if !defined(TARGET_PLATFORM_ALLWINNER)
  11. //#error "This driver is for the Allwinner platform only"
  12. #endif
  13. MODULE_DESCRIPTION("GPIO driver for the Allwinner ARISC firmware");
  14. MODULE_LICENSE("GPL");
  15. static int32_t comp_id;
  16. static const uint8_t * comp_name = "arisc.gpio";
  17. static uint8_t cpu_id = ALLWINNER_H3;
  18. static char *CPU = "H3";
  19. RTAPI_MP_STRING(CPU, "Allwinner CPU name");
  20. static int8_t *in = "";
  21. RTAPI_MP_STRING(in, "input pins, comma separated");
  22. static int8_t *out = "";
  23. RTAPI_MP_STRING(out, "output pins, comma separated");
  24. static const char *gpio_name[GPIO_PORTS_CNT] =
  25. {"PA","PB","PC","PD","PE","PF","PG","PL"};
  26. static hal_u32_t **gpio_port_ID;
  27. static hal_bit_t **gpio_hal_0[GPIO_PORTS_CNT];
  28. static hal_bit_t **gpio_hal_1[GPIO_PORTS_CNT];
  29. static hal_bit_t gpio_hal_0_prev[GPIO_PORTS_CNT][GPIO_PINS_CNT];
  30. static hal_bit_t gpio_hal_1_prev[GPIO_PORTS_CNT][GPIO_PINS_CNT];
  31. static uint32_t gpio_real[GPIO_PORTS_CNT] = {0};
  32. static uint32_t gpio_real_prev[GPIO_PORTS_CNT] = {0};
  33. static uint32_t gpio_out_mask[GPIO_PORTS_CNT] = {0};
  34. static uint32_t gpio_in_mask[GPIO_PORTS_CNT] = {0};
  35. static uint32_t gpio_in_cnt = 0;
  36. static uint32_t gpio_out_cnt = 0;
  37. static const uint32_t gpio_mask[GPIO_PINS_CNT] =
  38. {
  39. 1U<< 0, 1U<< 1, 1U<< 2, 1U<< 3, 1U<< 4, 1U<< 5, 1U<< 6, 1U<< 7,
  40. 1U<< 8, 1U<< 9, 1U<<10, 1U<<11, 1U<<12, 1U<<13, 1U<<14, 1U<<15,
  41. 1U<<16, 1U<<17, 1U<<18, 1U<<19, 1U<<20, 1U<<21, 1U<<22, 1U<<23,
  42. 1U<<24, 1U<<25, 1U<<26, 1U<<27, 1U<<28, 1U<<29, 1U<<30, 1U<<31
  43. };
  44. // HAL functions
  45. static void gpio_read(void *arg, long period)
  46. {
  47. static uint32_t port, pin;
  48. static uint32_t* ports;
  49. if ( !gpio_in_cnt ) return;
  50. ports = gpio_all_get();
  51. for ( port = GPIO_PORTS_CNT; port--; )
  52. {
  53. if ( !gpio_in_mask[port] ) continue;
  54. gpio_real[port] = *(ports+port);
  55. if ( gpio_real_prev[port] == gpio_real[port] ) continue;
  56. for ( pin = GPIO_PINS_CNT; pin--; )
  57. {
  58. if ( !(gpio_in_mask[port] & gpio_mask[pin]) ) continue;
  59. if ( gpio_real[port] & gpio_mask[pin] )
  60. {
  61. *gpio_hal_0[port][pin] = 1;
  62. *gpio_hal_1[port][pin] = 0;
  63. }
  64. else
  65. {
  66. *gpio_hal_0[port][pin] = 0;
  67. *gpio_hal_1[port][pin] = 1;
  68. }
  69. }
  70. gpio_real_prev[port] = gpio_real[port];
  71. }
  72. }
  73. static void gpio_write(void *arg, long period)
  74. {
  75. static uint32_t port, pin;
  76. static uint32_t mask_0_cnt, mask_1_cnt;
  77. static uint32_t mask_0[GPIO_PORTS_CNT], mask_1[GPIO_PORTS_CNT];
  78. if ( !gpio_out_cnt ) return;
  79. mask_1_cnt = 0;
  80. mask_0_cnt = 0;
  81. for ( port = GPIO_PORTS_CNT; port--; )
  82. {
  83. mask_1[port] = 0;
  84. mask_0[port] = 0;
  85. if ( !gpio_out_mask[port] ) continue;
  86. for ( pin = GPIO_PINS_CNT; pin--; )
  87. {
  88. if ( !(gpio_out_mask[port] & gpio_mask[pin]) ) continue;
  89. if ( *gpio_hal_0[port][pin] != gpio_hal_0_prev[port][pin] )
  90. {
  91. gpio_hal_0_prev[port][pin] = *gpio_hal_0[port][pin];
  92. if ( *gpio_hal_0[port][pin] ) mask_1[port] |= gpio_mask[pin];
  93. else mask_0[port] |= gpio_mask[pin];
  94. }
  95. if ( *gpio_hal_1[port][pin] != gpio_hal_1_prev[port][pin] )
  96. {
  97. gpio_hal_1_prev[port][pin] = *gpio_hal_1[port][pin];
  98. if ( *gpio_hal_1[port][pin] ) mask_0[port] |= gpio_mask[pin];
  99. else mask_1[port] |= gpio_mask[pin];
  100. }
  101. }
  102. if ( mask_1[port] ) ++mask_1_cnt;
  103. if ( mask_0[port] ) ++mask_0_cnt;
  104. }
  105. if ( mask_1_cnt ) gpio_all_set(&mask_1[0]);
  106. if ( mask_0_cnt ) gpio_all_clear(&mask_0[0]);
  107. }
  108. // INIT
  109. static int32_t gpio_malloc_and_export(const char *comp_name, int32_t comp_id)
  110. {
  111. int8_t* arg_str[2] = {in, out};
  112. int8_t n, r;
  113. uint8_t port;
  114. // shared memory allocation
  115. for ( port = GPIO_PORTS_CNT; port--; )
  116. {
  117. gpio_hal_0[port] = hal_malloc(GPIO_PINS_CNT * sizeof(hal_bit_t *));
  118. gpio_hal_1[port] = hal_malloc(GPIO_PINS_CNT * sizeof(hal_bit_t *));
  119. if ( !gpio_hal_0[port] || !gpio_hal_1[port] )
  120. {
  121. rtapi_print_msg(RTAPI_MSG_ERR,
  122. "%s: port %s hal_malloc() failed \n",
  123. comp_name, gpio_name[port]);
  124. return -1;
  125. }
  126. }
  127. // export HAL pins
  128. for ( n = 2; n--; )
  129. {
  130. if ( !arg_str[n] ) continue;
  131. int8_t *data = arg_str[n], *token;
  132. uint8_t pin, found;
  133. int32_t retval;
  134. int8_t* type_str = n ? "out" : "in";
  135. while ( (token = strtok(data, ",")) != NULL )
  136. {
  137. if ( data != NULL ) data = NULL;
  138. if ( strlen(token) < 3 ) continue;
  139. // trying to find a correct port name
  140. for ( found = 0, port = GPIO_PORTS_CNT; port--; )
  141. {
  142. if ( 0 == memcmp(token, gpio_name[port], 2) )
  143. {
  144. found = 1;
  145. break;
  146. }
  147. }
  148. if ( !found ) continue;
  149. // trying to find a correct pin number
  150. pin = (uint8_t) strtoul(&token[2], NULL, 10);
  151. if ( (pin == 0 && token[2] != '0') || pin >= GPIO_PINS_CNT ) continue;
  152. // export pin function
  153. retval = hal_pin_bit_newf( (n ? HAL_IN : HAL_OUT),
  154. &gpio_hal_0[port][pin], comp_id,
  155. "%s.%s-%s", comp_name, token, type_str);
  156. // export pin inverted function
  157. retval += hal_pin_bit_newf( (n ? HAL_IN : HAL_OUT),
  158. &gpio_hal_1[port][pin], comp_id,
  159. "%s.%s-%s-not", comp_name, token, type_str);
  160. if (retval < 0)
  161. {
  162. rtapi_print_msg(RTAPI_MSG_ERR, "%s: pin %s export failed \n",
  163. comp_name, token);
  164. return -1;
  165. }
  166. // configure GPIO pin
  167. if ( n )
  168. {
  169. gpio_out_cnt++;
  170. gpio_out_mask[port] |= gpio_mask[pin];
  171. gpio_pin_setup_for_output(port, pin);
  172. }
  173. else
  174. {
  175. gpio_in_cnt++;
  176. gpio_in_mask[port] |= gpio_mask[pin];
  177. gpio_pin_setup_for_input(port, pin);
  178. }
  179. }
  180. }
  181. // export port ID pins
  182. gpio_port_ID = hal_malloc(GPIO_PORTS_CNT * sizeof(hal_u32_t));
  183. if ( !gpio_port_ID )
  184. {
  185. rtapi_print_msg(RTAPI_MSG_ERR, "%s: [GPIO] port ID pins malloc failed\n", comp_name);
  186. return -1;
  187. }
  188. for ( r = 0, port = GPIO_PORTS_CNT; port--; )
  189. {
  190. r += hal_pin_u32_newf(HAL_OUT, &gpio_port_ID[port], comp_id, "%s", gpio_name[port]);
  191. if (r) break;
  192. *gpio_port_ID[port] = port;
  193. }
  194. if ( r )
  195. {
  196. rtapi_print_msg(RTAPI_MSG_ERR, "%s: [GPIO] port ID pins export failed\n", comp_name);
  197. return -1;
  198. }
  199. // export HAL functions
  200. r = 0;
  201. r += hal_export_functf(gpio_write, 0, 0, 0, comp_id, "%s.write", comp_name);
  202. r += hal_export_functf(gpio_read, 0, 0, 0, comp_id, "%s.read", comp_name);
  203. if ( r )
  204. {
  205. rtapi_print_msg(RTAPI_MSG_ERR, "%s: [GPIO] functions export failed\n", comp_name);
  206. return -1;
  207. }
  208. return 0;
  209. }
  210. int32_t rtapi_app_main(void)
  211. {
  212. // get component id
  213. if ( (comp_id = hal_init(comp_name)) < 0 )
  214. {
  215. rtapi_print_msg(RTAPI_MSG_ERR, "%s: hal_init() failed\n", comp_name);
  216. return -1;
  217. }
  218. #define EXIT { hal_exit(comp_id); return -1; }
  219. // shared memory allocation and export
  220. cpu_id = allwinner_cpu_id_get(CPU);
  221. if ( msg_mem_init(cpu_id, comp_name) ) EXIT;
  222. if ( gpio_malloc_and_export(comp_name, comp_id) ) EXIT;
  223. // driver ready to work
  224. hal_ready(comp_id);
  225. return 0;
  226. }
  227. void rtapi_app_exit(void)
  228. {
  229. msg_mem_deinit();
  230. hal_exit(comp_id);
  231. }