hal_ppmc.c

来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 1,961 行 · 第 1/5 页

C
1,961
字号
/********************************************************************* Description:  hal_ppmc.c*               HAL driver for the the Pico Systems family of*               parallel port motion control boards, including*               the PPMC board set, the USC, and the UPC. ** Usage:  halcmd loadrt hal_ppmc port_addr=<addr1>[,addr2[,addr3]]*		[extradac=<slotcode1>,[<slotcode2>]]*		[extradout=<slotcode1,[<slotcode2>]]**               where 'addr1', 'addr2', and 'addr3' are the addresses*               of up to three parallel ports.**		extradac and extradout allow you to tell the driver* 		that you have an 8 bit DAC, or 8 digital outputs, on*		the 'extra' port of a USC or UPC board.  The slotcode*		is a two digit hex number of the form 0X12, where the*		first digit is the bus number (0, 1, or 2), and the*		second digit is the slot number on that bus (0 to F).*		The slotcode tells the driver which board(s) have the*		optional DAC or digital outs installed.** Author: John Kasunich, Jon Elson, Stephen Wille Padnos* License: GPL Version 2*    * Copyright (c) 2005 All rights reserved.*********************************************************************//** The driver searches the entire address space of the enhanced    parallel port (EPP) at 'port_addr', looking for any board(s)    in the PPMC family.  It then exports HAL pins for whatever it    finds, as well as a pair of functions, one that reads all     inputs, and one that writes all outputs.*//** 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.*/#ifndef RTAPI#error This is a realtime component only!#endif#include <linux/slab.h>		/* kmalloc() */#include "rtapi.h"		/* RTAPI realtime OS API */#include "rtapi_app.h"		/* RTAPI realtime module decls */#include "hal.h"		/* HAL public API decls */#define MAX_BUS 3	/* max number of parports (EPP busses) */#define	EPSILON		1e-20#ifdef MODULE/* module information */MODULE_AUTHOR("John Kasunich");MODULE_DESCRIPTION("HAL driver for Universal PWM Controller");MODULE_LICENSE("GPL");int port_addr[MAX_BUS] = { 0x0378, 0, 0 };  /* default, 1 bus at 0x0378 */void *port_registration[MAX_BUS] = {0,};RTAPI_MP_ARRAY_INT(port_addr, MAX_BUS, "port address(es) for EPP bus(es)");int extradac[MAX_BUS*8] = {        -1,-1,-1,-1,-1,-1,-1,-1,        -1,-1,-1,-1,-1,-1,-1,-1,        -1,-1,-1,-1,-1,-1,-1,-1 };  /* default, no extra stuff */RTAPI_MP_ARRAY_INT(extradac, MAX_BUS*8, "bus/slot locations of extra DAC modules");int extradout[MAX_BUS*8] = {        -1,-1,-1,-1,-1,-1,-1,-1,        -1,-1,-1,-1,-1,-1,-1,-1,        -1,-1,-1,-1,-1,-1,-1,-1 };  /* default, no extra stuff */RTAPI_MP_ARRAY_INT(extradout, MAX_BUS*8, "bus/slot locations of extra dig out modules");#endif /* MODULE *//************************************************************************                DEFINES (MOSTLY REGISTER ADDRESSES)                   *************************************************************************/#define SPPDATA(addr) addr#define STATUSPORT(addr) addr+1#define CONTROLPORT(addr) addr+2#define ADDRPORT(addr) addr+3#define DATAPORT(addr) addr+4#define NUM_SLOTS      16#define SLOT_SIZE      16#define SLOT_ID_OFFSET 15#define ENCCNT0     0x00	/*  EPP address to read first byte of encoder counter */#define ENCCNT1     0x03#define ENCCNT2     0x06#define ENCCNT3     0x09#define ENCCTRL     0x03	/* EPP address of encoder control register */#define ENCRATE     0x04	/* interrupt rate register, only on master encoder */#define ENCISR      0x0C	/* index detect latch register (read only) */#define ENCINDX     0x0D	/* index reset register (write only) */                                /* only available with rev 2 and above FPGA config */#define ENCLOAD     0x00	/* EPP address to write into first byte of preset */				/* register for channels 0 - 3 */#define DAC_0       0x00	/* EPP address of low byte of DAC chan 0 */#define DAC_1       0x02	/* EPP address of low byte of DAC chan 1 */#define DAC_2       0x04	/* EPP address of low byte of DAC chan 2 */#define DAC_3       0x06	/* EPP address of low byte of DAC chan 3 */#define DAC_MODE_0  0x4C#define DAC_WRITE_0 0x48#define DAC_MODE_1  0x5C#define DAC_WRITE_1 0x58#define PWM_GEN_0       0x10	/* EPP addr of low byte of PWM generator 0 LSB *///      PWM_GEN_0a      0x11	/* high byte MSB */#define PWM_GEN_1       0x12#define PWM_GEN_2       0x14#define PWM_GEN_3       0x16#define PWM_CTRL_0      0x1C#define PWM_FREQ_LO     0x1D#define PWM_FREQ_HI     0x1E#define RATE_GEN_0      0x10	/* EPP addr of low byte of rate generator 0 LSB *///      RATE_GEN_0a     0x11	/* middle byte *///      RATE_GEN_0b     0x12	/* MSB */#define RATE_GEN_1      0x13#define RATE_GEN_2      0x16#define RATE_GEN_3      0x19#define RATE_CTRL_0     0x1C#define RATE_SETUP_0    0x1D#define RATE_WIDTH_0    0x1E#define UxC_DINA        0x0D	/* EPP address of digital inputs on univstep */#define UxC_DINB        0x0E#define UxC_ESTOP_IN    0x0E/* The "estop" input will always report OFF to the software, regardless   of the actual state of the physical input, unless the "estop" output   has been turned on by the software. */#define UxC_EXTRA       0x0F    /* 8 bit "extra" port on USC and UPC *//* codes to indicate if/how the extra port is being used */#define EXTRA_UNUSED	0#define	EXTRA_DAC	1#define	EXTRA_DOUT	2#define UxC_DOUTA       0x1F	/* EPP address of digital outputs */#define UxC_ESTOP_OUT   0x1F#define UxC_SLAVE       0x06	/* EPP address of slave register *//* The physical output associated with the "estop" output will not come on   unless the physical "estop" input is also on.  All physical outputs   will not come on unless the physical "estop" output is on. */   /* The ESTOP function is completely implementd in FPGA hardware.  To getout of ESTOP, the safety chain must be a closed circuit (Green LED lit onboard), you then must satisfy the watchdog (if watchdog jumper is in ONposition) by writing to two adjacent velocity output channels (step, PWM orDAC) and finally by writing a 1 to the ESTOP command bit.  If all thesesafetys are satisfied, the board will come out of ESTOP, and the velocityand digital outputs will be enabled.  If any of these safety inputs indicatesan unsafe condition, then the board will immediately return to the ESTOP state.*/#define DIO_DINA        0x00	/* EPP address of digital inputs on DIO */#define DIO_DINB        0x01#define DIO_ESTOP_IN    0x02#define DIO_DOUTA       0x00	/* EPP address of digital outputs */#define DIO_ESTOP_OUT   0x02/************************************************************************                       STRUCTURE DEFINITIONS                          *************************************************************************//* this structure contains the runtime data for a digital output */typedef struct {    hal_bit_t *data;		/* output pin value */    hal_bit_t invert;		/* parameter to invert output pin */} dout_t;/* this structure contains the runtime data for a digital input */typedef struct {    hal_bit_t *data;		/* input pin value */    hal_bit_t *data_not;	/* inverted input pin value */} din_t;/* this structure contains the runtime data for a step pulse generator */typedef struct {    hal_bit_t *enable;		/* enable pin for step generator */    hal_float_t *vel;		/* velocity command pin*/    hal_float_t scale;		/* parameter: scaling for vel to Hz */    hal_float_t max_vel;	/* velocity limit */    hal_float_t freq;		/* parameter: velocity cmd scaled to Hz */} stepgen_t;/* runtime data for a set of 4 step pulse generators */typedef struct {    stepgen_t sg[4];		/* per generator data */    hal_u32_t setup_time_ns;	/* setup time in nanoseconds */    hal_u32_t pulse_width_ns;	/* pulse width in nanoseconds */    hal_u32_t pulse_space_ns;	/* min pulse space in nanoseconds */} stepgens_t;#define BOOT_NORMAL 0#define BOOT_REV    1#define BOOT_FWD    2/* this structure contains the runtime data for a PWM generator */typedef struct {    hal_bit_t *enable;		/* enable pin for PWM generator */    hal_float_t *value;		/* value command pin */    hal_float_t scale;		/* parameter: scaling */    hal_float_t max_dc;		/* maximum duty cycle 0.0-1.0 */    hal_float_t min_dc;		/* minimum duty cycle 0.0-1.0 */    hal_float_t duty_cycle;	/* actual duty cycle output */    hal_bit_t bootstrap;	/* enable bootstrap mode (pulses at startup) */    unsigned char boot_state;	/* state for bootstrap state machine */    unsigned char old_enable;	/* used to detect rising edge, for boot */} pwmgen_t;/* runtime data for a set of 4 PWM generators */typedef struct {    pwmgen_t pg[4];		/* per generator data */    hal_float_t freq;		/* PWM frequency */    hal_float_t old_freq;	/* previous value, to detect changes */    unsigned short period;	/* period in clock ticks */    double period_recip;	/* reciprocal of period */} pwmgens_t;/* this structure contains the runtime data for a 16-bit DAC */typedef struct {    hal_float_t *value;		/* value command pin */    hal_float_t scale;		/* parameter: scaling */} DAC_t;/* runtime data for a 4-channel 16-bit DAC */typedef struct {    DAC_t pg[4];		/* per DAC data */} DACs_t;/* runtime data for an "extra" port - can be either a DAC, or 8 digouts */typedef union {    DAC_t  dac;			/* if the port is used for a DAC */    dout_t douts[8];		/* if the port is used for digital outs */} extra_t;/* runtime data for a single encoder */typedef struct {    hal_float_t *position;      /* output: scaled position pointer */    hal_s32_t *count;           /* output: unscaled encoder counts */    hal_s32_t *delta;		/* output: delta counts since last read */    hal_float_t scale;          /* parameter: scale factor */    hal_bit_t *index;           /* output: index flag */    hal_bit_t *index_enable;    /* enable index pulse to reset encoder count */    signed long oldreading;     /* used to detect overflow / underflow of the counter */  unsigned int indres;        /* copy of reset-on-index register bits (only valid on 1st encoder of board)*/  unsigned int indrescnt;    /* counts servo cycles since index reset was turned on */} encoder_t;/* this structure contains the runtime data for a single EPP bus slot *//* A single slot can contain a wide variety of "stuff", ranging    from PWM or stepper or DAC outputs, to encoder inputs, to digital   I/O.  at runtime, the proper function(s) need to be invoked to    handle it.  We do that by having an array of functions that are   called in order.  The entries are filled in when the init code   scans the bus and determines what is in each slot */#define MAX_FUNCT 10struct slot_data_s;typedef void (slot_funct_t)(struct slot_data_s *slot);typedef struct slot_data_s {    unsigned char id;		/* slot id code */    unsigned char ver;		/* slot version code */    unsigned char strobe;	/* does this slot need a latch strobe */    unsigned char slot_base;	/* base addr of this 16 byte slot */    unsigned int port_addr;	/* addr of parport */    __u32 read_bitmap;		/* map showing which registers to read */    unsigned char num_rd_functs;/* number of read functions */    unsigned char rd_buf[32];	/* cached data read from epp bus */    slot_funct_t *rd_functs[MAX_FUNCT];	/* array of read functions */    __u32 write_bitmap;		/* map showing which registers to write */    unsigned char num_wr_functs;/* number of write functions */    unsigned char wr_buf[32];	/* cached data to be written to epp bus */    slot_funct_t *wr_functs[MAX_FUNCT];	/* array of write functions */    dout_t *digout;		/* ptr to shmem data for digital outputs */    din_t *digin;		/* ptr to shmem data for digital inputs */    stepgens_t *stepgen;	/* ptr to shmem data for step generators */    pwmgens_t *pwmgen;		/* ptr to shmem data for PWM generators */    encoder_t *encoder;         /* ptr to shmem data for encoders */    DACs_t *DAC;                /* ptr to shmem data for DACs */    int extra_mode;		/* indicates if/how "extra" port is used */    extra_t *extra;		/* ptr to shmem for "extra" port */} slot_data_t;/* this structure contains the runtime data for a complete EPP bus */typedef struct {//    unsigned int port_addr;	/* addr of parport to talk to board */    int busnum;			/* bus number */    unsigned char have_master;	/* true if a master has been configured */    unsigned int last_digout;	/* used for numbering digital outputs */    unsigned int last_digin;	/* used for numbering digital outputs */    unsigned int last_stepgen;	/* used for numbering step generators */    unsigned int last_pwmgen;	/* used for numbering PWM generators */    unsigned int last_encoder;	/* used for numbering encoders */    unsigned int last_DAC;	/* used for numbering DACs */    unsigned int last_extraDAC;	/* used for numbering DACs *///    unsigned int last_extradout;/* used for numbering digital outputs */    char slot_valid[NUM_SLOTS];	/* tags for slots that are used */    slot_data_t slot_data[NUM_SLOTS];  /* data for slots on EPP bus */} bus_data_t;/************************************************************************                          GLOBAL VARIABLES                            *************************************************************************/static bus_data_t *bus_array[MAX_BUS];static int comp_id;		/* component ID *//************************************************************************                    REALTIME FUNCTION DECLARATIONS                    *************************************************************************/static void read_all(void *arg, long period);static void write_all(void *arg, long period);static void read_digins(slot_data_t *slot);static void write_digouts(slot_data_t *slot);static void write_stepgens(slot_data_t *slot);static void write_pwmgens(slot_data_t *slot);static void read_encoders(slot_data_t *slot);static void write_DACs(slot_data_t *slot);static void write_extraDAC(slot_data_t *slot);/************************************************************************                  REALTIME I/O FUNCTION DECLARATIONS                  *************************************************************************/#if 0 /* FIXME not used */static void BusReset(unsigned int port_addr);#endifstatic int ClrTimeout(unsigned int port_addr);static unsigned short SelRead(unsigned char epp_addr, unsigned int port_addr);static unsigned short ReadMore(unsigned int port_addr);static void SelWrt(unsigned char byte, unsigned char epp_addr, unsigned int port_addr);static void WrtMore(unsigned char byte, unsigned int port_addr);/************************************************************************                  LOCAL FUNCTION DECLARATIONS                         *************************************************************************/static __u32 block(int min, int max);static int add_rd_funct(slot_funct_t *funct, slot_data_t *slot, __u32 cache_bitmap );static int add_wr_funct(slot_funct_t *funct, slot_data_t *slot, __u32 cache_bitmap );static int export_UxC_digin(slot_data_t *slot, bus_data_t *bus);static int export_UxC_digout(slot_data_t *slot, bus_data_t *bus);static int export_PPMC_digin(slot_data_t *slot, bus_data_t *bus);static int export_PPMC_digout(slot_data_t *slot, bus_data_t *bus);static int export_USC_stepgen(slot_data_t *slot, bus_data_t *bus);static int export_UPC_pwmgen(slot_data_t *slot, bus_data_t *bus);static int export_PPMC_DAC(slot_data_t *slot, bus_data_t *bus);static int export_encoders(slot_data_t *slot, bus_data_t *bus);static int export_extra_dac(slot_data_t *slot, bus_data_t *bus);static int export_extra_dout(slot_data_t *slot, bus_data_t *bus);/************************************************************************                       INIT AND EXIT CODE                             *************************************************************************/

⌨️ 快捷键说明

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