📄 hal_ppmc.c
字号:
rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.dout.%02d.out", bus->busnum, bus->last_digout); retval = hal_pin_bit_new(buf, HAL_RD, &(slot->digout[n].data), comp_id); if (retval != 0) { return retval; } /* export parameter for inversion */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.dout.%02d.invert", bus->busnum, bus->last_digout); retval = hal_param_bit_new(buf, HAL_WR, &(slot->digout[n].invert), comp_id); if (retval != 0) { return retval; } slot->digout[n].invert = 0; /* increment number to prepare for next output */ bus->last_digout++; } add_wr_funct(write_digouts, slot, UxC_DOUTA, UxC_DOUTA); return 0;}static int export_USC_stepgen(slot_data_t *slot, bus_data_t *bus){ int retval, n; char buf[HAL_NAME_LEN + 2]; stepgen_t *sg; rtapi_print_msg(RTAPI_MSG_INFO, "PPMC: exporting step generators\n"); /* do hardware init */ /* allocate shared memory for the digital output data */ slot->stepgen = hal_malloc(sizeof(stepgens_t)); if (slot->stepgen == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PPMC: ERROR: hal_malloc() failed\n"); return -1; } /* export params that apply to all four stepgens */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.stepgen.%02d-%02d.setup-time", bus->busnum, bus->last_stepgen, bus->last_stepgen+3); retval = hal_param_u8_new(buf, HAL_WR, &(slot->stepgen->setup_time), comp_id); if (retval != 0) { return retval; } /* 10uS default setup time */ slot->stepgen->setup_time = 100; rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.stepgen.%02d-%02d.pulse-width", bus->busnum, bus->last_stepgen, bus->last_stepgen+3); retval = hal_param_u8_new(buf, HAL_WR, &(slot->stepgen->pulse_width), comp_id); if (retval != 0) { return retval; } /* 4uS default pulse width */ slot->stepgen->pulse_width = 40; rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.stepgen.%02d-%02d.pulse-space-min", bus->busnum, bus->last_stepgen, bus->last_stepgen+3); retval = hal_param_u8_new(buf, HAL_WR, &(slot->stepgen->pulse_space), comp_id); if (retval != 0) { return retval; } /* 4uS default pulse spacing */ slot->stepgen->pulse_space = 40; /* export per-stepgen pins and params */ for ( n = 0 ; n < 4 ; n++ ) { /* pointer to the stepgen struct */ sg = &(slot->stepgen->sg[n]); /* enable pin */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.stepgen.%02d.enable", bus->busnum, bus->last_stepgen); retval = hal_pin_bit_new(buf, HAL_RD, &(sg->enable), comp_id); if (retval != 0) { return retval; } /* velocity command pin */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.stepgen.%02d.velocity", bus->busnum, bus->last_stepgen); retval = hal_pin_float_new(buf, HAL_RD, &(sg->vel), comp_id); if (retval != 0) { return retval; } /* velocity scaling parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.stepgen.%02d.scale", bus->busnum, bus->last_stepgen); retval = hal_param_float_new(buf, HAL_WR, &(sg->scale), comp_id); if (retval != 0) { return retval; } sg->scale = 1.0; /* maximum velocity parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.stepgen.%02d.max-vel", bus->busnum, bus->last_stepgen); retval = hal_param_float_new(buf, HAL_WR, &(sg->max_vel), comp_id); if (retval != 0) { return retval; } sg->max_vel = 0.0; /* actual frequency parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.stepgen.%02d.freq", bus->busnum, bus->last_stepgen); retval = hal_param_float_new(buf, HAL_RD, &(sg->freq), comp_id); if (retval != 0) { return retval; } /* increment number to prepare for next output */ bus->last_stepgen++; } add_wr_funct(write_stepgens, slot, RATE_GEN_0, RATE_WIDTH_0); return 0;}static int export_UPC_pwmgen(slot_data_t *slot, bus_data_t *bus){ int retval, n; char buf[HAL_NAME_LEN + 2]; pwmgen_t *pg; rtapi_print_msg(RTAPI_MSG_INFO, "PPMC: exporting PWM generators\n"); /* do hardware init */ /* allocate shared memory for the PWM generators */ slot->pwmgen = hal_malloc(sizeof(pwmgens_t)); if (slot->pwmgen == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PPMC: ERROR: hal_malloc() failed\n"); return -1; } /* export params that apply to all four pwmgens */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.pwm.%02d-%02d.freq", bus->busnum, bus->last_pwmgen, bus->last_pwmgen+3); retval = hal_param_float_new(buf, HAL_WR, &(slot->pwmgen->freq), comp_id); if (retval != 0) { return retval; } /* set initial value for param */ slot->pwmgen->freq = 0.0; /* export per-pwmgen pins and params, and set initial values */ for ( n = 0 ; n < 4 ; n++ ) { /* pointer to the pwmgen struct */ pg = &(slot->pwmgen->pg[n]); /* enable pin */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.pwm.%02d.enable", bus->busnum, bus->last_pwmgen); retval = hal_pin_bit_new(buf, HAL_RD, &(pg->enable), comp_id); if (retval != 0) { return retval; } /* value command pin */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.pwm.%02d.value", bus->busnum, bus->last_pwmgen); retval = hal_pin_float_new(buf, HAL_RD, &(pg->value), comp_id); if (retval != 0) { return retval; } /* output scaling parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.pwm.%02d.scale", bus->busnum, bus->last_pwmgen); retval = hal_param_float_new(buf, HAL_WR, &(pg->scale), comp_id); if (retval != 0) { return retval; } pg->scale = 1.0; /* maximum duty cycle parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.pwm.%02d.max-dc", bus->busnum, bus->last_pwmgen); retval = hal_param_float_new(buf, HAL_WR, &(pg->max_dc), comp_id); if (retval != 0) { return retval; } pg->max_dc = 1.0; /* minimum duty cycle parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.pwm.%02d.min-dc", bus->busnum, bus->last_pwmgen); retval = hal_param_float_new(buf, HAL_WR, &(pg->min_dc), comp_id); if (retval != 0) { return retval; } pg->min_dc = 0.0; /* actual duty cycle parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.pwm.%02d.duty-cycle", bus->busnum, bus->last_pwmgen); retval = hal_param_float_new(buf, HAL_RD, &(pg->duty_cycle), comp_id); if (retval != 0) { return retval; } /* bootstrap mode parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.pwm.%02d.bootstrap", bus->busnum, bus->last_pwmgen); retval = hal_param_bit_new(buf, HAL_WR, &(pg->bootstrap), comp_id); if (retval != 0) { return retval; } pg->bootstrap = 0; pg->boot_state = 0; pg->old_enable = 0; /* increment number to prepare for next output */ bus->last_pwmgen++; } add_wr_funct(write_pwmgens, slot, PWM_GEN_0, PWM_GEN_3+1); return 0;}/* Each of the encoders has the following: params: ppmc.n.encoder.m.scale float pins: ppmc.n.encoder.m.position float ppmc.n.encoder.m.counts s32 ppmc.n.encoder.m.index bit the output value is position=counts * scale Additionally, the encoder registers are zeroed, and the mode is set to latch */static int export_encoders(slot_data_t *slot, bus_data_t *bus){ int retval, n; char buf[HAL_NAME_LEN+2]; rtapi_print_msg(RTAPI_MSG_INFO, "PPMC: exporting encoder pins / params\n"); /* do hardware init */ /* clear encoder control register */ SelWrt(0x00, slot->slot_base+ENCCTRL, slot->port_addr); /* is there already another board generating a latch strobe? */ if ( bus->have_master == 0 ) { /* no, flag this slot to generate the strobe */ slot->strobe = 1; /* make this a master board */ SelWrt(0x10, slot->slot_base+ENCRATE, slot->port_addr); /* don't need any more masters */ bus->have_master = 1; } else { /* already have a master, don't need a strobe */ slot->strobe = 0; /* make this a slave board */ SelWrt(0x00, slot->slot_base+ENCRATE, slot->port_addr); } /* we'll reset all counters to 0 */ SelWrt(0xF0, slot->slot_base+ENCCTRL, slot->port_addr); /* clear encoder count load register */ SelWrt(0x00, slot->slot_base+ENCLOAD, slot->port_addr); WrtMore(0x00, slot->port_addr); WrtMore(0x00, slot->port_addr); /* extra delay, just to be sure */ ClrTimeout(slot->port_addr); ClrTimeout(slot->port_addr); ClrTimeout(slot->port_addr); /* clear encoder control register */ SelWrt(0x00, slot->slot_base+ENCCTRL, slot->port_addr); /* allocate shared memory for the encoder data */ slot->encoder = hal_malloc(4 * sizeof(encoder_t)); if (slot->encoder == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "PPMC: ERROR: hal_malloc() failed\n"); return -1; } /* export per-encoder pins and params */ for ( n = 0 ; n < 4 ; n++ ) { /* scale input parameter */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.encoder.%02d.scale", bus->busnum, bus->last_encoder); retval = hal_param_float_new(buf, HAL_WR, &(slot->encoder[n].scale), comp_id); if (retval != 0) { return retval; } /* scaled encoder position */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.encoder.%02d.position", bus->busnum, bus->last_encoder); retval = hal_pin_float_new(buf, HAL_WR, &(slot->encoder[n].position), comp_id); if (retval != 0) { return retval; } /* raw encoder position */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.encoder.%02d.count", bus->busnum, bus->last_encoder); retval = hal_pin_s32_new(buf, HAL_WR, &(slot->encoder[n].count), comp_id); if (retval != 0) { return retval; } /* raw encoder delta */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.encoder.%02d.delta", bus->busnum, bus->last_encoder); retval = hal_pin_s32_new(buf, HAL_WR, &(slot->encoder[n].delta), comp_id); if (retval != 0) { return retval; } /* encoder index bit */ rtapi_snprintf(buf, HAL_NAME_LEN, "ppmc.%d.encoder.%02d.index", bus->busnum, bus->last_encoder); retval = hal_pin_bit_new(buf, HAL_WR, &(slot->encoder[n].index), comp_id); if (retval != 0) { return retval; } /* increment number to prepare for next output */ bus->last_encoder++; } add_rd_funct(read_encoders, slot, ENCCNT0, ENCISR); return 0;}/* utility functions for EPP bus *//* reset all boards attached to the EPP bus */static void BusReset(unsigned int port_addr){ rtapi_outb(0,CONTROLPORT(port_addr)); rtapi_outb(4,CONTROLPORT(port_addr)); return;}/* tests for an EPP bus timeout, and clears it if so */static int ClrTimeout(unsigned int port_addr){ unsigned char r; r = rtapi_inb(STATUSPORT(port_addr)); if (!(r & 0x01)) { return 0; }/* remove after testing */rtapi_print("EPP Bus Timeout!\n" ); /* To clear timeout some chips require double read */ BusReset(port_addr); r = rtapi_inb(STATUSPORT(port_addr)); rtapi_outb(r | 0x01, STATUSPORT(port_addr)); /* Some reset by writing 1 */ r = rtapi_inb(STATUSPORT(port_addr)); return !(r & 0x01);}/* sets the EPP address and then reads one byte from that address */static unsigned short SelRead(unsigned char epp_addr, unsigned int port_addr){ unsigned char b; ClrTimeout(port_addr); /* set port direction to output */ rtapi_outb(0x04,CONTROLPORT(port_addr)); /* write epp address to port */ rtapi_outb(epp_addr,ADDRPORT(port_addr)); /* set port direction to input */ rtapi_outb(0x24,CONTROLPORT(port_addr)); /* read data value */ b = rtapi_inb(DATAPORT(port_addr)); return b;}/* reads one byte from EPP, use only after SelRead, and only when hardware has auto-increment address cntr */static unsigned short ReadMore(unsigned int port_addr){ unsigned char b; b = rtapi_inb(DATAPORT(port_addr)); return b;}/* sets the EPP address and then writes one byte to that address */static void SelWrt(unsigned char byte, unsigned char epp_addr, unsigned int port_addr){ ClrTimeout(port_addr); /* set port direction to output */ rtapi_outb(0x04,CONTROLPORT(port_addr)); /* write epp address to port */ rtapi_outb(epp_addr,ADDRPORT(port_addr)); /* write data to port */ rtapi_outb(byte,DATAPORT(port_addr)); return;}/* writes one byte to EPP, use only after SelWrt, and only when hardware has auto-increment address cntr */static void WrtMore(unsigned char byte, unsigned int port_addr){ rtapi_outb(byte,DATAPORT(port_addr)); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -