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 + -
显示快捷键?