#include <rtapi_pci.h>
#include <rtapi_io.h>
#include "rtapi.h"
#include "rtapi_app.h"
#include "hal.h"
#include "gm.h"
#include "rtapi_math.h"
MODULE_AUTHOR("Bence Kovacs");
MODULE_DESCRIPTION("Driver for General Mechatronics 6-Axis Motion Control Card for EMC HAL");
MODULE_LICENSE("GPL");
typedef struct { hal_bit_t *reset;
hal_s32_t *counts;
hal_float_t *position;
hal_float_t *velocity;
hal_s32_t *rawcounts;
hal_bit_t *index_enable;
hal_bit_t counter_mode;
hal_bit_t index_mode;
hal_bit_t index_invert;
hal_u32_t counts_per_rev;
hal_float_t position_scale;
hal_float_t min_speed_estimate;
hal_s32_t raw_offset;
hal_s32_t index_offset;
hal_s32_t last_index_latch;
hal_bit_t first_index;
hal_bit_t module_exist;
} encoder_t;
typedef struct { hal_bit_t *home;
hal_bit_t *homeNot;
hal_bit_t *posLimSwIn;
hal_bit_t *posLimSwInNot;
hal_bit_t *negLimSwIn;
hal_bit_t *negLimSwInNot;
} switches_t;
typedef struct { hal_bit_t *in;
hal_bit_t *inNot;
} estop_t;
typedef struct { hal_bit_t *in;
hal_bit_t *inNot;
hal_bit_t *out;
hal_bit_t isOut;
hal_bit_t invertOut;
} gpio_t;
typedef struct { hal_bit_t *out_0;
hal_bit_t *out_1;
hal_bit_t *out_2;
hal_bit_t *out_3;
hal_bit_t *out_4;
hal_bit_t *out_5;
hal_bit_t *out_6;
hal_bit_t *out_7;
hal_bit_t invertOut_0;
hal_bit_t invertOut_1;
hal_bit_t invertOut_2;
hal_bit_t invertOut_3;
hal_bit_t invertOut_4;
hal_bit_t invertOut_5;
hal_bit_t invertOut_6;
hal_bit_t invertOut_7;
} RS485_8output_t;
typedef struct { hal_bit_t *in_0;
hal_bit_t *inNot_0;
hal_bit_t *in_1;
hal_bit_t *inNot_1;
hal_bit_t *in_2;
hal_bit_t *inNot_2;
hal_bit_t *in_3;
hal_bit_t *inNot_3;
hal_bit_t *in_4;
hal_bit_t *inNot_4;
hal_bit_t *in_5;
hal_bit_t *inNot_5;
hal_bit_t *in_6;
hal_bit_t *inNot_6;
hal_bit_t *in_7;
hal_bit_t *inNot_7;
} RS485_8input_t;
typedef struct { hal_float_t *DAC_0;
hal_float_t *DAC_1;
hal_float_t *DAC_2;
hal_float_t *DAC_3;
hal_bit_t *dac_0_enable;
hal_bit_t *dac_1_enable;
hal_bit_t *dac_2_enable;
hal_bit_t *dac_3_enable;
hal_float_t *ADC_0;
hal_float_t *ADC_1;
hal_float_t *ADC_2;
hal_float_t *ADC_3;
hal_float_t *ADC_4;
hal_float_t *ADC_5;
hal_float_t *ADC_6;
hal_float_t *ADC_7;
hal_float_t DAC_0_offset;
hal_float_t DAC_1_offset;
hal_float_t DAC_2_offset;
hal_float_t DAC_3_offset;
hal_float_t DAC_0_min;
hal_float_t DAC_1_min;
hal_float_t DAC_2_min;
hal_float_t DAC_3_min;
hal_float_t DAC_0_max;
hal_float_t DAC_1_max;
hal_float_t DAC_2_max;
hal_float_t DAC_3_max;
hal_float_t ADC_0_offset;
hal_float_t ADC_1_offset;
hal_float_t ADC_2_offset;
hal_float_t ADC_3_offset;
hal_float_t ADC_4_offset;
hal_float_t ADC_5_offset;
hal_float_t ADC_6_offset;
hal_float_t ADC_7_offset;
hal_float_t ADC_0_scale;
hal_float_t ADC_1_scale;
hal_float_t ADC_2_scale;
hal_float_t ADC_3_scale;
hal_float_t ADC_4_scale;
hal_float_t ADC_5_scale;
hal_float_t ADC_6_scale;
hal_float_t ADC_7_scale;
} RS485_DacAdc_t;
typedef struct { hal_float_t *ADC_0;
hal_float_t *ADC_1;
hal_float_t *ADC_2;
hal_float_t *ADC_3;
hal_float_t *ADC_4;
hal_float_t *ADC_5;
hal_bit_t *in_0;
hal_bit_t *inNot_0;
hal_bit_t *in_1;
hal_bit_t *inNot_1;
hal_bit_t *in_2;
hal_bit_t *inNot_2;
hal_bit_t *in_3;
hal_bit_t *inNot_3;
hal_bit_t *in_4;
hal_bit_t *inNot_4;
hal_bit_t *in_5;
hal_bit_t *inNot_5;
hal_bit_t *in_6;
hal_bit_t *inNot_6;
hal_bit_t *in_7;
hal_bit_t *inNot_7;
hal_bit_t *enc_reset;
hal_s32_t *enc_counts;
hal_float_t *enc_position;
hal_s32_t *enc_rawcounts;
hal_float_t ADC_0_offset;
hal_float_t ADC_1_offset;
hal_float_t ADC_2_offset;
hal_float_t ADC_3_offset;
hal_float_t ADC_4_offset;
hal_float_t ADC_5_offset;
hal_float_t ADC_0_scale;
hal_float_t ADC_1_scale;
hal_float_t ADC_2_scale;
hal_float_t ADC_3_scale;
hal_float_t ADC_4_scale;
hal_float_t ADC_5_scale;
hal_float_t enc_position_scale;
hal_s32_t enc_raw_offset;
} RS485_TeachPad_t;
typedef struct { hal_u32_t ID[16];
hal_u32_t BYTES_TO_WRITE[16];
hal_u32_t BYTES_TO_READ[16];
} RS485_mgr_t;
typedef struct { hal_float_t *value;
hal_bit_t *enable;
hal_float_t min;
hal_float_t max;
hal_float_t offset;
hal_bit_t invert_serial;
} axisdac_t;
typedef struct { hal_float_t *position_cmd;
hal_float_t *velocity_cmd;
hal_float_t *position_fb;
hal_s32_t *count_fb;
hal_bit_t *enable;
hal_u32_t step_type; hal_bit_t control_type; hal_u32_t steplen;
hal_u32_t stepspace;
hal_u32_t dirdelay;
hal_float_t maxaccel;
hal_float_t maxvel;
hal_bit_t polarity_A;
hal_bit_t polarity_B;
hal_float_t position_scale;
hal_u32_t curr_steplen;
hal_u32_t curr_stepspace;
hal_u32_t curr_dirdelay;
hal_float_t curr_maxaccel;
hal_float_t curr_maxvel;
hal_float_t curr_position_scale;
hal_u32_t stepgen_fb_offset;
hal_float_t old_pos_cmd;
hal_float_t max_dv;
hal_float_t old_vel;
hal_float_t steprate_scale;
} stepgen_t;
typedef struct { hal_bit_t *cardEnable;
hal_bit_t *power_enable;
hal_bit_t *power_fault;
hal_bit_t *watchdog_expired;
hal_bit_t watchdog_enable;
hal_u32_t watchdog_timeout_ns;
hal_u32_t card_control_reg;
hal_bit_t disable;
hal_u32_t dbg_PCI_counter_last;
hal_u32_t cntr;
} cardMgr_t;
typedef struct { hal_bit_t *enable;
hal_float_t *position_cmd;
hal_float_t *position_fb;
hal_float_t position_scale;
} CAN_GM_t;
typedef struct { hal_bit_t Ext; hal_u32_t ID;
hal_u32_t data[8];
hal_u32_t DLC;
hal_bit_t RTR;
}CANmsg_t;
typedef struct { card *pCard;
int boardID; int cardID;
switches_t switches[6];
gpio_t gpio[32];
estop_t estop[2];
RS485_mgr_t RS485_mgr;
RS485_8input_t RS485_8input[16];
RS485_8output_t RS485_8output[16];
RS485_DacAdc_t RS485_DacAdc[16];
RS485_TeachPad_t RS485_TeachPad[16];
CAN_GM_t CAN_GM[6];
stepgen_t stepgen[6];
hal_u32_t stepgen_status;
axisdac_t axisdac[6];
encoder_t encoder[6];
cardMgr_t cardMgr;
hal_u32_t period_ns;
hal_float_t period_s;
hal_float_t rec_period_s;
} gm_device_t;
typedef struct { int comp_id;
gm_device_t *device[MAX_GM_DEVICES];
} gm_driver_t;
static gm_driver_t driver;
static int num_boards = 0;
static int failed_errno = 0;
static struct
rtapi_pci_device_id gm_pci_tbl[] = {
{
.vendor = PLX_VENDOR_ID,
.device = GM_DEVICE_ID,
.subvendor = PLX_VENDOR_ID,
.subdevice = GM_SUBDEVICE_ID_1,
},
{
.vendor = PLX_VENDOR_ID,
.device = GM_DEVICE_ID,
.subvendor = PLX_VENDOR_ID,
.subdevice = GM_SUBDEVICE_ID_2,
},
{0,},
};
static int ExportFunctions(void *arg, int comp_id, int boardId);
static int ExportEncoder(void *arg, int comp_id, int version);
static int ExportStepgen(void *arg, int comp_id, int version);
static int ExportDAC(void *arg, int comp_id, int version);
static int ExportRS485(void *arg, int comp_id, int version);
static int ExportCAN(void *arg, int comp_id, int version);
static int ExportMixed(void *arg, int comp_id);
static int gm_pci_probe(struct rtapi_pci_dev *dev, const struct rtapi_pci_device_id *id);
static void gm_pci_remove(struct rtapi_pci_dev *dev);
static void read(void *arg, long period);
static void write(void *arg, long period);
static void RS485(void *arg, long period);
static void stepgen(void *arg, long period);
static void stepgenControl(void *arg, long period, unsigned int i);
static void stepgenCheckParameters(void *arg, long period, unsigned int channel);
static unsigned int RS485_CheckChecksum(hal_u32_t* data, hal_u32_t length);
static unsigned int RS485_CalcChecksum(hal_u32_t* data, hal_u32_t length);
static void RS485_OrderDataRead(hal_u32_t* dataIn32, hal_u32_t* dataOut8, hal_u32_t length);
static void RS485_OrderDataWrite(hal_u32_t* dataIn8, hal_u32_t* dataOut32, hal_u32_t length);
static void encoder(void *arg, long period);
static void GM_CAN_SERVO(void *arg);
static void CAN_SendDataFrame(void *arg, CANmsg_t *Msg);
static void CAN_ReceiveDataFrame(void *arg, CANmsg_t *Msg);
#ifdef CANOPEN
static void CAN_Reset(void *arg);
static void CAN_SetBaud(void *arg, hal_u32_t Baud);
#endif
static int CAN_ReadStatus(void *arg, hal_u32_t *RxCnt, hal_u32_t *TxCnt);
static void card_mgr(void *arg, long period);
static int
gm_pci_probe(struct rtapi_pci_dev *dev, const struct rtapi_pci_device_id *id)
{
int error=0;
card *pCard = NULL;
gm_device_t *pDevice;
if (num_boards >= MAX_GM_DEVICES) {
rtapi_print_msg(RTAPI_MSG_ERR,"skipping AnyIO board at %s, this driver can only handle %d\n", rtapi_pci_name(dev), MAX_GM_DEVICES);
return -EINVAL;
}
if (rtapi_pci_enable_device(dev)) {
rtapi_print_msg(RTAPI_MSG_ERR,"skipping AnyIO board at %s, failed to enable PCI device\n", rtapi_pci_name(dev));
return failed_errno = -ENODEV;
}
pDevice = hal_malloc(sizeof(gm_device_t));
if (pDevice == 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR: hal_malloc() failed.\n");
hal_exit(driver.comp_id);
return(-ENOMEM);
}
driver.device[num_boards] = pDevice;
pCard = (card *)rtapi_pci_ioremap_bar(dev, 5);
rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: Card address @ %p, Len = %d.\n", pCard, (int)rtapi_pci_resource_len(dev, 5));
pDevice->pCard = pCard;
pDevice->boardID = num_boards++;
pDevice->cardID = pCard->cardID;
rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: Card ID: 0x%X.\n", pDevice->cardID);
if ( (pDevice->cardID & IDmask_card) != cardVersion1 ) {
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR, unknown card detected.\nPlease, download the latest driver.\n");
hal_exit(driver.comp_id);
return(-ENODEV);
}
rtapi_set_msg_level(RTAPI_MSG_WARN);
pDevice->cardMgr.disable = 0; pDevice->period_ns = 0;
error = ExportEncoder(pDevice, driver.comp_id, pDevice->cardID & IDmask_encoder);
if(error == 0) error = ExportStepgen(pDevice, driver.comp_id, pDevice->cardID & IDmask_stepgen);
if(error == 0) error = ExportDAC(pDevice, driver.comp_id, pDevice->cardID & IDmask_dac);
if(error == 0) error = ExportRS485(pDevice, driver.comp_id, pDevice->cardID & IDmask_rs485);
if(error == 0) error = ExportCAN(pDevice, driver.comp_id, pDevice->cardID & IDmask_can);
if(error == 0) error = ExportMixed(pDevice, driver.comp_id);
if(error == 0) error = ExportFunctions(pDevice, driver.comp_id, pDevice->boardID);
pDevice->cardMgr.card_control_reg = 0;
rtapi_set_msg_level(RTAPI_MSG_ALL);
if(error){
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: Error exporting pins and parameters.\n");
hal_exit(driver.comp_id);
return -EINVAL;
}
return 0;
}
static void
gm_pci_remove(struct rtapi_pci_dev *dev)
{
int i;
gm_device_t *pDevice;
for(i = 0; i < MAX_GM_DEVICES; i++){
if((pDevice = driver.device[i]) != NULL)
{
pDevice->pCard->card_control_reg = (hal_s32_t) 0;
rtapi_iounmap((void *)(pDevice->pCard));
rtapi_pci_disable_device(dev);
rtapi_pci_set_drvdata(dev, NULL);
}
}
}
static struct
rtapi_pci_driver gm_pci_driver = {
.name = "hal_gm",
.id_table = gm_pci_tbl,
.probe = gm_pci_probe,
.remove = gm_pci_remove,
};
int
rtapi_app_main(void)
{
int r = 0;
int msgLevel, i = 0;
msgLevel = rtapi_get_msg_level();
rtapi_set_msg_level(RTAPI_MSG_ALL);
rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: Driver version 1.1.3 loading...\n");
driver.comp_id = hal_init("hal_gm");
if (driver.comp_id < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR: hal_init() failed.\n");
return(-EINVAL);
}
for(i = 0; i < MAX_GM_DEVICES; i++){
driver.device[i] = NULL;
}
r = rtapi_pci_register_driver(&gm_pci_driver);
if (r != 0) {
rtapi_print_msg(RTAPI_MSG_ERR,"error registering PCI driver\n");
hal_exit(driver.comp_id);
return r;
}
if(failed_errno) {
hal_exit(driver.comp_id);
rtapi_pci_unregister_driver(&gm_pci_driver);
return failed_errno;
}
if(num_boards == 0) {
hal_exit(driver.comp_id);
rtapi_pci_unregister_driver(&gm_pci_driver);
return -ENODEV;
}
if(num_boards == 0){
rtapi_print_msg(RTAPI_MSG_WARN, "General Mechatronics: No General Mechatronics card detected :(. \n");
hal_exit(driver.comp_id);
return -ENODEV;
}
hal_ready(driver.comp_id);
rtapi_set_msg_level(msgLevel);
return(0);
}
void
rtapi_app_exit(void)
{
rtapi_pci_unregister_driver(&gm_pci_driver);
hal_exit(driver.comp_id);
}
static int
ExportEncoder(void *arg, int comp_id, int version)
{
int i, error=0, boardId;
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
boardId = device->boardID;
switch (version)
{
case notPresented:
for(i=0;i<6;i++)
{
device->encoder[i].module_exist = 0;
}
rtapi_print_msg(RTAPI_MSG_WARN, "General Mechatronics: No encoder module available in this version of the Card.\n");
break;
case encoderVersion1:
for(i=0;i<6;i++)
{
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->encoder[i].reset), comp_id, "gm.%1d.encoder.%1d.reset", boardId, i);
if(error == 0) error = hal_pin_s32_newf(HAL_OUT, &(device->encoder[i].counts), comp_id, "gm.%1d.encoder.%1d.counts", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->encoder[i].position), comp_id, "gm.%1d.encoder.%1d.position", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->encoder[i].velocity), comp_id, "gm.%1d.encoder.%1d.velocity", boardId, i);
if(error == 0) error = hal_pin_s32_newf(HAL_OUT, &(device->encoder[i].rawcounts), comp_id, "gm.%1d.encoder.%1d.rawcounts", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IO, &(device->encoder[i].index_enable), comp_id, "gm.%1d.encoder.%1d.index-enable", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->encoder[i].counter_mode), comp_id, "gm.%1d.encoder.%1d.counter-mode", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->encoder[i].index_mode), comp_id, "gm.%1d.encoder.%1d.index-mode", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->encoder[i].index_invert), comp_id, "gm.%1d.encoder.%1d.index-invert", boardId, i);
if(error == 0) error = hal_param_u32_newf(HAL_RW, &(device->encoder[i].counts_per_rev), comp_id, "gm.%1d.encoder.%1d.counts-per-rev", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->encoder[i].position_scale), comp_id, "gm.%1d.encoder.%1d.position-scale", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->encoder[i].min_speed_estimate), comp_id, "gm.%1d.encoder.%1d.min-speed-estimate", boardId, i);
device->encoder[i].raw_offset = pCard->ENC_counter[i];
device->encoder[i].index_offset = 0;
device->encoder[i].last_index_latch = pCard->ENC_index_latch[i];
device->encoder[i].first_index = 1;
device->encoder[i].module_exist = 1;
}
break;
default:
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR, unknown encoder version.\nPlease, download the latest driver.\n");
}
return error;
}
static int
ExportStepgen(void *arg, int comp_id, int version)
{
int i, error=0, boardId;
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
boardId = device->boardID;
switch (version)
{
case notPresented:
for(i=0;i<6;i++)
{
device->stepgen[i].enable = &(device->cardMgr.disable); device->stepgen[i].position_cmd = &(device->stepgen[i].old_pos_cmd);
}
rtapi_print_msg(RTAPI_MSG_WARN, "General Mechatronics: No stepgen module available in this version of the Card.\n");
break;
case stepgenVersion1:
device->stepgen_status=0;
pCard->StepGen_status = 0;
for(i = 0; i < 6; i++)
{
if(error == 0) error = hal_pin_float_newf(HAL_IN, &(device->stepgen[i].position_cmd), comp_id, "gm.%1d.stepgen.%1d.position-cmd", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->stepgen[i].position_fb), comp_id, "gm.%1d.stepgen.%1d.position-fb", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_IN, &(device->stepgen[i].velocity_cmd), comp_id, "gm.%1d.stepgen.%1d.velocity-cmd", boardId, i);
if(error == 0) error = hal_pin_s32_newf(HAL_OUT, &(device->stepgen[i].count_fb), comp_id, "gm.%1d.stepgen.%1d.count-fb", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->stepgen[i].enable), comp_id, "gm.%1d.stepgen.%1d.enable", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->stepgen[i].control_type), comp_id, "gm.%1d.stepgen.%1d.control-type", boardId, i); if(error == 0) error = hal_param_u32_newf(HAL_RW, &(device->stepgen[i].step_type), comp_id, "gm.%1d.stepgen.%1d.step-type", boardId, i); if(error == 0) error = hal_param_u32_newf(HAL_RW, &(device->stepgen[i].steplen), comp_id, "gm.%1d.stepgen.%1d.steplen", boardId, i);
if(error == 0) error = hal_param_u32_newf(HAL_RW, &(device->stepgen[i].stepspace), comp_id, "gm.%1d.stepgen.%1d.stepspace", boardId, i);
if(error == 0) error = hal_param_u32_newf(HAL_RW, &(device->stepgen[i].dirdelay), comp_id, "gm.%1d.stepgen.%1d.dirdelay", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->stepgen[i].maxaccel), comp_id, "gm.%1d.stepgen.%1d.maxaccel", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->stepgen[i].maxvel), comp_id, "gm.%1d.stepgen.%1d.maxvel", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->stepgen[i].polarity_A), comp_id, "gm.%1d.stepgen.%1d.invert-step1", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->stepgen[i].polarity_B), comp_id, "gm.%1d.stepgen.%1d.invert-step2", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->stepgen[i].position_scale), comp_id, "gm.%1d.stepgen.%1d.position-scale", boardId, i);
if(error != 0) break;
device->stepgen[i].curr_steplen = 0;
device->stepgen[i].curr_stepspace = 0;
device->stepgen[i].curr_dirdelay = 0;
device->stepgen[i].curr_maxaccel = 0.0;
device->stepgen[i].curr_maxvel = 0.0;
device->stepgen[i].curr_position_scale = 1.0;
device->stepgen[i].steprate_scale = 30 / 1000000000.0 * 4294967296.0;
device->stepgen[i].stepgen_fb_offset = pCard->StepGen_fb[i];
pCard->StepGen_time_params[i] = 0;
pCard->StepGen_steprate[i] = 0;
}
break;
default:
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR, unknown stepgen version.\nPlease, download the latest driver.\n");
error = -1;
}
return error;
}
static int
ExportDAC(void *arg, int comp_id, int version)
{
int i, error=0, boardId;
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
boardId = device->boardID;
switch (version)
{
case notPresented:
for(i=0;i<6;i++)
{
device->axisdac[i].enable = &(device->cardMgr.disable); }
rtapi_print_msg(RTAPI_MSG_WARN, "General Mechatronics: No DAC module available in this version of the Card.\n");
break;
case dacVersion1:
for(i=0;i<6;i++)
{
device->axisdac[i].enable = &(device->cardMgr.disable); }
rtapi_print_msg(RTAPI_MSG_WARN, "General Mechatronics: This card supports DAC ver.1 only, which is no longer produced. No DAC pins will be exported to HAL. If you need DAC, contact to bence.kovacs@generalmechatronics.com for firmware upgrade.\n");
break;
case dacVersion2:
for(i=0;i<6;i++)
{
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->axisdac[i].enable), comp_id, "gm.%1d.dac.%1d.enable", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_IN, &(device->axisdac[i].value), comp_id, "gm.%1d.dac.%1d.value", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->axisdac[i].min), comp_id, "gm.%1d.dac.%1d.low-limit", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->axisdac[i].max), comp_id, "gm.%1d.dac.%1d.high-limit", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->axisdac[i].offset), comp_id, "gm.%1d.dac.%1d.offset", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->axisdac[i].invert_serial), comp_id, "gm.%1d.dac.%1d.invert-serial", boardId, i);
device->axisdac[i].max = 10;
device->axisdac[i].min = -10;
device->axisdac[i].offset = 0;
device->axisdac[i].invert_serial = 0;
pCard->DAC_0 = 0x1FFF1FFF;
pCard->DAC_1 = 0x1FFF1FFF;
pCard->DAC_2 = 0x1FFF1FFF;
}
break;
default:
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR, unknown axis DAC version.\nPlease, download the latest driver.\n");
error = -1;
}
return error;
}
static int
ExportRS485(void *arg, int comp_id, int version)
{
int i, error=0, boardId, temp;
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
boardId = device->boardID;
switch (version)
{
case notPresented:
rtapi_print_msg(RTAPI_MSG_WARN, "General Mechatronics: No RS485 module available in this version of the Card.\n");
break;
case rs485Version1:
for(i=0; i<8; i++)
{
temp=(hal_u32_t)pCard->moduleId[i];
if(((temp & 0xff)^0xaa) == ((temp & 0xff00)>>8))
{
device-> RS485_mgr.ID[2*i]=(temp >> 8) & 0xff;
}
else device-> RS485_mgr.ID[2*i] = 0;
if(((temp & 0xff0000)^0xaa0000) == ((temp & 0xff000000)>>8))
{
device-> RS485_mgr.ID[2*i+1]=(temp & 0xff000000)>>24;
}
else device-> RS485_mgr.ID[2*i+1]=0;
}
for(i = 0; i < 16; i++)
{
switch (device-> RS485_mgr.ID[i])
{
case 0:
break;
case RS485MODUL_ID_8INPUT:
device-> RS485_mgr.BYTES_TO_WRITE[i]=0;
device-> RS485_mgr.BYTES_TO_READ[i]=2;
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].in_0), comp_id, "gm.%1d.rs485.%02d.in-0", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].inNot_0), comp_id, "gm.%1d.rs485.%02d.in-not-0", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].in_1), comp_id, "gm.%1d.rs485.%02d.in-1", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].inNot_1), comp_id, "gm.%1d.rs485.%02d.in-not-1", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].in_2), comp_id, "gm.%1d.rs485.%02d.in-2", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].inNot_2), comp_id, "gm.%1d.rs485.%02d.in-not-2", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].in_3), comp_id, "gm.%1d.rs485.%02d.in-3", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].inNot_3), comp_id, "gm.%1d.rs485.%02d.in-not-3", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].in_4), comp_id, "gm.%1d.rs485.%02d.in-4", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].inNot_4), comp_id, "gm.%1d.rs485.%02d.in-not-4", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].in_5), comp_id, "gm.%1d.rs485.%02d.in-5", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].inNot_5), comp_id, "gm.%1d.rs485.%02d.in-not-5", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].in_6), comp_id, "gm.%1d.rs485.%02d.in-6", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].inNot_6), comp_id, "gm.%1d.rs485.%02d.in-not-6", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].in_7), comp_id, "gm.%1d.rs485.%02d.in-7", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_8input[i].inNot_7), comp_id, "gm.%1d.rs485.%02d.in-not-7", boardId, i);
break;
case RS485MODUL_ID_8OUTPUT:
device-> RS485_mgr.BYTES_TO_WRITE[i]=2; device-> RS485_mgr.BYTES_TO_READ[i]=0;
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_8output[i].out_0), comp_id, "gm.%1d.rs485.%02d.relay-0", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_8output[i].out_1), comp_id, "gm.%1d.rs485.%02d.relay-1", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_8output[i].out_2), comp_id, "gm.%1d.rs485.%02d.relay-2", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_8output[i].out_3), comp_id, "gm.%1d.rs485.%02d.relay-3", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_8output[i].out_4), comp_id, "gm.%1d.rs485.%02d.relay-4", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_8output[i].out_5), comp_id, "gm.%1d.rs485.%02d.relay-5", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_8output[i].out_6), comp_id, "gm.%1d.rs485.%02d.relay-6", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_8output[i].out_7), comp_id, "gm.%1d.rs485.%02d.relay-7", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->RS485_8output[i].invertOut_0), comp_id, "gm.%1d.rs485.%02d.invert-relay-0", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->RS485_8output[i].invertOut_1), comp_id, "gm.%1d.rs485.%02d.invert-relay-1", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->RS485_8output[i].invertOut_2), comp_id, "gm.%1d.rs485.%02d.invert-relay-2", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->RS485_8output[i].invertOut_3), comp_id, "gm.%1d.rs485.%02d.invert-relay-3", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->RS485_8output[i].invertOut_4), comp_id, "gm.%1d.rs485.%02d.invert-relay-4", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->RS485_8output[i].invertOut_5), comp_id, "gm.%1d.rs485.%02d.invert-relay-5", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->RS485_8output[i].invertOut_6), comp_id, "gm.%1d.rs485.%02d.invert-relay-6", boardId, i);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->RS485_8output[i].invertOut_7), comp_id, "gm.%1d.rs485.%02d.invert-relay-7", boardId, i);
break;
case RS485MODUL_ID_DACADC:
device-> RS485_mgr.BYTES_TO_WRITE[i]=5; device-> RS485_mgr.BYTES_TO_READ[i]=9;
if(error == 0) error = hal_pin_float_newf(HAL_IN, &(device->RS485_DacAdc[i].DAC_0), comp_id, "gm.%1d.rs485.%02d.dac-0", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_IN, &(device->RS485_DacAdc[i].DAC_1), comp_id, "gm.%1d.rs485.%02d.dac-1", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_IN, &(device->RS485_DacAdc[i].DAC_2), comp_id, "gm.%1d.rs485.%02d.dac-2", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_IN, &(device->RS485_DacAdc[i].DAC_3), comp_id, "gm.%1d.rs485.%02d.dac-3", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_DacAdc[i].dac_0_enable), comp_id, "gm.%1d.rs485.%02d.dac-enable-0", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_DacAdc[i].dac_1_enable), comp_id, "gm.%1d.rs485.%02d.dac-enable-1", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_DacAdc[i].dac_2_enable), comp_id, "gm.%1d.rs485.%02d.dac-enable-2", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_DacAdc[i].dac_3_enable), comp_id, "gm.%1d.rs485.%02d.dac-enable-3", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_DacAdc[i].ADC_0), comp_id, "gm.%1d.rs485.%02d.adc-0", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_DacAdc[i].ADC_1), comp_id, "gm.%1d.rs485.%02d.adc-1", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_DacAdc[i].ADC_2), comp_id, "gm.%1d.rs485.%02d.adc-2", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_DacAdc[i].ADC_3), comp_id, "gm.%1d.rs485.%02d.adc-3", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_DacAdc[i].ADC_4), comp_id, "gm.%1d.rs485.%02d.adc-4", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_DacAdc[i].ADC_5), comp_id, "gm.%1d.rs485.%02d.adc-5", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_DacAdc[i].ADC_6), comp_id, "gm.%1d.rs485.%02d.adc-6", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_DacAdc[i].ADC_7), comp_id, "gm.%1d.rs485.%02d.adc-7", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_0_offset), comp_id, "gm.%1d.rs485.%02d.dac-offset-0", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_1_offset), comp_id, "gm.%1d.rs485.%02d.dac-offset-1", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_2_offset), comp_id, "gm.%1d.rs485.%02d.dac-offset-2", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_3_offset), comp_id, "gm.%1d.rs485.%02d.dac-offset-3", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_0_max), comp_id, "gm.%1d.rs485.%02d.dac-high-limit-0", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_1_max), comp_id, "gm.%1d.rs485.%02d.dac-high-limit-1", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_2_max), comp_id, "gm.%1d.rs485.%02d.dac-high-limit-2", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_3_max), comp_id, "gm.%1d.rs485.%02d.dac-high-limit-3", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_0_min), comp_id, "gm.%1d.rs485.%02d.dac-low-limit-0", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_1_min), comp_id, "gm.%1d.rs485.%02d.dac-low-limit-1", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_2_min), comp_id, "gm.%1d.rs485.%02d.dac-low-limit-2", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].DAC_3_min), comp_id, "gm.%1d.rs485.%02d.dac-low-limit-3", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_0_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-0", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_1_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-1", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_2_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-2", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_3_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-3", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_4_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-4", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_5_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-5", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_6_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-6", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_7_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-7", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_0_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-0", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_1_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-1", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_2_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-2", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_3_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-3", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_4_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-4", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_5_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-5", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_6_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-6", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_DacAdc[i].ADC_7_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-7", boardId, i);
device->RS485_DacAdc[i].DAC_0_max = 10;
device->RS485_DacAdc[i].DAC_0_min = -10;
device->RS485_DacAdc[i].DAC_1_max = 10;
device->RS485_DacAdc[i].DAC_1_min = -10;
device->RS485_DacAdc[i].DAC_2_max = 10;
device->RS485_DacAdc[i].DAC_2_min = -10;
device->RS485_DacAdc[i].DAC_3_max = 10;
device->RS485_DacAdc[i].DAC_3_min = -10;
device->RS485_DacAdc[i].ADC_0_scale = 1;
device->RS485_DacAdc[i].ADC_1_scale = 1;
device->RS485_DacAdc[i].ADC_2_scale = 1;
device->RS485_DacAdc[i].ADC_3_scale = 1;
device->RS485_DacAdc[i].ADC_4_scale = 1;
device->RS485_DacAdc[i].ADC_5_scale = 1;
device->RS485_DacAdc[i].ADC_6_scale = 1;
device->RS485_DacAdc[i].ADC_7_scale = 1;
break;
case RS485MODUL_ID_TEACHPAD:
device-> RS485_mgr.BYTES_TO_WRITE[i]=0;
device-> RS485_mgr.BYTES_TO_READ[i]=12;
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].in_0), comp_id, "gm.%1d.rs485.%02d.in-0", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].inNot_0), comp_id, "gm.%1d.rs485.%02d.in-not-0", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].in_1), comp_id, "gm.%1d.rs485.%02d.in-1", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].inNot_1), comp_id, "gm.%1d.rs485.%02d.in-not-1", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].in_2), comp_id, "gm.%1d.rs485.%02d.in-2", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].inNot_2), comp_id, "gm.%1d.rs485.%02d.in-not-2", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].in_3), comp_id, "gm.%1d.rs485.%02d.in-3", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].inNot_3), comp_id, "gm.%1d.rs485.%02d.in-not-3", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].in_4), comp_id, "gm.%1d.rs485.%02d.in-4", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].inNot_4), comp_id, "gm.%1d.rs485.%02d.in-not-4", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].in_5), comp_id, "gm.%1d.rs485.%02d.in-5", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].inNot_5), comp_id, "gm.%1d.rs485.%02d.in-not-5", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].in_6), comp_id, "gm.%1d.rs485.%02d.in-6", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].inNot_6), comp_id, "gm.%1d.rs485.%02d.in-not-6", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].in_7), comp_id, "gm.%1d.rs485.%02d.in-7", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->RS485_TeachPad[i].inNot_7), comp_id, "gm.%1d.rs485.%02d.in-not-7", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_TeachPad[i].ADC_0), comp_id, "gm.%1d.rs485.%02d.adc-0", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_TeachPad[i].ADC_1), comp_id, "gm.%1d.rs485.%02d.adc-1", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_TeachPad[i].ADC_2), comp_id, "gm.%1d.rs485.%02d.adc-2", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_TeachPad[i].ADC_3), comp_id, "gm.%1d.rs485.%02d.adc-3", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_TeachPad[i].ADC_4), comp_id, "gm.%1d.rs485.%02d.adc-4", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_TeachPad[i].ADC_5), comp_id, "gm.%1d.rs485.%02d.adc-5", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_0_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-0", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_1_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-1", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_2_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-2", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_3_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-3", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_4_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-4", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_5_offset), comp_id, "gm.%1d.rs485.%02d.adc-offset-5", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_0_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-0", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_1_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-1", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_2_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-2", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_3_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-3", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_4_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-4", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].ADC_5_scale), comp_id, "gm.%1d.rs485.%02d.adc-scale-5", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->RS485_TeachPad[i].enc_reset), comp_id, "gm.%1d.rs485.%02d.enc-reset", boardId, i);
if(error == 0) error = hal_pin_s32_newf(HAL_OUT, &(device->RS485_TeachPad[i].enc_counts), comp_id, "gm.%1d.rs485.%02d.enc-counts", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->RS485_TeachPad[i].enc_position), comp_id, "gm.%1d.rs485.%02d.enc-position", boardId, i);
if(error == 0) error = hal_pin_s32_newf(HAL_OUT, &(device->RS485_TeachPad[i].enc_rawcounts), comp_id, "gm.%1d.rs485.%02d.enc-rawcounts", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->RS485_TeachPad[i].enc_position_scale), comp_id, "gm.%1d.rs485.%02d.enc-position-scale", boardId, i);
device->RS485_TeachPad[i].ADC_0_scale = 1;
device->RS485_TeachPad[i].ADC_1_scale = 1;
device->RS485_TeachPad[i].ADC_2_scale = 1;
device->RS485_TeachPad[i].ADC_3_scale = 1;
device->RS485_TeachPad[i].ADC_4_scale = 1;
device->RS485_TeachPad[i].ADC_5_scale = 1;
device->RS485_TeachPad[i].ADC_0_offset = 0;
device->RS485_TeachPad[i].ADC_1_offset = 0;
device->RS485_TeachPad[i].ADC_2_offset = 0;
device->RS485_TeachPad[i].ADC_3_offset = 0;
device->RS485_TeachPad[i].ADC_4_offset = 0;
device->RS485_TeachPad[i].ADC_5_offset = 0;
device->RS485_TeachPad[i].enc_raw_offset = 0;
device->RS485_TeachPad[i].enc_position_scale=1;
break;
default:
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR, unknown rs485 module type.\nPlease, download the latest driver.\n");
}
}
break;
default:
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR, unknown rs485 version.\nPlease, download the latest driver.\n");
}
return error;
}
static int
ExportCAN(void *arg, int comp_id, int version)
{
int i, error=0, boardId;
gm_device_t *device = (gm_device_t *)arg;
boardId = device->boardID;
switch (version)
{
case notPresented:
for(i=0;i<6;i++)
{
device->CAN_GM[i].enable = &(device->cardMgr.disable); }
rtapi_print_msg(RTAPI_MSG_WARN, "General Mechatronics: No CAN module available in this version of the Card.\n");
break;
case canVersion1:
for(i=0;i<6;i++)
{
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->CAN_GM[i].enable), comp_id, "gm.%1d.can-gm.%1d.enable", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_IN, &(device->CAN_GM[i].position_cmd), comp_id, "gm.%1d.can-gm.%1d.position-cmd", boardId, i);
if(error == 0) error = hal_pin_float_newf(HAL_OUT, &(device->CAN_GM[i].position_fb), comp_id, "gm.%1d.can-gm.%1d.position-fb", boardId, i);
if(error == 0) error = hal_param_float_newf(HAL_RW, &(device->CAN_GM[i].position_scale), comp_id, "gm.%1d.can-gm.%1d.position-scale", boardId, i);
}
break;
default:
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics: ERROR, unknown encoder version.\nPlease, download the latest driver.\n");
}
return error;
}
static int
ExportMixed(void *arg, int comp_id)
{
int i, j, error=0, boardId;
gm_device_t *device = (gm_device_t *)arg;
boardId = device->boardID;
for(i = 0; i < 6; i++)
{
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->switches[i].home), comp_id, "gm.%1d.axis.%1d.home-sw-in", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->switches[i].homeNot), comp_id, "gm.%1d.axis.%1d.home-sw-in-not", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->switches[i].posLimSwIn), comp_id, "gm.%1d.axis.%1d.pos-lim-sw-in", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->switches[i].posLimSwInNot), comp_id, "gm.%1d.axis.%1d.pos-lim-sw-in-not", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->switches[i].negLimSwIn), comp_id, "gm.%1d.axis.%1d.neg-lim-sw-in", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->switches[i].negLimSwInNot), comp_id, "gm.%1d.axis.%1d.neg-lim-sw-in-not", boardId, i);
}
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->cardMgr.power_enable), comp_id, "gm.%1d.power-enable", boardId);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->cardMgr.power_fault), comp_id, "gm.%1d.power-fault", boardId);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->cardMgr.watchdog_enable), comp_id, "gm.%1d.watchdog-enable", boardId);
if(error == 0) error = hal_param_u32_newf(HAL_RW, &(device->cardMgr.watchdog_timeout_ns), comp_id, "gm.%1d.watchdog-timeout-ns", boardId);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->cardMgr.watchdog_expired), comp_id, "gm.%1d.watchdog-expired", boardId);
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->gpio[i*8+j].in), comp_id, "gm.%1d.gpio.%1d.in-%1d", boardId, i, j);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->gpio[i*8+j].inNot), comp_id, "gm.%1d.gpio.%1d.in-not-%1d", boardId, i, j);
if(error == 0) error = hal_pin_bit_newf(HAL_IN, &(device->gpio[i*8+j].out), comp_id, "gm.%1d.gpio.%1d.out-%1d", boardId, i, j);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->gpio[i*8+j].isOut), comp_id, "gm.%1d.gpio.%1d.is-out-%1d", boardId, i, j);
if(error == 0) error = hal_param_bit_newf(HAL_RW, &(device->gpio[i*8+j].invertOut), comp_id, "gm.%1d.gpio.%1d.invert-out-%1d", boardId, i, j);
}
}
for(i=0;i<2;i++)
{
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->estop[i].in), comp_id, "gm.%1d.estop.%1d.in", boardId, i);
if(error == 0) error = hal_pin_bit_newf(HAL_OUT, &(device->estop[i].inNot), comp_id, "gm.%1d.estop.%1d.in-not", boardId, i);
}
device->cardMgr.cntr = 0;
return error;
}
static int ExportFunctions(void *arg, int comp_id, int boardId)
{
int error;
char str[HAL_NAME_LEN + 1];
gm_device_t *device = (gm_device_t *)arg;
rtapi_snprintf(str, sizeof(str), "gm.%d.write", boardId);
error = hal_export_funct(str, write, device, 1, 0, comp_id);
if(error == 0)
{
rtapi_snprintf(str, sizeof(str), "gm.%d.read", boardId);
error = hal_export_funct(str, read, device, 1, 0, comp_id);
}
if(error == 0)
{
rtapi_snprintf(str, sizeof(str), "gm.%d.RS485", boardId);
error = hal_export_funct(str, RS485, device, 1, 0, comp_id);
}
return error;
}
static void
read(void *arg, long period)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
int i;
hal_u32_t temp;
card_mgr(arg, period);
temp=pCard->gpio;
for(i = 0; i < 32; i++)
{
*(device->gpio[i].in) = (hal_bit_t)((temp & (0x0001 << i)) == 0 ? 0 : 1);
*(device->gpio[i].inNot) = (hal_bit_t)((temp & (0x0001 << i)) == 0 ? 1 : 0);
}
encoder(arg, period);
}
static void
write(void *arg, long period)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
int i, temp1=0, temp2=0;
hal_float_t DAC[6];
hal_u32_t DAC_INTEGER[6];
for(i=0;i<6;i++)
{
if(*(device->axisdac[i].enable))
{
if( (*(device->axisdac[i].value) + device->axisdac[i].offset) > device->axisdac[i].max)
{
DAC[i] = device->axisdac[i].max;
}
else if ( (*(device->axisdac[i].value) + device->axisdac[i].offset) < device->axisdac[i].min)
{
DAC[i] = device->axisdac[i].min;
}
else
{
DAC[i] = (*(device->axisdac[i].value) + device->axisdac[i].offset);
}
}
else
{
DAC[i] = 0;
}
DAC[i] = (DAC[i] * 819.15) + 8191.5;
if(DAC[i] < 0) DAC[i] = 0;
else if (DAC[i] > 16383) DAC[i] = 16383;
DAC_INTEGER[i] = (hal_u32_t)(DAC[i]);
if(device->axisdac[i].invert_serial) DAC_INTEGER[i] |= 0x8000;
}
pCard->DAC_0 = ((DAC_INTEGER[1] & 0xFFFF) << 16) | (DAC_INTEGER[0] & 0xFFFF);
pCard->DAC_1 = ((DAC_INTEGER[3] & 0xFFFF) << 16) | (DAC_INTEGER[2] & 0xFFFF);
pCard->DAC_2 = ((DAC_INTEGER[5] & 0xFFFF) << 16) | (DAC_INTEGER[4] & 0xFFFF);
stepgen(arg, period);
GM_CAN_SERVO(arg);
temp1 = 0;
for(i = 0; i < 32; i++)
{
if(device->gpio[i].isOut) temp1 |= 0x0001 << i; if((*(device->gpio[i].out)) ^ (device->gpio[i].invertOut)) temp2 |= 0x0001 << i; }
pCard->gpioDir=temp1;
pCard->gpio=temp2;
}
static void
GM_CAN_SERVO(void *arg)
{
gm_device_t *device = (gm_device_t *)arg;
hal_u32_t Rx_buf_cntr, Tx_buf_cntr;
hal_u32_t i, temp=0;
hal_s32_t posFb;
CANmsg_t CAN_msg;
for(i=0;i<6;i++){
if(*(device->CAN_GM[i].enable) == 1) temp++;
}
if(temp == 0) return;
CAN_ReadStatus(arg, &Rx_buf_cntr, &Tx_buf_cntr);
for(i=0;i<Rx_buf_cntr;i++)
{
CAN_ReceiveDataFrame(arg, &CAN_msg);
if((CAN_msg.ID >= 0x20) && (CAN_msg.ID <= 0x25))
{
if((device->CAN_GM[CAN_msg.ID - 0x20].position_scale<10e-6) && (device->CAN_GM[CAN_msg.ID - 0x20].position_scale>-10e-6))
{
device->CAN_GM[CAN_msg.ID - 0x20].position_scale = 1;
}
posFb = (CAN_msg.data[3] << 24) | (CAN_msg.data[2] << 16) | (CAN_msg.data[1] << 8) | CAN_msg.data[0];
*(device->CAN_GM[CAN_msg.ID - 0x20].position_fb) = (hal_float_t)posFb / device->CAN_GM[CAN_msg.ID - 0x20].position_scale;
}
}
for(i=0;i<6;i++)
{
if(*(device->CAN_GM[i].enable) == 1)
{
CAN_msg.RTR = 0; CAN_msg.Ext = 0; CAN_msg.DLC = 4; CAN_msg.ID = 0x10 + i;
if((device->CAN_GM[i].position_scale<10e-6) && (device->CAN_GM[i].position_scale>-10e-6))
{
device->CAN_GM[i].position_scale = 1;
}
temp = (hal_u32_t)(*(device->CAN_GM[i].position_cmd) * device->CAN_GM[i].position_scale);
CAN_msg.data[0] = temp & 0xFF;
CAN_msg.data[1] = (temp >> 8) & 0xFF;
CAN_msg.data[2] = (temp >> 16) & 0xFF;
CAN_msg.data[3] = (temp >> 24) & 0xFF;
CAN_msg.data[4] = 0;
CAN_msg.data[5] = 0;
CAN_msg.data[6] = 0;
CAN_msg.data[7] = 0;
CAN_SendDataFrame(arg, &CAN_msg);
}
}
}
static int
CAN_ReadStatus(void *arg, hal_u32_t *RxCnt, hal_u32_t *TxCnt)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
hal_u32_t temp;
temp = pCard->CAN_status_reg;
*TxCnt = temp & 0x3FF;
*RxCnt = (temp >> 10) & 0x3FF;
return (temp >> 20) & 0xFF; }
static void
CAN_ReceiveDataFrame(void *arg, CANmsg_t *Msg)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
hal_u32_t temp;
temp = pCard->CAN_RX_buffer[0];
if(temp & 0x80000000)
{
Msg->Ext = 1;
Msg->ID = temp & 0x1FFFFFFF;
}
else
{
Msg->Ext = 0;
Msg->ID = temp;
}
temp=pCard->CAN_RX_buffer[2];
Msg->data[0] = (temp>>24) & 0xFF;
Msg->data[1] = (temp>>16) & 0xFF;
Msg->data[2] = (temp>>8) & 0xFF;
Msg->data[3] = (temp) & 0xFF;
temp=pCard->CAN_RX_buffer[1];
Msg->data[4] = (temp>>24) & 0xFF;
Msg->data[5] = (temp>>16) & 0xFF;
Msg->data[6] = (temp>>8) & 0xFF;
Msg->data[7] = (temp) & 0xFF;
temp = pCard->CAN_RX_buffer[3];
Msg->DLC = temp & 0xF;
if(temp & 0x10) Msg->RTR = 1;
else Msg->RTR = 0;
}
static void
CAN_SendDataFrame(void *arg, CANmsg_t *Msg)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
hal_u32_t ID;
ID = Msg->ID; if(Msg->Ext) ID |= 0x80000000;
pCard->CAN_TX_buffer[0]=ID;
pCard->CAN_TX_buffer[2] = ((Msg->data[0] & 0xFF) << 24) |((Msg->data[1] & 0xFF) << 16) |((Msg->data[2] & 0xFF) << 8) |((Msg->data[3] & 0xFF) << 0);
if(Msg->DLC > 4) pCard->CAN_TX_buffer[1] = ((Msg->data[4] & 0xFF) << 24) |((Msg->data[5] & 0xFF) << 16) |((Msg->data[6] & 0xFF) << 8) |((Msg->data[7] & 0xFF) << 0);
pCard->CAN_TX_buffer[3] = Msg->DLC;
}
#ifdef CANOPEN
static void
CAN_Reset(void *arg)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
pCard->CAN_TX_buffer[3] = 0x81;
}
static void
CAN_SetBaud(void *arg, hal_u32_t Baud)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
switch(Baud)
{
case 125:
pCard->CAN_TX_buffer[2] = 0x01880700;
pCard->CAN_TX_buffer[3] = 0x82;
break;
case 250:
pCard->CAN_TX_buffer[2] = 0x01880300;
pCard->CAN_TX_buffer[3] = 0x82;
break;
case 500:
pCard->CAN_TX_buffer[2] = 0x01880100;
pCard->CAN_TX_buffer[3] = 0x82;
break;
case 1000:
pCard->CAN_TX_buffer[2] = 0x01880000;
pCard->CAN_TX_buffer[3] = 0x82;
break;
default:
rtapi_print_msg(RTAPI_MSG_ERR, "General Mechatronics:Not valid CAN Baud Rate. Supported: 125,250,500 and 1000 kBit/s.\n");
}
}
#endif
static void
card_mgr(void *arg, long period)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
hal_u32_t temp=0, i, j;
temp = pCard->card_status_reg;
*(device->cardMgr.watchdog_expired) = (hal_bit_t)((temp & (0x0001 << 0)) == 0 ? 0 : 1);
*(device->cardMgr.power_fault) = (hal_bit_t)((temp & (0x0001 << 2)) == 0 ? 0 : 1);
*(device->estop[0].in) = (hal_bit_t)((temp & (0x0001 << 3)) == 0 ? 0 : 1);
*(device->estop[0].inNot) = (hal_bit_t)((temp & (0x0001 << 3)) == 0 ? 1 : 0);
*(device->estop[1].in) = (hal_bit_t)((temp & (0x0001 << 4)) == 0 ? 0 : 1);
*(device->estop[1].inNot) = (hal_bit_t)((temp & (0x0001 << 4)) == 0 ? 1 : 0);
for(i=5, j=0; i<11; i++,j++)
{
*(device->switches[j].home) = (hal_bit_t)((temp & (0x0001 << i)) == 0 ? 0 : 1);
*(device->switches[j].homeNot) = (hal_bit_t)((temp & (0x0001 << i)) == 0 ? 1 : 0);
}
for(j=0;i<17;i++,j++){
*(device->switches[j].posLimSwIn) = (hal_bit_t)((temp & (0x0001 << i)) == 0 ? 0 : 1);
*(device->switches[j].posLimSwInNot) = (hal_bit_t)((temp & (0x0001 << i)) == 0 ? 1 : 0);
}
for(j=0;i<23;i++,j++){
*(device->switches[j].negLimSwIn) = (hal_bit_t)((temp & (0x0001 << i)) == 0 ? 0 : 1);
*(device->switches[j].negLimSwInNot) = (hal_bit_t)((temp & (0x0001 << i)) == 0 ? 1 : 0);
}
temp = 1; if(*(device->cardMgr.power_enable)) temp |= (0x0001 << 1);
if(device->cardMgr.watchdog_enable) {
if(device->cardMgr.watchdog_timeout_ns < 256) temp |= 0x100;
else temp |= (device->cardMgr.watchdog_timeout_ns & 0xFFFFFF00);
}
if(temp != device->cardMgr.card_control_reg)
{
device->cardMgr.card_control_reg = temp;
pCard->card_control_reg = temp;
}
if(device->cardMgr.cntr < 17)
{
if(device->cardMgr.cntr == 0) device->cardMgr.dbg_PCI_counter_last = pCard->PCI_clk_counter;
else if(device->cardMgr.cntr == 16)
{
temp = rtapi_get_msg_level();
rtapi_set_msg_level(RTAPI_MSG_ALL);
rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: PCI clk frequency is %d khz.\n",
(int)((hal_float_t)(pCard->PCI_clk_counter - device->cardMgr.dbg_PCI_counter_last)/period*62500)); rtapi_set_msg_level(temp);
}
device->cardMgr.cntr++;
}
}
static void
encoder(void *arg, long period)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
int i;
hal_s32_t temp1 = 0, temp2;
hal_float_t vel;
for(i=0; i<6; i++)
{
if(device->encoder[i].index_invert == 1) temp1 |= (0x1 << i);
if(device->encoder[i].counter_mode == 1) temp1 |= (0x1 << (i+6));
}
pCard->ENC_control_reg = temp1;
for(i = 0; i < 6; i++)
if(device->encoder[i].module_exist)
{
temp1 = pCard->ENC_counter[i];
temp2 = pCard->ENC_index_latch[i];
if(*(device->encoder[i].reset) == 1) {
device->encoder[i].index_offset = temp1;
}
else if(*(device->encoder[i].index_enable) == 1) {
if (temp2 != device->encoder[i].last_index_latch) {
if(device->encoder[i].index_mode == 0) {
device->encoder[i].index_offset = temp2;
*(device->encoder[i].index_enable) = 0; }
else {
if(device->encoder[i].first_index == 1) {
device->encoder[i].first_index = 0;
}
else
{
if(temp2 > (device->encoder[i].last_index_latch + (hal_s32_t)(device->encoder[i].counts_per_rev/4)))
{
device->encoder[i].index_offset -= device->encoder[i].last_index_latch + device->encoder[i].counts_per_rev - temp2;
}
else if(temp2 < (device->encoder[i].last_index_latch - (hal_s32_t)(device->encoder[i].counts_per_rev/4)))
{
device->encoder[i].index_offset -= device->encoder[i].last_index_latch - device->encoder[i].counts_per_rev - temp2;
}
else
{
device->encoder[i].index_offset -= device->encoder[i].last_index_latch - temp2;
}
}
}
}
}
device->encoder[i].last_index_latch = temp2;
*(device->encoder[i].rawcounts) = temp1 - device->encoder[i].raw_offset;
*(device->encoder[i].counts) = *(device->encoder[i].rawcounts) - device->encoder[i].index_offset;
if((device->encoder[i].position_scale < 0.000001) && (device->encoder[i].position_scale > -0.000001)) device->encoder[i].position_scale = 1; *(device->encoder[i].position) = (hal_float_t) *(device->encoder[i].counts) / device->encoder[i].position_scale;
vel = (hal_float_t) pCard->ENC_period[i];
if(vel == 0) vel = 1;
vel = 33333333 / ( vel * device->encoder[i].position_scale);
if(fabs(vel) > device->encoder[i].min_speed_estimate)
{
*(device->encoder[i].velocity) = vel;
}
else
{
*(device->encoder[i].velocity) = 0;
}
}
}
static void
stepgen(void *arg, long period)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
int i;
for(i=0;i<6;i++)
{
if(*(device->stepgen[i].enable) == 1) device->stepgen_status |= (0x1 << i); else
{
device->stepgen_status &= ~(0x1 << i); pCard->StepGen_steprate[i] = 0;
}
}
for(i=0;i<6;i++)
{
if(*(device->stepgen[i].enable) == 1)
{
stepgenCheckParameters(arg, period, i);
}
}
pCard->StepGen_status = device->stepgen_status;
for(i=0;i<6;i++)
{
if(*(device->stepgen[i].enable) == 1)
{
stepgenControl(arg, period, i);
}
}
for(i=0;i<6;i++)
{
device->stepgen[i].old_pos_cmd = *(device->stepgen[i].position_cmd);
}
}
static void
stepgenCheckParameters(void *arg, long period, unsigned int channel)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
hal_u32_t temp1, temp2;
hal_float_t min_period, max_vel;
if(device->period_ns != period)
{
device->period_s = period * 0.000000001;
device->rec_period_s = 1.0/device->period_s;
}
if(device->stepgen[channel].curr_position_scale != device->stepgen[channel].position_scale)
{
device->stepgen[channel].steprate_scale = device->stepgen[channel].position_scale * 30.0 / 1000000000.0 * 4294967296.0;
}
if((device->stepgen[channel].steplen != device->stepgen[channel].curr_steplen) || (device->stepgen[channel].stepspace != device->stepgen[channel].curr_stepspace) ||
(device->stepgen[channel].maxvel != device->stepgen[channel].curr_maxvel) || (device->stepgen[channel].curr_position_scale != device->stepgen[channel].position_scale))
{
min_period = (device->stepgen[channel].steplen + device->stepgen[channel].stepspace) * 0.000000001;
max_vel = 1/((hal_float_t)min_period * fabs(device->stepgen[channel].position_scale));
if(device->stepgen[channel].maxvel <= 0)
{
device->stepgen[channel].maxvel = max_vel;
}
else
{
if(max_vel < device->stepgen[channel].maxvel) {
device->stepgen[channel].maxvel = max_vel;
rtapi_print_msg(RTAPI_MSG_ERR, "GM: stepgen.%d.maxvel can not be reached with given 'steplen' and 'stepspace' parameters.\n", channel);
}
}
}
if((device->stepgen[channel].steplen != device->stepgen[channel].curr_steplen) || (device->stepgen[channel].dirdelay != device->stepgen[channel].curr_dirdelay))
{
temp1= (device->stepgen[channel].steplen <= 1900000) ? (device->stepgen[channel].steplen/30) : 63333;
temp2= (device->stepgen[channel].dirdelay <= 1900000) ? (device->stepgen[channel].dirdelay/30) : 63333;
if((device->stepgen[channel].steplen > 1900000) || (device->stepgen[channel].dirdelay > 1900000))
{
rtapi_print_msg(RTAPI_MSG_ERR, "GM: stepgen: 'steplen' and 'dirdelay' must be lower than 1 900 000 ns.\n");
}
pCard->StepGen_time_params[channel] = (temp1 << 16) | (temp2 & 0xFFFF);
}
if (*(device->stepgen[channel].enable) == 1) device->stepgen_status |= (0x1 << channel); else device->stepgen_status &= ~(0x1 << channel);
if (device->stepgen[channel].step_type == 1) device->stepgen_status |= (0x1 << (channel + 6)); else device->stepgen_status &= ~(0x1 << (channel + 6));
if (device->stepgen[channel].step_type == 2) device->stepgen_status |= (0x1 << (channel + 12));
else device->stepgen_status &= ~(0x1 << (channel + 12));
if (device->stepgen[channel].polarity_A == 1) device->stepgen_status |= (0x1 << (channel + 18)); else device->stepgen_status &= ~(0x1 << (channel + 18));
if (device->stepgen[channel].polarity_B == 1) device->stepgen_status |= (0x1 << (channel + 24)); else device->stepgen_status &= ~(0x1 << (channel + 24));
pCard->StepGen_status = device->stepgen_status;
if((device->stepgen[channel].maxvel != device->stepgen[channel].curr_maxvel) || (device->stepgen[channel].maxaccel != device->stepgen[channel].curr_maxaccel) || (device->period_ns != period))
{
if(device->stepgen[channel].maxaccel <= 1e-20)
{
device->stepgen[channel].maxaccel = device->stepgen[channel].maxvel * device->rec_period_s;
device->stepgen[channel].max_dv = device->stepgen[channel].maxvel;
}
else
{
device->stepgen[channel].max_dv = device->stepgen[channel].maxaccel * device->period_s; }
}
device->period_ns = period;
device->stepgen[channel].curr_position_scale = device->stepgen[channel].position_scale;
device->stepgen[channel].curr_stepspace = device->stepgen[channel].stepspace;
device->stepgen[channel].curr_maxvel = device->stepgen[channel].maxvel;
device->stepgen[channel].curr_maxaccel = device->stepgen[channel].maxaccel;
device->stepgen[channel].curr_steplen = device->stepgen[channel].steplen;
device->stepgen[channel].curr_dirdelay= device->stepgen[channel].dirdelay;
}
static void
stepgenControl(void *arg, long period, unsigned int channel)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
hal_s32_t stepgen_fb, stepgen_fb_int, last_count_fb_LS16_bits, last_count_fb_MS16_bits, last_count_fb;
hal_float_t ref_vel, match_acc, match_time, avg_v, est_out, est_cmd, est_err, dp;
stepgen_fb = pCard->StepGen_fb[channel]; stepgen_fb -= device->stepgen[channel].stepgen_fb_offset;
stepgen_fb_int= stepgen_fb >> 16;
last_count_fb = *(device->stepgen[channel].count_fb);
last_count_fb_LS16_bits = last_count_fb & 0xFFFF;
last_count_fb_MS16_bits = last_count_fb & 0xFFFF0000;
if(stepgen_fb_int > last_count_fb_LS16_bits + 32768) {
*(device->stepgen[channel].count_fb) = (last_count_fb_MS16_bits + stepgen_fb_int - 65536);
}
else if (stepgen_fb_int + 32768 < last_count_fb_LS16_bits) {
*(device->stepgen[channel].count_fb) = (last_count_fb_MS16_bits + stepgen_fb_int + 65536);
}
else {
*(device->stepgen[channel].count_fb) = (last_count_fb_MS16_bits + stepgen_fb_int);
}
*(device->stepgen[channel].position_fb) = (*(device->stepgen[channel].count_fb) + ((hal_float_t)(stepgen_fb & 0xFFFF))/65536)/device->stepgen[channel].position_scale;
if(device->stepgen[channel].control_type == 1)
{
ref_vel = *(device->stepgen[channel].velocity_cmd);
}
else if(device->stepgen[channel].control_type == 0)
{
ref_vel = (*(device->stepgen[channel].position_cmd) - device->stepgen[channel].old_pos_cmd) * device->rec_period_s;
if(ref_vel > device->stepgen[channel].old_vel)
{
match_acc = device->stepgen[channel].maxaccel;
}
else
{
match_acc = -device->stepgen[channel].maxaccel;
}
match_time = (ref_vel - device->stepgen[channel].old_vel) / match_acc;
avg_v = (ref_vel + device->stepgen[channel].old_vel) * 0.5;
est_out = *(device->stepgen[channel].position_fb) + avg_v * match_time;;
est_cmd = *(device->stepgen[channel].position_cmd) + ref_vel * (match_time - 1.5 * device->period_s);
est_err = est_out - est_cmd;
if(match_time < device->period_s)
{
if(fabs(est_err) > 0.0001) {
ref_vel -= 0.5 * est_err * device->rec_period_s;
}
}
else
{
dp = -2.0 * match_acc * device->period_s * match_time;
if(fabs(est_err + dp*2.0) < fabs(est_err))
{
match_acc = -match_acc;
}
ref_vel = device->stepgen[channel].old_vel + match_acc * device->period_s;
}
}
if(ref_vel > device->stepgen[channel].maxvel) ref_vel = device->stepgen[channel].maxvel;
else if(ref_vel < -device->stepgen[channel].maxvel) ref_vel = -device->stepgen[channel].maxvel;
if((device->stepgen[channel].old_vel-ref_vel) > device->stepgen[channel].max_dv)
{
ref_vel=device->stepgen[channel].old_vel-device->stepgen[channel].max_dv;
}
else if((device->stepgen[channel].old_vel-ref_vel) < -device->stepgen[channel].max_dv)
{
ref_vel=device->stepgen[channel].old_vel+device->stepgen[channel].max_dv;
}
device->stepgen[channel].old_vel=ref_vel;
pCard->StepGen_steprate[channel] = (hal_s32_t)(ref_vel * device->stepgen[channel].steprate_scale);
}
static void
RS485(void *arg, long period)
{
gm_device_t *device = (gm_device_t *)arg;
card *pCard = device->pCard;
unsigned int i, j;
hal_float_t temp;
hal_u32_t temp_u32;
bool data_wr = 0;
static hal_bit_t failed=0;
hal_u32_t RS485DataIn8[32], RS485DataOut32[8];
hal_u32_t RS485DataIn32[8], RS485DataOut8[32];
for(i=0; i<8; i++)
{
temp_u32=(hal_u32_t)pCard->moduleId[i];
if(((temp_u32 & 0xff)^0xaa) == ((temp_u32 & 0xff00)>>8))
{
if((device-> RS485_mgr.ID[2*i]) != ((temp_u32 >> 8) & 0xff))
{
if(failed == 0) {
failed=1;
rtapi_print_msg(RTAPI_MSG_ERR, "GM: ERROR: RS485 module ID:%2d failed.\n", 2*i);
}
*(device->cardMgr.power_fault) = 1;
}
}
if(((temp_u32 & 0xff0000)^0xaa0000) == ((temp_u32 & 0xff000000)>>8))
{
if((device-> RS485_mgr.ID[2*i+1]) != ((temp_u32 & 0xff000000)>>24))
{
if(failed == 0) {
failed=1;
rtapi_print_msg(RTAPI_MSG_ERR, "GM: ERROR: RS485 module ID:%2d failed.\n", 2*i+1);
}
*(device->cardMgr.power_fault) = 1;
}
}
}
for(i=0;i<16;i++) if((device-> RS485_mgr.ID[i] != 0) && (device-> RS485_mgr.BYTES_TO_READ[i] != 0)) {
if(i != 0) *(&(pCard->serialModulesDataIn[i-1][7]));
else *(&(pCard->serialModulesDataOut[15][7]));
for(j=0; j<8; j++) RS485DataIn32[j]= (hal_u32_t)pCard->serialModulesDataIn[i][j];
RS485_OrderDataRead(RS485DataIn32, RS485DataOut8, device-> RS485_mgr.BYTES_TO_READ[i]);
if(RS485_CheckChecksum(RS485DataOut8, device-> RS485_mgr.BYTES_TO_READ[i]) == 0)
{
switch (device-> RS485_mgr.ID[i])
{
case RS485MODUL_ID_8INPUT:
*(device->RS485_8input[i].in_0) = ((hal_bit_t)(RS485DataOut8[0] & 0x1) ? 1 : 0);
*(device->RS485_8input[i].inNot_0) = (hal_bit_t)(RS485DataOut8[0] & 0x1) ? 0 : 1;
*(device->RS485_8input[i].in_1) = (hal_bit_t)((RS485DataOut8[0] >> 1) & 0x1) ? 1 : 0;
*(device->RS485_8input[i].inNot_1) = (hal_bit_t)((RS485DataOut8[0] >> 1) & 0x1) ? 0 : 1;
*(device->RS485_8input[i].in_2) = (hal_bit_t)((RS485DataOut8[0] >> 2) & 0x1) ? 1 : 0;
*(device->RS485_8input[i].inNot_2) = (hal_bit_t)((RS485DataOut8[0] >> 2) & 0x1) ? 0 : 1;
*(device->RS485_8input[i].in_3) = (hal_bit_t)((RS485DataOut8[0] >> 3) & 0x1) ? 1 : 0;
*(device->RS485_8input[i].inNot_3) = (hal_bit_t)((RS485DataOut8[0] >> 3) & 0x1) ? 0 : 1;
*(device->RS485_8input[i].in_4) = (hal_bit_t)((RS485DataOut8[0] >> 4) & 0x1) ? 1 : 0;
*(device->RS485_8input[i].inNot_4) = (hal_bit_t)((RS485DataOut8[0] >> 4) & 0x1) ? 0 : 1;
*(device->RS485_8input[i].in_5) = (hal_bit_t)((RS485DataOut8[0] >> 5) & 0x1) ? 1 : 0;
*(device->RS485_8input[i].inNot_5) = (hal_bit_t)((RS485DataOut8[0] >> 5) & 0x1) ? 0 : 1;
*(device->RS485_8input[i].in_6) = (hal_bit_t)((RS485DataOut8[0] >> 6) & 0x1) ? 1 : 0;
*(device->RS485_8input[i].inNot_6) = (hal_bit_t)((RS485DataOut8[0] >> 6) & 0x1) ? 0 : 1;
*(device->RS485_8input[i].in_7) = (hal_bit_t)((RS485DataOut8[0] >> 7) & 0x1) ? 1 : 0;
*(device->RS485_8input[i].inNot_7) = (hal_bit_t)((RS485DataOut8[0] >> 7) & 0x1) ? 0 : 1;
break;
case RS485MODUL_ID_DACADC:
*(device->RS485_DacAdc[i].ADC_0) = (((hal_float_t)RS485DataOut8[0])/25.5-5) * device->RS485_DacAdc[i].ADC_0_scale - device->RS485_DacAdc[i].ADC_0_offset;
*(device->RS485_DacAdc[i].ADC_1) = (((hal_float_t)RS485DataOut8[1])/25.5-5) * device->RS485_DacAdc[i].ADC_1_scale - device->RS485_DacAdc[i].ADC_1_offset;
*(device->RS485_DacAdc[i].ADC_2) = (((hal_float_t)RS485DataOut8[2])/25.5-5) * device->RS485_DacAdc[i].ADC_2_scale - device->RS485_DacAdc[i].ADC_2_offset;
*(device->RS485_DacAdc[i].ADC_3) = (((hal_float_t)RS485DataOut8[3])/25.5-5) * device->RS485_DacAdc[i].ADC_3_scale - device->RS485_DacAdc[i].ADC_3_offset;
*(device->RS485_DacAdc[i].ADC_4) = (((hal_float_t)RS485DataOut8[4])/25.5-5) * device->RS485_DacAdc[i].ADC_4_scale - device->RS485_DacAdc[i].ADC_4_offset;
*(device->RS485_DacAdc[i].ADC_5) = (((hal_float_t)RS485DataOut8[5])/25.5-5) * device->RS485_DacAdc[i].ADC_5_scale - device->RS485_DacAdc[i].ADC_5_offset;
*(device->RS485_DacAdc[i].ADC_6) = (((hal_float_t)RS485DataOut8[6])/25.5-5) * device->RS485_DacAdc[i].ADC_6_scale - device->RS485_DacAdc[i].ADC_6_offset;
*(device->RS485_DacAdc[i].ADC_7) = (((hal_float_t)RS485DataOut8[7])/25.5-5) * device->RS485_DacAdc[i].ADC_7_scale - device->RS485_DacAdc[i].ADC_7_offset;
break;
case RS485MODUL_ID_TEACHPAD:
*(device->RS485_TeachPad[i].in_0) = ((hal_bit_t)(RS485DataOut8[0] & 0x1) ? 1 : 0);
*(device->RS485_TeachPad[i].inNot_0) = (hal_bit_t)(RS485DataOut8[0] & 0x1) ? 0 : 1;
*(device->RS485_TeachPad[i].in_1) = (hal_bit_t)((RS485DataOut8[0] >> 1) & 0x1) ? 1 : 0;
*(device->RS485_TeachPad[i].inNot_1) = (hal_bit_t)((RS485DataOut8[0] >> 1) & 0x1) ? 0 : 1;
*(device->RS485_TeachPad[i].in_2) = (hal_bit_t)((RS485DataOut8[0] >> 2) & 0x1) ? 1 : 0;
*(device->RS485_TeachPad[i].inNot_2) = (hal_bit_t)((RS485DataOut8[0] >> 2) & 0x1) ? 0 : 1;
*(device->RS485_TeachPad[i].in_3) = (hal_bit_t)((RS485DataOut8[0] >> 3) & 0x1) ? 1 : 0;
*(device->RS485_TeachPad[i].inNot_3) = (hal_bit_t)((RS485DataOut8[0] >> 3) & 0x1) ? 0 : 1;
*(device->RS485_TeachPad[i].in_4) = (hal_bit_t)((RS485DataOut8[0] >> 4) & 0x1) ? 1 : 0;
*(device->RS485_TeachPad[i].inNot_4) = (hal_bit_t)((RS485DataOut8[0] >> 4) & 0x1) ? 0 : 1;
*(device->RS485_TeachPad[i].in_5) = (hal_bit_t)((RS485DataOut8[0] >> 5) & 0x1) ? 1 : 0;
*(device->RS485_TeachPad[i].inNot_5) = (hal_bit_t)((RS485DataOut8[0] >> 5) & 0x1) ? 0 : 1;
*(device->RS485_TeachPad[i].in_6) = (hal_bit_t)((RS485DataOut8[0] >> 6) & 0x1) ? 1 : 0;
*(device->RS485_TeachPad[i].inNot_6) = (hal_bit_t)((RS485DataOut8[0] >> 6) & 0x1) ? 0 : 1;
*(device->RS485_TeachPad[i].in_7) = (hal_bit_t)((RS485DataOut8[0] >> 7) & 0x1) ? 1 : 0;
*(device->RS485_TeachPad[i].inNot_7) = (hal_bit_t)((RS485DataOut8[0] >> 7) & 0x1) ? 0 : 1;
*(device->RS485_TeachPad[i].ADC_0) = (hal_float_t)RS485DataOut8[1]/51.2 * device->RS485_TeachPad[i].ADC_0_scale - device->RS485_TeachPad[i].ADC_0_offset;
*(device->RS485_TeachPad[i].ADC_1) = (hal_float_t)RS485DataOut8[2]/51.2 * device->RS485_TeachPad[i].ADC_1_scale - device->RS485_TeachPad[i].ADC_1_offset;
*(device->RS485_TeachPad[i].ADC_2) = (hal_float_t)RS485DataOut8[3]/51.2 * device->RS485_TeachPad[i].ADC_2_scale - device->RS485_TeachPad[i].ADC_2_offset;
*(device->RS485_TeachPad[i].ADC_3) = (hal_float_t)RS485DataOut8[4]/51.2 * device->RS485_TeachPad[i].ADC_3_scale - device->RS485_TeachPad[i].ADC_3_offset;
*(device->RS485_TeachPad[i].ADC_4) = (hal_float_t)RS485DataOut8[5]/51.2 * device->RS485_TeachPad[i].ADC_4_scale - device->RS485_TeachPad[i].ADC_4_offset;
*(device->RS485_TeachPad[i].ADC_5) = (hal_float_t)RS485DataOut8[6]/51.2 * device->RS485_TeachPad[i].ADC_5_scale - device->RS485_TeachPad[i].ADC_5_offset;
*(device->RS485_TeachPad[i].enc_rawcounts)= (RS485DataOut8[7] & 0xff) | ((RS485DataOut8[8] & 0xff) << 8) | ((RS485DataOut8[9] & 0xff) << 16) | (RS485DataOut8[10] << 24);
if(*(device->RS485_TeachPad[i].enc_reset))
{
device->RS485_TeachPad[i].enc_raw_offset = *(device->RS485_TeachPad[i].enc_rawcounts);
}
*(device->RS485_TeachPad[i].enc_counts) = *(device->RS485_TeachPad[i].enc_rawcounts) - device->RS485_TeachPad[i].enc_raw_offset;
if((device->RS485_TeachPad[i].enc_position_scale < 0.000001) && (device->RS485_TeachPad[i].enc_position_scale > -0.000001)) device->RS485_TeachPad[i].enc_position_scale=1;
*(device->RS485_TeachPad[i].enc_position) = *(device->RS485_TeachPad[i].enc_counts) / device->RS485_TeachPad[i].enc_position_scale;
default:
break;
}
}
}
for(i=0;i<16;i++) if((device-> RS485_mgr.ID[i] != 0) && (device-> RS485_mgr.BYTES_TO_WRITE[i] != 0)) {
switch (device-> RS485_mgr.ID[i])
{
case RS485MODUL_ID_8OUTPUT:
RS485DataIn8[0]=((*(device->RS485_8output[i].out_7) ^ (device->RS485_8output[i].invertOut_7)) << 7) |
((*(device->RS485_8output[i].out_6) ^ (device->RS485_8output[i].invertOut_6)) << 6) |
((*(device->RS485_8output[i].out_5) ^ (device->RS485_8output[i].invertOut_5)) << 5) |
((*(device->RS485_8output[i].out_4) ^ (device->RS485_8output[i].invertOut_4)) << 4) |
((*(device->RS485_8output[i].out_3) ^ (device->RS485_8output[i].invertOut_3)) << 3) |
((*(device->RS485_8output[i].out_2) ^ (device->RS485_8output[i].invertOut_2)) << 2) |
((*(device->RS485_8output[i].out_1) ^ (device->RS485_8output[i].invertOut_1)) << 1) |
((*(device->RS485_8output[i].out_0) ^ (device->RS485_8output[i].invertOut_0)) << 0);
break;
case RS485MODUL_ID_DACADC:
if(*(device->RS485_DacAdc[i].dac_0_enable))
{
temp = *(device->RS485_DacAdc[i].DAC_0)+ device->RS485_DacAdc[i].DAC_0_offset;
if(temp > device->RS485_DacAdc[i].DAC_0_max) { temp = device->RS485_DacAdc[i].DAC_0_max; }
else if(temp < device->RS485_DacAdc[i].DAC_0_min) { temp = device->RS485_DacAdc[i].DAC_0_min; }
temp = (temp + 10)*12.8 + 0.5;
}
else temp=128;
if(temp>255) temp=255;
else if(temp <0) temp=0;
RS485DataIn8[0]= (hal_u32_t)temp;
if(*(device->RS485_DacAdc[i].dac_1_enable))
{
temp = *(device->RS485_DacAdc[i].DAC_1)+ device->RS485_DacAdc[i].DAC_1_offset;
if(temp > device->RS485_DacAdc[i].DAC_1_max) { temp = device->RS485_DacAdc[i].DAC_1_max; }
else if(temp < device->RS485_DacAdc[i].DAC_1_min) { temp = device->RS485_DacAdc[i].DAC_1_min; }
temp = (temp + 10)*12.8 + 0.5;
}
else temp=128;
if(temp>255) temp=255;
else if(temp <0) temp=0;
RS485DataIn8[1]= (hal_u32_t)temp;
if(*(device->RS485_DacAdc[i].dac_2_enable))
{
temp = *(device->RS485_DacAdc[i].DAC_2)+ device->RS485_DacAdc[i].DAC_2_offset;
if(temp > device->RS485_DacAdc[i].DAC_2_max) { temp = device->RS485_DacAdc[i].DAC_2_max; }
else if(temp < device->RS485_DacAdc[i].DAC_2_min) { temp = device->RS485_DacAdc[i].DAC_2_min; }
temp = (temp + 10)*12.8 + 0.5;
}
else temp=128;
if(temp>255) temp=255;
else if(temp <0) temp=0;
RS485DataIn8[2]= (hal_u32_t)temp;
if(*(device->RS485_DacAdc[i].dac_3_enable))
{
temp = *(device->RS485_DacAdc[i].DAC_3)+ device->RS485_DacAdc[i].DAC_3_offset;
if(temp > device->RS485_DacAdc[i].DAC_3_max) { temp = device->RS485_DacAdc[i].DAC_3_max; }
else if(temp < device->RS485_DacAdc[i].DAC_3_min) { temp = device->RS485_DacAdc[i].DAC_3_min; }
temp = (temp + 10)*12.8 + 0.5;
}
else temp=128;
if(temp>255) temp=255;
else if(temp <0) temp=0;
RS485DataIn8[3]= (hal_u32_t)temp;
break;
default:
break;
}
RS485DataIn8[device-> RS485_mgr.BYTES_TO_WRITE[i]-1]=RS485_CalcChecksum(RS485DataIn8, device-> RS485_mgr.BYTES_TO_WRITE[i] - 1);
RS485_OrderDataWrite(RS485DataIn8, RS485DataOut32, device-> RS485_mgr.BYTES_TO_WRITE[i]); for(j=7;(7-j) < ((unsigned int)(device-> RS485_mgr.BYTES_TO_WRITE[i]-1)/4) + 1;j--)
{
*(&(pCard->serialModulesDataOut[i][j])) = RS485DataOut32[j];
}
data_wr=1;
}
if(data_wr == 0) *(&(pCard->serialModulesDataOut[0][0])) = 0;
}
static void
RS485_OrderDataRead(hal_u32_t* dataIn32, hal_u32_t* dataOut8, hal_u32_t length)
{
int i, j;
if(length > 0 && length < 32)
for(i=length-1; i>=0; i--)
{
j = length-1-i;
dataOut8[i]= (dataIn32[(unsigned int)(j/4)] >> ((j%4)*8)) & 0xff;
}
}
static void
RS485_OrderDataWrite(hal_u32_t* dataIn8, hal_u32_t* dataOut32, hal_u32_t length)
{
int i, j;
for(i=0;i<length;i+=4)
{
j=7-(i >> 2); dataOut32[j]=(dataIn8[i+3] & 0xff) | ((dataIn8[i+2] & 0xff) << 8) | ((dataIn8[i+1] & 0xff) << 16) | (dataIn8[i] << 24);
}
}
static unsigned int
RS485_CheckChecksum(hal_u32_t* data, hal_u32_t length)
{
unsigned int i=0, tempChecksum=0;
if(length > 0 && length < 32)
for(i=0; i < length-1; i++)
{
tempChecksum += data[i];
}
if((data[i] ^ 0xaa) == (tempChecksum & 0xff)) return 0;
return -1;
}
static unsigned int
RS485_CalcChecksum(hal_u32_t* data, hal_u32_t length)
{
unsigned int i, tempChecksum=0;
if(length > 0 && length < 32)
for(i=0; i < length; i++)
{
tempChecksum += data[i];
}
return (tempChecksum & 0xff) ^ 0xaa;
}