📄 hal_parport.c
字号:
/* 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; } /* are we using the control port for input? */ if (port->use_control_in) { /* yes, force those pins high */ outdata |= 0x0F; } else { int reset_mask=0, reset_val=0; /* no, assemble output byte from 4 source variables */ mask = 0x01; 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; } if (port->control_reset[b]) { reset_mask |= mask; if(port->control_inv[b]) reset_val |= mask; } mask <<= 1; } port->reset_mask_ctrl = reset_mask; port->reset_val_ctrl = reset_val; port->outdata_ctrl = outdata; } /* correct for hardware inverters on pins 1, 14, & 17 */ outdata ^= 0x0B; /* write it to the hardware */ rtapi_outb(outdata, port->base_addr + 2); port->write_time_ctrl = rtapi_get_clocks();}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 use_control_in[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; use_control_in[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; use_control_in[num_ports] = 0; n++; } else if ((argv[n][0] == 'o') || (argv[n][0] == 'O')) { /* anything starting with 'o' means 'out' */ data_dir[num_ports] = 0; use_control_in[num_ports] = 0; n++; } else if ((argv[n][0] == 'x') || (argv[n][0] == 'X')) { /* experimental: some parports support a bidirectional * control port. Enable this with pins 2-9 in output mode, * which gives a very nice 8 outs and 9 ins. */ data_dir[num_ports] = 0; use_control_in[num_ports] = 1; 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]; port_data_array[n].use_control_in = use_control_in[n]; /* set data port (pins 2-9) direction to "in" if needed */ if (data_dir[n]) { rtapi_outb(rtapi_inb(port_addr[n]+2) | 0x20, port_addr[n]+2); } /* 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, port->data_reset, 0); retval += export_output_pin(portnum, 3, port->data_out, port->data_inv, port->data_reset, 1); retval += export_output_pin(portnum, 4, port->data_out, port->data_inv, port->data_reset, 2); retval += export_output_pin(portnum, 5, port->data_out, port->data_inv, port->data_reset, 3); retval += export_output_pin(portnum, 6, port->data_out, port->data_inv, port->data_reset, 4); retval += export_output_pin(portnum, 7, port->data_out, port->data_inv, port->data_reset, 5); retval += export_output_pin(portnum, 8, port->data_out, port->data_inv, port->data_reset, 6); retval += export_output_pin(portnum, 9, port->data_out, port->data_inv, port->data_reset, 7); retval += hal_param_u32_newf(HAL_RW, &port->reset_time, comp_id, "parport.%d.reset-time", portnum); retval += hal_param_u32_newf(HAL_RW, &port->debug1, comp_id, "parport.%d.debug1", portnum); retval += hal_param_u32_newf(HAL_RW, &port->debug2, comp_id, "parport.%d.debug2", portnum); port->write_time = 0; } if(port->use_control_in == 0) { /* declare output variables (control port) */ retval += export_output_pin(portnum, 1, port->control_out, port->control_inv, port->control_reset, 0); retval += export_output_pin(portnum, 14, port->control_out, port->control_inv, port->control_reset, 1); retval += export_output_pin(portnum, 16, port->control_out, port->control_inv, port->control_reset, 2); retval += export_output_pin(portnum, 17, port->control_out, port->control_inv, port->control_reset, 3); } else { /* declare input variables (control port) */ retval += export_input_pin(portnum, 1, port->control_in, 0); retval += export_input_pin(portnum, 14, port->control_in, 1); retval += export_input_pin(portnum, 16, port->control_in, 2); retval += export_input_pin(portnum, 17, port->control_in, 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){ int retval; /* export write only HAL pin for the input bit */ retval = hal_pin_bit_newf(HAL_OUT, base + (2 * n), comp_id, "parport.%d.pin-%02d-in", portnum, pin); if (retval != 0) { return retval; } /* export another write only HAL pin for the same bit inverted */ retval = hal_pin_bit_newf(HAL_OUT, base + (2 * n) + 1, comp_id, "parport.%d.pin-%02d-in-not", portnum, pin); return retval;}static int export_output_pin(int portnum, int pin, hal_bit_t ** dbase, hal_bit_t * pbase, hal_bit_t * rbase, int n){ int retval; /* export read only HAL pin for output data */ retval = hal_pin_bit_newf(HAL_IN, dbase + n, comp_id, "parport.%d.pin-%02d-out", portnum, pin); if (retval != 0) { return retval; } /* export parameter for polarity */ retval = hal_param_bit_newf(HAL_RW, pbase + n, comp_id, "parport.%d.pin-%02d-out-invert", portnum, pin); if (retval != 0) { return retval; } /* export parameter for reset */ if (rbase) retval = hal_param_bit_newf(HAL_RW, rbase + n, comp_id, "parport.%d.pin-%02d-out-reset", portnum, pin); return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -