diff --git a/src/Kbuild b/src/Kbuild index bd1ac298..d17c12ad 100644 --- a/src/Kbuild +++ b/src/Kbuild @@ -39,5 +39,7 @@ lcec-objs := \ lcec_deasda.o \ lcec_dems300.o \ lcec_omrg5.o \ - lcec_ph3lm2rm.o + lcec_ph3lm2rm.o\ + lcec_ex260.o + diff --git a/src/lcec.h b/src/lcec.h index 13528cf3..68358b63 100644 --- a/src/lcec.h +++ b/src/lcec.h @@ -62,6 +62,7 @@ do { \ #define LCEC_DELTA_VID 0x000001dd #define LCEC_MODUSOFT_VID 0x00000907 #define LCEC_OMRON_VID 0x00000083 +#define LCEC_SMC_VID 0x00000114 // State update period (ns) #define LCEC_STATE_UPDATE_PERIOD 1000000000LL diff --git a/src/lcec_conf.c b/src/lcec_conf.c index f88c8a34..02f024fc 100644 --- a/src/lcec_conf.c +++ b/src/lcec_conf.c @@ -311,6 +311,11 @@ static const LCEC_CONF_TYPELIST_T slaveTypes[] = { // modusoft PH3LM2RM converter { "Ph3LM2RM", lcecSlaveTypePh3LM2RM, NULL }, + // modusoft PH3LM2RM converter + { "EX260-SEC1", lcecSlaveTypeEX260_SEC1, NULL }, + { "EX260-SEC2", lcecSlaveTypeEX260_SEC2, NULL }, + { "EX260-SEC3", lcecSlaveTypeEX260_SEC3, NULL }, + { "EX260-SEC4", lcecSlaveTypeEX260_SEC4, NULL }, { NULL } }; diff --git a/src/lcec_conf.h b/src/lcec_conf.h index efffc7e1..badb094d 100644 --- a/src/lcec_conf.h +++ b/src/lcec_conf.h @@ -193,7 +193,11 @@ typedef enum { lcecSlaveTypeOmrG5_KN50F, lcecSlaveTypeOmrG5_KN75F, lcecSlaveTypeOmrG5_KN150F, - lcecSlaveTypePh3LM2RM + lcecSlaveTypePh3LM2RM, + lcecSlaveTypeEX260_SEC1, + lcecSlaveTypeEX260_SEC2, + lcecSlaveTypeEX260_SEC3, + lcecSlaveTypeEX260_SEC4 } LCEC_SLAVE_TYPE_T; typedef struct { diff --git a/src/lcec_ex260.c b/src/lcec_ex260.c new file mode 100644 index 00000000..caa9018c --- /dev/null +++ b/src/lcec_ex260.c @@ -0,0 +1,92 @@ +// +// Created by chad on 2021-05-28. +// + +#include "lcec_ex260.h" + +typedef struct { + hal_bit_t *sol_1a; + hal_bit_t *sol_1b; + hal_bit_t *sol_2a; + hal_bit_t *sol_2b; + hal_bit_t *sol_3a; + hal_bit_t *sol_3b; + hal_bit_t *sol_4a; + hal_bit_t *sol_4b; + unsigned int pdo_os; + unsigned int pdo_bp; +} lcec_ex260_pin_t; + +static const lcec_pindesc_t slave_pins[] = { + { HAL_BIT, HAL_IN, offsetof(lcec_ex260_pin_t, sol_1a), "%s.%s.%s.sol-%d-1a" }, + { HAL_BIT, HAL_IN, offsetof(lcec_ex260_pin_t, sol_1b), "%s.%s.%s.sol-%d-1b" }, + { HAL_BIT, HAL_IN, offsetof(lcec_ex260_pin_t, sol_2a), "%s.%s.%s.sol-%d-2a" }, + { HAL_BIT, HAL_IN, offsetof(lcec_ex260_pin_t, sol_2b), "%s.%s.%s.sol-%d-2b" }, + { HAL_BIT, HAL_IN, offsetof(lcec_ex260_pin_t, sol_3a), "%s.%s.%s.sol-%d-3a" }, + { HAL_BIT, HAL_IN, offsetof(lcec_ex260_pin_t, sol_3b), "%s.%s.%s.sol-%d-3b" }, + { HAL_BIT, HAL_IN, offsetof(lcec_ex260_pin_t, sol_4a), "%s.%s.%s.sol-%d-4a" }, + { HAL_BIT, HAL_IN, offsetof(lcec_ex260_pin_t, sol_4b), "%s.%s.%s.sol-%d-4b" }, + { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } +}; + +void lcec_ex260_write(struct lcec_slave *slave, long period); + +int lcec_ex260_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { + lcec_master_t *master = slave->master; + lcec_ex260_pin_t *hal_data; + lcec_ex260_pin_t *pin; + int i; + int err; + + // initialize callbacks + slave->proc_write = lcec_ex260_write; + + // alloc hal memory + if ((hal_data = hal_malloc(sizeof(lcec_ex260_pin_t) * slave->pdo_entry_count)) == NULL) { + rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); + return -EIO; + } + memset(hal_data, 0, sizeof(lcec_ex260_pin_t) * slave->pdo_entry_count); + slave->hal_data = hal_data; + + // initialize pins + for (i=0, pin=hal_data; ipdo_entry_count; i++, pin++) { + // initialize PDO entry + LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x3101, 0x01 + i, &pin->pdo_os, &pin->pdo_bp); + + if ((err = lcec_pin_newf_list(pin, slave_pins, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { + return err; + } + + } + + return 0; +} + +void lcec_ex260_write(struct lcec_slave *slave, long period) { + lcec_master_t *master = slave->master; + lcec_ex260_pin_t *hal_data = (lcec_ex260_pin_t *) slave->hal_data; + uint8_t *pd = master->process_data; + lcec_ex260_pin_t *pin; + int i, s; + + // wait for slave to be operational + if (!slave->state.operational) { + return; + } + + // set outputs + for (i=0, pin=hal_data; ipdo_entry_count; i++, pin++) { + s = *(pin->sol_1a); + s |= *(pin->sol_1b) << 1; + s |= *(pin->sol_2a) << 2; + s |= *(pin->sol_2b) << 3; + s |= *(pin->sol_3a) << 4; + s |= *(pin->sol_3b) << 5; + s |= *(pin->sol_4a) << 6; + s |= *(pin->sol_4b) << 7; + EC_WRITE_U8(&pd[pin->pdo_os], s); + + } +} + diff --git a/src/lcec_ex260.h b/src/lcec_ex260.h new file mode 100644 index 00000000..f67d3ad4 --- /dev/null +++ b/src/lcec_ex260.h @@ -0,0 +1,31 @@ +// +// Created by chad on 2021-05-28. +// + +#ifndef _LCEC_EX260_H +#define _LCEC_EX260_H + +#include "lcec.h" +#include "lcec_conf.h" + +/* Master 0, Slave 3, "EX260-SEC3" +* Vendor ID: 0x00000114 +* Product code: 0x01000003 +* Revision number: 0x00010002 +*/ + +#define LCEC_EX260_VID LCEC_SMC_VID +#define LCEC_EX260_SEC1_PID 0x01000001 +#define LCEC_EX260_SEC2_PID 0x01000002 +#define LCEC_EX260_SEC3_PID 0x01000003 +#define LCEC_EX260_SEC4_PID 0x01000004 + +#define LCEC_EX260_SEC1_PDOS 4 +#define LCEC_EX260_SEC2_PDOS 4 +#define LCEC_EX260_SEC3_PDOS 2 +#define LCEC_EX260_SEC4_PDOS 2 + + +int lcec_ex260_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); + +#endif //_LCEC_EX260_H diff --git a/src/lcec_main.c b/src/lcec_main.c index f5b87686..9b2cd2e0 100644 --- a/src/lcec_main.c +++ b/src/lcec_main.c @@ -55,6 +55,7 @@ #include "lcec_dems300.h" #include "lcec_omrg5.h" #include "lcec_ph3lm2rm.h" +#include "lcec_ex260.h" #include "rtapi_app.h" @@ -257,6 +258,11 @@ static const lcec_typelist_t types[] = { { lcecSlaveTypeOmrG5_KN75F, LCEC_OMRG5_VID, LCEC_OMRG5_R88D_KN75F_ECT_PID, LCEC_OMRG5_PDOS, 0, NULL, lcec_omrg5_init}, { lcecSlaveTypeOmrG5_KN150F, LCEC_OMRG5_VID, LCEC_OMRG5_R88D_KN150F_ECT_PID, LCEC_OMRG5_PDOS, 0, NULL, lcec_omrg5_init}, + { lcecSlaveTypeEX260_SEC1, LCEC_EX260_VID, LCEC_EX260_SEC1_PID, LCEC_EX260_SEC1_PDOS, lcec_ex260_init}, + { lcecSlaveTypeEX260_SEC2, LCEC_EX260_VID, LCEC_EX260_SEC2_PID, LCEC_EX260_SEC2_PDOS, lcec_ex260_init}, + { lcecSlaveTypeEX260_SEC3, LCEC_EX260_VID, LCEC_EX260_SEC3_PID, LCEC_EX260_SEC3_PDOS, lcec_ex260_init}, + { lcecSlaveTypeEX260_SEC4, LCEC_EX260_VID, LCEC_EX260_SEC4_PID, LCEC_EX260_SEC4_PDOS, lcec_ex260_init}, + // modusoft PH3LM2RM converter { lcecSlaveTypePh3LM2RM, LCEC_PH3LM2RM_VID, LCEC_PH3LM2RM_PID, LCEC_PH3LM2RM_PDOS, 0, NULL, lcec_ph3lm2rm_init},