Advertisement
Guest User

Untitled

a guest
Mar 28th, 2013
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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