hal_ppmc.c

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

C
1,961
字号
int rtapi_app_main(void){    int msg, rv, rv1, busnum, slotnum, n, boards;    int bus_slot_code, need_extra_dac, need_extra_dout;    int idcode, id, ver;    bus_data_t *bus;    slot_data_t *slot;    char buf[HAL_NAME_LEN + 2];    rtapi_print_msg(RTAPI_MSG_INFO, "PPMC: installing driver\n");    /* 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);    /* validate port addresses */    n = 0;    /* if an error occurs, bailing out in the middle of init can leave       a mess of partially allocated stuff.  So we don't normally bail       out, instead we set rv non-zero to indicate failure, and carry       on.  Later, we see that rv is set, and clean up anything that       might have been allocated before we return. */    rv = 0;    for ( busnum = 0 ; busnum < MAX_BUS ; busnum++ ) {	/* init pointer to bus data */	bus_array[busnum] = NULL;	/* check to see if a port address was specified */	if ( port_addr[busnum] == 0 ) {	    /* nope, skip it */	    continue;	}	/* is it legal? */	if ( port_addr[busnum] > 65535 ) {	    /* nope, complain and skip it */            rtapi_print_msg(RTAPI_MSG_ERR,                 "PARPORT: ERROR: request_region(%x) failed\n"                 , port_addr[busnum]);            rtapi_print_msg(RTAPI_MSG_ERR,                 "(make sure the kernel module 'parport' is unloaded)\n");	    rv = -1;	    continue;	}        port_registration[busnum] =            rtapi_request_region(port_addr[busnum], 8, "hal_ppmc");        if(port_registration[busnum] == 0) {	    rtapi_print_msg(RTAPI_MSG_ERR, 		"PPMC: ERROR: invalid port_addr: %0X\n", port_addr[busnum]);            rv = -1;            continue;        }	/* got a good one */	n++;    }    if ( rv != 0 ) {        for(busnum = 0; busnum < MAX_BUS; busnum++) {            if(port_registration[busnum])                rtapi_release_region(port_addr[busnum], 8);            port_registration[busnum] = 0;        }	/* one or more invalid addresses, already printed msg */	return -1;    }    if ( n == 0 ) {	rtapi_print_msg(RTAPI_MSG_ERR, 	    "PPMC: ERROR: no ports specified\n");	return -1;    }    /* have valid config info, connect to the HAL */    comp_id = hal_init("hal_ppmc");    if (comp_id < 0) {	rtapi_print_msg(RTAPI_MSG_ERR, "PPMC: ERROR: hal_init() failed\n");	return -1;    }    /* begin init - loop thru all busses */    for ( busnum = 0 ; busnum < MAX_BUS ; busnum++ ) {	/* 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_DAC = 0;	bus->last_encoder = 0;	bus->last_extraDAC = 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->read_bitmap = 0;	    slot->write_bitmap = 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->DAC = NULL;            slot->encoder = NULL;	    slot->extra_mode = EXTRA_UNUSED;	    slot->extra = 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");		rv1 += export_PPMC_DAC(slot, bus);		break;	    case 0x30:		boards++;		rtapi_print_msg(RTAPI_MSG_INFO, "PPMC Digital I/O card\n");		rv1 += export_PPMC_digin(slot, bus);		rv1 += export_PPMC_digout(slot, bus);		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);		bus_slot_code = (busnum << 4) | slotnum;		need_extra_dac = 0;		need_extra_dout = 0;		for ( n = 0; n < MAX_BUS*8 ; n++ ) {		    if ( extradac[n] == bus_slot_code ) {			need_extra_dac = 1;			extradac[n] = -1;		    }		    if ( extradout[n] == bus_slot_code ) {			need_extra_dout = 1;			extradout[n] = -1;		    }		}		if ( need_extra_dac && need_extra_dout ) {		    rtapi_print_msg(RTAPI_MSG_ERR,			"PPMC: ERROR: Can't have extra DAC and DOUT on same slot\n");		} else if ( need_extra_dac ) {		    rv1 += export_extra_dac(slot, bus);		} else if ( need_extra_dout ) {		    rv1 += export_extra_dout(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);		bus_slot_code = (busnum << 4) | slotnum;		need_extra_dac = 0;		need_extra_dout = 0;		for ( n = 0; n < MAX_BUS*8 ; n++ ) {		    if ( extradac[n] == bus_slot_code ) {			need_extra_dac = 1;			extradac[n] = -1;		    }		    if ( extradout[n] == bus_slot_code ) {			need_extra_dout = 1;			extradout[n] = -1;		    }		}		if ( need_extra_dac && need_extra_dout ) {		    rtapi_print_msg(RTAPI_MSG_ERR,			"PPMC: ERROR: Can't have extra DAC and DOUT on same slot\n");		} else if ( need_extra_dac ) {		    rv1 += export_extra_dac(slot, bus);		} else if ( need_extra_dout ) {		    rv1 += export_extra_dout(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;            }	    rtapi_print_msg(RTAPI_MSG_INFO,"read cache bitmap: %08x\n", slot->read_bitmap );	    rtapi_print_msg(RTAPI_MSG_INFO,"write cache bitmap: %08x\n", slot->write_bitmap );	} /* 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);    }    for ( n = 0 ; n < MAX_BUS*8 ; n++ ) {	if ( extradac[n] != -1 ) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"PPMC: ERROR: no USC/UPC for extra dac at bus %d, slot %d\n",		extradac[n]>>4, extradac[n] & 0x0F );	    rv = -1;	}	if ( extradout[n] != -1 ) {	    rtapi_print_msg(RTAPI_MSG_ERR,		"PPMC: ERROR: no USC/UPC for extra douts at bus %d, slot %d\n",		extradout[n]>>4, extradout[n] & 0x0F );	    rv = -1;	}    }    /* 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);	    }            /* if ioports were requested, release them */	    if(port_registration[busnum])                rtapi_release_region(port_addr[busnum], 8);            port_registration[busnum] = 0;	}	/* disconnect from HAL */	hal_exit(comp_id);	return -1;    }        rtapi_print_msg(RTAPI_MSG_INFO, "PPMC: driver installed\n");    hal_ready(comp_id);    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);	}    }    for(busnum = 0; busnum < MAX_BUS; busnum++) {        if(port_registration[busnum])            rtapi_release_region(port_addr[busnum], 8);        port_registration[busnum] = 0;    }    /* 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, addr_ok;    unsigned char n, eppaddr;    __u32 bitmap;    /* get pointer to bus data structure */    bus = *(bus_data_t **)(arg);    /* test to make sure it hasn't been freed */    if ( bus == NULL ) {	return;    }

⌨️ 快捷键说明

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