Advertisement
Guest User

Untitled

a guest
Mar 28th, 2013
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.29 KB | None | 0 0
  1. /* A component to convert 7i73 bytecodes to bit pins */
  2. #include "rtapi.h"
  3. #include "rtapi_app.h"
  4. #include "hal.h"
  5. #include <linux/input.h>
  6. #include <linux/uinput.h>
  7.  
  8. #ifndef SIM // KERNEL (RTAPI) MODE
  9.  
  10. #define keyb_dev_t struct input_dev *
  11. #define CREATE_KB_DEV input_allocate_device()
  12. #define UNLOAD_KB_DEV(kb) input_unregister_device(kb)
  13. #define REGISTER_KB(kb) input_register_device(kb)
  14. #define NAME_KB(kb, n) kb->name = n;
  15. #define SETEVENT(kb) set_bit(EV_KEY, kb->evbit);
  16. #define SETKEY(kb, ev_code) set_bit(ev_code, kb->keybit);
  17. #define KEYUP(kb, ev_code) input_report_key(kb, ev_code, 0); \
  18. input_sync(kb);
  19. #define KEYDOWN(kb, ev_code)input_report_key(kb, ev_code, 1); \
  20. input_sync(kb);
  21.  
  22. #else // SIM OR USERLAND MODE
  23.  
  24. #include <stdio.h>
  25. #include <fcntl.h>
  26. #include <unistd.h>
  27. #define keyb_dev_t int
  28. #define CREATE_KB_DEV open("/dev/uinput", O_WRONLY | O_NONBLOCK)
  29. #define UNLOAD_KB_DEV(kb) ioctl(kb, UI_DEV_DESTROY)
  30. #define REGISTER_KB(kb) ioctl(kb, UI_DEV_CREATE)
  31. //the "if" suppresses a compiler warning. There may be a better way
  32. #define NAME_KB(kb, n) snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "%s", n); \
  33. uidev.id.bustype = BUS_VIRTUAL; \
  34. if(write(kb, &uidev, sizeof(uidev)))
  35. #define SETEVENT(kb) ioctl(kb, UI_SET_EVBIT, EV_KEY); \
  36. ioctl(kb, UI_SET_EVBIT, EV_SYN)
  37. #define SETKEY(kb, ev_code) ioctl(kb, UI_SET_KEYBIT, ev_code)
  38. #define KEYUP(kb, ev_code) ev.type = EV_KEY; ev.code = ev_code; ev.value = 0; \
  39. if(write(kb, &ev, sizeof(ev))); \
  40. ev.type = EV_SYN; ev.code = 0; ev.value = 0; \
  41. if(write(kb, &ev, sizeof(ev)))
  42. #define KEYDOWN(kb, ev_code)ev.type = EV_KEY; ev.code = ev_code; ev.value = 1; \
  43. if(write(kb, &ev, sizeof(ev))); \
  44. ev.type = EV_SYN; ev.code = 0; ev.value = 0; \
  45. if(write(kb, &ev, sizeof(ev)))
  46. #endif
  47.  
  48. #define MAX_CHAN 8
  49. #define MAX_ROLLOVER 8
  50.  
  51. /* module information */
  52. MODULE_AUTHOR("Andy Pugh");
  53. MODULE_DESCRIPTION("Hal-to-text component for Mesa 7i73 and similar");
  54. MODULE_LICENSE("GPL");
  55.  
  56. typedef struct {
  57. struct {
  58. hal_bit_t **key;
  59. hal_bit_t **rows;
  60. hal_bit_t **cols;
  61. hal_u32_t *keycode;
  62. } hal;
  63. struct {
  64. hal_u32_t *code;
  65. hal_u32_t rollover;
  66. hal_bit_t invert;
  67. } param;
  68. hal_u32_t ncols;
  69. hal_u32_t nrows;
  70. hal_u32_t *now;
  71. hal_u32_t *then;
  72. hal_u32_t keys[MAX_ROLLOVER];
  73. hal_bit_t invert;
  74. char name[HAL_NAME_LEN + 1];
  75. keyb_dev_t key_dev;
  76. hal_u32_t index;
  77. int keydown;
  78. int keyup;
  79. int rowshift;
  80. int row;
  81. int num_keys;
  82. int lastkey;
  83. hal_bit_t scan;
  84. hal_bit_t keystroke;
  85. }kb_inst_t;
  86.  
  87. typedef struct {
  88. kb_inst_t *insts;
  89. int num_insts;
  90. }kb_t;
  91.  
  92. static int comp_id;
  93. static kb_t *kb;
  94. struct input_event ev;
  95. struct uinput_user_dev uidev;
  96.  
  97. char *config[MAX_CHAN];
  98. RTAPI_MP_ARRAY_STRING(config, MAX_CHAN, "screen formatting scancodes")
  99. char *names[MAX_CHAN];
  100. RTAPI_MP_ARRAY_STRING(names, MAX_CHAN, "component names")
  101.  
  102. void keyup(kb_inst_t *inst){
  103. int r, c;
  104. int keycode = *inst->hal.keycode & ~(inst->keydown | inst->keyup);
  105.  
  106. r = keycode >> inst->rowshift;
  107. c = keycode & ~(0xFFFFFFFF << inst->rowshift);
  108.  
  109. if (r < 0
  110. || c < 0
  111. || r >= inst->nrows
  112. || c >= inst->ncols
  113. || inst->hal.key[r * inst->ncols + c] == NULL){
  114. return;
  115. }
  116.  
  117. if (inst->num_keys > 0) inst->num_keys--;
  118.  
  119. *inst->hal.key[r * inst->ncols + c] = 0;
  120.  
  121. if(inst->keystroke){
  122. if (inst->param.code[r * inst->ncols + c]){
  123. KEYUP(inst->key_dev, inst->param.code[r * inst->ncols + c]);
  124. }
  125. }
  126.  
  127. }
  128. void keydown(kb_inst_t *inst){
  129. int r, c;
  130. int keycode = *inst->hal.keycode & ~(inst->keydown | inst->keyup);
  131.  
  132. r = keycode >> inst->rowshift;
  133. c = keycode & ~(0xFFFFFFFF << inst->rowshift);
  134.  
  135. if (r < 0
  136. || c < 0
  137. || r >= inst->nrows
  138. || c >= inst->ncols
  139. || inst->hal.key[r * inst->ncols + c] == NULL){
  140. return;
  141. }
  142.  
  143. if (inst->num_keys >= inst->param.rollover) return;
  144. inst->num_keys++;
  145.  
  146. *inst->hal.key[r * inst->ncols + c] = 1;
  147.  
  148. if (inst->keystroke){
  149. if (inst->param.code[r * inst->ncols + c]){
  150. KEYDOWN(inst->key_dev, inst->param.code[r * inst->ncols + c]);
  151. }
  152. }
  153. }
  154.  
  155. void loop(void *arg, long period){
  156. int c;
  157. hal_u32_t scan = 0;
  158. kb_inst_t *inst = arg;
  159.  
  160. if (inst->param.rollover > MAX_ROLLOVER) inst->param.rollover = MAX_ROLLOVER;
  161.  
  162. if (inst->scan){ //scanning request
  163. for (c = 0; c < inst->ncols; c++){
  164. scan += ((*inst->hal.cols[c] != inst->param.invert) << c);
  165. }
  166. if (scan == inst->now[inst->row] && scan != inst->then[inst->row]){
  167. // debounced and changed
  168. for (c = 0; c < inst->ncols; c++){
  169. int mask = 1 << c;
  170. if ((inst->then[inst->row] & mask) && !(scan & mask)){ //keyup
  171. *inst->hal.keycode = inst->keyup
  172. + (inst->row << inst->rowshift)
  173. + c;
  174. keyup(inst);
  175. }
  176. else if (!(inst->then[inst->row] & mask) && (scan & mask)){//keydown
  177. *inst->hal.keycode = inst->keydown
  178. + (inst->row << inst->rowshift)
  179. + c;
  180.  
  181. keydown(inst);
  182. }
  183. }
  184. }
  185.  
  186. inst->then[inst->row] = inst->now[inst->row];
  187. inst->now[inst->row] = scan;
  188.  
  189. *inst->hal.rows[inst->row] = inst->param.invert;
  190. inst->row++;
  191. if (inst->row >= inst->nrows) inst->row = 0;
  192. *inst->hal.rows[inst->row] = !inst->param.invert;
  193. }
  194. else
  195. {
  196. if (*inst->hal.keycode == inst->lastkey) return;
  197. //lastkey is just to trap a 7i73 bug: keyup 0,0 == allup.
  198. if (*inst->hal.keycode & inst->keydown){
  199. keydown(inst);
  200. }
  201. else
  202. {
  203. keyup(inst);
  204. }
  205. inst->lastkey = *inst->hal.keycode;
  206. }
  207. }
  208.  
  209.  
  210. int rtapi_app_main(void){
  211. int i, j, n;
  212. int retval;
  213. comp_id = hal_init("matrix_kb");
  214. if (comp_id < 0) {
  215. rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: ERROR: hal_init() failed\n");
  216. return -1;
  217. }
  218.  
  219. // allocate shared memory for data
  220. kb = hal_malloc(sizeof(kb_t));
  221. if (kb == 0) {
  222. rtapi_print_msg(RTAPI_MSG_ERR,
  223. "matrix_kb component: Out of Memory\n");
  224. hal_exit(comp_id);
  225. return -1;
  226. }
  227.  
  228. // Count the instances.
  229. for (kb->num_insts = 0; config[kb->num_insts];kb->num_insts++);
  230. // Count the names.
  231. for (n = 0; names[n];n++);
  232.  
  233. if (n && n != kb->num_insts){
  234. rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Number of sizes and number"
  235. " of names must match\n");
  236. hal_exit(comp_id);
  237. return -1;
  238. }
  239.  
  240. kb->insts = hal_malloc(kb->num_insts * sizeof(kb_inst_t));
  241.  
  242. for (i = 0; i < kb->num_insts; i++){
  243. int a = 0;
  244. int c, r;
  245. kb_inst_t *inst = &kb->insts[i];
  246.  
  247. inst->index = i;
  248. inst->nrows = 0;
  249. inst->ncols = 0;
  250. inst->scan = 0;
  251. inst->keystroke = 0;
  252. inst->hal.keycode = 0;
  253. inst->lastkey = 0;
  254. inst->param.invert = 1;
  255.  
  256. for(j = 0; config[i][j] !=0; j++){
  257. int n = (config[i][j] | 0x20); //lower case
  258. if (n == 'x'){
  259. inst->nrows = a;
  260. a = 0;
  261. }
  262. else if (n >= '0' && n <= '9'){
  263. a = (a * 10) + (n - '0');
  264. }
  265. else if (n == 's'){
  266. inst->scan = 1;
  267. }
  268. else if (n == 'k'){
  269. inst->keystroke = 1;
  270. }
  271. }
  272. inst->ncols = a;
  273.  
  274. if (inst->ncols == 0 || inst->nrows == 0){
  275. rtapi_print_msg(RTAPI_MSG_ERR,
  276. "matrix_kb: Invalid size format. should be NxN\n");
  277. hal_exit(comp_id);
  278. return -1;
  279. }
  280.  
  281. if (inst->ncols > 32){
  282. rtapi_print_msg(RTAPI_MSG_ERR,
  283. "matrix_kb: maximum number of columns is 32. Sorry\n");
  284. hal_exit(comp_id);
  285. return -1;
  286. }
  287.  
  288. for (inst->rowshift = 1; inst->ncols > (1 << inst->rowshift); inst->rowshift++);
  289. for (inst->keydown = 0x40, inst->keyup = 0x80
  290. ; (inst->nrows << inst->rowshift) > inst->keydown
  291. ; inst->keydown <<= 1, inst->keyup <<= 1);
  292.  
  293. inst->hal.key = (hal_bit_t **)hal_malloc(inst->nrows * inst->ncols * sizeof(hal_bit_t*));
  294. inst->param.code = hal_malloc(inst->nrows * inst->ncols * sizeof(inst->param.code));
  295. inst->now = hal_malloc(inst->nrows * sizeof(hal_u32_t));
  296. inst->then = hal_malloc(inst->nrows * sizeof(hal_u32_t));
  297. inst->row = 0;
  298. inst->param.rollover = 2;
  299.  
  300.  
  301. if (names[i]){
  302. rtapi_snprintf(inst->name, sizeof(inst->name), "%s", names[i]);
  303. }
  304. else
  305. {
  306. rtapi_snprintf(inst->name, sizeof(inst->name), "matrix_kb.%i", i);
  307. }
  308.  
  309. for (c = 0; c < inst->ncols; c++){
  310. for (r = 0; r < inst->nrows; r++){
  311. retval = hal_pin_bit_newf(HAL_OUT,
  312. &(inst->hal.key[r * inst->ncols + c]),
  313. comp_id,
  314. "%s.key.r%xc%x",
  315. inst->name, r, c);
  316. if (retval != 0) {
  317. rtapi_print_msg(RTAPI_MSG_ERR,
  318. "matrix_kb: Failed to create output pin\n");
  319. hal_exit(comp_id);
  320. return -1;
  321. }
  322.  
  323. if (inst->keystroke){
  324. retval = hal_param_u32_newf(HAL_RW,
  325. &inst->param.code[r * inst->ncols + c],
  326. comp_id,
  327. "%s.code.r%xc%x",
  328. inst->name, r, c);
  329. if (retval != 0) {
  330. rtapi_print_msg(RTAPI_MSG_ERR,
  331. "matrix_kb: Failed to create output pin\n");
  332. hal_exit(comp_id);
  333. return -1;
  334. }
  335. }
  336. }
  337. }
  338.  
  339. if (inst->scan){ //internally generated scanning
  340. inst->hal.rows = (hal_bit_t **)hal_malloc(inst->nrows * sizeof(hal_bit_t*));
  341. inst->hal.cols = (hal_bit_t **)hal_malloc(inst->ncols * sizeof(hal_bit_t*));
  342.  
  343. for (r = 0; r < inst->nrows; r++){
  344. retval = hal_pin_bit_newf(HAL_OUT,
  345. &(inst->hal.rows[r]), comp_id,
  346. "%s.row-%02i-out",inst->name, r);
  347. if (retval != 0) {
  348. rtapi_print_msg(RTAPI_MSG_ERR,
  349. "matrix_kb: Failed to create output row pin\n");
  350. hal_exit(comp_id);
  351. return -1;
  352. }
  353. }
  354. for (c = 0; c < inst->ncols; c++){
  355. retval = hal_pin_bit_newf(HAL_IN,
  356. &(inst->hal.cols[c]), comp_id,
  357. "%s.col-%02i-in",inst->name, c);
  358. if (retval != 0) {
  359. rtapi_print_msg(RTAPI_MSG_ERR,
  360. "matrix_kb: Failed to create input col pin\n");
  361. hal_exit(comp_id);
  362. return -1;
  363. }
  364. }
  365.  
  366. retval = hal_pin_u32_newf(HAL_OUT,
  367. &(inst->hal.keycode), comp_id,
  368. "%s.keycode",inst->name);
  369. if (retval != 0) {
  370. rtapi_print_msg(RTAPI_MSG_ERR,
  371. "matrix_kb: Failed to create output pin\n");
  372. hal_exit(comp_id);
  373. return -1;
  374. }
  375.  
  376. retval = hal_param_bit_newf(HAL_RW,
  377. &(inst->param.invert), comp_id,
  378. "%s.negative-logic",inst->name);
  379. if (retval != 0) {
  380. rtapi_print_msg(RTAPI_MSG_ERR,
  381. "matrix_kb: Failed to create output pin\n");
  382. hal_exit(comp_id);
  383. return -1;
  384. }
  385.  
  386.  
  387. retval = hal_param_u32_newf(HAL_RW,
  388. &(inst->param.rollover), comp_id,
  389. "%s.key_rollover",inst->name);
  390. if (retval != 0) {
  391. rtapi_print_msg(RTAPI_MSG_ERR,
  392. "matrix_kb: Failed to create rollover param\n");
  393. hal_exit(comp_id);
  394. return -1;
  395. }
  396.  
  397. }
  398. else // scanning by 7i73 or similar
  399. {
  400. retval = hal_pin_u32_newf(HAL_IN,
  401. &(inst->hal.keycode), comp_id,
  402. "%s.keycode",inst->name);
  403. if (retval != 0) {
  404. rtapi_print_msg(RTAPI_MSG_ERR,
  405. "matrix_kb: Failed to create input pin\n");
  406. hal_exit(comp_id);
  407. return -1;
  408. }
  409. }
  410.  
  411. retval = hal_export_funct(inst->name, loop, inst, 1, 0, comp_id); //needs fp?
  412. if (retval < 0) {
  413. rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: ERROR: function export failed\n");
  414. return -1;
  415. }
  416.  
  417. if (inst->keystroke){ // keyboard output needed
  418. inst->key_dev = CREATE_KB_DEV;
  419. if (inst->key_dev <= 0) {
  420. rtapi_print_msg(RTAPI_MSG_ERR,"matrix_kb: failed to create dev\n");
  421. return -1;
  422. }
  423.  
  424. SETEVENT(inst->key_dev);
  425. for(j = 0; j < 226 ; j++){
  426. SETKEY(inst->key_dev, j);
  427. }
  428.  
  429. NAME_KB(inst->key_dev, inst->name);
  430. retval = REGISTER_KB(inst->key_dev);
  431.  
  432. if (retval < 0) {
  433. rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Failed to register device %i\n", retval);
  434. return -1;
  435. }
  436. }
  437. }
  438. hal_ready(comp_id);
  439.  
  440. return 0;
  441. }
  442.  
  443. void rtapi_app_exit(void)
  444. {
  445. hal_exit(comp_id);
  446. {
  447. int i;
  448. for (i = 0; i < kb->num_insts ; i++){
  449. if (kb->insts[i].keystroke) UNLOAD_KB_DEV(kb->insts[i].key_dev);
  450. }
  451. }
  452. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement