Merge branch 'amor-selene'
Conflicts: .gitignore sinqEPICSApp/src/pmacAxis.cpp sinqEPICSApp/src/pmacAxis.h sinqEPICSApp/src/pmacController.cpp sinqEPICSApp/src/pmacController.h
This commit is contained in:
124
.gitignore
vendored
124
.gitignore
vendored
@ -1,3 +1,121 @@
|
|||||||
O.*
|
# Took these from the https://github.com/github/gitignore project on October 21, 2011
|
||||||
.cvsignore
|
|
||||||
.gitignore
|
# **** 'Personal' entries don't belong in here - put them in your .git/info/exclude file ****
|
||||||
|
|
||||||
|
# Ignore text editor (e.g. emacs) autosave files
|
||||||
|
*~
|
||||||
|
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.d
|
||||||
|
SICServer*
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
|
||||||
|
# Compiled python files
|
||||||
|
*.py[co]
|
||||||
|
|
||||||
|
# Eclipse-generated files
|
||||||
|
*.pydevproject
|
||||||
|
.project
|
||||||
|
.metadata
|
||||||
|
bin/**
|
||||||
|
tmp/**
|
||||||
|
tmp/**/*
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.classpath
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# CDT-specific
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# PDT-specific
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
*.sln
|
||||||
|
*.vcproj
|
||||||
|
*.exe
|
||||||
|
*.vcxproj
|
||||||
|
*.filters
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
*.sdf
|
||||||
|
|
||||||
|
#Test results
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.vspscc
|
||||||
|
.builds
|
||||||
|
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Others
|
||||||
|
*.autosave
|
||||||
|
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
|
||||||
|
# Mac OS X Finder
|
||||||
|
.DS_Store
|
||||||
|
._*
|
||||||
|
1
10-llbDevices.rules
Normal file
1
10-llbDevices.rules
Normal file
@ -0,0 +1 @@
|
|||||||
|
SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="1002", MODE="0666" GROUP="plugdev", TAG+="uaccess"
|
@ -2,7 +2,7 @@
|
|||||||
include /ioc/tools/driver.makefile
|
include /ioc/tools/driver.makefile
|
||||||
|
|
||||||
MODULE=sinq
|
MODULE=sinq
|
||||||
|
LIBVERSION=koennecke
|
||||||
BUILDCLASSES=Linux
|
BUILDCLASSES=Linux
|
||||||
|
|
||||||
# additional module dependencies
|
# additional module dependencies
|
||||||
|
6
sinqEPICSApp/Db/motorSet.db
Normal file
6
sinqEPICSApp/Db/motorSet.db
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# workaround over set position
|
||||||
|
record(ao, "$(P)$(M)-SetPosition") {
|
||||||
|
field(DTYP, "asynFloat64")
|
||||||
|
field(OUT, "@asyn($(PORT),$(N),1) SET_MOTOR_POSITION")
|
||||||
|
field(PINI, "YES")
|
||||||
|
}
|
@ -10,8 +10,8 @@
|
|||||||
#include "SINQController.h"
|
#include "SINQController.h"
|
||||||
#include "asynMotorController.h"
|
#include "asynMotorController.h"
|
||||||
|
|
||||||
SINQController::SINQController(const char *portName, const char *SINQPortName, int numAxes)
|
SINQController::SINQController(const char *portName, const char *SINQPortName, int numAxes, const int& extraParams)
|
||||||
: asynMotorController(portName, numAxes+1, NUM_MOTOR_DRIVER_PARAMS+2,
|
: asynMotorController(portName, numAxes+1, NUM_MOTOR_DRIVER_PARAMS+extraParams,
|
||||||
0, // No additional interfaces beyond those in base class
|
0, // No additional interfaces beyond those in base class
|
||||||
0, // No additional callback interfaces beyond those in base class
|
0, // No additional callback interfaces beyond those in base class
|
||||||
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
|
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
class epicsShareClass SINQController : public asynMotorController
|
class epicsShareClass SINQController : public asynMotorController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SINQController(const char *portName, const char *SINQPortName, int numAxes);
|
SINQController(const char *portName, const char *SINQPortName, int numAxes, const int& extraParams=2);
|
||||||
|
|
||||||
friend class SINQAxis;
|
friend class SINQAxis;
|
||||||
protected:
|
protected:
|
||||||
|
@ -44,6 +44,9 @@
|
|||||||
|
|
||||||
#define MULT 1000.
|
#define MULT 1000.
|
||||||
|
|
||||||
|
#define IDLEPOLL 2.
|
||||||
|
#define BUSYPOLL .05
|
||||||
|
|
||||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||||
|
|
||||||
extern "C" void shutdownCallback(void *pPvt)
|
extern "C" void shutdownCallback(void *pPvt)
|
||||||
@ -56,9 +59,10 @@ extern "C" void shutdownCallback(void *pPvt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// These are the pmacAxis class methods
|
// These are the pmacAxis class methods
|
||||||
pmacAxis::pmacAxis(pmacController *pC, int axisNo)
|
pmacAxis::pmacAxis(pmacController *pC, int axisNo, bool enable)
|
||||||
: SINQAxis(pC, axisNo),
|
: SINQAxis(pC, axisNo),
|
||||||
pC_(pC)
|
pC_(pC),
|
||||||
|
autoEnable(enable)
|
||||||
{
|
{
|
||||||
static const char *functionName = "pmacAxis::pmacAxis";
|
static const char *functionName = "pmacAxis::pmacAxis";
|
||||||
|
|
||||||
@ -80,6 +84,7 @@ pmacAxis::pmacAxis(pmacController *pC, int axisNo)
|
|||||||
status6Time = 0;
|
status6Time = 0;
|
||||||
starting = 0;
|
starting = 0;
|
||||||
homing = 0;
|
homing = 0;
|
||||||
|
next_poll = -1;
|
||||||
|
|
||||||
/* Set an EPICS exit handler that will shut down polling before asyn kills the IP sockets */
|
/* Set an EPICS exit handler that will shut down polling before asyn kills the IP sockets */
|
||||||
epicsAtExit(shutdownCallback, pC_);
|
epicsAtExit(shutdownCallback, pC_);
|
||||||
@ -156,13 +161,18 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enable the axis. After startup, the axis are disabled on the controller...
|
// Enable the axis. After startup, the axis are disabled on the controller...
|
||||||
sprintf(command, "M%2.2d14=1", axisNo_);
|
// Warning: Selene lift axis should not be automatically enabled
|
||||||
cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
|
|
||||||
if (cmdStatus ) {
|
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: enaabling axis %d failed.\n", functionName, axisNo_);
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (autoEnable) {
|
||||||
|
sprintf(command, "M%2.2d14=1\n", axisNo_);
|
||||||
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "Enable axis %d: %s",axisNo_,command);
|
||||||
|
cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
|
||||||
|
if (cmdStatus ) {
|
||||||
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: enaabling axis %d failed.\n", functionName, axisNo_);
|
||||||
|
return asynError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callParamCallbacks();
|
callParamCallbacks();
|
||||||
|
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
@ -202,7 +212,9 @@ asynStatus pmacAxis::move(double position, int relative, double min_velocity, do
|
|||||||
sprintf( command, "P%2.2d23=0 Q%2.2d01=%12.4f M%2.2d=1", axisNo_, axisNo_, realPosition, axisNo_);
|
sprintf( command, "P%2.2d23=0 Q%2.2d01=%12.4f M%2.2d=1", axisNo_, axisNo_, realPosition, axisNo_);
|
||||||
|
|
||||||
status = pC_->lowLevelWriteRead(axisNo_,command, response);
|
status = pC_->lowLevelWriteRead(axisNo_,command, response);
|
||||||
|
|
||||||
|
next_poll = -1;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +236,8 @@ asynStatus pmacAxis::home(double min_velocity, double max_velocity, double accel
|
|||||||
status = pC_->lowLevelWriteRead(axisNo_,command, response);
|
status = pC_->lowLevelWriteRead(axisNo_,command, response);
|
||||||
homing = 1;
|
homing = 1;
|
||||||
|
|
||||||
|
next_poll = time(NULL) + BUSYPOLL;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +260,8 @@ asynStatus pmacAxis::setPosition(double position)
|
|||||||
{
|
{
|
||||||
//int status = 0;
|
//int status = 0;
|
||||||
static const char *functionName = "pmacAxis::setPosition";
|
static const char *functionName = "pmacAxis::setPosition";
|
||||||
|
errlogPrintf("executing : %s\n", functionName);
|
||||||
|
|
||||||
pC_->debugFlow(functionName);
|
pC_->debugFlow(functionName);
|
||||||
|
|
||||||
// Cannot do this.
|
// Cannot do this.
|
||||||
@ -276,6 +291,11 @@ asynStatus pmacAxis::poll(bool *moving)
|
|||||||
static const char *functionName = "pmacAxis::poll";
|
static const char *functionName = "pmacAxis::poll";
|
||||||
char message[132];
|
char message[132];
|
||||||
|
|
||||||
|
// Protect against excessive polling
|
||||||
|
if(time(NULL) < next_poll){
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(message, "%s: Polling axis: %d", functionName, this->axisNo_);
|
sprintf(message, "%s: Polling axis: %d", functionName, this->axisNo_);
|
||||||
pC_->debugFlow(message);
|
pC_->debugFlow(message);
|
||||||
|
|
||||||
@ -284,7 +304,13 @@ asynStatus pmacAxis::poll(bool *moving)
|
|||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"%s: getAxisStatus failed to return asynSuccess. Controller: %s, Axis: %d.\n", functionName, pC_->portName, axisNo_);
|
"%s: getAxisStatus failed to return asynSuccess. Controller: %s, Axis: %d.\n", functionName, pC_->portName, axisNo_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(*moving){
|
||||||
|
next_poll = time(NULL) + BUSYPOLL;
|
||||||
|
} else {
|
||||||
|
next_poll = time(NULL) + IDLEPOLL;
|
||||||
|
}
|
||||||
|
|
||||||
callParamCallbacks();
|
callParamCallbacks();
|
||||||
return status ? asynError : asynSuccess;
|
return status ? asynError : asynSuccess;
|
||||||
}
|
}
|
||||||
@ -345,8 +371,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
|
|||||||
int done = 0, posChanging = 0;
|
int done = 0, posChanging = 0;
|
||||||
double position = 0;
|
double position = 0;
|
||||||
int nvals = 0;
|
int nvals = 0;
|
||||||
int axisProblemFlag = 0;
|
int axisProblemFlag = 0, axStat = 0;
|
||||||
epicsUInt32 axErr = 0, axStat = 0, highLim = 0, lowLim= 0;
|
epicsUInt32 axErr = 0, highLim = 0, lowLim= 0;
|
||||||
char message[132], *axMessage;
|
char message[132], *axMessage;
|
||||||
|
|
||||||
|
|
||||||
@ -744,6 +770,9 @@ asynStatus SeleneAxis::setPosition(double position)
|
|||||||
"Setting Position on %d to value %f, command: %s",
|
"Setting Position on %d to value %f, command: %s",
|
||||||
axisNo_, position/MULT, command);
|
axisNo_, position/MULT, command);
|
||||||
|
|
||||||
|
|
||||||
|
next_poll = -1;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
/*======================================= Selene Lift Axis Code ===========================================*/
|
/*======================================= Selene Lift Axis Code ===========================================*/
|
||||||
@ -776,6 +805,8 @@ asynStatus LiftAxis::move(double position, int relative, double min_velocity,
|
|||||||
status = pC_->lowLevelWriteRead(axisNo_,command, response);
|
status = pC_->lowLevelWriteRead(axisNo_,command, response);
|
||||||
waitStart = 1;
|
waitStart = 1;
|
||||||
|
|
||||||
|
next_poll = -1;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------------------------------
|
||||||
@ -786,6 +817,11 @@ asynStatus LiftAxis::poll(bool *moving)
|
|||||||
{
|
{
|
||||||
asynStatus status;
|
asynStatus status;
|
||||||
|
|
||||||
|
// Protect against excessive polling
|
||||||
|
if(time(NULL) < next_poll){
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
status = getAxisStatus(moving);
|
status = getAxisStatus(moving);
|
||||||
if(*moving == false && waitStart == 1){
|
if(*moving == false && waitStart == 1){
|
||||||
*moving = true;
|
*moving = true;
|
||||||
@ -795,6 +831,12 @@ asynStatus LiftAxis::poll(bool *moving)
|
|||||||
if(*moving){
|
if(*moving){
|
||||||
waitStart = 0;
|
waitStart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(*moving){
|
||||||
|
next_poll = time(NULL) + BUSYPOLL;
|
||||||
|
} else {
|
||||||
|
next_poll = time(NULL) + IDLEPOLL;
|
||||||
|
}
|
||||||
callParamCallbacks();
|
callParamCallbacks();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ class pmacAxis : public SINQAxis
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* These are the methods we override from the base class */
|
/* These are the methods we override from the base class */
|
||||||
pmacAxis(pmacController *pController, int axisNo);
|
pmacAxis(pmacController *pController, int axisNo, bool enable=true);
|
||||||
virtual ~pmacAxis();
|
virtual ~pmacAxis();
|
||||||
asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration);
|
asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration);
|
||||||
asynStatus moveVelocity(double min_velocity, double max_velocity, double acceleration);
|
asynStatus moveVelocity(double min_velocity, double max_velocity, double acceleration);
|
||||||
@ -62,6 +62,10 @@ class pmacAxis : public SINQAxis
|
|||||||
int homing;
|
int homing;
|
||||||
double statusPos;
|
double statusPos;
|
||||||
|
|
||||||
|
time_t next_poll;
|
||||||
|
|
||||||
|
bool autoEnable;
|
||||||
|
|
||||||
friend class pmacController;
|
friend class pmacController;
|
||||||
};
|
};
|
||||||
/*----------------------------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------------------------*/
|
||||||
@ -83,12 +87,11 @@ class pmacHRPTAxis : public pmacAxis
|
|||||||
/*--------------------------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------------------------*/
|
||||||
class SeleneAxis : public pmacAxis
|
class SeleneAxis : public pmacAxis
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
public:
|
SeleneAxis(SeleneController *pController, int axisNo, double limitTarget);
|
||||||
SeleneAxis(SeleneController *pController, int axisNo, double limitTarget);
|
asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration);
|
||||||
asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration);
|
asynStatus setPosition(double position);
|
||||||
asynStatus setPosition(double position);
|
asynStatus home(double min_velocity, double max_velocity, double acceleration, int forwards);
|
||||||
asynStatus home(double min_velocity, double max_velocity, double acceleration, int forwards);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class SeleneController;
|
friend class SeleneController;
|
||||||
@ -112,6 +115,10 @@ class SeleneAxis : public pmacAxis
|
|||||||
|
|
||||||
Mark Koennecke, February 2020
|
Mark Koennecke, February 2020
|
||||||
|
|
||||||
|
The axis should not be enabled automatically
|
||||||
|
|
||||||
|
Michele Brambilla, February 2020
|
||||||
|
|
||||||
*/
|
*/
|
||||||
class LiftAxis : public pmacAxis
|
class LiftAxis : public pmacAxis
|
||||||
{
|
{
|
||||||
|
@ -140,8 +140,8 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pmacController::pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
pmacController::pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||||
int numAxes, double movingPollPeriod, double idlePollPeriod)
|
int numAxes, double movingPollPeriod, double idlePollPeriod, const int& extraParams)
|
||||||
: SINQController(portName, lowLevelPortName, numAxes+1)
|
: SINQController(portName, lowLevelPortName, numAxes+1, extraParams)
|
||||||
{
|
{
|
||||||
static const char *functionName = "pmacController::pmacController";
|
static const char *functionName = "pmacController::pmacController";
|
||||||
|
|
||||||
@ -544,7 +544,20 @@ asynStatus SeleneCreateController(const char *portName, const char *lowLevelPort
|
|||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
SeleneController::SeleneController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||||
|
int numAxes, double movingPollPeriod, double idlePollPeriod) : pmacController(portName,
|
||||||
|
lowLevelPortName,
|
||||||
|
lowLevelPortAddress,
|
||||||
|
numAxes,
|
||||||
|
movingPollPeriod,
|
||||||
|
idlePollPeriod, 3) {
|
||||||
|
static const char *functionName = "seleneController::seleneController";
|
||||||
|
createParam(MotorSetPositionString, asynParamFloat64, &setMotorPosition_);
|
||||||
|
callParamCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C wrapper for the pmacAxis constructor.
|
* C wrapper for the pmacAxis constructor.
|
||||||
* See pmacAxis::pmacAxis.
|
* See pmacAxis::pmacAxis.
|
||||||
@ -711,9 +724,9 @@ asynStatus SeleneController::writeFloat64(asynUser *pasynUser, epicsFloat64 valu
|
|||||||
/* Set the parameter and readback in the parameter library. */
|
/* Set the parameter and readback in the parameter library. */
|
||||||
status = pAxis->setDoubleParam(function, value);
|
status = pAxis->setDoubleParam(function, value);
|
||||||
|
|
||||||
// TODO: somethign is really shitty here: lowLimit and highLimit cannot be on the command
|
|
||||||
if (function == motorLowLimit_) {
|
if (function == motorLowLimit_) {
|
||||||
sprintf(command, "Q%d54=%f", pAxis->axisNo_, (float)value/(float)MULT);
|
sprintf(command, "Q%d54=%f", pAxis->axisNo_, (float)value/(float)MULT);
|
||||||
|
// sprintf(command, "Q%d54=%d", pAxis->axisNo_, (int)(value/pAxis->scale_/MULT));
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||||
"%s: Setting low limit on controller %s, axis %d to %f\n",
|
"%s: Setting low limit on controller %s, axis %d to %f\n",
|
||||||
functionName, portName, pAxis->axisNo_, value);
|
functionName, portName, pAxis->axisNo_, value);
|
||||||
@ -724,7 +737,13 @@ asynStatus SeleneController::writeFloat64(asynUser *pasynUser, epicsFloat64 valu
|
|||||||
"%s: Setting high limit on controller %s, axis %d to %f\n",
|
"%s: Setting high limit on controller %s, axis %d to %f\n",
|
||||||
functionName, portName, pAxis->axisNo_, value);
|
functionName, portName, pAxis->axisNo_, value);
|
||||||
errlogPrintf("Setting high limit of axis %d to %f, command = %s\n", pAxis->axisNo_, value, command);
|
errlogPrintf("Setting high limit of axis %d to %f, command = %s\n", pAxis->axisNo_, value, command);
|
||||||
}
|
} else if(function == setMotorPosition_){
|
||||||
|
snprintf(command,sizeof(command),"Q%d59=%f", pAxis->axisNo_, value);
|
||||||
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||||
|
"%s: Defining position of axis%d to %f\n",
|
||||||
|
functionName, pAxis->axisNo_, value);
|
||||||
|
errlogPrintf("Defining position of axis %d to %f, command = %s\n", pAxis->axisNo_, value, command);
|
||||||
|
}
|
||||||
|
|
||||||
//Execute the command.
|
//Execute the command.
|
||||||
if (command[0] != 0 && status == asynSuccess) {
|
if (command[0] != 0 && status == asynSuccess) {
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
class pmacController : public SINQController {
|
class pmacController : public SINQController {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, int numAxes, double movingPollPeriod,
|
pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, int numAxes, double movingPollPeriod,
|
||||||
double idlePollPeriod);
|
double idlePollPeriod, const int& extraParams=2);
|
||||||
|
|
||||||
virtual ~pmacController();
|
virtual ~pmacController();
|
||||||
|
|
||||||
@ -143,22 +143,24 @@ class pmacController : public SINQController {
|
|||||||
|
|
||||||
#define NUM_PMAC_PARAMS (&LAST_PMAC_PARAM - &FIRST_PMAC_PARAM + 1)
|
#define NUM_PMAC_PARAMS (&LAST_PMAC_PARAM - &FIRST_PMAC_PARAM + 1)
|
||||||
|
|
||||||
|
#define MotorSetPositionString "SET_MOTOR_POSITION"
|
||||||
|
|
||||||
class SeleneController : public pmacController {
|
class SeleneController : public pmacController {
|
||||||
public:
|
public:
|
||||||
SeleneController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
SeleneController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||||
int numAxes, double movingPollPeriod, double idlePollPeriod) : pmacController(portName,
|
int numAxes, double movingPollPeriod, double idlePollPeriod);
|
||||||
lowLevelPortName,
|
|
||||||
lowLevelPortAddress,
|
~SeleneController(void) { }
|
||||||
numAxes,
|
|
||||||
movingPollPeriod,
|
|
||||||
idlePollPeriod) {};
|
|
||||||
|
|
||||||
// overloaded because we have a different command to set the limits
|
// overloaded because we have a different command to set the limits
|
||||||
asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
|
asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
|
||||||
|
|
||||||
friend class SeleneAxis;
|
friend class SeleneAxis;
|
||||||
friend class pmacAxis;
|
friend class pmacAxis;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int setMotorPosition_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
88
testEuroMoveUsb.py
Executable file
88
testEuroMoveUsb.py
Executable file
@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: iso-8859-1 -*-
|
||||||
|
"""
|
||||||
|
Created on Thur Feb 06 10:22:42 2020
|
||||||
|
|
||||||
|
@author: gaston emmanuel exil
|
||||||
|
"""
|
||||||
|
|
||||||
|
#pip install pyusb
|
||||||
|
#sudo cp 10-llbDevices.rules /etc/udev/rules.d/
|
||||||
|
#sudo udevadm control --reload-rules && udevadm trigger
|
||||||
|
#reboot
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import usb.core
|
||||||
|
import usb.util
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
# 1. Device
|
||||||
|
llbVendorID=0x04B4
|
||||||
|
llbProductID=0x1002
|
||||||
|
|
||||||
|
# 2. Configuration
|
||||||
|
CONFIGURATION_EV3 = 1 # 1-based
|
||||||
|
# 3. Interface
|
||||||
|
INTERFACE_EV3 = 0 # 0-based
|
||||||
|
# 4. Alternate setting
|
||||||
|
SETTING_EV3 = 0 # 0-based
|
||||||
|
# 5. Endpoint
|
||||||
|
ENDPOINT_EV3 = 1 # 0-based
|
||||||
|
|
||||||
|
# find our device
|
||||||
|
device = usb.core.find(idVendor=llbVendorID, idProduct=llbProductID)
|
||||||
|
|
||||||
|
# was it found?
|
||||||
|
if device is None:
|
||||||
|
raise ValueError('Device not found')
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
if device._manufacturer is None:
|
||||||
|
device._manufacturer = usb.util.get_string(device, device.iManufacturer)
|
||||||
|
print("manufacturer: ", str(device._manufacturer))
|
||||||
|
if device._product is None:
|
||||||
|
device._product = usb.util.get_string(device, device.iProduct)
|
||||||
|
print("product: ", str(device._product))
|
||||||
|
|
||||||
|
|
||||||
|
# By default, the kernel will claim the device and make it available via
|
||||||
|
# /dev/usb/hiddevN and /dev/hidrawN which also prevents us
|
||||||
|
# from communicating otherwise. This removes these kernel devices.
|
||||||
|
# Yes, it is weird to specify an interface before we get to a configuration.
|
||||||
|
|
||||||
|
if device.is_kernel_driver_active(INTERFACE_EV3):
|
||||||
|
print("Detaching kernel driver")
|
||||||
|
device.detach_kernel_driver(INTERFACE_EV3)
|
||||||
|
|
||||||
|
# claim the device
|
||||||
|
usb.util.claim_interface(device, INTERFACE_EV3)
|
||||||
|
|
||||||
|
# write endpoint
|
||||||
|
endpoint_BulkOut = device[0][(0,0)][0]
|
||||||
|
# Read endpoint
|
||||||
|
endpoint_BulkIn = device[0][(0,0)][2]
|
||||||
|
try:
|
||||||
|
command = "L"+chr(13)
|
||||||
|
assert device.write(endpoint_BulkOut, command.encode('utf-8'), 100) == len(command)
|
||||||
|
ret = device.read(endpoint_BulkIn, endpoint_BulkIn.wMaxPacketSize, timeout=30000)
|
||||||
|
print(ret)
|
||||||
|
#byte_str = "".join(chr(n) for n in ret)
|
||||||
|
print(ret.tostring())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
command = "A1,4"+chr(13)
|
||||||
|
assert device.write(endpoint_BulkOut, command.encode('utf-8'), 100) == len(command)
|
||||||
|
ret = device.read(endpoint_BulkIn, endpoint_BulkIn.wMaxPacketSize, timeout=30000)
|
||||||
|
print(ret)
|
||||||
|
byte_str = "".join(chr(n) for n in ret)
|
||||||
|
print(ret.tostring())
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
|
||||||
|
# release the device
|
||||||
|
usb.util.release_interface(device, INTERFACE_EV3)
|
||||||
|
# reattach the device to the OS kernel
|
||||||
|
#device.attach_kernel_driver(INTERFACE_EV3)
|
Reference in New Issue
Block a user