📄 hal_parport.c
字号:
rtapi_print_msg(RTAPI_MSG_ERR, "PARPORT: ERROR: read all funct param failed\n"); hal_exit(comp_id); return -1; } retval = hal_param_s8_new("parport.write_all", HAL_RD_WR, &write_funct_flags[0], comp_id); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PARPORT: ERROR: write all funct param failed\n"); hal_exit(comp_id); return -1; } rtapi_print_msg(RTAPI_MSG_INFO, "PARPORT: installed driver for %d ports\n", num_ports); /* capture INT (ctrl-C) and TERM signals */ signal(SIGINT, quit); signal(SIGTERM, quit); /*************************************/ /* main loop - loops forever until */ /* SIGINT (ctrl-C) or SIGTERM (kill) */ /*************************************/ while (!done) { if (read_funct_flags[0]) { /* run the function */ read_all(port_data_array, 0); /* if flag is positive, reset it */ if (read_funct_flags[0] > 0) { read_funct_flags[0] = 0; } } for (n = 0; n < num_ports; n++) { if (read_funct_flags[n + 1]) { /* run the function */ read_port(&(port_data_array[n]), 0); /* if flag is positive, reset it */ if (read_funct_flags[n + 1] > 0) { read_funct_flags[n + 1] = 0; } } } if (write_funct_flags[0]) { /* run the function */ write_all(port_data_array, 0); /* if flag is positive, reset it */ if (write_funct_flags[0] > 0) { write_funct_flags[0] = 0; } } for (n = 0; n < num_ports; n++) { if (write_funct_flags[n + 1]) { /* run the function */ write_port(&(port_data_array[n]), 0); /* if flag is positive, reset it */ if (write_funct_flags[n + 1] > 0) { write_funct_flags[n + 1] = 0; } } } /* set timeout to 0.05 seconds (20 Hz update rate if nothing else is running) */ tv.tv_sec = 0; tv.tv_usec = 50000; /* call select() with no file descriptors and a timeout to yield the CPU for (at least) 0,05 seconds - see NOTES section of man 2 select for details */ select(0, 0, 0, 0, &tv); } hal_exit(comp_id); return 0;}#endif/************************************************************************ REALTIME PORT READ AND WRITE FUNCTIONS *************************************************************************/static void read_port(void *arg, long period){ parport_t *port; int b; unsigned char indata, mask; port = arg; /* read the status port */ indata = rtapi_inb(port->base_addr + 1); /* invert bit 7 (pin 11) to compensate for hardware inverter */ indata ^= 0x80; /* split the bits into 10 variables (5 regular, 5 inverted) */ mask = 0x08; for (b = 0; b < 10; b += 2) { *(port->status_in[b]) = indata & mask; *(port->status_in[b + 1]) = !(indata & mask); mask <<= 1; } /* are we using the data port for input? */ if (port->data_dir != 0) { /* yes, read the data port */ indata = rtapi_inb(port->base_addr); /* split the bits into 16 variables (8 regular, 8 inverted) */ mask = 0x01; for (b = 0; b < 16; b += 2) { *(port->data_in[b]) = indata & mask; *(port->data_in[b + 1]) = !(indata & mask); mask <<= 1; } }}static void write_port(void *arg, long period){ parport_t *port; int b; unsigned char outdata, mask; port = arg; /* are we using the data port for output? */ if (port->data_dir == 0) { /* yes */ outdata = 0x00; mask = 0x01; /* assemble output byte for data port from 8 source variables */ for (b = 0; b < 8; b++) { /* get the data, add to output byte */ if ((*(port->data_out[b])) && (!port->data_inv[b])) { outdata |= mask; } if ((!*(port->data_out[b])) && (port->data_inv[b])) { outdata |= mask; } mask <<= 1; } /* write it to the hardware */ rtapi_outb(outdata, port->base_addr); /* prepare to build control port byte, with direction bit clear */ outdata = 0x00; } else { /* prepare to build control port byte, with direction bit set */ outdata = 0x20; } mask = 0x01; /* assemble output byte for control port from 4 source variables */ for (b = 0; b < 4; b++) { /* get the data, add to output byte */ if ((*(port->control_out[b])) && (!port->control_inv[b])) { outdata |= mask; } if ((!*(port->control_out[b])) && (port->control_inv[b])) { outdata |= mask; } mask <<= 1; } /* correct for hardware inverters on pins 1, 14, & 17 */ outdata ^= 0x0B; /* write it to the hardware */ rtapi_outb(outdata, port->base_addr + 2);}void read_all(void *arg, long period){ parport_t *port; int n; port = arg; for (n = 0; n < num_ports; n++) { read_port(&(port[n]), period); }}void write_all(void *arg, long period){ parport_t *port; int n; port = arg; for (n = 0; n < num_ports; n++) { write_port(&(port[n]), period); }}/************************************************************************ LOCAL FUNCTION DEFINITIONS *************************************************************************/static int pins_and_params(char *argv[]){ unsigned short port_addr[MAX_PORTS]; int data_dir[MAX_PORTS]; int n, retval; /* clear port_addr and data_dir arrays */ for (n = 0; n < MAX_PORTS; n++) { port_addr[n] = 0; data_dir[n] = 0; } /* parse config string, results in port_addr[] and data_dir[] arrays */ num_ports = 0; n = 0; while ((num_ports < MAX_PORTS) && (argv[n] != 0)) { port_addr[num_ports] = parse_port_addr(argv[n]); if (port_addr[num_ports] == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PARPORT: ERROR: bad port address '%s'\n", argv[n]); return -1; } n++; if (argv[n] != 0) { /* is the next token 'in' or 'out' ? */ if ((argv[n][0] == 'i') || (argv[n][0] == 'I')) { /* we aren't picky, anything starting with 'i' means 'in' ;-) */ data_dir[num_ports] = 1; n++; } else if ((argv[n][0] == 'o') || (argv[n][0] == 'O')) { /* anything starting with 'o' means 'out' */ data_dir[num_ports] = 0; n++; } } num_ports++; } /* OK, now we've parsed everything */ if (num_ports == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PARPORT: ERROR: no ports configured\n"); return -1; } /* have good config info, connect to the HAL */ comp_id = hal_init("hal_parport"); if (comp_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PARPORT: ERROR: hal_init() failed\n"); return -1; } /* allocate shared memory for parport data */ port_data_array = hal_malloc(num_ports * sizeof(parport_t)); if (port_data_array == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PARPORT: ERROR: hal_malloc() failed\n"); hal_exit(comp_id); return -1; } /* export all the pins and params for each port */ for (n = 0; n < num_ports; n++) { /* config addr and direction */ port_data_array[n].base_addr = port_addr[n]; port_data_array[n].data_dir = data_dir[n]; /* export all vars */ retval = export_port(n, &(port_data_array[n])); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PARPORT: ERROR: port %d var export failed\n", n); hal_exit(comp_id); return -1; } } return 0;}static unsigned short parse_port_addr(char *cp){ unsigned short result; /* initial value */ result = 0; /* test for leading '0x' */ if (cp[0] == '0') { if ((cp[1] == 'X') || (cp[1] == 'x')) { /* leading '0x', skip it */ cp += 2; } } /* ok, now parse digits */ while (*cp != '\0') { /* if char is a hex digit, add it to result */ if ((*cp >= '0') && (*cp <= '9')) { result <<= 4; result += *cp - '0'; } else if ((*cp >= 'A') && (*cp <= 'F')) { result <<= 4; result += (*cp - 'A') + 10; } else if ((*cp >= 'a') && (*cp <= 'f')) { result <<= 4; result += (*cp - 'a') + 10; } else { /* not a valid hex digit */ return 0; } /* next char */ cp++; } return result;}static int export_port(int portnum, parport_t * port){ int retval, msg; /* This function exports a lot of stuff, which results in a lot of logging if msg_level is at INFO or ALL. So we save the current value of msg_level and restore it later. If you actually need to log this function's actions, change the second line below */ msg = rtapi_get_msg_level(); rtapi_set_msg_level(RTAPI_MSG_WARN); retval = 0; /* declare input pins (status port) */ retval += export_input_pin(portnum, 15, port->status_in, 0); retval += export_input_pin(portnum, 13, port->status_in, 1); retval += export_input_pin(portnum, 12, port->status_in, 2); retval += export_input_pin(portnum, 10, port->status_in, 3); retval += export_input_pin(portnum, 11, port->status_in, 4); if (port->data_dir != 0) { /* declare input pins (data port) */ retval += export_input_pin(portnum, 2, port->data_in, 0); retval += export_input_pin(portnum, 3, port->data_in, 1); retval += export_input_pin(portnum, 4, port->data_in, 2); retval += export_input_pin(portnum, 5, port->data_in, 3); retval += export_input_pin(portnum, 6, port->data_in, 4); retval += export_input_pin(portnum, 7, port->data_in, 5); retval += export_input_pin(portnum, 8, port->data_in, 6); retval += export_input_pin(portnum, 9, port->data_in, 7); } else { /* declare output pins (data port) */ retval += export_output_pin(portnum, 2, port->data_out, port->data_inv, 0); retval += export_output_pin(portnum, 3, port->data_out, port->data_inv, 1); retval += export_output_pin(portnum, 4, port->data_out, port->data_inv, 2); retval += export_output_pin(portnum, 5, port->data_out, port->data_inv, 3); retval += export_output_pin(portnum, 6, port->data_out, port->data_inv, 4); retval += export_output_pin(portnum, 7, port->data_out, port->data_inv, 5); retval += export_output_pin(portnum, 8, port->data_out, port->data_inv, 6); retval += export_output_pin(portnum, 9, port->data_out, port->data_inv, 7); } /* declare output variables (control port) */ retval += export_output_pin(portnum, 1, port->control_out, port->control_inv, 0); retval += export_output_pin(portnum, 14, port->control_out, port->control_inv, 1); retval += export_output_pin(portnum, 16, port->control_out, port->control_inv, 2); retval += export_output_pin(portnum, 17, port->control_out, port->control_inv, 3); /* restore saved message level */ rtapi_set_msg_level(msg); return retval;}static int export_input_pin(int portnum, int pin, hal_bit_t ** base, int n){ char buf[HAL_NAME_LEN + 2]; int retval; /* export write only HAL pin for the input bit */ rtapi_snprintf(buf, HAL_NAME_LEN, "parport.%d.pin-%02d-in", portnum, pin); retval = hal_pin_bit_new(buf, HAL_WR, base + (2 * n), comp_id); if (retval != 0) { return retval; } /* export another write only HAL pin for the same bit inverted */ rtapi_snprintf(buf, HAL_NAME_LEN, "parport.%d.pin-%02d-in-not", portnum, pin); retval = hal_pin_bit_new(buf, HAL_WR, base + (2 * n) + 1, comp_id); return retval;}static int export_output_pin(int portnum, int pin, hal_bit_t ** dbase, hal_bit_t * pbase, int n){ char buf[HAL_NAME_LEN + 2]; int retval; /* export read only HAL pin for output data */ rtapi_snprintf(buf, HAL_NAME_LEN, "parport.%d.pin-%02d-out", portnum, pin); retval = hal_pin_bit_new(buf, HAL_RD, dbase + n, comp_id); if (retval != 0) { return retval; } /* export parameter for polarity */ rtapi_snprintf(buf, HAL_NAME_LEN, "parport.%d.pin-%02d-out-invert", portnum, pin); retval = hal_param_bit_new(buf, HAL_WR, pbase + n, comp_id); return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -