Ejemplo n.º 1
0
void rtapi_app_exit(void)
{
    int retval;

    /* disable parallel port hardware interrupts */
    rtapi_outb(rtapi_inb(PARPORT_BASE_ADDRESS + 2) & (~0x10),
	PARPORT_BASE_ADDRESS + 2);

    /* clear ISR */
    retval = rtapi_disable_interrupt(PARPORT_IRQ);
    if (retval < 0) {
	rtapi_print("extint exit: rtapi_disable_interrupt returned %d\n",
	    retval);
	return;
    }
    retval = rtapi_irq_delete(PARPORT_IRQ);
    if (retval < 0) {
	rtapi_print("extint exit: rtapi_irq_delete returned %d\n", retval);
	return;
    }

    rtapi_print("extint exit: interrupt count is %d\n", timer_count);

    retval = rtapi_exit(module);
    if (retval < 0) {
	rtapi_print("extint exit: rtapi_exit returned %d\n", retval);
	return;
    }
}
Ejemplo n.º 2
0
int rtapi_app_main(void)
{
    int retval;

    module = rtapi_init("EXTINT");
    if (module < 0) {
	rtapi_print("extint init: rtapi_init returned %d\n", module);
	return -1;
    }
    /* set up ISR */
    retval = rtapi_irq_new(PARPORT_IRQ, module, parport_irq_handler);
    if (retval < 0) {
	rtapi_print("extint init: rtapi_irq_new returned %d\n", retval);
	return -1;
    }
    retval = rtapi_enable_interrupt(PARPORT_IRQ);
    if (retval < 0) {
	rtapi_print("extint init: rtapi_enable_interrupt returned %d\n",
	    retval);
	return -1;
    }

    /* enable parallel port hardware interrupts */
    rtapi_outb(rtapi_inb(PARPORT_BASE_ADDRESS + 2) | 0x10,
	PARPORT_BASE_ADDRESS + 2);

    return 0;
}
Ejemplo n.º 3
0
static void write_port(void *arg, long period)
{
    skeleton_t *port;
    unsigned char outdata;
    port = arg;

    outdata = *(port->data_out) & 0xFF;
    /* write it to the hardware */
    rtapi_outb(outdata, 0x378);
}
Ejemplo n.º 4
0
static void reset_port(void *arg, long period) {
    parport_t *port = arg;
    long long deadline, reset_time_tsc;
    unsigned char outdata = (port->outdata&~port->reset_mask) ^ port->reset_val;
   
    if(port->reset_time > period/4) port->reset_time = period/4;
    reset_time_tsc = ns2tsc(port->reset_time);

    if(outdata != port->outdata) {
        deadline = port->write_time + reset_time_tsc;
        while(rtapi_get_clocks() < deadline) {}
        rtapi_outb(outdata, port->base_addr);
    }

    outdata = (port->outdata_ctrl&~port->reset_mask_ctrl)^port->reset_val_ctrl;

    if(outdata != port->outdata_ctrl) {
	/* correct for hardware inverters on pins 1, 14, & 17 */
	outdata ^= 0x0B;
        deadline = port->write_time_ctrl + reset_time_tsc;
        while(rtapi_get_clocks() < deadline) {}
        rtapi_outb(outdata, port->base_addr + 2);
    }
}
Ejemplo n.º 5
0
static int pins_and_params(char *argv[])
{
    long port_addr[MAX_PORTS];
    int data_dir[MAX_PORTS];
    int use_control_in[MAX_PORTS];
    int force_epp[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;
	force_epp[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] == 'e') || (argv[n][0] == 'E')) {
		/* anything starting with 'e' means 'epp', which is just
                   like 'out' but with EPP mode requested, primarily for
                   the G540 with its charge pump missing-pullup drive
                   issue */
                data_dir[num_ports] = 0;
                use_control_in[num_ports] = 0;
                force_epp[num_ports] = 1;
		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++) {
        int modes = 0;

        if(use_control_in[n]) {
            modes = PARPORT_MODE_TRISTATE;
        } else if(force_epp[n]) {
            modes = PARPORT_MODE_EPP;
        }

        retval = hal_parport_get(comp_id, &port_data_array[n].portdata,
                port_addr[n], -1, modes);

        if(retval < 0) {
            // failure message already printed by hal_parport_get
	    hal_exit(comp_id);
            return retval;
        }

	/* config addr and direction */
	port_data_array[n].base_addr = port_data_array[n].portdata.base;
	port_data_array[n].data_dir = data_dir[n];
	port_data_array[n].use_control_in = use_control_in[n];

        if(force_epp[n] && port_data_array[n].portdata.base_hi) {
            /* select EPP mode in ECR */
            outb(0x94, port_data_array[n].portdata.base_hi + 2);
        }

	/* set data port (pins 2-9) direction to "in" if needed */
	if (data_dir[n]) {
	    rtapi_outb(rtapi_inb(port_data_array[n].base_addr+2) | 0x20, port_data_array[n].base_addr+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 retval;
	}
    }
    return 0;
}
Ejemplo n.º 6
0
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) {
	int reset_mask=0, reset_val=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;
	    }
	    if (port->data_reset[b]) {
		reset_mask |= mask;
		if(port->data_inv[b]) reset_val |= mask;
	    }
	    mask <<= 1;
	}
	/* write it to the hardware */
	rtapi_outb(outdata, port->base_addr);
	port->write_time = rtapi_get_clocks();
	port->reset_val = reset_val;
	port->reset_mask = reset_mask;
	port->outdata = outdata;
	/* 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();
}