From: Bence K. <gi...@gi...> - 2012-10-27 07:13:25
|
Add General Mechatronics 6 axis motion control card driver. Makefiles were modified in order to compile the driver with LinuxCNC. http://git.linuxcnc.org/?p=linuxcnc.git;a=commitdiff;h=1764a19 --- src/Makefile | 3 + src/Makefile.inc.in | 1 + src/hal/drivers/gm.h | 82 +++ src/hal/drivers/hal_gm.c | 1830 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1916 insertions(+) diff --git a/src/Makefile b/src/Makefile index b8d2fe7..39711c7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -727,6 +727,8 @@ obj-$(CONFIG_HAL_SKELETON) += hal_skeleton.o hal_skeleton-objs := hal/drivers/hal_skeleton.o $(MATHSTUB) obj-$(CONFIG_OPTO_AC5) += opto_ac5.o opto_ac5-objs := hal/drivers/opto_ac5.o $(MATHSTUB) +obj-$(CONFIG_HAL_GM) += hal_gm.o +hal_gm-objs := hal/drivers/hal_gm.o $(MATHSTUB) obj-$(CONFIG_HOSTMOT2) += hostmot2.o hm2_7i43.o hm2_pci.o hm2_test.o hostmot2-objs := \ @@ -939,6 +941,7 @@ endif ../rtlib/genserkins$(MODULE_EXT): $(addprefix objects/rt,$(genserkins-objs)) ../rtlib/pumakins$(MODULE_EXT): $(addprefix objects/rt,$(pumakins-objs)) ../rtlib/scarakins$(MODULE_EXT): $(addprefix objects/rt,$(scarakins-objs)) +../rtlib/hal_gm$(MODULE_EXT): $(addprefix objects/rt,$(hal_gm-objs)) ifeq ($(TRIVIAL_BUILD),no) RTDEPS := $(sort $(patsubst objects/%.o,depends/%.d,$(RTOBJS))) diff --git a/src/Makefile.inc.in b/src/Makefile.inc.in index 3327247..e7d99bc 100644 --- a/src/Makefile.inc.in +++ b/src/Makefile.inc.in @@ -209,6 +209,7 @@ CONFIG_HAL_PPMC=m CONFIG_PCI_8255=m CONFIG_HOSTMOT2=m CONFIG_OPTO_AC5=m +CONFIG_HAL_GM=m BUILD_PYTHON=@BUILD_PYTHON@ INCLUDEPY=@INCLUDEPY@ diff --git a/src/hal/drivers/gm.h b/src/hal/drivers/gm.h new file mode 100644 index 0000000..06716c7 --- /dev/null +++ b/src/hal/drivers/gm.h @@ -0,0 +1,82 @@ +#ifndef GM_H_ +#define GM_H_ + +#include "hal.h" + + +#define PLX_VENDOR_ID 0x10B5 //PLX Vendor ID +#define GM_DEVICE_ID 0x6ACC //GM 6 Axis Control Card, www.pcidatabase.com + +#define MAX_GM_DEVICES 3 + +#define RS485MODUL_ID_8INPUT 0x1 +#define RS485MODUL_ID_8OUTPUT 0x2 +#define RS485MODUL_ID_DACADC 0x3 + +#define IDmask_card 0xF0000000 +#define cardVersion1 0x10000000 +#define IDmask_can 0x000F0000 +#define canVersion1 0x00010000 +#define IDmask_rs485 0x0000F000 +#define rs485Version1 0x00001000 +#define IDmask_dac 0x00000F00 +#define dacVersion1 0x00000100 +#define IDmask_stepgen 0x000000F0 +#define stepgenVersion1 0x00000010 +#define IDmask_encoder 0x0000000F +#define encoderVersion1 0x00000001 +#define notPresented 0x00000000 + +typedef struct { + hal_u32_t serialModulesDataOut[16][8]; // 0000 0000 + hal_u32_t serialModulesDataIn[16][8]; // 1000 0000 + + hal_u32_t moduleId[8]; //addr 0 0000 000 + + hal_u32_t card_status_reg; //addr 1 0001 000 // ... Estop_2 | Estop_1 | Pwr_fault | Bus_err | Wdt_err //Card status read resets wdt + hal_u32_t cardID; // 0001 001 + hal_u32_t card_control_reg; // 0001 010 // Wdt_period(16 bit)[us] | ... | EstopEn_2 | EstopEn_1 | power_enable | card_enable + hal_u32_t reserved_0; // 0001 011 + hal_u32_t gpio; // 0001 100 + hal_u32_t gpioDir; // 0001 101 + hal_u32_t StepGen_status; // 0001 110 + hal_u32_t PCI_clk_counter; // 0001 111 + + hal_u32_t ENC_control_reg; //addr 2 0010 000 + hal_u32_t CAN_status_reg; + hal_u32_t CAN_control_reg; + hal_u32_t DAC_0; //DAC AXIS 3-0 + hal_u32_t DAC_1; //DAC AXIS 5-4 + hal_u32_t reserved_1[3]; + + hal_u32_t CAN_RX_buffer[4]; //addr 3 0011 000 + hal_u32_t CAN_TX_buffer[4]; + hal_u32_t reserved_2[8]; //addr 4 0100 000 + + hal_u32_t reserved_3[8]; //addr 5 0101 000 + + hal_u32_t reserved_4[8]; //addr 6 0110 000 + + hal_u32_t reserved_5[8]; //addr 7 0111 000 + + hal_s32_t ENC_counter[6]; //addr 8 1000 000 + hal_u32_t reserved_6[2]; + hal_s32_t ENC_period[6]; //addr 9 1001 000 + hal_u32_t reserved_7[2]; + hal_s32_t ENC_index_latch[6]; //addr 10 1010 000 + hal_u32_t reserved_8[2]; + hal_s32_t reserved_9[8]; //addr 11 1011 000 + + hal_s32_t StepGen_steprate[6]; //addr 12 1100 000 + hal_u32_t reserved_10[2]; + hal_u32_t StepGen_fb[6]; //addr 13 1101 000 + hal_u32_t reserved_11[2]; + hal_u32_t StepGen_time_params[6]; //addr 14 1110 000 + hal_u32_t reserved_12[2]; + hal_u32_t reserved_16[8]; //addr 15 1111 000 + +} volatile card; + + + +#endif diff --git a/src/hal/drivers/hal_gm.c b/src/hal/drivers/hal_gm.c new file mode 100644 index 0000000..0c3fef3 --- /dev/null +++ b/src/hal/drivers/hal_gm.c @@ -0,0 +1,1830 @@ +#include <linux/pci.h> + +#include "rtapi.h" // RTAPI realtime OS API +#include "rtapi_app.h" // RTAPI realtime module decls +#include "hal.h" // HAL public API decls +#include "gm.h" // Hardware dependent defines +#include "rtapi_math.h" + +// Module information. +MODULE_AUTHOR("Bence Kovacs"); +MODULE_DESCRIPTION("Driver for General Mechatronics 6-Axis Motion Control Card for EMC HAL"); +MODULE_LICENSE("GPL2"); + +typedef struct { //encoder_t + // Pins + 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; + + // Parameters + 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; + + // Private data + 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 { //switches_t + // Pins. + 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 { //estop_t + // Pins. + hal_bit_t *in; + hal_bit_t *inNot; +} estop_t; + +typedef struct { //gpio_t + // Pins. + hal_bit_t *in; + hal_bit_t *inNot; + hal_bit_t *out; + hal_bit_t isOut; + hal_bit_t invertOut; +} gpio_t; + +typedef struct { //RS485_8output_t + // Pins. + 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; + // Parameters + 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 { //RS485_8input_t + // Pins. + 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 { //RS485_DacAdc_t + // Pins. + 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; + + // Parameters. + 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 { //RS485_mgr_t + hal_u32_t ID[16]; + hal_u32_t BYTES_TO_WRITE[16]; + hal_u32_t BYTES_TO_READ[16]; +} RS485_mgr_t; + +typedef struct { //axisdac_t + // Pins. + hal_float_t *value; + hal_bit_t *enable; + + // Parameters. + hal_float_t min; + hal_float_t max; + hal_float_t offset; + + hal_bit_t invert_serial; +} axisdac_t; + +typedef struct { //stepgen_t + // Pins. + hal_float_t *position_cmd; + hal_float_t *velocity_cmd; + hal_float_t *position_fb; + hal_s32_t *count_fb; + hal_bit_t *enable; + + // Parameters + hal_u32_t step_type; //0: StepDir, 1: UpDown, 2: Quadrature + hal_bit_t control_type; //0: position, 1: velocity + 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; + + //Saved Parameters + 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; + + // Private data + 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 { //CardMgr_t + // Pins. + hal_bit_t *cardEnable; + hal_bit_t *power_enable; + hal_bit_t *power_fault; + hal_bit_t *watchdog_expired; + + // Parameters + hal_bit_t watchdog_enable; + hal_u32_t watchdog_timeout_ns; + + // Private data + 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 { //CAN_GM_t + //Pins + hal_bit_t *enable; + hal_float_t *position_cmd; + hal_float_t *position_fb; + + //Parameters + hal_float_t position_scale; + +} CAN_GM_t; + +typedef struct { //CANmsg_t + hal_bit_t Ext; //0: Standrad ID, 1: Extended ID + hal_u32_t ID; + hal_u32_t data[8]; + hal_u32_t DLC; + hal_bit_t RTR; +}CANmsg_t; + +typedef struct { //gm_device_t + // Card relatad data + card *pCard; + int boardID; //Sequential nr of cards, 0 - MAX_GM_DEVICES-1 + int cardID; //Version of the card and its modules + + // Driver related data + 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]; + + 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 { //gm_driver_t + int comp_id; + gm_device_t *device[MAX_GM_DEVICES]; +} gm_driver_t; + +static gm_driver_t driver; + +////////////////////////////////////////////////////////////////////////////// +// Function prototypes // +////////////////////////////////////////////////////////////////////////////// + +//Export Pins, Parameters and Functions + 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); + +//Methods exported to HAL + static void read(void *arg, long period); + static void write(void *arg, long period); + static void RS485(void *arg, long period); + +//Private methods + //StepGens + 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); + //RS485 + static unsigned int RS485_CheckCrc(hal_u32_t* data, hal_u32_t length); + static unsigned int RS485_CalcCrc(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); + //Encoders + static void encoder(void *arg, long period); + //CAN + 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); + static void CAN_Reset(void *arg); + static void CAN_SetBaud(void *arg, hal_u32_t Baud); + static int CAN_ReadStatus(void *arg, hal_u32_t *RxCnt, hal_u32_t *TxCnt); + //Card management + static void card_mgr(void *arg, long period); + + +////////////////////////////////////////////////////////////////////////////// +// RTAPI main and exit functions // +////////////////////////////////////////////////////////////////////////////// + +int +rtapi_app_main(void) +{ + int msgLevel, i, device_ctr, error=0; + struct pci_dev *pDev = NULL; + card *pCard = NULL; + gm_device_t *pDevice; + + msgLevel = rtapi_get_msg_level(); + rtapi_set_msg_level(RTAPI_MSG_ALL); + rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: Driver version 1.1.0 loading...\n"); + + // Connect to the HAL. + 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; + } + + // Find General Mechatronics cards + device_ctr = 0; + while((device_ctr < MAX_GM_DEVICES) && ((pDev = pci_find_device(PLX_VENDOR_ID, GM_DEVICE_ID, pDev)) != NULL)){ + + // Allocate memory for device object. + 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); + } + + // Save pointer to device object. + driver.device[device_ctr] = pDevice; + + // Map card into memory. + pCard = (card *)ioremap_nocache(pci_resource_start(pDev, 5), pci_resource_len(pDev, 5)); + rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: Card detected in slot %2x.\n", PCI_SLOT(pDev->devfn)); + rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: Card address @ %p, Len = %d.\n", pCard, (int)pci_resource_len(pDev, 5)); + + // Initialize device. + pDevice->pCard = pCard; + + // Give board id for the card, increasing from 0 + pDevice->boardID = device_ctr++; + + //Check card ID + 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); + } + + // Export and init pins, parameters, and functions + rtapi_set_msg_level(RTAPI_MSG_WARN); + pDevice->cardMgr.disable = 0; //Enable pointers of not presented modules will be referenced to this variable + pDevice->period_ns = 0; + + error = ExportEncoder(pDevice, driver.comp_id, pDevice->cardID & IDmask_encoder); if(error != 0) break; + error = ExportStepgen(pDevice, driver.comp_id, pDevice->cardID & IDmask_stepgen); if(error != 0) break; + error = ExportDAC(pDevice, driver.comp_id, pDevice->cardID & IDmask_dac); if(error != 0) break; + error = ExportRS485(pDevice, driver.comp_id, pDevice->cardID & IDmask_rs485); if(error != 0) break; + error = ExportCAN(pDevice, driver.comp_id, pDevice->cardID & IDmask_can); if(error != 0) break; + error = ExportMixed(pDevice, driver.comp_id); if(error != 0) break; + error = ExportFunctions(pDevice, driver.comp_id, pDevice->boardID); if(error != 0) break; + + 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; + } + + if(pCard == NULL){ + // No card detected + 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) +{ + int i; + gm_device_t *pDevice; + + hal_exit(driver.comp_id); + + for(i = 0; i < MAX_GM_DEVICES; i++){ + + if((pDevice = driver.device[i]) != NULL) + { + // turn off all + pDevice->pCard->card_control_reg = (hal_s32_t) 0; + + // Unmap card + iounmap((void *)(pDevice->pCard)); + } + } +} + +////////////////////////////////////////////////////////////////////////////// +// Export Pins, Parameters and Functions // +////////////////////////////////////////////////////////////////////////////// + +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; + + + //Export pins and parameters for encoder + switch (version) + { + case notPresented: + for(i=0;i<6;i++) + { + device->encoder[i].module_exist = 0; + } + rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: No encoder module available in this version of the Card.\n"); + break; + case encoderVersion1: + for(i=0;i<6;i++) + { + //Export Pins + 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); + + //Export Parameters + 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); + + //Init parameters + 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; + + //Export pins and parameters for step generator + switch (version) + { + case notPresented: + for(i=0;i<6;i++) + { + device->stepgen[i].enable = &(device->cardMgr.disable); //Set enable pointers to a 0 value variable + device->stepgen[i].position_cmd = &(device->stepgen[i].old_pos_cmd); + } + rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: No stepgen module available in this version of the Card.\n"); + break; + case stepgenVersion1: + device->stepgen_status=0; + pCard->StepGen_status = 0; + //Export pins and parameters + for(i = 0; i < 6; i++) + { + //Export Pins + 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); + + //Export Parameters. + 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); //0: StepDir, 1: UpDown, 2: Quadrature + 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); //0: position, 1: velocity + 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; + + //Init parameters + 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]; + + //Init FPGA registers + 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; + + //Export pins and parameters for DAC + switch (version) + { + case notPresented: + for(i=0;i<6;i++) + { + device->axisdac[i].enable = &(device->cardMgr.disable); //Set enable pointers to a 0 value variable + } + rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: No DAC module available in this version of the Card.\n"); + break; + case dacVersion1: + for(i=0;i<6;i++) + { + //Export Pins + 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); + + //Export Parameters. + 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); + + //Init Parameters + device->axisdac[i].max = 10; + device->axisdac[i].min = -10; + device->axisdac[i].offset = 0; + device->axisdac[i].invert_serial = 0; + + //Init FPGA regs + pCard->DAC_0 = 0x7F7F7F7F; + pCard->DAC_1 = 0x7F7F; + } + 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; + + //Export pins and parameters for connected RS485 modules + switch (version) + { + case notPresented: + rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: No RS485 module available in this version of the Card.\n"); + break; + case rs485Version1: + //READ IDs of connected modules + 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; //1 data byte + 1 CRC + + 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; // 1 data byte + 1 CRC + 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; // 8 data byte + 1 CRC + 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; + 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; + + //Export pins and parameters for encoder + switch (version) + { + case notPresented: + for(i=0;i<6;i++) + { + device->CAN_GM[i].enable = &(device->cardMgr.disable); //Set enable pointers to a 0 value variable + } + rtapi_print_msg(RTAPI_MSG_INFO, "General Mechatronics: No CAN module available in this version of the Card.\n"); + break; + case canVersion1: + + //Export Pins and Parameters for CAN GM Servo Controllers + for(i=0;i<6;i++) + { + //Export Pins + 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); + + //Export Parameters + 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); + } + + //Export Pins and Parameters for CANopen Servo Controllers + //In development... + + 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; + + //Homing and End switches pins and parameters + for(i = 0; i < 6; i++) + { + // Pins + 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); + } + + //Power bridge Fault and Error pins + 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); + + //Watchdog pins and parameters + 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); + + //Export pins and parameters for parallel IOs |