#include <rtapi_slab.h>
#include "rtapi.h"
#include "rtapi_string.h"
#include "rtapi_math.h"
#include "hal.h"
#include "hal/drivers/mesa-hostmot2/hostmot2.h"
void hm2_xy2mod_process_tram_read(hostmot2_t *hm2) {
int i;
for (i = 0; i < hm2->xy2mod.num_instances; i ++) {
hm2_xy2mod_instance_t *s = &hm2->xy2mod.instance[i];
rtapi_u32 posx = hm2->xy2mod.posx_reg[i];
rtapi_u32 posy = hm2->xy2mod.posy_reg[i];
rtapi_u32 velx = hm2->xy2mod.velx_reg[i];
rtapi_u32 vely = hm2->xy2mod.vely_reg[i];
rtapi_u32 mode = hm2->xy2mod.mode_reg[i];
if (fabs(*s->hal.pin.posx_scale) < 1e-6) {
if (*s->hal.pin.posx_scale >= 0.0) {
*s->hal.pin.posx_scale = 1.0;
HM2_ERR("xy2mod %d position_scalex is too close to 0, resetting to 1.0\n", i);
} else {
*s->hal.pin.posx_scale = -1.0;
HM2_ERR("xy2mod %d position_scalxe is too close to 0, resetting to -1.0\n", i);
}
}
if (fabs(*s->hal.pin.posy_scale) < 1e-6) {
if (*s->hal.pin.posy_scale >= 0.0) {
*s->hal.pin.posy_scale = 1.0;
HM2_ERR("xy2mod %d position_scaley is too close to 0, resetting to 1.0\n", i);
} else {
*s->hal.pin.posy_scale = -1.0;
HM2_ERR("xy2mod %d position_scaley is too close to 0, resetting to -1.0\n", i);
}
}
*(s->hal.pin.posx_fb) = ((double)(int32_t)(posx) / 65536.0) / *s->hal.pin.posx_scale;
*(s->hal.pin.posy_fb) = ((double)(int32_t)(posy) / 65536.0) / *s->hal.pin.posy_scale;
*(s->hal.pin.velx_fb) = ((double)(int32_t)velx) / (*s->hal.pin.posx_scale * (256*65536.0/(double)hm2->xy2mod.clock_frequency));
*(s->hal.pin.vely_fb) = ((double)(int32_t)vely) / (*s->hal.pin.posy_scale * (256*65536.0/(double)hm2->xy2mod.clock_frequency));
*(s->hal.pin.posx_overflow) = (mode & (1 << 6));
*(s->hal.pin.posy_overflow) = (mode & (1 << 7));
*(s->hal.pin.velx_overflow) = (mode & (1 << 8));
*(s->hal.pin.vely_overflow) = (mode & (1 << 9));
*(s->hal.pin.status) = (mode & (1 << 10));
}
}
static void hm2_xy2mod_instance_write(hostmot2_t *hm2, int i) {
double stepsx_cmd;
double stepsy_cmd;
double steps_per_secx_cmd;
double steps_per_secy_cmd;
double steps_per_sec2x_cmd;
double steps_per_sec2y_cmd;
rtapi_u32 laccx_reg;
rtapi_u32 laccy_reg;
rtapi_u32 lvelx_reg;
rtapi_u32 lvely_reg;
rtapi_u32 lposx_reg;
rtapi_u32 lposy_reg;
rtapi_u32 istride;
hm2_xy2mod_instance_t *s = &hm2->xy2mod.instance[i];
istride = i * sizeof(rtapi_u32);
if (*s->hal.pin.enable != 0) {
stepsx_cmd =( *s->hal.pin.posx_cmd * 65536.0) / *s->hal.pin.posx_scale;
stepsy_cmd =( *s->hal.pin.posy_cmd * 65536.0) / *s->hal.pin.posy_scale;
if (*s->hal.pin.posx_cmd != s->prev_posx_cmd) {
lposx_reg = (uint32_t)(int32_t)(stepsx_cmd);
hm2->xy2mod.posx_reg[i] = lposx_reg;
hm2->llio->write(hm2->llio, hm2->xy2mod.posx_addr + istride, &hm2->xy2mod.posx_reg[i], sizeof(rtapi_u32));
s->prev_posx_cmd = *s->hal.pin.posx_cmd;
}
if (*s->hal.pin.posy_cmd != s->prev_posy_cmd) {
lposy_reg = (uint32_t)(int32_t)(stepsy_cmd);
hm2->xy2mod.posy_reg[i] = lposy_reg;
hm2->llio->write(hm2->llio, hm2->xy2mod.posy_addr + istride, &hm2->xy2mod.posy_reg[i], sizeof(rtapi_u32));
s->prev_posy_cmd = *s->hal.pin.posy_cmd;
}
steps_per_secx_cmd = *s->hal.pin.velx_cmd * *s->hal.pin.posx_scale;
steps_per_secy_cmd = *s->hal.pin.vely_cmd * *s->hal.pin.posy_scale;
if (*s->hal.pin.velx_cmd != s->prev_velx_cmd) {
lvelx_reg = (uint32_t)(int32_t)(steps_per_secx_cmd * (256*65536.0 / (double)hm2->xy2mod.clock_frequency));
hm2->xy2mod.velx_reg[i] = lvelx_reg;
hm2->llio->write(hm2->llio, hm2->xy2mod.velx_addr + istride, &hm2->xy2mod.velx_reg[i], sizeof(rtapi_u32));
s->prev_velx_cmd = *s->hal.pin.velx_cmd;
}
if (*s->hal.pin.vely_cmd != s->prev_vely_cmd) {
lvely_reg = (uint32_t)(int32_t)(steps_per_secy_cmd * (256*65536.0 / (double)hm2->xy2mod.clock_frequency));
hm2->xy2mod.vely_reg[i] = lvely_reg;
hm2->llio->write(hm2->llio, hm2->xy2mod.vely_addr + istride, &hm2->xy2mod.vely_reg[i], sizeof(rtapi_u32));
s->prev_vely_cmd = *s->hal.pin.vely_cmd;
}
steps_per_sec2x_cmd = *s->hal.pin.accx_cmd * *s->hal.pin.posx_scale;
steps_per_sec2y_cmd = *s->hal.pin.accy_cmd * *s->hal.pin.posy_scale;
if (*s->hal.pin.accx_cmd != s->prev_accx_cmd) {
laccx_reg = (uint32_t)(int32_t)(steps_per_sec2x_cmd * (double)(4096.0*4294967296.0) / ((double)(hm2->xy2mod.clock_frequency*(double)hm2->xy2mod.clock_frequency*256)));
hm2->xy2mod.accx_reg[i] = laccx_reg;
hm2->llio->write(hm2->llio, hm2->xy2mod.accx_addr + istride, &hm2->xy2mod.accx_reg[i], sizeof(rtapi_u32));
s->prev_accx_cmd = *s->hal.pin.accx_cmd;
}
if (*s->hal.pin.accy_cmd != s->prev_accy_cmd) {
laccy_reg = (uint32_t)(int32_t)(steps_per_sec2y_cmd * (double)(4096.0*4294967296.0) / ((double)(hm2->xy2mod.clock_frequency*(double)hm2->xy2mod.clock_frequency*256)));
hm2->xy2mod.accy_reg[i] = laccy_reg;
hm2->llio->write(hm2->llio, hm2->xy2mod.accy_addr + istride, &hm2->xy2mod.accy_reg[i], sizeof(rtapi_u32));
s->prev_accy_cmd = *s->hal.pin.accy_cmd;
}
hm2->xy2mod.mode_reg[i] =
*s->hal.pin.controlx0<< 0 |
*s->hal.pin.controlx1<< 1 |
*s->hal.pin.controlx2<< 2 |
*s->hal.pin.controly0<< 3 |
*s->hal.pin.controly1<< 4 |
*s->hal.pin.controly2<< 5;
hm2->llio->write(hm2->llio,hm2->xy2mod.mode_addr + istride, &hm2->xy2mod.mode_reg[i], sizeof(rtapi_u32));
} else {
*s->hal.pin.posx_cmd = 0;
s->prev_posx_cmd = 0;
hm2->xy2mod.posx_reg[i] =0;
hm2->llio->write(hm2->llio, hm2->xy2mod.posx_addr + istride, &hm2->xy2mod.posx_reg[i], sizeof(rtapi_u32));
*s->hal.pin.posy_cmd = 0;
s->prev_posy_cmd = 0;
hm2->xy2mod.posy_reg[i] =0;
hm2->llio->write(hm2->llio, hm2->xy2mod.posy_addr + istride, &hm2->xy2mod.posy_reg[i], sizeof(rtapi_u32));
*s->hal.pin.velx_cmd = 0;
s->prev_velx_cmd = 0;
hm2->xy2mod.velx_reg[i] = 0;
hm2->llio->write(hm2->llio, hm2->xy2mod.velx_addr + istride, &hm2->xy2mod.velx_reg[i], sizeof(rtapi_u32));
*s->hal.pin.vely_cmd = 0;
s->prev_vely_cmd = 0;
hm2->xy2mod.vely_reg[i] = 0;
hm2->llio->write(hm2->llio, hm2->xy2mod.vely_addr + istride, &hm2->xy2mod.vely_reg[i], sizeof(rtapi_u32));
*s->hal.pin.accx_cmd = 0;
s->prev_accx_cmd = 0;
hm2->xy2mod.accx_reg[i] = 0;
hm2->llio->write(hm2->llio, hm2->xy2mod.accx_addr + istride, &hm2->xy2mod.accx_reg[i], sizeof(rtapi_u32));
*s->hal.pin.accy_cmd = 0;
s->prev_accy_cmd = 0;
hm2->xy2mod.accy_reg[i] = 0;
hm2->llio->write(hm2->llio, hm2->xy2mod.accy_addr + istride, &hm2->xy2mod.accy_reg[i], sizeof(rtapi_u32));
*s->hal.pin.controlx0 = 0;
*s->hal.pin.controlx1 = 0;
*s->hal.pin.controlx2 = 0;
*s->hal.pin.controly0 = 0;
*s->hal.pin.controly1 = 0;
*s->hal.pin.controly2 = 0;
hm2->xy2mod.mode_reg[i] = 0x000003C0; hm2->llio->write(hm2->llio, hm2->xy2mod.mode_addr + istride, &hm2->xy2mod.mode_reg[i], sizeof(rtapi_u32));
}
}
static void hm2_xy2mod_set_dpll_timer(hostmot2_t *hm2) {
rtapi_u32 data = 0;
if ((*hm2->xy2mod.hal->pin.dpll_timer_num < -1) || (*hm2->xy2mod.hal->pin.dpll_timer_num > 4)) {
*hm2->xy2mod.hal->pin.dpll_timer_num = 0;
}
if (*hm2->xy2mod.hal->pin.dpll_timer_num > -1) {
data = (*hm2->xy2mod.hal->pin.dpll_timer_num << 12) | (1 << 15);
}
hm2->llio->write(hm2->llio, hm2->xy2mod.dpll_timer_num_addr, &data, sizeof(rtapi_u32));
hm2->xy2mod.written_dpll_timer_num = *hm2->xy2mod.hal->pin.dpll_timer_num;
}
void hm2_xy2mod_write(hostmot2_t *hm2) {
int i;
for (i = 0; i < hm2->xy2mod.num_instances; i ++) {
hm2_xy2mod_instance_write(hm2, i);
}
if (hm2->xy2mod.num_instances > 0 && hm2->dpll_module_present) {
if (*hm2->xy2mod.hal->pin.dpll_timer_num != hm2->xy2mod.written_dpll_timer_num) {
hm2_xy2mod_set_dpll_timer(hm2);
}
}
}
static void hm2_xy2mod_force_write_dpll_timer(hostmot2_t *hm2) {
if (hm2->xy2mod.num_instances > 0 && hm2->dpll_module_present) {
hm2_xy2mod_set_dpll_timer(hm2);
}
}
void hm2_xy2mod_force_write(hostmot2_t *hm2) {
if (hm2->xy2mod.num_instances == 0) return;
hm2_xy2mod_force_write_dpll_timer(hm2);
}
void hm2_xy2mod_tram_init(hostmot2_t *hm2) {
int i;
for (i = 0; i < hm2->xy2mod.num_instances; i ++) {
*hm2->xy2mod.instance[i].hal.pin.posx_cmd = 0;
*hm2->xy2mod.instance[i].hal.pin.posy_cmd = 0;
*hm2->xy2mod.instance[i].hal.pin.velx_cmd = 0;
*hm2->xy2mod.instance[i].hal.pin.vely_cmd = 0;
*hm2->xy2mod.instance[i].hal.pin.accx_cmd = 0;
*hm2->xy2mod.instance[i].hal.pin.accy_cmd = 0;
}
}
void hm2_xy2mod_allocate_pins(hostmot2_t *hm2) {
HM2_PRINT("allocate pins entry");
int i;
for (i = 0; i < hm2->num_pins; i ++) {
if (
(hm2->pin[i].sec_tag != HM2_GTAG_XY2MOD)
|| (hm2->pin[i].sec_unit >= hm2->xy2mod.num_instances)
) {
continue;
}
hm2_set_pin_source(hm2, i, HM2_PIN_SOURCE_IS_SECONDARY);
if (hm2->pin[i].sec_pin & 0x80){
hm2_set_pin_direction(hm2, i, HM2_PIN_DIR_IS_OUTPUT);
}
}
HM2_PRINT("allocate pins exit");
}
int hm2_xy2mod_parse_md(hostmot2_t *hm2, int md_index) {
hm2_module_descriptor_t *md = &hm2->md[md_index];
int r;
if (hm2_md_is_consistent(hm2, md_index, 0, 8, 4, 0x007F)) {
} else {
HM2_ERR("unknown xy2mod MD:\n");
HM2_ERR(" Version = %d, expected 0-2\n", md->version);
HM2_ERR(" NumRegisters = %d, expected 8\n", md->num_registers);
HM2_ERR(" InstanceStride = 0x%08X, expected 4\n", md->instance_stride);
HM2_ERR(" MultipleRegisters = 0x%08X, expected 0x0000007F\n", md->multiple_registers);
return -EINVAL;
}
if (hm2->xy2mod.num_instances != 0) {
HM2_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_xy2mods > md->instances) {
HM2_ERR(
"config.num_xy2mods=%d, but only %d are available, not loading driver\n",
hm2->config.num_xy2mods,
md->instances
);
return -EINVAL;
}
if (hm2->config.num_xy2mods == 0) {
return 0;
}
if (hm2->config.num_xy2mods == -1) {
hm2->xy2mod.num_instances = md->instances;
} else {
hm2->xy2mod.num_instances = hm2->config.num_xy2mods;
}
hm2->xy2mod.hal = (hm2_xy2mod_module_global_t *)hal_malloc(sizeof(hm2_xy2mod_module_global_t));
if (hm2->xy2mod.hal == NULL) {
HM2_ERR("out of memory!\n");
r = -ENOMEM;
goto fail0;
}
hm2->xy2mod.instance = (hm2_xy2mod_instance_t *)hal_malloc(hm2->xy2mod.num_instances * sizeof(hm2_xy2mod_instance_t));
if (hm2->xy2mod.instance == NULL) {
HM2_ERR("out of memory!\n");
r = -ENOMEM;
goto fail0;
}
hm2->xy2mod.clock_frequency = md->clock_freq;
hm2->xy2mod.version = md->version;
hm2->xy2mod.accx_addr = md->base_address + (0 * md->register_stride);
hm2->xy2mod.accy_addr = md->base_address + (1 * md->register_stride);
hm2->xy2mod.velx_addr = md->base_address + (2 * md->register_stride);
hm2->xy2mod.vely_addr = md->base_address + (3 * md->register_stride);
hm2->xy2mod.posx_addr = md->base_address + (4 * md->register_stride);
hm2->xy2mod.posy_addr = md->base_address + (5 * md->register_stride);
hm2->xy2mod.mode_addr = md->base_address + (6 * md->register_stride);
hm2->xy2mod.dpll_timer_num_addr = md->base_address + (7 * md->register_stride);
r = hm2_register_tram_read_region(hm2, hm2->xy2mod.posx_addr, (hm2->xy2mod.num_instances * sizeof(rtapi_u32)), &hm2->xy2mod.posx_reg);
if (r < 0) {
HM2_ERR("error registering tram read region for xy2mod X Position register (%d)\n", r);
goto fail0;
}
r = hm2_register_tram_read_region(hm2, hm2->xy2mod.posy_addr, (hm2->xy2mod.num_instances * sizeof(rtapi_u32)), &hm2->xy2mod.posy_reg);
if (r < 0) {
HM2_ERR("error registering tram read region for xy2mod Y Position register (%d)\n", r);
goto fail0;
}
r = hm2_register_tram_read_region(hm2, hm2->xy2mod.velx_addr, (hm2->xy2mod.num_instances * sizeof(rtapi_u32)), &hm2->xy2mod.velx_reg);
if (r < 0) {
HM2_ERR("error registering tram read region for xy2mod X Velocity register (%d)\n", r);
goto fail0;
}
r = hm2_register_tram_read_region(hm2, hm2->xy2mod.vely_addr, (hm2->xy2mod.num_instances * sizeof(rtapi_u32)), &hm2->xy2mod.vely_reg);
if (r < 0) {
HM2_ERR("error registering tram read region for xy2mod Y Velocity register (%d)\n", r);
goto fail0;
}
r = hm2_register_tram_read_region(hm2, hm2->xy2mod.accx_addr, (hm2->xy2mod.num_instances * sizeof(rtapi_u32)), &hm2->xy2mod.accx_reg);
if (r < 0) {
HM2_ERR("error registering tram read region for xy2mod X Acceleration register (%d)\n", r);
goto fail0;
}
r = hm2_register_tram_read_region(hm2, hm2->xy2mod.accy_addr, (hm2->xy2mod.num_instances * sizeof(rtapi_u32)), &hm2->xy2mod.accy_reg);
if (r < 0) {
HM2_ERR("error registering tram read region for xy2mod Y Acceleration register (%d)\n", r);
goto fail0;
}
r = hm2_register_tram_read_region(hm2, hm2->xy2mod.mode_addr, (hm2->xy2mod.num_instances * sizeof(rtapi_u32)), &hm2->xy2mod.mode_reg);
if (r < 0) {
HM2_ERR("error registering tram read region for xy2mod mode register (%d)\n", r);
goto fail0;
}
hm2->xy2mod.mode_reg = (rtapi_u32 *)rtapi_kmalloc(hm2->xy2mod.num_instances * sizeof(rtapi_u32), RTAPI_GFP_KERNEL);
if (hm2->xy2mod.mode_reg == NULL) {
HM2_ERR("out of memory!\n");
r = -ENOMEM;
goto fail0;
}
{
int i;
char name[HAL_NAME_LEN + 1];
if (hm2->dpll_module_present) {
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.timer-number", hm2->llio->name);
r = hal_pin_s32_new(name, HAL_IN, &(hm2->xy2mod.hal->pin.dpll_timer_num), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding timer number param, aborting\n");
return -EINVAL;
}
*(hm2->xy2mod.hal->pin.dpll_timer_num) = -1;
}
for (i = 0; i < hm2->xy2mod.num_instances; i ++) {
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posx-cmd", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posx_cmd), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posy-cmd", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posy_cmd), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.velx-cmd", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.velx_cmd), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.vely-cmd", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.vely_cmd), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.accx-cmd", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.accx_cmd), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.accy-cmd", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.accy_cmd), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.velx-fb", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.velx_fb), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.vely-fb", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.vely_fb), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posx-fb", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posx_fb), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posy-fb", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posy_fb), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posx-scale", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posx_scale), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posy-scale", hm2->llio->name, i);
r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posy_scale), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.enable", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.enable), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.controlx0", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controlx0), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.controlx1", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controlx1), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.controlx2", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controlx2), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.controly0", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controly0), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.controly1", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controly1), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.controly2", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controly2), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posx-overflow", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posx_overflow), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posy-overflow", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posy_overflow), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.velx-overflow", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.velx_overflow), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.vely-overflow", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.vely_overflow), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.status", hm2->llio->name, i);
r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.status), hm2->llio->comp_id);
if (r < 0) {
HM2_ERR("error adding pin '%s', aborting\n", name);
r = -ENOMEM;
goto fail0;
}
*(hm2->xy2mod.instance[i].hal.pin.posx_cmd) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.posy_cmd) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.velx_cmd) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.vely_cmd) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.accx_cmd) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.accy_cmd) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.posx_fb) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.posy_fb) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.velx_fb) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.vely_fb) = 0.0;
*(hm2->xy2mod.instance[i].hal.pin.posx_scale) = 1.0;
*(hm2->xy2mod.instance[i].hal.pin.posy_scale) = 1.0;
*(hm2->xy2mod.instance[i].hal.pin.enable) = 0;
*(hm2->xy2mod.instance[i].hal.pin.controlx0) = 0;
*(hm2->xy2mod.instance[i].hal.pin.controlx1) = 0;
*(hm2->xy2mod.instance[i].hal.pin.controlx2) = 0;
*(hm2->xy2mod.instance[i].hal.pin.controly0) = 0;
*(hm2->xy2mod.instance[i].hal.pin.controly1) = 0;
*(hm2->xy2mod.instance[i].hal.pin.controly2) = 0;
}
}
return hm2->xy2mod.num_instances;
fail0:
hm2->xy2mod.num_instances = 0;
return r;
}
void hm2_xy2mod_cleanup(hostmot2_t *hm2) {
if (hm2->xy2mod.num_instances <= 0) {
return;
}
}
void hm2_xy2mod_print_module(hostmot2_t *hm2) {
int i;
if (hm2->xy2mod.num_instances <= 0) return;
HM2_PRINT("xy2mod: %d\n", hm2->xy2mod.num_instances);
HM2_PRINT(" clock_frequency: %d Hz (%s MHz)\n", hm2->xy2mod.clock_frequency, hm2_hz_to_mhz(hm2->xy2mod.clock_frequency));
HM2_PRINT(" version: %d\n", hm2->xy2mod.version);
HM2_PRINT(" accx_addr: 0x%04X\n", hm2->xy2mod.accx_addr);
HM2_PRINT(" accy_addr: 0x%04X\n", hm2->xy2mod.accy_addr);
HM2_PRINT(" velx_addr: 0x%04X\n", hm2->xy2mod.velx_addr);
HM2_PRINT(" vely_addr: 0x%04X\n", hm2->xy2mod.vely_addr);
HM2_PRINT(" posx_addr: 0x%04X\n", hm2->xy2mod.posx_addr);
HM2_PRINT(" posy_addr: 0x%04X\n", hm2->xy2mod.posy_addr);
HM2_PRINT(" mode_addr: 0x%04X\n", hm2->xy2mod.mode_addr);
for (i = 0; i < hm2->xy2mod.num_instances; i ++) {
HM2_PRINT(" instance %d:\n", i);
HM2_PRINT(" enable = %d\n", *hm2->xy2mod.instance[i].hal.pin.enable);
HM2_PRINT(" hw:\n");
HM2_PRINT(" accx = 0x%08X\n", hm2->xy2mod.accx_reg[i]);
HM2_PRINT(" accy = 0x%08X\n", hm2->xy2mod.accy_reg[i]);
HM2_PRINT(" velx = 0x%08X\n", hm2->xy2mod.velx_reg[i]);
HM2_PRINT(" vely = 0x%08X\n", hm2->xy2mod.vely_reg[i]);
HM2_PRINT(" posx = 0x%08X\n", hm2->xy2mod.posx_reg[i]);
HM2_PRINT(" posy = 0x%08X\n", hm2->xy2mod.posy_reg[i]);
HM2_PRINT(" mode = 0x%08X\n", hm2->xy2mod.mode_reg[i]);
}
}