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