150 lines
5.2 KiB
C++
150 lines
5.2 KiB
C++
/*************************************************************************\
|
|
* Copyright (c) 2019 European Spallation Source ERIC
|
|
* ecmc is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
*
|
|
* ecmcSocketCAN.h
|
|
*
|
|
* Created on: Mar 22, 2020
|
|
* Author: anderssandstrom
|
|
*
|
|
\*************************************************************************/
|
|
#ifndef ECMC_SOCKETCAN_H_
|
|
#define ECMC_SOCKETCAN_H_
|
|
|
|
#include <stdexcept>
|
|
#include "ecmcDataItem.h"
|
|
#include "ecmcAsynPortDriver.h"
|
|
#include "ecmcSocketCANDefs.h"
|
|
#include "ecmcSocketCANWriteBuffer.h"
|
|
#include "ecmcCANOpenDevice.h"
|
|
#include "ecmcCANOpenMaster.h"
|
|
#include "inttypes.h"
|
|
#include <string>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
#include <net/if.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <linux/can.h>
|
|
#include <linux/can/raw.h>
|
|
|
|
#define ECMC_CAN_MAX_WRITE_CMDS 128
|
|
#define ECMC_CAN_MAX_DEVICES 128
|
|
#define ECMC_CAN_ERROR_WRITE_FULL 10
|
|
#define ECMC_CAN_ERROR_WRITE_BUSY 11
|
|
#define ECMC_CAN_ERROR_WRITE_NO_DATA 12
|
|
#define ECMC_CAN_ERROR_WRITE_INCOMPLETE 13
|
|
#define ECMC_CAN_ERROR_WRITE_BUFFER_NULL 14
|
|
#define ECMC_CAN_ERROR_READ_INCOMPLETE 15
|
|
|
|
class ecmcSocketCAN {
|
|
public:
|
|
|
|
/** ecmc ecmcSocketCAN class
|
|
* This object can throw:
|
|
* - bad_alloc
|
|
* - invalid_argument
|
|
* - runtime_error
|
|
* - out_of_range
|
|
*/
|
|
ecmcSocketCAN(char* configStr,
|
|
char* portName,
|
|
int exeSampelTimeMs);
|
|
~ecmcSocketCAN();
|
|
|
|
void doReadWorker();
|
|
void doWriteWorker();
|
|
void doConnectWorker();
|
|
|
|
//virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
|
//virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
|
//virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value,
|
|
// size_t nElements, size_t *nIn);
|
|
//virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
|
|
void connectExternal();
|
|
int getConnected();
|
|
int addWriteCAN(uint32_t canId,
|
|
uint8_t len,
|
|
uint8_t data0,
|
|
uint8_t data1,
|
|
uint8_t data2,
|
|
uint8_t data3,
|
|
uint8_t data4,
|
|
uint8_t data5,
|
|
uint8_t data6,
|
|
uint8_t data7);
|
|
int getlastWritesError();
|
|
void execute(); // ecmc rt loop
|
|
|
|
void addMaster(uint32_t nodeId,
|
|
const char* name,
|
|
int lssSampleTimeMs,
|
|
int syncSampleTimeMs,
|
|
int heartSampleTimeMs);
|
|
|
|
void addDevice(uint32_t nodeId,
|
|
const char* name,
|
|
int heartTimeoutMs);
|
|
|
|
void addPDO(uint32_t nodeId,
|
|
uint32_t cobId,
|
|
ecmc_can_direction rw,
|
|
uint32_t ODSize,
|
|
int readTimeoutMs,
|
|
int writeCycleMs, //if <0 then write on demand.
|
|
const char* name);
|
|
|
|
void addSDO(uint32_t nodeId,
|
|
uint32_t cobIdTx, // 0x580 + CobId
|
|
uint32_t cobIdRx, // 0x600 + Cobid
|
|
ecmc_can_direction rw,
|
|
uint16_t ODIndex, // Object dictionary index
|
|
uint8_t ODSubIndex, // Object dictionary subindex
|
|
uint32_t ODSize,
|
|
int readSampleTimeMs,
|
|
const char* name);
|
|
|
|
int findDeviceWithNodeId(uint32_t nodeId);
|
|
|
|
private:
|
|
void parseConfigStr(char *configStr);
|
|
static std::string to_string(int value);
|
|
void connectPrivate();
|
|
int writeCAN(can_frame *frame);
|
|
char* cfgCanIFStr_; // Config: can interface can0, vcan0..
|
|
int cfgDbgMode_;
|
|
int cfgAutoConnect_;
|
|
int destructs_;
|
|
int connected_;
|
|
epicsEvent doConnectEvent_;
|
|
epicsEvent doWriteEvent_;
|
|
struct can_frame rxmsg_;
|
|
struct ifreq ifr_;
|
|
int socketId_;
|
|
struct sockaddr_can addr_;
|
|
struct can_frame txmsgBuffer_[ECMC_CAN_MAX_WRITE_CMDS];
|
|
int exeSampleTimeMs_;
|
|
ecmcSocketCANWriteBuffer *writeBuffer_;
|
|
|
|
int deviceCounter_;
|
|
ecmcCANOpenDevice *devices_[ECMC_CAN_MAX_DEVICES];
|
|
ecmcCANOpenMaster *masterDev_;
|
|
|
|
int errorCode_;
|
|
int refreshNeeded_;
|
|
//ASYN
|
|
void initAsyn();
|
|
void refreshAsynParams();
|
|
ecmcAsynDataItem *errorParam_;
|
|
ecmcAsynDataItem *connectedParam_;
|
|
};
|
|
|
|
#endif /* ECMC_SOCKETCAN_H_ */
|