stepgen.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 712 行 · 第 1/2 页
C
712 行
}static void hm2_stepgen_force_write_master_dds(hostmot2_t *hm2) { u32 val = 0xffffffff; hm2->llio->write( hm2->llio, hm2->stepgen.master_dds_addr, &val, sizeof(u32) );}void hm2_stepgen_force_write(hostmot2_t *hm2) { if (hm2->stepgen.num_instances == 0) return; hm2_stepgen_force_write_mode(hm2); hm2_stepgen_force_write_dir_setup_time(hm2); hm2_stepgen_force_write_dir_hold_time(hm2); hm2_stepgen_force_write_pulse_width_time(hm2); hm2_stepgen_force_write_pulse_idle_width(hm2); hm2_stepgen_force_write_master_dds(hm2);}void hm2_stepgen_tram_init(hostmot2_t *hm2) { int i; for (i = 0; i < hm2->stepgen.num_instances; i ++) { hm2->stepgen.instance[i].prev_accumulator = hm2->stepgen.accumulator_reg[i]; }}int hm2_stepgen_parse_md(hostmot2_t *hm2, int md_index) { hm2_module_descriptor_t *md = &hm2->md[md_index]; int r; // // some standard sanity checks // if (!hm2_md_is_consistent(hm2, md_index, 0, 10, 4, 0x01FF)) { ERR("inconsistent Module Descriptor!\n"); return -EINVAL; } if (hm2->stepgen.num_instances != 0) { ERR( "found duplicate Module Descriptor for %s (inconsistent firmware), not loading driver\n", hm2_get_general_function_name(md->gtag) ); return -EINVAL; } if (hm2->config.num_stepgens > md->instances) { ERR( "config.num_stepgens=%d, but only %d are available, not loading driver\n", hm2->config.num_stepgens, md->instances ); return -EINVAL; } if (hm2->config.num_stepgens == 0) { return 0; } // // looks good, start initializing // if (hm2->config.num_stepgens == -1) { hm2->stepgen.num_instances = md->instances; } else { hm2->stepgen.num_instances = hm2->config.num_stepgens; } hm2->stepgen.instance = (hm2_stepgen_instance_t *)hal_malloc(hm2->stepgen.num_instances * sizeof(hm2_stepgen_instance_t)); if (hm2->stepgen.instance == NULL) { ERR("out of memory!\n"); r = -ENOMEM; goto fail0; } hm2->stepgen.clock_frequency = md->clock_freq; hm2->stepgen.version = md->version; hm2->stepgen.step_rate_addr = md->base_address + (0 * md->register_stride); hm2->stepgen.accumulator_addr = md->base_address + (1 * md->register_stride); hm2->stepgen.mode_addr = md->base_address + (2 * md->register_stride); hm2->stepgen.dir_setup_time_addr = md->base_address + (3 * md->register_stride); hm2->stepgen.dir_hold_time_addr = md->base_address + (4 * md->register_stride); hm2->stepgen.pulse_width_addr = md->base_address + (5 * md->register_stride); hm2->stepgen.pulse_idle_width_addr = md->base_address + (6 * md->register_stride); hm2->stepgen.table_sequence_data_setup_addr = md->base_address + (7 * md->register_stride); hm2->stepgen.table_sequence_length_addr = md->base_address + (8 * md->register_stride); hm2->stepgen.master_dds_addr = md->base_address + (9 * md->register_stride); r = hm2_register_tram_write_region(hm2, hm2->stepgen.step_rate_addr, (hm2->stepgen.num_instances * sizeof(u32)), &hm2->stepgen.step_rate_reg); if (r < 0) { ERR("error registering tram write region for StepGen Step Rate register (%d)\n", r); goto fail0; } r = hm2_register_tram_read_region(hm2, hm2->stepgen.accumulator_addr, (hm2->stepgen.num_instances * sizeof(u32)), &hm2->stepgen.accumulator_reg); if (r < 0) { ERR("error registering tram read region for StepGen Accumulator register (%d)\n", r); goto fail0; } hm2->stepgen.mode_reg = (u32 *)kmalloc(hm2->stepgen.num_instances * sizeof(u32), GFP_KERNEL); if (hm2->stepgen.mode_reg == NULL) { ERR("out of memory!\n"); r = -ENOMEM; goto fail0; } hm2->stepgen.dir_setup_time_reg = (u32 *)kmalloc(hm2->stepgen.num_instances * sizeof(u32), GFP_KERNEL); if (hm2->stepgen.dir_setup_time_reg == NULL) { ERR("out of memory!\n"); r = -ENOMEM; goto fail1; } hm2->stepgen.dir_hold_time_reg = (u32 *)kmalloc(hm2->stepgen.num_instances * sizeof(u32), GFP_KERNEL); if (hm2->stepgen.dir_hold_time_reg == NULL) { ERR("out of memory!\n"); r = -ENOMEM; goto fail2; } hm2->stepgen.pulse_width_reg = (u32 *)kmalloc(hm2->stepgen.num_instances * sizeof(u32), GFP_KERNEL); if (hm2->stepgen.pulse_width_reg == NULL) { ERR("out of memory!\n"); r = -ENOMEM; goto fail3; } hm2->stepgen.pulse_idle_width_reg = (u32 *)kmalloc(hm2->stepgen.num_instances * sizeof(u32), GFP_KERNEL); if (hm2->stepgen.pulse_idle_width_reg == NULL) { ERR("out of memory!\n"); r = -ENOMEM; goto fail4; } // export to HAL { int i; char name[HAL_NAME_LEN + 2]; for (i = 0; i < hm2->stepgen.num_instances; i ++) { // pins rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.position-cmd", hm2->llio->name, i); r = hal_pin_float_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.position_cmd), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding pin '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.velocity-fb", hm2->llio->name, i); r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.velocity_fb), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding pin '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.position-fb", hm2->llio->name, i); r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.position_fb), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding pin '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.counts", hm2->llio->name, i); r = hal_pin_s32_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.counts), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding pin '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.enable", hm2->llio->name, i); r = hal_pin_bit_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.enable), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding pin '%s', aborting\n", name); r = -ENOMEM; goto fail5; } // parameters rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.position-scale", hm2->llio->name, i); r = hal_param_float_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.position_scale), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding param '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.maxvel", hm2->llio->name, i); r = hal_param_float_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.maxvel), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding param '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.maxaccel", hm2->llio->name, i); r = hal_param_float_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.maxaccel), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding param '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.steplen", hm2->llio->name, i); r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.steplen), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding param '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.stepspace", hm2->llio->name, i); r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.stepspace), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding param '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.dirsetup", hm2->llio->name, i); r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.dirsetup), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding param '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.dirhold", hm2->llio->name, i); r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.dirhold), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding param '%s', aborting\n", name); r = -ENOMEM; goto fail5; } rtapi_snprintf(name, HAL_NAME_LEN, "%s.stepgen.%02d.step_type", hm2->llio->name, i); r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.step_type), hm2->llio->comp_id); if (r != HAL_SUCCESS) { ERR("error adding param '%s', aborting\n", name); r = -ENOMEM; goto fail5; } // init *(hm2->stepgen.instance[i].hal.pin.position_cmd) = 0.0; *(hm2->stepgen.instance[i].hal.pin.counts) = 0; *(hm2->stepgen.instance[i].hal.pin.position_fb) = 0.0; *(hm2->stepgen.instance[i].hal.pin.velocity_fb) = 0.0; *(hm2->stepgen.instance[i].hal.pin.enable) = 0; hm2->stepgen.instance[i].hal.param.position_scale = 1.0; hm2->stepgen.instance[i].hal.param.maxvel = 1.0; hm2->stepgen.instance[i].hal.param.maxaccel = 1.0; // start out the slowest possible, let the user speed up if they want hm2->stepgen.instance[i].hal.param.steplen = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); hm2->stepgen.instance[i].hal.param.stepspace = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); hm2->stepgen.instance[i].hal.param.dirsetup = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); hm2->stepgen.instance[i].hal.param.dirhold = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); hm2->stepgen.instance[i].hal.param.step_type = 0; // step & dir hm2->stepgen.instance[i].written_steplen = 0; hm2->stepgen.instance[i].written_stepspace = 0; hm2->stepgen.instance[i].written_dirsetup = 0; hm2->stepgen.instance[i].written_dirhold = 0; hm2->stepgen.instance[i].written_step_type = 0xffffffff; hm2->stepgen.instance[i].prev_accumulator = 0; } } return hm2->stepgen.num_instances;fail5: kfree(hm2->stepgen.pulse_idle_width_reg);fail4: kfree(hm2->stepgen.pulse_width_reg);fail3: kfree(hm2->stepgen.dir_hold_time_reg);fail2: kfree(hm2->stepgen.dir_setup_time_reg);fail1: kfree(hm2->stepgen.mode_reg);fail0: hm2->stepgen.num_instances = 0; return r;}void hm2_stepgen_print_module(hostmot2_t *hm2) { int i; PRINT("StepGen: %d\n", hm2->stepgen.num_instances); if (hm2->stepgen.num_instances <= 0) return; PRINT(" clock_frequency: %d Hz (%s MHz)\n", hm2->stepgen.clock_frequency, hm2_hz_to_mhz(hm2->stepgen.clock_frequency)); PRINT(" version: %d\n", hm2->stepgen.version); PRINT(" step_rate_addr: 0x%04X\n", hm2->stepgen.step_rate_addr); PRINT(" accumulator_addr: 0x%04X\n", hm2->stepgen.accumulator_addr); PRINT(" mode_addr: 0x%04X\n", hm2->stepgen.mode_addr); PRINT(" dir_setup_time_addr: 0x%04X\n", hm2->stepgen.dir_setup_time_addr); PRINT(" dir_hold_time_addr: 0x%04X\n", hm2->stepgen.dir_hold_time_addr); PRINT(" pulse_width_addr: 0x%04X\n", hm2->stepgen.pulse_width_addr); PRINT(" pulse_idle_width_addr: 0x%04X\n", hm2->stepgen.pulse_idle_width_addr); PRINT(" table_sequence_data_setup_addr: 0x%04X\n", hm2->stepgen.table_sequence_data_setup_addr); PRINT(" table_sequence_length_addr: 0x%04X\n", hm2->stepgen.table_sequence_length_addr); PRINT(" master_dds_addr: 0x%04X\n", hm2->stepgen.master_dds_addr); for (i = 0; i < hm2->stepgen.num_instances; i ++) { PRINT(" instance %d:\n", i); PRINT(" enable = %d\n", *hm2->stepgen.instance[i].hal.pin.enable); PRINT(" hw:\n"); PRINT(" step_rate = 0x%08X\n", hm2->stepgen.step_rate_reg[i]); PRINT(" accumulator = 0x%08X\n", hm2->stepgen.accumulator_reg[i]); PRINT(" mode = 0x%08X\n", hm2->stepgen.mode_reg[i]); PRINT(" dir_setup_time = 0x%08X (%u ns)\n", hm2->stepgen.dir_setup_time_reg[i], hm2->stepgen.instance[i].hal.param.dirsetup); PRINT(" dir_hold_time = 0x%08X (%u ns)\n", hm2->stepgen.dir_hold_time_reg[i], hm2->stepgen.instance[i].hal.param.dirhold); PRINT(" pulse_width = 0x%08X (%u ns)\n", hm2->stepgen.pulse_width_reg[i], hm2->stepgen.instance[i].hal.param.steplen); PRINT(" pulse_idle_width = 0x%08X (%u ns)\n", hm2->stepgen.pulse_idle_width_reg[i], hm2->stepgen.instance[i].hal.param.stepspace); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?