Add asyn params for pdo, add write callbacks for sdo and pdo.
This commit is contained in:
@@ -124,6 +124,7 @@ int ecmcCANOpenDevice::addPDO(uint32_t cobId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pdos_[pdoCounter_] = new ecmcCANOpenPDO(writeBuffer_,
|
pdos_[pdoCounter_] = new ecmcCANOpenPDO(writeBuffer_,
|
||||||
|
nodeId_,
|
||||||
cobId,
|
cobId,
|
||||||
rw,
|
rw,
|
||||||
ODSize,
|
ODSize,
|
||||||
@@ -161,6 +162,7 @@ int ecmcCANOpenDevice::addSDO(uint32_t cobIdTx, // 0x580 + CobId
|
|||||||
exeSampleTimeMs_,
|
exeSampleTimeMs_,
|
||||||
name,
|
name,
|
||||||
&sdo1Lock_,
|
&sdo1Lock_,
|
||||||
|
sdoCounter_,
|
||||||
dbgMode_);
|
dbgMode_);
|
||||||
sdoCounter_++;
|
sdoCounter_++;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -15,11 +15,34 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "ecmcCANOpenPDO.h"
|
#include "ecmcCANOpenPDO.h"
|
||||||
|
#include "ecmcAsynPortDriver.h"
|
||||||
|
#include "ecmcPluginClient.h"
|
||||||
|
|
||||||
|
// Calback function to init write from asyn
|
||||||
|
asynStatus asynWritePDOValue(void* data, size_t bytes, asynParamType asynParType,void *userObj) {
|
||||||
|
// userobj = NULL
|
||||||
|
if(!userObj) {
|
||||||
|
printf("Error: asynWritePDOValue() fail, no user obj defined.\n");
|
||||||
|
return asynError;
|
||||||
|
}
|
||||||
|
ecmcCANOpenPDO* pdo = (ecmcCANOpenPDO*)userObj;
|
||||||
|
int bytesToCp = bytes;
|
||||||
|
if (bytes > 8) {
|
||||||
|
bytesToCp = 8;
|
||||||
|
}
|
||||||
|
uint64_t tempData = 0;
|
||||||
|
|
||||||
|
memcpy(&tempData,data,bytesToCp);
|
||||||
|
pdo->setValue(tempData);
|
||||||
|
pdo->writeValue();
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ecmc ecmcCANOpenPDO class
|
* ecmc ecmcCANOpenPDO class
|
||||||
*/
|
*/
|
||||||
ecmcCANOpenPDO::ecmcCANOpenPDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
ecmcCANOpenPDO::ecmcCANOpenPDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
||||||
|
uint32_t nodeId,
|
||||||
uint32_t cobId, // 0x580 + CobId
|
uint32_t cobId, // 0x580 + CobId
|
||||||
ecmc_can_direction rw,
|
ecmc_can_direction rw,
|
||||||
uint32_t ODSize,
|
uint32_t ODSize,
|
||||||
@@ -30,6 +53,7 @@ ecmcCANOpenPDO::ecmcCANOpenPDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
|||||||
int dbgMode) {
|
int dbgMode) {
|
||||||
|
|
||||||
writeBuffer_ = writeBuffer;
|
writeBuffer_ = writeBuffer;
|
||||||
|
nodeId_ = nodeId;
|
||||||
cobId_ = cobId;
|
cobId_ = cobId;
|
||||||
ODSize_ = ODSize;
|
ODSize_ = ODSize;
|
||||||
name_ = strdup(name);
|
name_ = strdup(name);
|
||||||
@@ -60,7 +84,7 @@ ecmcCANOpenPDO::ecmcCANOpenPDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
|||||||
writeFrame_.data[7] = 0;
|
writeFrame_.data[7] = 0;
|
||||||
|
|
||||||
dataMutex_ = epicsMutexCreate();
|
dataMutex_ = epicsMutexCreate();
|
||||||
|
initAsyn();
|
||||||
}
|
}
|
||||||
|
|
||||||
ecmcCANOpenPDO::~ecmcCANOpenPDO() {
|
ecmcCANOpenPDO::~ecmcCANOpenPDO() {
|
||||||
@@ -148,3 +172,81 @@ int ecmcCANOpenPDO::writeValue() {
|
|||||||
}
|
}
|
||||||
return writeBuffer_->addWriteCAN(&writeFrame_);
|
return writeBuffer_->addWriteCAN(&writeFrame_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ecmcCANOpenPDO::initAsyn() {
|
||||||
|
|
||||||
|
ecmcAsynPortDriver *ecmcAsynPort = (ecmcAsynPortDriver *)getEcmcAsynPortDriver();
|
||||||
|
if(!ecmcAsynPort) {
|
||||||
|
printf("ERROR: ecmcAsynPort NULL.");
|
||||||
|
throw std::runtime_error( "ERROR: ecmcAsynPort NULL." );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add resultdata "plugin.can.dev%d.<name>"
|
||||||
|
std::string paramName = ECMC_PLUGIN_ASYN_PREFIX + std::string(".dev") +
|
||||||
|
to_string(nodeId_) + ".pdo" /*+ to_string(objIndex_) */
|
||||||
|
+ "." + std::string(name_);
|
||||||
|
|
||||||
|
dataParam_ = ecmcAsynPort->addNewAvailParam(
|
||||||
|
paramName.c_str(), // name
|
||||||
|
asynParamInt8Array, // asyn type
|
||||||
|
dataBuffer_, // pointer to data
|
||||||
|
ODSize_, // size of data
|
||||||
|
ECMC_EC_U8, // ecmc data type
|
||||||
|
0); // die if fail
|
||||||
|
|
||||||
|
if(!dataParam_) {
|
||||||
|
printf("ERROR: Failed create asyn param for data.");
|
||||||
|
throw std::runtime_error( "ERROR: Failed create asyn param for data: " + paramName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow different types depending on size
|
||||||
|
if(ODSize_>1){
|
||||||
|
dataParam_->addSupportedAsynType(asynParamInt16Array);
|
||||||
|
}
|
||||||
|
if(ODSize_>3){
|
||||||
|
dataParam_->addSupportedAsynType(asynParamInt32Array);
|
||||||
|
dataParam_->addSupportedAsynType(asynParamFloat32Array);
|
||||||
|
dataParam_->addSupportedAsynType(asynParamInt32);
|
||||||
|
}
|
||||||
|
if(ODSize_>7){
|
||||||
|
dataParam_->addSupportedAsynType(asynParamFloat64Array);
|
||||||
|
dataParam_->addSupportedAsynType(asynParamFloat64);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataParam_->setAllowWriteToEcmc(rw_ == DIR_WRITE);
|
||||||
|
|
||||||
|
if(rw_ == DIR_WRITE) {
|
||||||
|
dataParam_->setExeCmdFunctPtr(asynWritePDOValue,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataParam_->refreshParam(1); // read once into asyn param lib
|
||||||
|
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
||||||
|
|
||||||
|
// Add resultdata "plugin.can.dev%d.error"
|
||||||
|
paramName = ECMC_PLUGIN_ASYN_PREFIX + std::string(".dev") +
|
||||||
|
to_string(nodeId_) + ".sdo" /*+ to_string(objIndex_)*/ + std::string(".error");
|
||||||
|
|
||||||
|
errorParam_ = ecmcAsynPort->addNewAvailParam(
|
||||||
|
paramName.c_str(), // name
|
||||||
|
asynParamInt32, // asyn type
|
||||||
|
(uint8_t*)&errorCode_, // pointer to data
|
||||||
|
sizeof(errorCode_), // size of data
|
||||||
|
ECMC_EC_U32, // ecmc data type
|
||||||
|
0); // die if fail
|
||||||
|
|
||||||
|
if(!errorParam_) {
|
||||||
|
printf("ERROR: Failed create asyn param for data.");
|
||||||
|
throw std::runtime_error( "ERROR: Failed create asyn param for data: " + paramName);
|
||||||
|
}
|
||||||
|
|
||||||
|
errorParam_->setAllowWriteToEcmc(false); // need to callback here
|
||||||
|
errorParam_->refreshParam(1); // read once into asyn param lib
|
||||||
|
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid issues with std:to_string()
|
||||||
|
std::string ecmcCANOpenPDO::to_string(int value) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << value;
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
class ecmcCANOpenPDO {
|
class ecmcCANOpenPDO {
|
||||||
public:
|
public:
|
||||||
ecmcCANOpenPDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
ecmcCANOpenPDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
||||||
|
uint32_t nodeId,
|
||||||
uint32_t cobId,
|
uint32_t cobId,
|
||||||
ecmc_can_direction rw,
|
ecmc_can_direction rw,
|
||||||
uint32_t ODSize,
|
uint32_t ODSize,
|
||||||
@@ -48,6 +49,7 @@ class ecmcCANOpenPDO {
|
|||||||
int validateFrame(can_frame *frame);
|
int validateFrame(can_frame *frame);
|
||||||
ecmcSocketCANWriteBuffer *writeBuffer_;
|
ecmcSocketCANWriteBuffer *writeBuffer_;
|
||||||
uint32_t cobId_; // with cobid
|
uint32_t cobId_; // with cobid
|
||||||
|
uint32_t nodeId_;
|
||||||
int readTimeoutMs_;
|
int readTimeoutMs_;
|
||||||
int writeCycleMs_;
|
int writeCycleMs_;
|
||||||
int exeSampleTimeMs_;
|
int exeSampleTimeMs_;
|
||||||
@@ -63,6 +65,12 @@ class ecmcCANOpenPDO {
|
|||||||
epicsMutexId dataMutex_;
|
epicsMutexId dataMutex_;
|
||||||
char* name_;
|
char* name_;
|
||||||
|
|
||||||
|
static std::string to_string(int value);
|
||||||
|
|
||||||
|
//ASYN
|
||||||
|
void initAsyn();
|
||||||
|
ecmcAsynDataItem *dataParam_;
|
||||||
|
ecmcAsynDataItem *errorParam_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ECMC_CANOPEN_PDO_H_ */
|
#endif /* ECMC_CANOPEN_PDO_H_ */
|
||||||
|
|||||||
@@ -21,6 +21,19 @@
|
|||||||
|
|
||||||
#define ECMC_SDO_TRANSFER_MAX_BYTES 7
|
#define ECMC_SDO_TRANSFER_MAX_BYTES 7
|
||||||
|
|
||||||
|
// Calback function to init write from asyn
|
||||||
|
asynStatus asynWriteSDOValue(void* data, size_t bytes, asynParamType asynParType,void *userObj) {
|
||||||
|
// userobj = NULL
|
||||||
|
if(!userObj) {
|
||||||
|
printf("Error: asynWriteSDOValue() fail, no user obj defined.\n");
|
||||||
|
return asynError;
|
||||||
|
}
|
||||||
|
ecmcCANOpenSDO* sdo = (ecmcCANOpenSDO*)userObj;
|
||||||
|
|
||||||
|
sdo->setValue((uint8_t*)data,bytes);
|
||||||
|
sdo->writeValue();
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* ecmc ecmcCANOpenSDO class
|
* ecmc ecmcCANOpenSDO class
|
||||||
*/
|
*/
|
||||||
@@ -36,6 +49,7 @@ ecmcCANOpenSDO::ecmcCANOpenSDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
|||||||
int exeSampleTimeMs,
|
int exeSampleTimeMs,
|
||||||
const char *name,
|
const char *name,
|
||||||
std::atomic_flag *ptrSdo1Lock,
|
std::atomic_flag *ptrSdo1Lock,
|
||||||
|
int objIndex,
|
||||||
int dbgMode) {
|
int dbgMode) {
|
||||||
|
|
||||||
writeBuffer_ = writeBuffer;
|
writeBuffer_ = writeBuffer;
|
||||||
@@ -45,13 +59,16 @@ ecmcCANOpenSDO::ecmcCANOpenSDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
|||||||
ODIndex_ = ODIndex;
|
ODIndex_ = ODIndex;
|
||||||
ODSubIndex_ = ODSubIndex;
|
ODSubIndex_ = ODSubIndex;
|
||||||
ODSize_ = ODSize;
|
ODSize_ = ODSize;
|
||||||
|
objIndex_ = objIndex;
|
||||||
dbgMode_ = dbgMode;
|
dbgMode_ = dbgMode;
|
||||||
name_ = strdup(name);
|
name_ = strdup(name);
|
||||||
errorCode_ = 0;
|
errorCode_ = 0;
|
||||||
ptrSdo1Lock_ = ptrSdo1Lock;
|
ptrSdo1Lock_ = ptrSdo1Lock;
|
||||||
dataMutex_ = epicsMutexCreate();
|
dataMutex_ = epicsMutexCreate();
|
||||||
getLockMutex_ = epicsMutexCreate();
|
getLockMutex_ = epicsMutexCreate();
|
||||||
|
errorParam_ = NULL;
|
||||||
|
dataParam_ = NULL;
|
||||||
|
writePending_ = NULL;
|
||||||
// convert to ODIndex_ to indiviual bytes struct
|
// convert to ODIndex_ to indiviual bytes struct
|
||||||
memcpy(&ODIndexBytes_, &ODIndex, 2);
|
memcpy(&ODIndexBytes_, &ODIndex, 2);
|
||||||
memcpy(&ODLengthBytes_, &ODSize_, 4);
|
memcpy(&ODLengthBytes_, &ODSize_, 4);
|
||||||
@@ -66,7 +83,7 @@ ecmcCANOpenSDO::ecmcCANOpenSDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
|||||||
writeStates_ = WRITE_IDLE;
|
writeStates_ = WRITE_IDLE;
|
||||||
useTg1Frame_ = 1;
|
useTg1Frame_ = 1;
|
||||||
dataBuffer_ = new uint8_t(ODSize_);
|
dataBuffer_ = new uint8_t(ODSize_);
|
||||||
tempReadBuffer_ = new uint8_t(ODSize_);
|
tempDataBuffer_ = new uint8_t(ODSize_);
|
||||||
busyCounter_ = 0;
|
busyCounter_ = 0;
|
||||||
// Request data (send on slave RX)
|
// Request data (send on slave RX)
|
||||||
// w 0x603 [8] 0x40 0x40 0x26 0x00 0x00 0x00 0x00 0x00
|
// w 0x603 [8] 0x40 0x40 0x26 0x00 0x00 0x00 0x00 0x00
|
||||||
@@ -185,7 +202,7 @@ ecmcCANOpenSDO::ecmcCANOpenSDO(ecmcSocketCANWriteBuffer* writeBuffer,
|
|||||||
|
|
||||||
ecmcCANOpenSDO::~ecmcCANOpenSDO() {
|
ecmcCANOpenSDO::~ecmcCANOpenSDO() {
|
||||||
delete[] dataBuffer_;
|
delete[] dataBuffer_;
|
||||||
delete[] tempReadBuffer_;
|
delete[] tempDataBuffer_;
|
||||||
free(name_);
|
free(name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,14 +217,19 @@ void ecmcCANOpenSDO::execute() {
|
|||||||
if(busyCounter_>ECMC_SDO_REPLY_TIMOUT_MS) {
|
if(busyCounter_>ECMC_SDO_REPLY_TIMOUT_MS) {
|
||||||
// cancel read or write
|
// cancel read or write
|
||||||
printf("SDO BUSY timeout!! %s\n",name_);
|
printf("SDO BUSY timeout!! %s\n",name_);
|
||||||
memset(tempReadBuffer_,0,ODSize_);
|
memset(tempDataBuffer_,0,ODSize_);
|
||||||
readStates_ = READ_IDLE;
|
readStates_ = READ_IDLE;
|
||||||
writeStates_ = WRITE_IDLE;
|
writeStates_ = WRITE_IDLE;
|
||||||
exeCounter_ = 0;
|
exeCounter_ = 0;
|
||||||
busyCounter_ = 0;
|
busyCounter_ = 0;
|
||||||
errorCode_ = ECMC_CAN_ERROR_SDO_TIMEOUT;
|
errorCode_ = ECMC_CAN_ERROR_SDO_TIMEOUT;
|
||||||
|
errorParam_->refreshParamRT(1);
|
||||||
unlockSdo1();
|
unlockSdo1();
|
||||||
}
|
}
|
||||||
|
if(!busy_ && writePending_) {
|
||||||
|
// Try to write pending value in tempDataBuffer_
|
||||||
|
writeValue();
|
||||||
|
}
|
||||||
|
|
||||||
if(exeCounter_* exeSampleTimeMs_ < readSampleTimeMs_ && rw_ == DIR_READ) { // do not risk overflow
|
if(exeCounter_* exeSampleTimeMs_ < readSampleTimeMs_ && rw_ == DIR_READ) { // do not risk overflow
|
||||||
exeCounter_++;
|
exeCounter_++;
|
||||||
@@ -258,6 +280,10 @@ void ecmcCANOpenSDO::newRxFrame(can_frame *frame) {
|
|||||||
else { // Write
|
else { // Write
|
||||||
errorCode = writeDataStateMachine(frame);
|
errorCode = writeDataStateMachine(frame);
|
||||||
}
|
}
|
||||||
|
if(errorCode && errorCode_ != errorCode) {
|
||||||
|
errorCode_ = errorCode;
|
||||||
|
errorParam_->refreshParamRT(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ecmcCANOpenSDO::readDataStateMachine(can_frame *frame) {
|
int ecmcCANOpenSDO::readDataStateMachine(can_frame *frame) {
|
||||||
@@ -283,7 +309,7 @@ int ecmcCANOpenSDO::readDataStateMachine(can_frame *frame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(bytesToRead + recivedBytes_ <= ODSize_) {
|
if(bytesToRead + recivedBytes_ <= ODSize_) {
|
||||||
memcpy(tempReadBuffer_ + recivedBytes_, &(frame->data[1]),bytesToRead);
|
memcpy(tempDataBuffer_ + recivedBytes_, &(frame->data[1]),bytesToRead);
|
||||||
recivedBytes_ += bytesToRead;
|
recivedBytes_ += bytesToRead;
|
||||||
}
|
}
|
||||||
if(recivedBytes_ < ODSize_) { // Ask for more data but must toggle so alternat the prepared frames
|
if(recivedBytes_ < ODSize_) { // Ask for more data but must toggle so alternat the prepared frames
|
||||||
@@ -304,13 +330,14 @@ int ecmcCANOpenSDO::readDataStateMachine(can_frame *frame) {
|
|||||||
useTg1Frame_ = 0;
|
useTg1Frame_ = 0;
|
||||||
|
|
||||||
epicsMutexLock(dataMutex_);
|
epicsMutexLock(dataMutex_);
|
||||||
memcpy(dataBuffer_,tempReadBuffer_,ODSize_);
|
memcpy(dataBuffer_,tempDataBuffer_,ODSize_);
|
||||||
epicsMutexUnlock(dataMutex_);
|
epicsMutexUnlock(dataMutex_);
|
||||||
if(dbgMode_) {
|
if(dbgMode_) {
|
||||||
printf("STATE = READ_IDLE %s\n",name_);
|
printf("STATE = READ_IDLE %s\n",name_);
|
||||||
printf("All data read from slave SDO.\n");
|
printf("All data read from slave SDO.\n");
|
||||||
//copy complete data to dataBuffer_
|
//copy complete data to dataBuffer_
|
||||||
printBuffer();
|
printBuffer();
|
||||||
|
dataParam_->refreshParamRT(1);
|
||||||
}
|
}
|
||||||
unlockSdo1();
|
unlockSdo1();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -457,8 +484,9 @@ void ecmcCANOpenSDO::setValue(uint8_t *data, size_t bytes) {
|
|||||||
if(bytesToCopy == 0) {
|
if(bytesToCopy == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// always write to tempDatabuffer then transfer
|
||||||
epicsMutexLock(dataMutex_);
|
epicsMutexLock(dataMutex_);
|
||||||
memcpy(dataBuffer_, &data, ODSize_);
|
memcpy(tempDataBuffer_, data, ODSize_);
|
||||||
epicsMutexUnlock(dataMutex_);
|
epicsMutexUnlock(dataMutex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,17 +495,25 @@ int ecmcCANOpenSDO::writeValue() {
|
|||||||
printf("WRITEVALUE %s\n",name_);
|
printf("WRITEVALUE %s\n",name_);
|
||||||
|
|
||||||
if(busy_) {
|
if(busy_) {
|
||||||
|
writePending_ = true;
|
||||||
return ECMC_CAN_ERROR_SDO_WRITE_BUSY;
|
return ECMC_CAN_ERROR_SDO_WRITE_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tryLockSdo1()) {
|
if(!tryLockSdo1()) {
|
||||||
// wait for busy to go down
|
// wait for busy to go down
|
||||||
|
writePending_ = true;
|
||||||
return ECMC_CAN_ERROR_SDO_WRITE_BUSY;
|
return ECMC_CAN_ERROR_SDO_WRITE_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(writeStates_ != WRITE_IDLE ) {
|
if(writeStates_ != WRITE_IDLE ) {
|
||||||
|
writePending_ = true;
|
||||||
return ECMC_CAN_ERROR_SDO_WRITE_BUSY;
|
return ECMC_CAN_ERROR_SDO_WRITE_BUSY;
|
||||||
}
|
}
|
||||||
|
writePending_ = false;
|
||||||
|
|
||||||
|
epicsMutexLock(dataMutex_);
|
||||||
|
memcpy(dataBuffer_, tempDataBuffer_, ODSize_);
|
||||||
|
epicsMutexUnlock(dataMutex_);
|
||||||
|
|
||||||
writeStates_ = WRITE_REQ_TRANSFER;
|
writeStates_ = WRITE_REQ_TRANSFER;
|
||||||
if(dbgMode_) {
|
if(dbgMode_) {
|
||||||
@@ -551,7 +587,9 @@ void ecmcCANOpenSDO::initAsyn() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add resultdata "plugin.can.dev%d.<name>"
|
// Add resultdata "plugin.can.dev%d.<name>"
|
||||||
std::string paramName = ECMC_PLUGIN_ASYN_PREFIX + std::string(".dev") + to_string(nodeId_) + "." + std::string(name_);
|
std::string paramName = ECMC_PLUGIN_ASYN_PREFIX + std::string(".dev") +
|
||||||
|
to_string(nodeId_) + ".sdo" /*+ to_string(objIndex_) */
|
||||||
|
+ "." + std::string(name_);
|
||||||
|
|
||||||
dataParam_ = ecmcAsynPort->addNewAvailParam(
|
dataParam_ = ecmcAsynPort->addNewAvailParam(
|
||||||
paramName.c_str(), // name
|
paramName.c_str(), // name
|
||||||
@@ -582,157 +620,34 @@ void ecmcCANOpenSDO::initAsyn() {
|
|||||||
|
|
||||||
dataParam_->setAllowWriteToEcmc(rw_ == DIR_WRITE);
|
dataParam_->setAllowWriteToEcmc(rw_ == DIR_WRITE);
|
||||||
|
|
||||||
|
if(rw_ == DIR_WRITE) {
|
||||||
|
dataParam_->setExeCmdFunctPtr(asynWriteSDOValue,this);
|
||||||
|
}
|
||||||
|
|
||||||
dataParam_->refreshParam(1); // read once into asyn param lib
|
dataParam_->refreshParam(1); // read once into asyn param lib
|
||||||
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
||||||
|
|
||||||
// Add enable "plugin.scope%d.enable"
|
// Add resultdata "plugin.can.dev%d.error"
|
||||||
/*paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
paramName = ECMC_PLUGIN_ASYN_PREFIX + std::string(".dev") +
|
||||||
"." + ECMC_PLUGIN_ASYN_ENABLE;
|
to_string(nodeId_) + ".sdo" /*+ to_string(objIndex_)*/ + std::string(".error");
|
||||||
|
|
||||||
enbaleParam_ = ecmcAsynPort->addNewAvailParam(
|
errorParam_ = ecmcAsynPort->addNewAvailParam(
|
||||||
paramName.c_str(), // name
|
paramName.c_str(), // name
|
||||||
asynParamInt32, // asyn type
|
asynParamInt32, // asyn type
|
||||||
(uint8_t*)&cfgEnable_, // pointer to data
|
(uint8_t*)&errorCode_, // pointer to data
|
||||||
sizeof(cfgEnable_), // size of data
|
sizeof(errorCode_), // size of data
|
||||||
ECMC_EC_S32, // ecmc data type
|
ECMC_EC_U32, // ecmc data type
|
||||||
0); // die if fail
|
0); // die if fail
|
||||||
|
|
||||||
if(!enbaleParam_) {
|
if(!errorParam_) {
|
||||||
SOCKETCAN_DBG_PRINT("ERROR: Failed create asyn param for enable.");
|
printf("ERROR: Failed create asyn param for data.");
|
||||||
throw std::runtime_error( "ERROR: Failed create asyn param for enable: " + paramName);
|
throw std::runtime_error( "ERROR: Failed create asyn param for data: " + paramName);
|
||||||
}
|
}
|
||||||
|
|
||||||
enbaleParam_->setAllowWriteToEcmc(true);
|
errorParam_->setAllowWriteToEcmc(false); // need to callback here
|
||||||
enbaleParam_->refreshParam(1); // read once into asyn param lib
|
errorParam_->refreshParam(1); // read once into asyn param lib
|
||||||
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
||||||
|
|
||||||
// Add missed triggers "plugin.scope%d.missed"
|
|
||||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
|
||||||
"." + ECMC_PLUGIN_ASYN_MISSED;
|
|
||||||
|
|
||||||
asynMissedTriggs_ = ecmcAsynPort->addNewAvailParam(
|
|
||||||
paramName.c_str(), // name
|
|
||||||
asynParamInt32, // asyn type
|
|
||||||
(uint8_t*)&missedTriggs_, // pointer to data
|
|
||||||
sizeof(missedTriggs_), // size of data
|
|
||||||
ECMC_EC_S32, // ecmc data type
|
|
||||||
0); // die if fail
|
|
||||||
|
|
||||||
if(!asynMissedTriggs_) {
|
|
||||||
SOCKETCAN_DBG_PRINT("ERROR: Failed create asyn param for missed trigg counter.");
|
|
||||||
throw std::runtime_error( "ERROR: Failed create asyn param for missed trigg counter: " + paramName);
|
|
||||||
}
|
|
||||||
|
|
||||||
asynMissedTriggs_->setAllowWriteToEcmc(false);
|
|
||||||
asynMissedTriggs_->refreshParam(1); // read once into asyn param lib
|
|
||||||
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
|
||||||
|
|
||||||
// Add trigger counter "plugin.scope%d.count"
|
|
||||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
|
||||||
"." + ECMC_PLUGIN_ASYN_TRIGG_COUNT;
|
|
||||||
|
|
||||||
asynTriggerCounter_ = ecmcAsynPort->addNewAvailParam(
|
|
||||||
paramName.c_str(), // name
|
|
||||||
asynParamInt32, // asyn type
|
|
||||||
(uint8_t*)&triggerCounter_, // pointer to data
|
|
||||||
sizeof(triggerCounter_), // size of data
|
|
||||||
ECMC_EC_S32, // ecmc data type
|
|
||||||
0); // die if fail
|
|
||||||
|
|
||||||
if(!asynTriggerCounter_) {
|
|
||||||
SOCKETCAN_DBG_PRINT("ERROR: Failed create asyn param for trigg counter.");
|
|
||||||
throw std::runtime_error( "ERROR: Failed create asyn param for trigg counter: " + paramName);
|
|
||||||
}
|
|
||||||
|
|
||||||
asynTriggerCounter_->setAllowWriteToEcmc(false);
|
|
||||||
asynTriggerCounter_->refreshParam(1); // read once into asyn param lib
|
|
||||||
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
|
||||||
|
|
||||||
// Add trigger counter "plugin.scope%d.scantotrigg"
|
|
||||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
|
||||||
"." + ECMC_PLUGIN_ASYN_SCAN_TO_TRIGG_OFFSET;
|
|
||||||
|
|
||||||
asynTimeTrigg2Sample_ = ecmcAsynPort->addNewAvailParam(
|
|
||||||
paramName.c_str(), // name
|
|
||||||
asynParamFloat64, // asyn type
|
|
||||||
(uint8_t*)&samplesSinceLastTrigg_, // pointer to data
|
|
||||||
sizeof(samplesSinceLastTrigg_), // size of data
|
|
||||||
ECMC_EC_S64, // ecmc data type
|
|
||||||
0); // die if fail
|
|
||||||
|
|
||||||
if(!asynTimeTrigg2Sample_) {
|
|
||||||
SOCKETCAN_DBG_PRINT("ERROR: Failed create asyn param for time trigg to sample.");
|
|
||||||
throw std::runtime_error( "ERROR: Failed create asyn param for time trigg to sample: " + paramName);
|
|
||||||
}
|
|
||||||
|
|
||||||
asynTimeTrigg2Sample_->addSupportedAsynType(asynParamFloat64);
|
|
||||||
asynTimeTrigg2Sample_->setAllowWriteToEcmc(false);
|
|
||||||
asynTimeTrigg2Sample_->refreshParam(1); // read once into asyn param lib
|
|
||||||
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
|
||||||
|
|
||||||
// Add enable "plugin.scope%d.source"
|
|
||||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
|
||||||
"." + ECMC_PLUGIN_ASYN_SCOPE_SOURCE;
|
|
||||||
|
|
||||||
sourceStrParam_ = ecmcAsynPort->addNewAvailParam(
|
|
||||||
paramName.c_str(), // name
|
|
||||||
asynParamInt8Array, // asyn type
|
|
||||||
(uint8_t*)cfgDataSourceStr_,// pointer to data
|
|
||||||
strlen(cfgDataSourceStr_), // size of data
|
|
||||||
ECMC_EC_U8, // ecmc data type
|
|
||||||
0); // die if fail
|
|
||||||
|
|
||||||
if(!sourceStrParam_) {
|
|
||||||
SOCKETCAN_DBG_PRINT("ERROR: Failed create asyn param for data source.");
|
|
||||||
throw std::runtime_error( "ERROR: Failed create asyn param for data source: " + paramName);
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceStrParam_->setAllowWriteToEcmc(false); // read only
|
|
||||||
sourceStrParam_->refreshParam(1); // read once into asyn param lib
|
|
||||||
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
|
||||||
|
|
||||||
// Add enable "plugin.scope%d.trigg"
|
|
||||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
|
||||||
"." + ECMC_PLUGIN_ASYN_SCOPE_TRIGG;
|
|
||||||
|
|
||||||
triggStrParam_ = ecmcAsynPort->addNewAvailParam(
|
|
||||||
paramName.c_str(), // name
|
|
||||||
asynParamInt8Array, // asyn type
|
|
||||||
(uint8_t*)cfgTriggStr_,// pointer to data
|
|
||||||
strlen(cfgTriggStr_), // size of data
|
|
||||||
ECMC_EC_U8, // ecmc data type
|
|
||||||
0); // die if fail
|
|
||||||
|
|
||||||
if(!triggStrParam_) {
|
|
||||||
SOCKETCAN_DBG_PRINT("ERROR: Failed create asyn param for trigger.");
|
|
||||||
throw std::runtime_error( "ERROR: Failed create asyn param for trigger: " + paramName);
|
|
||||||
}
|
|
||||||
|
|
||||||
triggStrParam_->setAllowWriteToEcmc(false); // read only
|
|
||||||
triggStrParam_->refreshParam(1); // read once into asyn param lib
|
|
||||||
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
|
||||||
|
|
||||||
// Add enable "plugin.scope%d.nexttime"
|
|
||||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
|
||||||
"." + ECMC_PLUGIN_ASYN_SCOPE_NEXT_SYNC;
|
|
||||||
|
|
||||||
sourceNexttimeStrParam_ = ecmcAsynPort->addNewAvailParam(
|
|
||||||
paramName.c_str(), // name
|
|
||||||
asynParamInt8Array, // asyn type
|
|
||||||
(uint8_t*)cfgDataNexttimeStr_,// pointer to data
|
|
||||||
strlen(cfgDataNexttimeStr_), // size of data
|
|
||||||
ECMC_EC_U8, // ecmc data type
|
|
||||||
0); // die if fail
|
|
||||||
|
|
||||||
if(!sourceNexttimeStrParam_) {
|
|
||||||
SOCKETCAN_DBG_PRINT("ERROR: Failed create asyn param for nexttime.");
|
|
||||||
throw std::runtime_error( "ERROR: Failed create asyn param for nexttime: " + paramName);
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceNexttimeStrParam_->setAllowWriteToEcmc(false); // read only
|
|
||||||
sourceNexttimeStrParam_->refreshParam(1); // read once into asyn param lib
|
|
||||||
ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid issues with std:to_string()
|
// Avoid issues with std:to_string()
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class ecmcCANOpenSDO {
|
|||||||
int exeSampleTimeMs,
|
int exeSampleTimeMs,
|
||||||
const char *name,
|
const char *name,
|
||||||
std::atomic_flag *ptrSdo1Lock,
|
std::atomic_flag *ptrSdo1Lock,
|
||||||
|
int objIndex,
|
||||||
int dbgMode);
|
int dbgMode);
|
||||||
~ecmcCANOpenSDO();
|
~ecmcCANOpenSDO();
|
||||||
void execute();
|
void execute();
|
||||||
@@ -86,8 +87,10 @@ class ecmcCANOpenSDO {
|
|||||||
|
|
||||||
int dbgMode_;
|
int dbgMode_;
|
||||||
int errorCode_;
|
int errorCode_;
|
||||||
|
int objIndex_;
|
||||||
|
|
||||||
uint8_t *dataBuffer_;
|
uint8_t *dataBuffer_;
|
||||||
uint8_t *tempReadBuffer_;
|
uint8_t *tempDataBuffer_;
|
||||||
uint32_t recivedBytes_;
|
uint32_t recivedBytes_;
|
||||||
int useTg1Frame_;
|
int useTg1Frame_;
|
||||||
ecmc_read_states readStates_;
|
ecmc_read_states readStates_;
|
||||||
@@ -100,12 +103,16 @@ class ecmcCANOpenSDO {
|
|||||||
int busyCounter_;
|
int busyCounter_;
|
||||||
std::atomic_flag *ptrSdo1Lock_;
|
std::atomic_flag *ptrSdo1Lock_;
|
||||||
bool busy_;
|
bool busy_;
|
||||||
|
bool writePending_;
|
||||||
|
|
||||||
//ASYN
|
//ASYN
|
||||||
void initAsyn();
|
void initAsyn();
|
||||||
static std::string to_string(int value);
|
static std::string to_string(int value);
|
||||||
|
|
||||||
ecmcAsynDataItem *dataParam_;
|
ecmcAsynDataItem *dataParam_;
|
||||||
|
ecmcAsynDataItem *errorParam_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* ECMC_CANOPEN_SDO_H_ */
|
#endif /* ECMC_CANOPEN_SDO_H_ */
|
||||||
|
|||||||
+12
-12
@@ -1,12 +1,12 @@
|
|||||||
REQMOD:mcag-trgt-muts--26598:MODULES
|
REQMOD:mcag-trgt-muts--6100:MODULES
|
||||||
REQMOD:mcag-trgt-muts--26598:VERSIONS
|
REQMOD:mcag-trgt-muts--6100:VERSIONS
|
||||||
REQMOD:mcag-trgt-muts--26598:MOD_VER
|
REQMOD:mcag-trgt-muts--6100:MOD_VER
|
||||||
REQMOD:mcag-trgt-muts--26598:exit
|
REQMOD:mcag-trgt-muts--6100:exit
|
||||||
REQMOD:mcag-trgt-muts--26598:BaseVersion
|
REQMOD:mcag-trgt-muts--6100:BaseVersion
|
||||||
REQMOD:mcag-trgt-muts--26598:require_VER
|
REQMOD:mcag-trgt-muts--6100:require_VER
|
||||||
REQMOD:mcag-trgt-muts--26598:ecmccfg_VER
|
REQMOD:mcag-trgt-muts--6100:ecmccfg_VER
|
||||||
REQMOD:mcag-trgt-muts--26598:asyn_VER
|
REQMOD:mcag-trgt-muts--6100:asyn_VER
|
||||||
REQMOD:mcag-trgt-muts--26598:exprtk_VER
|
REQMOD:mcag-trgt-muts--6100:exprtk_VER
|
||||||
REQMOD:mcag-trgt-muts--26598:motor_VER
|
REQMOD:mcag-trgt-muts--6100:motor_VER
|
||||||
REQMOD:mcag-trgt-muts--26598:ecmc_VER
|
REQMOD:mcag-trgt-muts--6100:ecmc_VER
|
||||||
REQMOD:mcag-trgt-muts--26598:ecmc_plugin_socketcan_VER
|
REQMOD:mcag-trgt-muts--6100:ecmc_plugin_socketcan_VER
|
||||||
|
|||||||
Reference in New Issue
Block a user