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

📄 hal_parport.c

📁 CNC 的开放码,EMC2 V2.2.8版
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************************************* Description:  hal_parport.c*               This file, 'hal_parport.c', is a HAL component that *               provides a driver for the standard PC parallel port.** Author: John Kasunich* License: GPL Version 2*    * Copyright (c) 2003 All rights reserved.** Last change: # $Revision: 1.34 $* $Author: cradek $* $Date: 2007/10/14 00:23:43 $********************************************************************//** This file, 'hal_parport.c', is a HAL component that provides a    driver for the standard PC parallel port.    It supports up to eight parallel ports, and if the port hardware    is bidirectional, the eight data bits can be configured as inputs    or outputs.    The configuration is determined by command line arguments for the    user space version of the driver, and by a config string passed    to insmod for the realtime version.  The format is similar for    both, and consists of a port address, followed by an optional    direction, repeated for each port.  The direction is either "in"    or "out" and determines the direction of the 8 bit data port.    The default is out.  The 5 bits of the status port are always    inputs, and the 4 bits of the control port are always outputs.    Example command lines are as follows:    user:        hal_parport 378 in 278    realtime:    insmod hal_parport.o cfg="378 in 278"    Both of these commands install the driver and configure parports    at base addresses 0x0378 (using data port as input) and 0x0278    (using data port as output).    The driver creates HAL pins and parameters for each port pin    as follows:    Each physical output has a correspinding HAL pin, named    'parport.<portnum>.pin-<pinnum>-out', and a HAL parameter    'parport.<portnum>.pin-<pinnum>-out-invert'.    Each physical input has two corresponding HAL pins, named    'parport.<portnum>.pin-<pinnum>-in' and    'parport.<portnum>.pin-<pinnum>-in-not'.    <portnum> is the port number, starting from zero.  <pinnum> is    the physical pin number on the DB-25 connector.    The realtime version of the driver exports two HAL functions for    each port, 'parport.<portnum>.read' and 'parport.<portnum>.write'.    It also exports two additional functions, 'parport.read-all' and    'parport.write-all'.  Any or all of these functions can be added    to realtime HAL threads to update the port data periodically.    The user space version of the driver cannot export functions,    instead it exports parameters with the same names.  The main()    function sits in a loop checking the parameters.  If they are    zero, it does nothing.  If any parameter is greater than zero,    the corresponding function runs once, then the parameter is    reset to zero.  If any parameter is less than zero, the    corresponding function runs on every pass through the loop.    The driver will loop forever, until it receives either    SIGINT (ctrl-C) or SIGTERM, at which point it cleans up and    exits.*//** Copyright (C) 2003 John Kasunich                       <jmkasunich AT users DOT sourceforge DOT net>*//** This program is free software; you can redistribute it and/or    modify it under the terms of version 2 of the GNU General    Public License as published by the Free Software Foundation.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111 USA    THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR    ANY HARM OR LOSS RESULTING FROM ITS USE.  IT IS _EXTREMELY_ UNWISE    TO RELY ON SOFTWARE ALONE FOR SAFETY.  Any machinery capable of    harming persons must have provisions for completely removing power    from all motors, etc, before persons enter any danger area.  All    machinery must be designed to comply with local and national safety    codes, and the authors of this software can not, and do not, take    any responsibility for such compliance.    This code was written as part of the EMC HAL project.  For more    information, go to www.linuxcnc.org.*/#if ( !defined RTAPI ) && ( !defined ULAPI )#error parport needs RTAPI/ULAPI, check makefile and flags#endif#include "rtapi.h"		/* RTAPI realtime OS API */#include "rtapi_ctype.h"	/* isspace() */#ifdef RTAPI			/* realtime */#include "rtapi_app.h"		/* RTAPI realtime module decls */#else /* user space */#include <signal.h>		/* signal() */#include <sys/time.h>		/* stuct timeval */#include <sys/types.h>		/* for select() */#include <unistd.h>		/* for select() */#include <sys/io.h>		/* iopl() */#endif#include "hal.h"		/* HAL public API decls *//* If FASTIO is defined, uses outb() and inb() from <asm.io>,   instead of rtapi_outb() and rtapi_inb() - the <asm.io> ones   are inlined, and save a microsecond or two (on my 233MHz box)*/#define FASTIO#ifdef FASTIO#define rtapi_inb inb#define rtapi_outb outb#ifdef RTAPI			/* for ULAPI, sys/io.h defines these functs */#include <asm/io.h>#endif#endif#ifdef RTAPI			/* realtime */#ifdef MODULE/* module information */MODULE_AUTHOR("John Kasunich");MODULE_DESCRIPTION("Parallel Port Driver for EMC HAL");MODULE_LICENSE("GPL");static char *cfg = "0x0278";	/* config string, default 1 output port at 278 */RTAPI_MP_STRING(cfg, "config string");#endif /* MODULE */#endif /* RTAPI *//************************************************************************                STRUCTURES AND GLOBAL VARIABLES                       *************************************************************************//* this structure contains the runtime data needed by the   parallel port driver for a single port*/typedef struct {    unsigned short base_addr;	/* base I/O address (0x378, etc.) */    unsigned char data_dir;	/* non-zero if pins 2-9 are input */    unsigned char use_control_in; /* non-zero if pins 1, 4, 16, 17 are input */     hal_bit_t *status_in[10];	/* ptrs for in pins 15, 13, 12, 10, 11 */    hal_bit_t *data_in[16];	/* ptrs for input pins 2 - 9 */    hal_bit_t *data_out[8];	/* ptrs for output pins 2 - 9 */    hal_bit_t data_inv[8];	/* polarity params for output pins 2 - 9 */    hal_bit_t data_reset[8];	/* reset flag for output pins 2 - 9 */    hal_bit_t *control_in[8];	/* ptrs for in pins 1, 14, 16, 17 */    hal_bit_t *control_out[4];	/* ptrs for out pins 1, 14, 16, 17 */    hal_bit_t control_inv[4];	/* pol. params for output pins 1, 14, 16, 17 */    hal_bit_t control_reset[4];	/* reset flag for output pins 1, 14, 16, 17 */    hal_u32_t reset_time;       /* min ns between write and reset */    hal_u32_t debug1, debug2;    long long write_time;    unsigned char outdata;    unsigned char reset_mask;       /* reset flag for pin 2..9 */    unsigned char reset_val;        /* reset values for pin 2..9 */    long long write_time_ctrl;    unsigned char outdata_ctrl;    unsigned char reset_mask_ctrl;  /* reset flag for pin 1, 14, 16, 17 */    unsigned char reset_val_ctrl;   /* reset values for pin 1, 14, 16, 17 */} parport_t;/* pointer to array of parport_t structs in shared memory, 1 per port */static parport_t *port_data_array;/* other globals */static int comp_id;		/* component ID */static int num_ports;		/* number of ports configured */static unsigned long ns2tsc_factor;#define ns2tsc(x) (((x) * (unsigned long long)ns2tsc_factor) >> 12)/************************************************************************                  LOCAL FUNCTION DECLARATIONS                         *************************************************************************//* These are the functions that actually do the I/O   everything else is just init code*/static void read_port(void *arg, long period);static void reset_port(void *arg, long period);static void write_port(void *arg, long period);static void read_all(void *arg, long period);static void write_all(void *arg, long period);/* 'pins_and_params()' does most of the work involved in setting up   the driver.  It parses the command line (argv[]), then if the   command line is OK, it calls hal_init(), allocates shared memory   for the parport_t data structure(s), and exports pins and parameters   It does not set up functions, since that is handled differently in   realtime and user space.*/static int pins_and_params(char *argv[]);static unsigned short parse_port_addr(char *cp);static int export_port(int portnum, parport_t * addr);static int export_input_pin(int portnum, int pin, hal_bit_t ** base, int n);static int export_output_pin(int portnum, int pin, hal_bit_t ** dbase,    hal_bit_t * pbase, hal_bit_t * rbase, int n);/************************************************************************                       INIT AND EXIT CODE                             *************************************************************************/#define MAX_PORTS 8#ifdef RTAPI			/* realtime */#define MAX_TOK ((MAX_PORTS*2)+3)int rtapi_app_main(void){    char *cp;    char *argv[MAX_TOK];    char name[HAL_NAME_LEN + 2];    int n, retval;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)    // this calculation fits in a 32-bit unsigned     // as long as CPUs are under about 6GHz    ns2tsc_factor = (cpu_khz << 6) / 15625ul;#else    ns2tsc_factor = 1ll<<12;#endif    /* test for config string */    if (cfg == 0) {	rtapi_print_msg(RTAPI_MSG_ERR, "PARPORT: ERROR: no config string\n");	return -1;    }rtapi_print ( "config string '%s'\n", cfg );    /* as a RT module, we don't get a nice argc/argv command line, we only       get a single string... so we need to tokenize it ourselves */    /* in addition, it seems that insmod under kernel 2.6 will truncate        a string parameter at the first whitespace.  So we allow '_' as       an alternate token separator. */    cp = cfg;    for (n = 0; n < MAX_TOK; n++) {	/* strip leading whitespace */	while ((*cp != '\0') && ( isspace(*cp) || ( *cp == '_') ))	    cp++;	/* mark beginning of token */	argv[n] = cp;	/* find end of token */	while ((*cp != '\0') && !( isspace(*cp) || ( *cp == '_') ))	    cp++;	/* mark end of this token, prepare to search for next one */	if (*cp != '\0') {	    *cp = '\0';	    cp++;	}    }    for (n = 0; n < MAX_TOK; n++) {	/* is token empty? */	if (argv[n][0] == '\0') {	    /* yes - make pointer NULL */	    argv[n] = NULL;	}    }    /* parse "command line", set up pins and parameters */    retval = pins_and_params(argv);    if (retval != 0) {	return retval;    }    /* export functions for each port */    for (n = 0; n < num_ports; n++) {	/* make read function name */	rtapi_snprintf(name, HAL_NAME_LEN, "parport.%d.read", n);	/* export read function */	retval = hal_export_funct(name, read_port, &(port_data_array[n]),	    0, 0, comp_id);	if (retval != 0) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"PARPORT: ERROR: port %d read funct export failed\n", n);	    hal_exit(comp_id);	    return -1;	}	/* make write function name */	rtapi_snprintf(name, HAL_NAME_LEN, "parport.%d.write", n);	/* export write function */	retval = hal_export_funct(name, write_port, &(port_data_array[n]),	    0, 0, comp_id);	if (retval != 0) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"PARPORT: ERROR: port %d write funct export failed\n", n);	    hal_exit(comp_id);	    return -1;	}	/* make reset function name */	rtapi_snprintf(name, HAL_NAME_LEN, "parport.%d.reset", n);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -