Initial version of sinqMotor
This commit is contained in:
246
.clang-format
Normal file
246
.clang-format
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveShortCaseStatements:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCaseColons: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
OverEmptyLines: 0
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowBreakBeforeNoexceptSpecifier: Never
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortCompoundRequirementOnASingleLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakAdjacentStringLiterals: true
|
||||||
|
BreakAfterAttributes: Leave
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakArrays: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInlineASMColon: OnlyMultiline
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IfMacros:
|
||||||
|
- KJ_IF_MAYBE
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentRequiresClause: true
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertBraces: false
|
||||||
|
InsertNewlineAtEOF: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
IntegerLiteralSeparator:
|
||||||
|
Binary: 0
|
||||||
|
BinaryMinDigits: 0
|
||||||
|
Decimal: 0
|
||||||
|
DecimalMinDigits: 0
|
||||||
|
Hex: 0
|
||||||
|
HexMinDigits: 0
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
KeepEmptyLinesAtEOF: false
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
LineEnding: DeriveLF
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PackConstructorInitializers: BinPack
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakScopeResolution: 500
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
PPIndentWidth: -1
|
||||||
|
QualifierAlignment: Leave
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: true
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RemoveParentheses: Leave
|
||||||
|
RemoveSemicolon: false
|
||||||
|
RequiresClausePosition: OwnLine
|
||||||
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
SeparateDefinitionBlocks: Leave
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SkipMacroDefinitionBody: false
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: LexicographicNumeric
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeJsonColon: false
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: true
|
||||||
|
AfterForeachMacros: true
|
||||||
|
AfterFunctionDefinitionName: false
|
||||||
|
AfterFunctionDeclarationName: false
|
||||||
|
AfterIfMacros: true
|
||||||
|
AfterOverloadedOperator: false
|
||||||
|
AfterPlacementOperator: true
|
||||||
|
AfterRequiresInClause: false
|
||||||
|
AfterRequiresInExpression: false
|
||||||
|
BeforeNonEmptyParentheses: false
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParens: Never
|
||||||
|
SpacesInParensOptions:
|
||||||
|
InCStyleCasts: false
|
||||||
|
InConditionalStatements: false
|
||||||
|
InEmptyParentheses: false
|
||||||
|
Other: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Latest
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
VerilogBreakBetweenInstancePorts: true
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- STRINGIZE
|
||||||
|
...
|
||||||
|
|
49
src/Makefile
Normal file
49
src/Makefile
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
TOP=../..
|
||||||
|
|
||||||
|
include $(TOP)/configure/CONFIG
|
||||||
|
#----------------------------------------
|
||||||
|
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||||
|
#=============================
|
||||||
|
|
||||||
|
#=============================
|
||||||
|
# Build the IOC application
|
||||||
|
|
||||||
|
PROD_IOC = sinqEPICS
|
||||||
|
# sinqEPICS.dbd will be created and installed
|
||||||
|
DBD += sinqEPICS.dbd
|
||||||
|
|
||||||
|
# sinqEPICS.dbd will be made up from these files:
|
||||||
|
sinqEPICS_DBD += base.dbd
|
||||||
|
|
||||||
|
# Include dbd files from all support applications:
|
||||||
|
sinqEPICS_DBD += sinq.dbd
|
||||||
|
#sinqEPICS_DBD += pmacAsynIPPort.dbd pmacAsynMotorPort.dbd
|
||||||
|
|
||||||
|
# Add all the support libraries needed by this IOC
|
||||||
|
sinqEPICS_LIBS += motor asyn busy synAppsStd streamdevice pcre
|
||||||
|
|
||||||
|
# sinqEPICS_registerRecordDeviceDriver.cpp derives from sinqEPICS.dbd
|
||||||
|
sinqEPICS_SRCS += sinqEPICS_registerRecordDeviceDriver.cpp
|
||||||
|
sinqEPICS_SRCS += EL734Driver.cpp devScalerEL737.c pmacAsynIPPort.c sinqAxis.cpp sinqController.cpp
|
||||||
|
sinqEPICS_SRCS += pmacController.cpp pmacAxis.cpp
|
||||||
|
sinqEPICS_SRCS += NanotecDriver.cpp stptok.cpp
|
||||||
|
sinqEPICS_SRCS += PhytronDriver.cpp
|
||||||
|
sinqEPICS_SRCS += EuroMoveDriver.cpp
|
||||||
|
|
||||||
|
|
||||||
|
# Build the main IOC entry point on workstation OSs.
|
||||||
|
sinqEPICS_SRCS_DEFAULT += sinqEPICSMain.cpp
|
||||||
|
sinqEPICS_SRCS_vxWorks += -nil-
|
||||||
|
|
||||||
|
# Add support from base/src/vxWorks if needed
|
||||||
|
#sinqEPICS_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
||||||
|
|
||||||
|
# Finally link to the EPICS Base libraries
|
||||||
|
sinqEPICS_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||||
|
|
||||||
|
#===========================
|
||||||
|
|
||||||
|
include $(TOP)/configure/RULES
|
||||||
|
#----------------------------------------
|
||||||
|
# ADD RULES AFTER THIS LINE
|
||||||
|
|
91
src/sinqAxis.cpp
Normal file
91
src/sinqAxis.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "sinqAxis.h"
|
||||||
|
#include "sinqController.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
sinqAxis::sinqAxis(class sinqController *pC, int axis)
|
||||||
|
: asynMotorAxis((asynMotorController *)pC, axis), pC_(pC) {
|
||||||
|
|
||||||
|
bool initial_poll_ = true;
|
||||||
|
int init_poll_counter_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
asynStatus sinqAxis::atFirstPoll() { return asynSuccess; }
|
||||||
|
|
||||||
|
asynStatus sinqAxis::poll(bool *moving) {
|
||||||
|
// Local variable declaration
|
||||||
|
asynStatus pl_status = asynSuccess;
|
||||||
|
asynStatus poll_status = asynSuccess;
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
// If this poll is the initial poll, check if the parameter library has
|
||||||
|
// already been initialized. If not, force EPCIS to repeat the poll until
|
||||||
|
// the initialization is complete (or until a timeout is reached). Once the
|
||||||
|
// parameter library has been initialized, read configuration data from the
|
||||||
|
// motor controller into it.
|
||||||
|
if (initial_poll_) {
|
||||||
|
poll_status = atFirstPoll();
|
||||||
|
if (poll_status == asynSuccess) {
|
||||||
|
initial_poll_ = false;
|
||||||
|
} else {
|
||||||
|
// Send a message to the IOC shell every 10 trials.
|
||||||
|
init_poll_counter_ += 1;
|
||||||
|
if (init_poll_counter_ % 10 == 0) {
|
||||||
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"%s => line %d:\nRunning function 'atFirstPoll' "
|
||||||
|
"failed %d times with error %s.",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__, init_poll_counter_,
|
||||||
|
pC_->stringifyAsynStatus(poll_status));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for 100 ms until trying the entire poll again
|
||||||
|
usleep(100000);
|
||||||
|
return poll_status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The poll function is just a wrapper around doPoll and
|
||||||
|
// handles mainly the callParamCallbacks() function. This wrapper is used
|
||||||
|
// to make sure callParamCallbacks() is called in case of a premature
|
||||||
|
// return.
|
||||||
|
poll_status = doPoll(moving);
|
||||||
|
|
||||||
|
// If the poll status is ok, reset the error indicators in the parameter
|
||||||
|
// library
|
||||||
|
if (poll_status == asynSuccess) {
|
||||||
|
pl_status = setIntegerParam(pC_->motorStatusProblem_, false);
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
pC_->paramLibAccessFailed(pl_status, "motorStatusProblem_",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
pl_status = setIntegerParam(pC_->motorStatusCommsError_, false);
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
pC_->paramLibAccessFailed(pl_status, "motorStatusCommsError_",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
pl_status = setStringParam(pC_->motorMessageText_, "");
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// According to the function documentation of asynMotorAxis::poll, this
|
||||||
|
// function should be called at the end of a poll implementation.
|
||||||
|
pl_status = callParamCallbacks();
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
// If we can't communicate with the parameter library, it doesn't make
|
||||||
|
// sense to try and upstream this to the user -> Just log the error
|
||||||
|
asynPrint(
|
||||||
|
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"%s => line %d:\ncallParamCallbacks failed with %s for axis %d",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__,
|
||||||
|
pC_->stringifyAsynStatus(poll_status), axisNo_);
|
||||||
|
poll_status = pl_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return poll_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
asynStatus sinqAxis::doPoll(bool *moving) { return asynSuccess; }
|
39
src/sinqAxis.h
Normal file
39
src/sinqAxis.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
This class extends asynMotorAxis by some features used in SINQ.
|
||||||
|
|
||||||
|
Stefan Mathis, November 2024
|
||||||
|
*/
|
||||||
|
#ifndef __SINQDRIVER
|
||||||
|
#define __SINQDRIVER
|
||||||
|
#include "asynMotorAxis.h"
|
||||||
|
|
||||||
|
class epicsShareClass sinqAxis : public asynMotorAxis {
|
||||||
|
public:
|
||||||
|
sinqAxis(class sinqController *pC_, int axis);
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function is executed at the very first poll after the IOC startup. If
|
||||||
|
it returns anything else than 'asynSuccess', the function is evaluated again
|
||||||
|
after 100 ms until it succeeds. Every 10 trials a warning is emitted.
|
||||||
|
*/
|
||||||
|
asynStatus atFirstPoll();
|
||||||
|
|
||||||
|
asynStatus poll(bool *moving);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Implementation of the "proper", device-specific poll method. This method
|
||||||
|
should be implemented by a child class of sinqAxis.
|
||||||
|
*/
|
||||||
|
asynStatus doPoll(bool *moving);
|
||||||
|
|
||||||
|
friend class sinqController;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool initial_poll_;
|
||||||
|
int init_poll_counter_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
sinqController *pC_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
124
src/sinqController.cpp
Normal file
124
src/sinqController.cpp
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
This class contains the necessary changes to have an additional text fields
|
||||||
|
for messages with each axis.
|
||||||
|
|
||||||
|
Code lifted from Torsten Boegershausen ESS code.
|
||||||
|
|
||||||
|
Mark Koennecke, March 2017
|
||||||
|
|
||||||
|
Added code to manage an interMessageSleep
|
||||||
|
|
||||||
|
Mark Koennecke, February 2024
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sinqController.h"
|
||||||
|
#include "asynMotorController.h"
|
||||||
|
#include "epicsExport.h"
|
||||||
|
#include "iocsh.h"
|
||||||
|
#include <errlog.h>
|
||||||
|
|
||||||
|
sinqController::sinqController(const char *portName, const char *SINQPortName,
|
||||||
|
int numAxes, const int &extraParams)
|
||||||
|
: asynMotorController(
|
||||||
|
portName, numAxes + 1, NUM_MOTOR_DRIVER_PARAMS + extraParams,
|
||||||
|
0, // No additional interfaces beyond those in base class
|
||||||
|
0, // No additional callback interfaces beyond those in base class
|
||||||
|
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
|
||||||
|
1, // autoconnect
|
||||||
|
0, 0) // Default priority and stack size
|
||||||
|
{
|
||||||
|
createParam(motorMessageIsFromDriverString, asynParamInt32,
|
||||||
|
&motorMessageIsFromDriver_);
|
||||||
|
createParam(motorMessageTextString, asynParamOctet, &motorMessageText_);
|
||||||
|
}
|
||||||
|
|
||||||
|
asynStatus sinqController::errMsgCouldNotParseResponse(const char *command,
|
||||||
|
const char *response,
|
||||||
|
int axisNo_,
|
||||||
|
const char *functionName,
|
||||||
|
int lineNumber) {
|
||||||
|
asynPrint(lowLevelPortUser_, ASYN_TRACE_ERROR,
|
||||||
|
"%s => line %d:\n Could not interpret response %s for "
|
||||||
|
"command %s.\n",
|
||||||
|
functionName, lineNumber, response, command);
|
||||||
|
|
||||||
|
setStringParam(motorMessageText_,
|
||||||
|
"Could not interpret MCU response. Please "
|
||||||
|
"call the software support");
|
||||||
|
setIntegerParam(motorStatusCommsError_, 1);
|
||||||
|
return asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
asynStatus sinqController::paramLibAccessFailed(asynStatus status,
|
||||||
|
const char *parameter,
|
||||||
|
const char *functionName,
|
||||||
|
int lineNumber) {
|
||||||
|
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
// Log the error message and try to propagate it
|
||||||
|
asynPrint(lowLevelPortUser_, ASYN_TRACE_ERROR,
|
||||||
|
"%s => line %d:\n Accessing the parameter library failed for "
|
||||||
|
"parameter %s",
|
||||||
|
functionName, lineNumber, parameter);
|
||||||
|
setStringParam(
|
||||||
|
motorMessageText_,
|
||||||
|
"Accessing paramLib failed. Please call the software support.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static pointers (valid for the entire lifetime of the IOC). The number behind
|
||||||
|
// the strings gives the integer number of each variant (see also method
|
||||||
|
// stringifyAsynStatus)
|
||||||
|
static char *asynSuccessStringified = "success"; // 0
|
||||||
|
static char *asynTimeoutStringified = "timeout"; // 1
|
||||||
|
static char *asynOverflowStringified = "overflow"; // 2
|
||||||
|
static char *asynErrorStringified = "error"; // 3
|
||||||
|
static char *asynDisconnectedStringified = "disconnected"; // 4
|
||||||
|
static char *asynDisabledStringified = "disabled"; // 5
|
||||||
|
static char *asynParamAlreadyExistsStringified =
|
||||||
|
"parameter already exists"; // 6
|
||||||
|
static char *asynParamNotFoundStringified = "parameter not found"; // 7
|
||||||
|
static char *asynParamWrongTypeStringified = "wrong type"; // 8
|
||||||
|
static char *asynParamBadIndexStringified = "bad index"; // 9
|
||||||
|
static char *asynParamUndefinedStringified = "parameter undefined"; // 10
|
||||||
|
static char *asynParamInvalidListStringified = "invalid list"; // 11
|
||||||
|
|
||||||
|
char *sinqController::stringifyAsynStatus(asynStatus status) {
|
||||||
|
// See
|
||||||
|
// https://github.com/epics-modules/asyn/blob/master/asyn/asynDriver/asynDriver.h
|
||||||
|
// and
|
||||||
|
// https://github.com/epics-modules/asyn/blob/master/asyn/asynPortDriver/paramErrors.h
|
||||||
|
// for the definition of the error codes
|
||||||
|
switch (status) {
|
||||||
|
case asynSuccess:
|
||||||
|
return asynSuccessStringified;
|
||||||
|
case asynTimeout:
|
||||||
|
return asynTimeoutStringified;
|
||||||
|
case asynOverflow:
|
||||||
|
return asynOverflowStringified;
|
||||||
|
case asynError:
|
||||||
|
return asynErrorStringified;
|
||||||
|
case asynDisconnected:
|
||||||
|
return asynDisconnectedStringified;
|
||||||
|
case asynDisabled:
|
||||||
|
return asynDisabledStringified;
|
||||||
|
case asynParamAlreadyExists:
|
||||||
|
return asynParamAlreadyExistsStringified;
|
||||||
|
case asynParamNotFound:
|
||||||
|
return asynParamNotFoundStringified;
|
||||||
|
case asynParamWrongType:
|
||||||
|
return asynParamWrongTypeStringified;
|
||||||
|
case asynParamBadIndex:
|
||||||
|
return asynParamBadIndexStringified;
|
||||||
|
case asynParamUndefined:
|
||||||
|
return asynParamUndefinedStringified;
|
||||||
|
case asynParamInvalidList:
|
||||||
|
return asynParamInvalidListStringified;
|
||||||
|
}
|
||||||
|
|
||||||
|
errlogPrintf("%s => line %d:\nReached unreachable code.",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
return "unreachable code reached";
|
||||||
|
}
|
54
src/sinqController.h
Normal file
54
src/sinqController.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
This class contains the necessary changes to have an additional text fields
|
||||||
|
for messages with each axis.
|
||||||
|
|
||||||
|
Code lifted from Torsten Boegershausens ESS code.
|
||||||
|
|
||||||
|
Mark Koennecke, March 2017
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __sinqController
|
||||||
|
#define __sinqController
|
||||||
|
#include "asynMotorController.h"
|
||||||
|
|
||||||
|
#define motorMessageIsFromDriverString "MOTOR_MESSAGE_DRIVER"
|
||||||
|
#define motorMessageTextString "MOTOR_MESSAGE_TEXT"
|
||||||
|
|
||||||
|
class epicsShareClass sinqController : public asynMotorController {
|
||||||
|
public:
|
||||||
|
sinqController(const char *portName, const char *SINQPortName, int numAxes,
|
||||||
|
const int &extraParams = 2);
|
||||||
|
|
||||||
|
friend class sinqAxis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
If accessing the parameter library failed (return status != asynSuccess),
|
||||||
|
calling this function writes a standardized message to both the IOC shell
|
||||||
|
and the motor message text PV. It then returns the input status.
|
||||||
|
*/
|
||||||
|
asynStatus paramLibAccessFailed(asynStatus status, const char *parameter,
|
||||||
|
const char *functionName, int lineNumber);
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function writes a standardized message to both the IOC shell and
|
||||||
|
the motor message text PV in case parsing a response (e.g. via sscanf)
|
||||||
|
failed. It always returns asynError.
|
||||||
|
*/
|
||||||
|
asynStatus errMsgCouldNotParseResponse(const char *command,
|
||||||
|
const char *response, int axisNo_,
|
||||||
|
const char *functionName,
|
||||||
|
int lineNumber);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert an asynStatus into a descriptive string. This string can then e.g.
|
||||||
|
be used to create debugging messages.
|
||||||
|
*/
|
||||||
|
char *stringifyAsynStatus(asynStatus status);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
asynUser *lowLevelPortUser_;
|
||||||
|
int motorMessageIsFromDriver_;
|
||||||
|
int motorMessageText_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user