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

📄 hal_ppmc.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* check to see if a port address was specified */	if ( port_addr[busnum] == 0 ) {	    /* nope, skip to next bus */	    continue;	}	rtapi_print_msg(RTAPI_MSG_INFO,	    "PPMC: checking EPP bus %d at port %04X\n",	    busnum, port_addr[busnum]);	boards = 0;	/* allocate memory for bus data - this is not shared memory */	bus = kmalloc(sizeof(bus_data_t), GFP_KERNEL);	if (bus == 0) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"PPMC: ERROR: kmalloc() failed\n");	    rv = -1;	    /* skip to next bus */	    continue;	}	/* clear the bus data structure */	bus->busnum = busnum;	bus->have_master = 0;	bus->last_digout = 0;	bus->last_digin = 0;	bus->last_stepgen = 0;	bus->last_pwmgen = 0;	bus->last_encoder = 0;	/* clear the slot data structures (part of the bus struct) */	for ( slotnum = 0 ; slotnum < NUM_SLOTS ; slotnum ++ ) {	    /* clear slot valid flag in bus struct */	    bus->slot_valid[slotnum] = 0;	    /* point to slot struct */	    slot = &(bus->slot_data[slotnum]);	    /* clear stuff */	    slot->id = 0;	    slot->ver = 0;	    slot->strobe = 0;	    slot->slot_base = slotnum * SLOT_SIZE;	    slot->port_addr = port_addr[busnum];	    slot->first_rd = 31;	    slot->last_rd = 0;	    slot->first_wr = 31;	    slot->last_wr = 0;	    /* clear EPP read and write caches */	    for ( n = 0 ; n < 32 ; n++ ) {		slot->rd_buf[n] = 0;		slot->wr_buf[n] = 0;	    }	    /* clear function pointers */	    slot->num_rd_functs = 0;	    slot->num_wr_functs = 0;	    for ( n = 0 ; n < MAX_FUNCT ; n++ ) {		slot->rd_functs[n] = NULL;		slot->wr_functs[n] = NULL;	    }	    slot->digout = NULL;            slot->digin = NULL;            slot->stepgen = NULL;            slot->pwmgen = NULL;            slot->encoder = NULL;	}    	/* scan the bus */	for ( slotnum = 0 ; slotnum < NUM_SLOTS ; slotnum ++ ) {	    /* point to slot struct */	    slot = &(bus->slot_data[slotnum]);	    /* rv1 is used to flag errors that fail one bus */	    rv1 = 0;	    rtapi_print_msg(RTAPI_MSG_INFO, "PPMC: slot %d: ", slotnum);		    /* check slot */	    idcode = SelRead(slot->slot_base+SLOT_ID_OFFSET, slot->port_addr);	    if ( ( idcode == 0 ) || ( idcode == 0xFF ) ) {		slot->id = 0;		slot->ver = 0;		rtapi_print_msg(RTAPI_MSG_INFO, "nothing detected\n");		ClrTimeout(slot->port_addr);		/* skip to next slot */		continue;	    }	    rtapi_print_msg(RTAPI_MSG_INFO, "ID code: %02X ", idcode);	    slot->id = id = idcode & 0xF0;	    slot->ver = ver = idcode & 0x0F;	    /* mark slot as occupied */	    bus->slot_valid[slotnum] = 1;	    	    /* do board specific init and configuration */	    switch ( id ) {	    case 0x10:		boards++;		rtapi_print_msg(RTAPI_MSG_INFO, "PPMC encoder card\n");		rv1 += export_encoders(slot, bus);		break;	    case 0x20:		boards++;		rtapi_print_msg(RTAPI_MSG_INFO, "PPMC DAC card\n");		break;	    case 0x30:		boards++;		rtapi_print_msg(RTAPI_MSG_INFO, "PPMC Digital I/O card\n");		break;	    case 0x40:		boards++;		rtapi_print_msg(RTAPI_MSG_INFO, "Univ. Stepper Controller\n");		rv1 += export_UxC_digin(slot, bus);		rv1 += export_UxC_digout(slot, bus);		rv1 += export_USC_stepgen(slot, bus);		rv1 += export_encoders(slot, bus);		/* the USC occupies two slots, so skip the second one */		slotnum++;		break;	    case 0x50:		boards++;		rtapi_print_msg(RTAPI_MSG_INFO, "Univ. PWM Controller\n");		rv1 += export_UxC_digin(slot, bus);		rv1 += export_UxC_digout(slot, bus);		rv1 += export_UPC_pwmgen(slot, bus);		rv1 += export_encoders(slot, bus);		/* the UPC occupies two slots, so skip the second one */		slotnum++;		break;	    default:		rtapi_print_msg(RTAPI_MSG_ERR, "Unknown! (ERROR)\n");		/* mark slot as empty */		bus->slot_valid[slotnum] = 0;		/* mark bus failed */		rv1 = -1;		break;            }	} /* end of slot loop */	if ( rv1 != 0 ) {	    /* error during slot scan, already printed */	    rv = -1;	    /* skip to next bus */	    continue;	}	if ( boards == 0 ) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"PPMC: ERROR: no boards found on bus %d, port %04X\n",		busnum, port_addr[busnum] );	    rv = -1;	    /* skip to next bus */	    continue;	}	/* export functions */	rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.read", busnum);	rv1 = hal_export_funct(buf, read_all, &(bus_array[busnum]),	    1, 0, comp_id);	if (rv1 != 0) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"PPMC: ERROR: read funct export failed\n");	    rv = -1;	    /* skip to next bus */	    continue;	}	rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.write", busnum);	rv1 = hal_export_funct(buf, write_all, &(bus_array[busnum]),	    1, 0, comp_id);	if (rv1 != 0) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"PPMC: ERROR: write funct export failed\n");	    rv = -1;	    /* skip to next bus */	    continue;	}	/* save pointer to bus data */	bus_array[busnum] = bus;	rtapi_print_msg(RTAPI_MSG_INFO, "PPMC: bus %d complete\n", busnum);    }    /* restore saved message level */    rtapi_set_msg_level(msg);    /* final check for errors */    if ( rv != 0 ) {	/* something went wrong, cleanup and exit */	rtapi_print_msg(RTAPI_MSG_ERR, "PPMC: shutting down\n");	for ( busnum = 0 ; busnum < MAX_BUS ; busnum++ ) {	    /* check to see if memory was allocated for bus */	    if ( bus_array[busnum] != NULL ) {		/* save ptr to memory block */		bus = bus_array[busnum];		/* mark it invalid so RT code won't access */		bus_array[busnum] = NULL;		/* and free the block */		kfree(bus);	    }	}	/* disconnect from HAL */	hal_exit(comp_id);	return -1;    }        rtapi_print_msg(RTAPI_MSG_INFO, "PPMC: driver installed\n");    return 0;}void rtapi_app_exit(void){    int busnum, n, m;    bus_data_t *bus;    rtapi_print_msg(RTAPI_MSG_ERR, "PPMC: shutting down\n");    for ( busnum = 0 ; busnum < MAX_BUS ; busnum++ ) {	/* check to see if memory was allocated for bus */	if ( bus_array[busnum] != NULL ) {	    /* save ptr to memory block */	    bus = bus_array[busnum];	    /* mark it invalid so RT code won't access */	    bus_array[busnum] = NULL;	    /* want to make sure everything is turned off */	    /* write zero to the first byte of each slot */	    for ( n = 0 ; n < 256 ; n += 16 ) {		SelWrt(0, n, bus->slot_data[0].port_addr);		/* and to the remainder of the slot */		for ( m = 1 ; m < 32 ; m++ ) {		    WrtMore(0, bus->slot_data[0].port_addr);		}	    }	    /* and free the memory block */	    kfree(bus);	}    }    /* disconnect from HAL */    hal_exit(comp_id);}/************************************************************************                         REALTIME FUNCTIONS                           *************************************************************************/static void read_all(void *arg, long period){    bus_data_t *bus;    slot_data_t *slot;    int slotnum, functnum;    unsigned char n, eppaddr;    /* get pointer to bus data structure */    bus = *(bus_data_t **)(arg);    /* test to make sure it hasn't been freed */    if ( bus == NULL ) {	return;    }    /* loop thru all slots */    for ( slotnum = 0 ; slotnum < NUM_SLOTS ; slotnum++ ) {	/* check for anthing in slot */	if ( bus->slot_valid[slotnum] ) {	    /* point at slot data */	    slot = &(bus->slot_data[slotnum]);	    /* We should check if this slot needs a latch strobe, but the	       docs aren't clear about master operation without auto-latching.	       So, we always latch the values for all boards, and never use master mode */	    /* the check would be:  if ( slot->strobe == 1 )  */	    /* set the strobe bit, slave mode */	    SelWrt(0x20, slot->slot_base + ENCRATE, slot->port_addr);	    /* repeat to guarantee at least 2uS */	    SelWrt(0x20, slot->slot_base + ENCRATE, slot->port_addr);	    /* end of strobe pulse, stay in slave mode */	    SelWrt(0x00, slot->slot_base + ENCRATE, slot->port_addr);	    /* fetch data from EPP to cache */	    if ( slot->first_rd <= slot->last_rd ) {		/* need to read some data */		n = slot->first_rd;		eppaddr = slot->slot_base + slot->first_rd;		/* read first byte */		slot->rd_buf[n++] = SelRead(eppaddr, slot->port_addr);		/* read the rest */		while ( n <= slot->last_rd ) {		    slot->rd_buf[n++] = ReadMore(slot->port_addr);		}	    }	    /* loop thru all functions associated with slot */	    for ( functnum = 0 ; functnum < slot->num_rd_functs ; functnum++ ) {		/* call function */		(slot->rd_functs[functnum])(slot);	    }	}    }}static void write_all(void *arg, long period){    bus_data_t *bus;    slot_data_t *slot;    int slotnum, functnum;    unsigned char n, eppaddr;    /* get pointer to bus data structure */    bus = *(bus_data_t **)(arg);    /* test to make sure it hasn't been freed */    if ( bus == NULL ) {	return;    }    /* loop thru all slots */    for ( slotnum = 0 ; slotnum < NUM_SLOTS ; slotnum++ ) {	/* check for anthing in slot */	if ( bus->slot_valid[slotnum] ) {	    /* point at slot data */	    slot = &(bus->slot_data[slotnum]);	    /* loop thru all functions associated with slot */	    for ( functnum = 0 ; functnum < slot->num_wr_functs ; functnum++ ) {		/* call function */		(slot->wr_functs[functnum])(slot);	    }	    /* write data from cache to EPP */	    if ( slot->first_wr <= slot->last_wr ) {		/* need to write some data */		n = slot->first_wr;		eppaddr = slot->slot_base + slot->first_wr;		/* write first byte */		SelWrt(slot->wr_buf[n++], eppaddr, slot->port_addr);		/* write the rest */		while ( n <= slot->last_wr ) {		    WrtMore(slot->wr_buf[n++], slot->port_addr);		}	    }	}    }}static void read_digins(slot_data_t *slot){    int b;    unsigned char indata, mask;    /* read the first 8 inputs */    indata = slot->rd_buf[UxC_DINA];    /* split the bits into 16 variables (8 regular, 8 inverted) */    b = 0;    mask = 0x01;    while ( b < 8 ) {	*(slot->digin[b].data) = indata & mask;	*(slot->digin[b].data_not) = !(indata & mask);	mask <<= 1;	b++;    }    /* read the next 8 inputs */    indata = slot->rd_buf[UxC_DINB];    /* and split them too */    mask = 0x01;    while ( b < 16 ) {	*(slot->digin[b].data) = indata & mask;	*(slot->digin[b].data_not) = !(indata & mask);	mask <<= 1;	b++;    }}static void write_digouts(slot_data_t *slot){    int b;    unsigned char outdata, mask;    outdata = 0x00;    mask = 0x01;    /* assemble output byte from 8 source variables */    for (b = 0; b < 8; b++) {	/* get the data, add to output byte */	if ((*(slot->digout[b].data)) && (!slot->digout[b].invert)) {	    outdata |= mask;	}	if ((!*(slot->digout[b].data)) && (slot->digout[b].invert)) {	    outdata |= mask;	}	mask <<= 1;    }    /* write it to the hardware (cache) */    slot->wr_buf[UxC_DOUTA] = outdata;}static void read_encoders(slot_data_t *slot){    int i, byteindex;    hal_u8_t mask = 0x01, indextemp;    union pos_tag {        signed long l;        struct byte_tag {            signed char b0;            signed char b1;            signed char b2;            signed char b3;        } byte;    } pos, oldpos;        indextemp = (hal_u8_t)(slot->rd_buf[ENCISR]);    byteindex = ENCCNT0;        /* first encoder count register */    for (i = 0; i < 4; i++) {        oldpos.l = slot->encoder[i].oldreading;	pos.byte.b0 = (signed char)slot->rd_buf[byteindex++];	pos.byte.b1 = (signed char)slot->rd_buf[byteindex++];	pos.byte.b2 = (signed char)slot->rd_buf[byteindex++];        pos.byte.b3 = oldpos.byte.b3;

⌨️ 快捷键说明

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