##############################################################################
## Example: Demo of ecmc SocketCAN plugin
## https://github.com/anderssandstrom/e3-ecmc_plugin_socketcan
##
## The plugin exposes:
##

## Initiation:
epicsEnvSet("IOC" ,"$(IOC="IOC_TEST")")
epicsEnvSet("ECMCCFG_INIT" ,"")  #Only run startup once (auto at PSI, need call at ESS), variable set to "#" in startup.cmd
epicsEnvSet("SCRIPTEXEC" ,"$(SCRIPTEXEC="iocshLoad")")

require ecmccfg 6.3.2

# run module startup.cmd (only needed at ESS  PSI auto call at require)
$(ECMCCFG_INIT)$(SCRIPTEXEC) ${ecmccfg_DIR}startup.cmd, "IOC=$(IOC),ECMC_VER=6.3.2,MASTER_ID=-1"

##############################################################################
## Configure hardware:
# No EtherCAT hardware (in this example)..

##############################################################################
## Load plugin:
require ecmc_plugin_socketcan master

epicsEnvSet(ECMC_PLUGIN_FILNAME,"/home/dev/epics/base-7.0.4/require/${E3_REQUIRE_VERSION}/siteMods/ecmc_plugin_socketcan/master/lib/${EPICS_HOST_ARCH=linux-x86_64}/libecmc_plugin_socketcan.so")
epicsEnvSet(ECMC_PLUGIN_CONFIG,"IF=vcan0;DBG_PRINT=1;") # Only one option implemented in this plugin
${SCRIPTEXEC} ${ecmccfg_DIR}loadPlugin.cmd, "PLUGIN_ID=0,FILE=${ECMC_PLUGIN_FILNAME},CONFIG='${ECMC_PLUGIN_CONFIG}', REPORT=1"
epicsEnvUnset(ECMC_PLUGIN_FILNAME)
epicsEnvUnset(ECMC_PLUGIN_CONFIG)

##############################################################################
## PLC 0
# $(SCRIPTEXEC) $(ecmccfg_DIR)loadPLCFile.cmd, "PLC_ID=0, SAMPLE_RATE_MS=1000,FILE=./plc/can.plc")

##############################################################################
############# Prepare virt can for test:

# Install can utils:
#   $ git clone https://github.com/linux-can/can-utils
#   $ cd can-utils
#   $ make
#   $ make install
#
# Start virt can 0 (vcan0) and candump:
#   $ sudo modprobe vcan
#   $ sudo ip link add dev vcan0 type vcan
#   $ sudo ip link set up vcan0
#   $ candump vcan0

##############################################################################
############# Configure CAN plugin:
# Commands:
#   ecmcCANOpenAddMaster -h
#      Use ecmcCANOpenAddMaster(<name>, <node id>,....)
#                <name>                     : Name of master device.
#                <node id>                  : CANOpen node id of master.
#                <LSS sample time ms>       : Sample time for LSS.
#                <Sync sample time ms>      : Sample time for SYNC.
#                <Heartbeat sample time ms> : Sample time for Heartbeat.
#
ecmcCANOpenAddMaster("ecmcCANOpenMaster",0,1000,1000,1000)

#    ecmcCANOpenAddDevice -h
#      Use ecmcCANOpenAddDevice(<name>, <node id>)
#          <name>      : Name of device.
#          <node id>   : CANOpen node id of device.
#
ecmcCANOpenAddDevice("testDevice",3)

#     ecmcCANOpenAddPDO -h
#       Use "ecmcCANOpenAddPDO(<name>, <node id>
#           <name>            : Name of master device.
#           <node id>         : CANOpen node id of device/master.
#           <cob id>          : CANOpen cob id of PDO.
#           <dir>             : Direction 1=write and 2=read.
#           <ODSize>          : Size of PDO (max 8 bytes).
#           <readTimeoutMs>   : Readtimeout in ms.
#           <writeCycleMs>    : Cycle time for write (if <= 0 then only write on change).
ecmcCANOpenAddPDO("status1",3,0x183,2,8,10000,0)  # READ
dbLoadRecords(ecmcPluginSocketCAN_PDO_input.template, "P=${ECMC_PREFIX},PORT=${ECMC_ASYN_PORT},ADDR=0,TIMEOUT=1,T_SMP_MS=${ECMC_SAMPLE_RATE_MS},TSE=${ECMC_TSE},NELM=${NELM=1},CH_ID=03,DEV_ID=3,suffix=PDO01-Array,source=status1,NELM=8")

#     ecmcCANOpenAddSDO -h
#        Use ecmcCANOpenAddSDO(<name>, <node id>,.....)
#           <name>            : Name of master device.
#           <node id>         : CANOpen node id of device/master.
#           <cob id tx>       : CANOpen cob id of Tx of slave SDO.
#           <cob id rx>       : CANOpen cob id of Rx of slave SDO.
#           <dir>             : Direction 1=write and 2=read.
#           <ODIndex>         : OD index of SDO.
#           <ODSubIndex>      : OD sub index of SDO.
#           <ODSize>          : OS Size.
#           <readTimeoutMs>   : Readtimeout in ms.
#
ecmcCANOpenAddSDO("analogValues1",3,0x583,0x603,2,0x2640,0x0,56,7000) # READ
ecmcCANOpenAddSDO("analogValues2",3,0x583,0x603,2,0x2640,0x0,56,7000) # READ
ecmcCANOpenAddSDO("analogValues3",3,0x583,0x603,2,0x2640,0x0,56,7000) # READ
ecmcCANOpenAddSDO("analogValues4",3,0x583,0x603,2,0x2640,0x0,56,7000) # READ
dbLoadTemplate(ecmcPluginSocketCAN_SDO.substitutions, "P=${ECMC_PREFIX},PORT=${ECMC_ASYN_PORT},ADDR=0,TIMEOUT=1,T_SMP_MS=${ECMC_SAMPLE_RATE_MS},TSE=${ECMC_TSE}")

ecmcCANOpenAddSDO("basicConfig",3,0x583,0x603,1,0x2690,0x1,7,0)      # WRITE
dbLoadRecords(ecmcPluginSocketCAN_SDO_output.template, "P=${ECMC_PREFIX},PORT=${ECMC_ASYN_PORT},ADDR=0,TIMEOUT=1,T_SMP_MS=${ECMC_SAMPLE_RATE_MS},TSE=${ECMC_TSE},NELM=${NELM=1},CH_ID=03,DEV_ID=3,suffix=BasicConfig,source=basicConfig,DTYP=asynInt8ArrayOut,FTVL=CHAR,NELM=7")
##############################################################################
############# Go to realtime:

ecmcConfigOrDie "Cfg.SetAppMode(1)"
iocInit
dbl > pvs.log

#ecmcGrepParam *plugin.can.*
