⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_parport.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -