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

📄 hal_vti.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 2 页
字号:
static void vti_dacs_write(void *arg, long period){    vti_struct *vti;    float volts;    unsigned short ncounts, i;    vti = arg;    for (i = 0; i < num_chan; i++) {	/* scale the voltage to be written based on offset and gain */	volts =	    (*(vti->dac_value[i]) - vti->dac_offset[i]) * vti->dac_gain[i];	/* compute the value for the DAC, the extra - in there is vti specific */        ncounts = ((volts / 10) * 0x7fff) + 0x8000;		/* write it to the card */	vti_dac_write(i, ncounts);    }}/* The VTI board has no ADCs. Procedure is retained only as a stub, should it be called from   elsewhere in the application. */   static void vti_adcs_read(void *arg, long period){    return;}// helper function to extract the data out of a char and place it into HAL data// written by JMKstatic void split_input(unsigned char data, io_pin * dest, int num){    int b;    unsigned char mask;    /* splits a byte into 'num' HAL pins (and their NOTs) */    mask = 0x01;    for (b = 0; b < num; b++) {	if (data & mask) {	    /* input high, which means FALSE (active low) */	    *(dest->data) = 0;	    *(dest->io.not) = 1;	} else {	    /* input low, which means TRUE */	    *(dest->data) = 1;	    *(dest->io.not) = 0;	}	mask <<= 1;	dest++;    }}// helper function to extract the data out of HAL and place it into a char// written by JMKunsigned char build_output(io_pin * src, int num){    int b;    unsigned char data, mask;    data = 0x00;    mask = 0x01;    /* assemble output byte for data port from 'num' source variables */    for (b = 0; b < num; b++) {	/* get the data, add to output byte */	if (*(src->data)) {	    if (!(src->io.invert)) {		data |= mask;	    }	} else {	    if ((src->io.invert)) {		data |= mask;	    }	}	mask <<= 1;	src++;    }    return data;}static void vti_di_read(void *arg, long period)	//reads digital inputs from the vti{    vti_struct *vti;    int i;    char latchedVal;    vti = arg;    if (diocount == 0) return; // No DIO enabled    /* Get ENCDAC onboard inputs */    latchedVal = encoder->DIO;    if (vti->dir_bits[0] == 0)	split_input(latchedVal, &(vti->port[0][0]), 4);    if (vti->dir_bits[1] == 0)	split_input(latchedVal, &(vti->port[0][4]), 4);		    /* Get Extended I/O inputs */   if (diocount <= 8) return; // No extended I/O enabled   for (i = 1; i < (diocount / 8); i++) {   	latchedVal = dac->DIO[i - 1];	if (vti->dir_bits[i * 2] == 0)	    split_input(latchedVal, &(vti->port[i][0]), 4);	if (vti->dir_bits[i * 2 + 1] == 0)	    split_input(latchedVal, &(vti->port[i][4]), 4);      }}static void vti_do_write(void *arg, long period)	//writes digital outputs to the vti{    vti_struct *vti;    int i;        vti = arg;    /* Write ENCDAC onboard outputs */    if (diocount == 0) return; // No DIO    encoder->DIO = build_output(&(vti->port[0][0]), 8);    if (diocount <= 8) return; // No extended I/O        /* Write Extended I/O outputs */     for (i = 1; i < diocount / 8; i++) {	dac->DIO[i - 1] = build_output(&(vti->port[i][0]), 8);       } }/************************************************************************                      BOARD SPECIFIC FUNCTIONS                        **       execute board related things (write/read to/from the vti)      *************************************************************************//************************************************************************                            INIT FUNCTIONS                            *************************************************************************//*  vti_counter_init() - Initializes the channel  works the same for both cards (vti & STG2)*/static int vti_counter_init(int counters){    int i, retval=0;    /* export all the variables for each counter, dac */    for (i = 0; i < counters; i++) {	/* export all vars */	retval = export_counter(i, vti_driver);	if (retval != 0) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"VTI: ERROR: counter %d var export failed\n", i + 1);	    hal_exit(comp_id);	    return -1;	}	/* init counter */	*(vti_driver->count[i]) = 0;	*(vti_driver->pos[i]) = 0.0;	vti_driver->pos_scale[i] = 1.0;    }    return 0;}/*  vti_dac_init() - Initializes the dac channel  works the same for both cards (vti & STG2)*/static int vti_dac_init(int channels){    int retval, i;        encoder->DAC = DAC_IND_MODE;  // Enable DACs for output indpendent of watchdog    for (i = 0; i < channels; i++) {	retval = export_dac(i, vti_driver);	if (retval != 0) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"VTI: ERROR: dac %d var export failed\n", i + 1);	    hal_exit(comp_id);	    return -1;	}	/* init counter */	*(vti_driver->dac_value[i]) = 0;	vti_driver->dac_offset[i] = 0.0;	vti_driver->dac_gain[i] = 1.0;	vti_dac_write(i, DAC_ZERO_VOLTS);    }    return 0;}/*  vti_adc_init() - Initializes the adc channel *//*  VTI card has no ADCs.                        */static int vti_adc_init(int channels){    return 0;}static int vti_dio_init(int nibbles){    unsigned int mask;    int i;        /* we will select the directions of each port */    /* First initialize the 8 on board I/O points */    if (diocount == 0) return 0; // No DIO    encoder->DIO = 0;		// Turn all inputs / outputs off    mask = encoder->Interrupt;    mask &= 0xfffffcff;		// Mask off direction bits    if (vti_driver->dir_bits[0] == 1)	mask |= 0x00000100;	// Set mask for bits 0-3    if (vti_driver->dir_bits[1] == 1)	mask |= 0x00000200;	// Set mask for bits 4-7    encoder->Interrupt = mask;    /* Now initialize all extended I/O */    if (diocount <= 8) return 0; // No extended I/O    for (i = 0; i < (diocount - 8) / 8; i++) {	dac->DIO[i] = 0;	// Turn all extended I/O off    }    mask = 0;    for (i = 0; i < 8; i++) {	// Set direction for extended I/O points 0..63	if (vti_driver->dir_bits[(i * 2) + 2] == 1)	    mask |= (1 << i);    }    dac->config0 = mask;    mask = 0;    for (i = 0; i < 8; i++) {	// Set direction for extended I/O points 64..127	if (vti_driver->dir_bits[(i * 2) + 18] == 1)	    mask |= (1 << i);    }    dac->config1 = mask;    return 0;}/************************************************************************                          ACTION FUNCTIONS                            **            these do the actual data exchange with the board          *************************************************************************//*  vti_counter_read() - reads one channel  FIXME - todo, extend to 32 bits in software  works the same for both cards (vti & STG2)*/static long vti_counter_read(int axis){    unsigned int status;    unsigned int count;    Longword EncData;    static long int lastCount;//    static unsigned short lastdac;        if ((axis > MAX_CHANS) || (axis < 0)) {	return 0x80000000;	// Return encoder error value      }    lastCount = enc_counts[axis];    status = encoder->Status;       // latch status from vti board    count = encoder->Counter[axis]; // latch count from vti board        EncData.Long = (long int)enc_counts[axis];    if (status & (1 << axis)) {      if (status & (1 << (axis + 4))) {	EncData.Word[1] += 1;          }      else {	EncData.Word[1] -= 1;          }      }            EncData.Word[0] = count;//    Filter out spurious roll overs / roll unders        if ((EncData.Long - lastCount) > 0x7fff)       EncData.Word[1] -= 1;    else       if ((lastCount - EncData.Long) > 0x7fff)        EncData.Word[1] += 1;    enc_counts[axis] = EncData.Long;	    return EncData.Long;}/*  vti_dac_write() - writes a dac channel*/static int vti_dac_write(int axis, short value){    short junk;    /* write the DAC */    if ((axis > MAX_CHANS) || (axis < 0)) {	return -1;      }    junk = dac->mode;         // Read from mode to trigger update dac immediately    dac->dac[axis] = value;   // Write dac value         return 0;}/* int vti_adc_start(void *arg, unsigned short wAxis){    return 0;			// VTI card has do ADCs} *//* static short vti_adc_read(void *arg, int axis){    return 0;			// VTI card has no ADCs} *//************************************************************************                       BOARD INIT FUNCTIONS                           **                  functions for autodetec, irq init                   *************************************************************************//*static int vti_set_interrupt(short interrupt){    return 0;			// No interrupts necessary for VTI board}*/static int vti_init_card(){    int retval=vti_autodetect();    if (retval == 0) {	encoder = (volatile struct encoder *)	    ioremap(pci_resource_start(dev, 2), sizeof(encoder));	dac =	    (volatile struct dac *) ioremap(pci_resource_start(dev,		4), sizeof(dac));	timer =	    (volatile struct timer *) ioremap(pci_resource_start(dev,		3), sizeof(timer));	ip = (volatile struct ip *) ioremap(pci_resource_start(dev, 5),	    sizeof(ip));    } else {	return (retval);    }    rtapi_print_msg(RTAPI_MSG_INFO, "VTI: Encoders mapped to : %x2\n",	(int) encoder);    rtapi_print_msg(RTAPI_MSG_INFO, "VTI: DACs mapped to : %x2\n",	(int) dac);    rtapi_print_msg(RTAPI_MSG_INFO, "VTI: Timers mapped to : %x2\n",	(int) timer);    rtapi_print_msg(RTAPI_MSG_INFO, "VTI: Industry pack mapped to : %x2\n",	(int) ip);    encoder->Status = 0;    encoder->Reset = 0;    // all ok    return 0;}/* scans possible addresses for vti cards */static int vti_autodetect(){    dev = pci_find_device(VENDOR, DEVICE, dev);    if (dev) {	rtapi_print_msg(RTAPI_MSG_INFO,	    "VTI: Card detected in slot: %2x\n", PCI_SLOT(dev->devfn));	return (0);    } else {	rtapi_print_msg(RTAPI_MSG_INFO, "VTI: Exiting with auto detect failed\n");	return (-ENODEV);    }}/************************************************************************                   LOCAL FUNCTION DEFINITIONS                         **     these are functions used for exporting various HAL pins/prams    *************************************************************************/static int export_counter(int num, vti_struct * addr){    int retval, msg;    char buf[HAL_NAME_LEN + 2];    /* 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);    /* export pin for counts captured by update() */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.%d.counts", num);    retval = hal_pin_s32_new(buf, HAL_WR, &addr->count[num], comp_id);    if (retval != 0) {	return retval;    }    /* export pin for scaled position captured by update() */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.%d.position", num);    retval = hal_pin_float_new(buf, HAL_WR, &addr->pos[num], comp_id);    if (retval != 0) {	return retval;    }    /* export parameter for scaling */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.%d.position-scale", num);    retval = hal_param_float_new(buf, HAL_WR, &addr->pos_scale[num], comp_id);    if (retval != 0) {	return retval;    }    /* restore saved message level */    rtapi_set_msg_level(msg);    return 0;}static int export_dac(int num, vti_struct * addr){    int retval, msg;    char buf[HAL_NAME_LEN + 2];    /* 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);    /* export pin for voltage received by the board() */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.%d.dac-value", num);    retval = hal_pin_float_new(buf, HAL_RD, &addr->dac_value[num], comp_id);    if (retval != 0) {	return retval;    }    /* export parameter for offset */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.%d.dac-offset", num);    retval =	hal_param_float_new(buf, HAL_WR, &addr->dac_offset[num], comp_id);    if (retval != 0) {	return retval;    }    /* export parameter for gain */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.%d.dac-gain", num);    retval = hal_param_float_new(buf, HAL_WR, &addr->dac_gain[num], comp_id);    if (retval != 0) {	return retval;    }    /* restore saved message level */    rtapi_set_msg_level(msg);    return 0;}/* static int export_adc(int num, vti_struct * addr){    return 0;  // No ADCs to export} */static int export_dio_pins(int io_points){    int i, msg, retval=0;    /* 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 */    if (io_points == 0) return 0;    msg = rtapi_get_msg_level();    rtapi_set_msg_level(RTAPI_MSG_WARN);    for (i = 0; i < io_points; i++) {	/*          point, direction, driver */	retval |= export_pin(i, vti_driver->dir_bits[i / 4], vti_driver);    }    /* restore saved message level */ rtapi_set_msg_level(msg);    return retval;}static int export_pin(int num, int dir, vti_struct * addr){    int retval;    if (dir != 0)	retval =	    export_output_pin(outpinnum++, &(addr->port[num / 8][num % 8]));    else	retval =	    export_input_pin(inputpinnum++, &(addr->port[num / 8][num % 8]));    if (retval != 0)	return retval;    return 0;}static int export_input_pin(int pinnum, io_pin * pin){    char buf[HAL_NAME_LEN + 2];    int retval;    /* export read only HAL pin for input data */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.in-%02d", pinnum);    retval = hal_pin_bit_new(buf, HAL_WR, &(pin->data), comp_id);    if (retval != 0)	return retval;    /* export additional pin for inverted input data */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.in-%02d-not", pinnum);    retval = hal_pin_bit_new(buf, HAL_WR, &(pin->io.not), comp_id);    /* initialize HAL pins */    *(pin->data) = 0;    *(pin->io.not) = 1;    return retval;}static int export_output_pin(int pinnum, io_pin * pin){    char buf[HAL_NAME_LEN + 2];    int retval;    /* export read only HAL pin for output data */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.out-%02d", pinnum);    retval = hal_pin_bit_new(buf, HAL_RD, &(pin->data), comp_id);    if (retval != 0)	return retval;    /* export parameter for polarity */    rtapi_snprintf(buf, HAL_NAME_LEN, "vti.out-%02d-invert", pinnum);    retval = hal_param_bit_new(buf, HAL_WR, &(pin->io.invert), comp_id);    /* initialize HAL pin and param */    *(pin->data) = 0;    pin->io.invert = 0;    return retval;}

⌨️ 快捷键说明

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