Compare commits
16 Commits
lift_axis_
...
home_zero
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d46b3ac0c | |||
| ed0525e811 | |||
| 683fa2138f | |||
| 354e9d90fb | |||
| deea821e3f | |||
| 7a46788fd5 | |||
| 9e77eb585c | |||
| 7e1fc78f76 | |||
| 9e0d8a4322 | |||
| 3cccfe930c | |||
| 8860d0c59f | |||
| b6c38be113 | |||
| b14b50c25a | |||
| 477ffdbc0b | |||
| 0a23ec8f22 | |||
| 39098fd0d1 |
236
.clang-format
Normal file
236
.clang-format
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: 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
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
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
|
||||||
|
BreakAfterAttributes: Never
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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: 4
|
||||||
|
UseTab: Never
|
||||||
|
VerilogBreakBetweenInstancePorts: true
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- STRINGIZE
|
||||||
|
...
|
||||||
|
|
||||||
21
.gitea/workflows/action.yaml
Normal file
21
.gitea/workflows/action.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: Test And Build
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Lint:
|
||||||
|
runs-on: linepics
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: cppcheck
|
||||||
|
run: cppcheck --std=c++17 --addon=cert --addon=misc --error-exitcode=1 sinqEPICSApp/src/*.cpp
|
||||||
|
- name: formatting
|
||||||
|
run: clang-format --style=file --Werror --dry-run sinqEPICSApp/src/*.cpp sinqEPICSApp/src/*.c sinqEPICSApp/src/*.h
|
||||||
|
Build:
|
||||||
|
runs-on: linepics
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- run: |
|
||||||
|
sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile.RHEL8
|
||||||
|
make -f Makefile.RHEL8 install
|
||||||
@@ -4,7 +4,7 @@ include /ioc/tools/driver.makefile
|
|||||||
MODULE=sinq
|
MODULE=sinq
|
||||||
BUILDCLASSES=Linux
|
BUILDCLASSES=Linux
|
||||||
EPICS_VERSIONS=7.0.7
|
EPICS_VERSIONS=7.0.7
|
||||||
ARCH_FILTER=RHEL%
|
ARCH_FILTER=RHEL8%
|
||||||
|
|
||||||
# additional module dependencies
|
# additional module dependencies
|
||||||
REQUIRED+=SynApps
|
REQUIRED+=SynApps
|
||||||
@@ -12,13 +12,11 @@ REQUIRED+=stream
|
|||||||
REQUIRED+=scaler
|
REQUIRED+=scaler
|
||||||
REQUIRED+=motorBase
|
REQUIRED+=motorBase
|
||||||
|
|
||||||
# Release version
|
|
||||||
LIBVERSION=2025
|
|
||||||
|
|
||||||
# DB files to include in the release
|
# DB files to include in the release
|
||||||
TEMPLATES += sinqEPICSApp/Db/dimetix.db
|
TEMPLATES += sinqEPICSApp/Db/dimetix.db
|
||||||
TEMPLATES += sinqEPICSApp/Db/slsvme.db
|
TEMPLATES += sinqEPICSApp/Db/slsvme.db
|
||||||
TEMPLATES += sinqEPICSApp/Db/spsamor.db
|
TEMPLATES += sinqEPICSApp/Db/spsamor.db
|
||||||
|
TEMPLATES += sinqEPICSApp/Db/el734.db
|
||||||
|
|
||||||
# DBD files to include in the release
|
# DBD files to include in the release
|
||||||
DBDS += sinqEPICSApp/src/sinq.dbd
|
DBDS += sinqEPICSApp/src/sinq.dbd
|
||||||
|
|||||||
@@ -38,3 +38,12 @@ Those political problems require a special development model:
|
|||||||
Take care of the sinqEPICsApp/src/sinq.dbd file. This is the one which differs mostly between
|
Take care of the sinqEPICsApp/src/sinq.dbd file. This is the one which differs mostly between
|
||||||
amorsim and master branches.
|
amorsim and master branches.
|
||||||
|
|
||||||
|
# Formatting
|
||||||
|
|
||||||
|
Formatting is done via the [`.clang-format`](./.clang-format) file checked into
|
||||||
|
the repository. One option to apply the formatting to a given file is via the
|
||||||
|
command below.
|
||||||
|
|
||||||
|
```
|
||||||
|
clang-format -i -style=file <file>
|
||||||
|
```
|
||||||
|
|||||||
34
sinqEPICSApp/Db/el734.db
Normal file
34
sinqEPICSApp/Db/el734.db
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
record(motor,"$(P)$(M)")
|
||||||
|
{
|
||||||
|
field(DESC,"$(DESC)")
|
||||||
|
field(DTYP,"$(DTYP)")
|
||||||
|
field(DIR,"$(DIR)")
|
||||||
|
field(VELO,"$(VELO)")
|
||||||
|
field(HVEL,"$(VELO)")
|
||||||
|
field(VBAS,"$(VELO)")
|
||||||
|
field(VMAX, "${VMAX}")
|
||||||
|
field(ACCL,"$(ACCL)")
|
||||||
|
field(BDST,"$(BDST)")
|
||||||
|
field(BVEL,"$(BVEL)")
|
||||||
|
field(BACC,"$(BACC)")
|
||||||
|
field(OUT,"@asyn($(PORT),$(ADDR))")
|
||||||
|
field(MRES,"$(MRES)")
|
||||||
|
field(PREC,"$(PREC)")
|
||||||
|
field(EGU,"$(EGU)")
|
||||||
|
field(DHLM,"$(DHLM)")
|
||||||
|
field(DLLM,"$(DLLM)")
|
||||||
|
field(INIT,"$(INIT)")
|
||||||
|
field(PINI, "NO")
|
||||||
|
field(TWV,"1")
|
||||||
|
field(RTRY,"0")
|
||||||
|
}
|
||||||
|
|
||||||
|
# The message text
|
||||||
|
record(waveform, "$(P)$(M)-MsgTxt") {
|
||||||
|
field(DTYP, "asynOctetRead")
|
||||||
|
field(INP, "@asyn($(PORT),$(N),1) MOTOR_MESSAGE_TEXT")
|
||||||
|
field(FTVL, "CHAR")
|
||||||
|
field(NELM, "80")
|
||||||
|
field(SCAN, "I/O Intr")
|
||||||
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ January 2019
|
|||||||
#include "PhytronDriver.h"
|
#include "PhytronDriver.h"
|
||||||
#include <epicsExport.h>
|
#include <epicsExport.h>
|
||||||
|
|
||||||
#define IDLEPOLL 60
|
#define IDLEPOLL 5
|
||||||
|
|
||||||
/** Creates a new PhytronController object.
|
/** Creates a new PhytronController object.
|
||||||
* \param[in] portName The name of the asyn port that will be created for this driver
|
* \param[in] portName The name of the asyn port that will be created for this driver
|
||||||
@@ -56,7 +56,7 @@ January 2019
|
|||||||
* \param[in] numAxes The number of axes that this controller supports
|
* \param[in] numAxes The number of axes that this controller supports
|
||||||
*/
|
*/
|
||||||
PhytronController::PhytronController(const char *portName, const char *PhytronPortName, const char *sel ,
|
PhytronController::PhytronController(const char *portName, const char *PhytronPortName, const char *sel ,
|
||||||
int encX, int encY)
|
int encX, int encY, int ignoreLimitsX, int ignoreLimitsY)
|
||||||
: SINQController(portName, PhytronPortName,2)
|
: SINQController(portName, PhytronPortName,2)
|
||||||
{
|
{
|
||||||
asynStatus status;
|
asynStatus status;
|
||||||
@@ -82,8 +82,8 @@ PhytronController::PhytronController(const char *portName, const char *PhytronPo
|
|||||||
new PhytronDoseAxis(this, 1, encX);
|
new PhytronDoseAxis(this, 1, encX);
|
||||||
new PhytronDoseAxis(this, 2, encY);
|
new PhytronDoseAxis(this, 2, encY);
|
||||||
} else {
|
} else {
|
||||||
new PhytronAxis(this, 1, encX);
|
new PhytronAxis(this, 1, encX, ignoreLimitsX);
|
||||||
new PhytronAxis(this, 2, encY);
|
new PhytronAxis(this, 2, encY, ignoreLimitsY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ PhytronController::PhytronController(const char *portName, const char *PhytronPo
|
|||||||
|
|
||||||
PhytronDoseController::PhytronDoseController(const char *portName, const char *PhytronPortName, const char *sel ,
|
PhytronDoseController::PhytronDoseController(const char *portName, const char *PhytronPortName, const char *sel ,
|
||||||
int encX, int encY)
|
int encX, int encY)
|
||||||
: PhytronController(portName, PhytronPortName, sel, encX, encY)
|
: PhytronController(portName, PhytronPortName, sel, encX, encY, 0, 0)
|
||||||
{
|
{
|
||||||
new PhytronDoseAxis(this, 1, encX);
|
new PhytronDoseAxis(this, 1, encX);
|
||||||
new PhytronDoseAxis(this, 2, encY);
|
new PhytronDoseAxis(this, 2, encY);
|
||||||
@@ -106,9 +106,9 @@ PhytronDoseController::PhytronDoseController(const char *portName, const char *P
|
|||||||
* \param[in] numAxes The number of axes that this controller supports
|
* \param[in] numAxes The number of axes that this controller supports
|
||||||
*/
|
*/
|
||||||
extern "C" int PhytronCreateController(const char *portName, const char *PhytronPortName, const char *selector,
|
extern "C" int PhytronCreateController(const char *portName, const char *PhytronPortName, const char *selector,
|
||||||
int encX, int encY)
|
int encX, int encY, int ignoreLimitsX, int ignoreLimitsY)
|
||||||
{
|
{
|
||||||
new PhytronController(portName, PhytronPortName,selector, encX, encY);
|
new PhytronController(portName, PhytronPortName,selector, encX, encY, ignoreLimitsX, ignoreLimitsY);
|
||||||
return(asynSuccess);
|
return(asynSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,10 +178,10 @@ PhytronDoseAxis* PhytronDoseController::getAxis(int axisNo)
|
|||||||
|
|
||||||
asynStatus PhytronController::transactController(int axisNo,char command[COMLEN], char reply[COMLEN])
|
asynStatus PhytronController::transactController(int axisNo,char command[COMLEN], char reply[COMLEN])
|
||||||
{
|
{
|
||||||
asynStatus status;
|
asynStatus status = asynSuccess;
|
||||||
size_t in, out;
|
size_t in = 0, out = 0;
|
||||||
int reason;
|
int reason = 0;
|
||||||
char myReply[COMLEN+10], myCommand[COMLEN+10], *pPtr;
|
char myReply[COMLEN+10] = {0}, myCommand[COMLEN+10] = {0}, *pPtr = {0};
|
||||||
SINQAxis *axis = getAxis(axisNo);
|
SINQAxis *axis = getAxis(axisNo);
|
||||||
|
|
||||||
|
|
||||||
@@ -237,11 +237,12 @@ asynStatus PhytronController::transactController(int axisNo,char command[COMLEN]
|
|||||||
*
|
*
|
||||||
* Initializes register numbers, etc.
|
* Initializes register numbers, etc.
|
||||||
*/
|
*/
|
||||||
PhytronAxis::PhytronAxis(PhytronController *pC, int axisNo, int enc)
|
PhytronAxis::PhytronAxis(PhytronController *pC, int axisNo, int enc, int ignoreLimits)
|
||||||
: SINQAxis(pC, axisNo),
|
: SINQAxis(pC, axisNo),
|
||||||
pC_(pC)
|
pC_(pC)
|
||||||
{
|
{
|
||||||
encoder = enc;
|
encoder = enc;
|
||||||
|
ignore_limits = ignoreLimits;
|
||||||
if(axisNo == 1){
|
if(axisNo == 1){
|
||||||
phytronChar = 'X';
|
phytronChar = 'X';
|
||||||
} else {
|
} else {
|
||||||
@@ -250,6 +251,8 @@ PhytronAxis::PhytronAxis(PhytronController *pC, int axisNo, int enc)
|
|||||||
haveBrake = 0;
|
haveBrake = 0;
|
||||||
brakeIO = -1;
|
brakeIO = -1;
|
||||||
next_poll = -1;
|
next_poll = -1;
|
||||||
|
homing = 0;
|
||||||
|
homing_direction = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PhytronAxis::setBrake(int brakeNO)
|
int PhytronAxis::setBrake(int brakeNO)
|
||||||
@@ -434,8 +437,9 @@ asynStatus PhytronAxis::setPosition(double position)
|
|||||||
|
|
||||||
errlogPrintf("PhytronAxis::setPosition called with %lf\n", position);
|
errlogPrintf("PhytronAxis::setPosition called with %lf\n", position);
|
||||||
|
|
||||||
sprintf(command, "%s%cP22S%f", pC_->selector,phytronChar, position/1000.);
|
// writing encoder register is wrong
|
||||||
status = pC_->transactController(axisNo_,command,reply);
|
//sprintf(command, "%s%cP22S%f", pC_->selector,phytronChar, position/1000.);
|
||||||
|
//status = pC_->transactController(axisNo_,command,reply);
|
||||||
sprintf(command, "%s%cP20S%f", pC_->selector,phytronChar, position/1000.);
|
sprintf(command, "%s%cP20S%f", pC_->selector,phytronChar, position/1000.);
|
||||||
status = pC_->transactController(axisNo_,command,reply);
|
status = pC_->transactController(axisNo_,command,reply);
|
||||||
next_poll = -1;
|
next_poll = -1;
|
||||||
@@ -465,8 +469,6 @@ asynStatus PhytronAxis::poll(bool *moving)
|
|||||||
{
|
{
|
||||||
asynStatus comStatus = asynSuccess;
|
asynStatus comStatus = asynSuccess;
|
||||||
char command[COMLEN], reply[COMLEN];
|
char command[COMLEN], reply[COMLEN];
|
||||||
double lowlim;
|
|
||||||
|
|
||||||
|
|
||||||
// protect against excessive polling
|
// protect against excessive polling
|
||||||
if(time(NULL) < next_poll){
|
if(time(NULL) < next_poll){
|
||||||
@@ -536,13 +538,7 @@ asynStatus PhytronAxis::poll(bool *moving)
|
|||||||
|
|
||||||
if(!*moving) {
|
if(!*moving) {
|
||||||
if(homing){
|
if(homing){
|
||||||
if(homing_direction) {
|
setIntegerParam(pC_->motorStatusAtHome_, true);
|
||||||
pC_->getDoubleParam(axisNo_,pC_->motorHighLimit_,&lowlim);
|
|
||||||
} else {
|
|
||||||
pC_->getDoubleParam(axisNo_,pC_->motorLowLimit_,&lowlim);
|
|
||||||
}
|
|
||||||
setPosition(lowlim);
|
|
||||||
setIntegerParam(pC_->motorStatusAtHome_, true);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
check limits and errors, upper
|
check limits and errors, upper
|
||||||
@@ -554,7 +550,7 @@ asynStatus PhytronAxis::poll(bool *moving)
|
|||||||
updateMsgTxtFromDriver("No connection to phytron controller");
|
updateMsgTxtFromDriver("No connection to phytron controller");
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
if(strstr(reply,"ACKE") != NULL){
|
if(strstr(reply,"ACKE") != NULL && ignore_limits == 0){
|
||||||
setIntegerParam(pC_->motorStatusHighLimit_, true);
|
setIntegerParam(pC_->motorStatusHighLimit_, true);
|
||||||
updateMsgTxtFromDriver("Hit High Limit");
|
updateMsgTxtFromDriver("Hit High Limit");
|
||||||
comStatus = asynError;
|
comStatus = asynError;
|
||||||
@@ -573,7 +569,7 @@ asynStatus PhytronAxis::poll(bool *moving)
|
|||||||
updateMsgTxtFromDriver("No connection to phytron controller");
|
updateMsgTxtFromDriver("No connection to phytron controller");
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
if(strstr(reply,"ACKE") != NULL){
|
if(strstr(reply,"ACKE") != NULL && ignore_limits == 0){
|
||||||
setIntegerParam(pC_->motorStatusLowLimit_, true);
|
setIntegerParam(pC_->motorStatusLowLimit_, true);
|
||||||
updateMsgTxtFromDriver("Low Limit Hit");
|
updateMsgTxtFromDriver("Low Limit Hit");
|
||||||
comStatus = asynError;
|
comStatus = asynError;
|
||||||
@@ -614,7 +610,7 @@ asynStatus PhytronAxis::poll(bool *moving)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
PhytronDoseAxis::PhytronDoseAxis(PhytronController *pC, int axisNo, int enc)
|
PhytronDoseAxis::PhytronDoseAxis(PhytronController *pC, int axisNo, int enc)
|
||||||
: PhytronAxis(pC, axisNo, enc)
|
: PhytronAxis(pC, axisNo, enc, 0)
|
||||||
{
|
{
|
||||||
if(axisNo == 1){
|
if(axisNo == 1){
|
||||||
doseChar = '3';
|
doseChar = '3';
|
||||||
@@ -718,15 +714,19 @@ static const iocshArg PhytronCreateControllerArg1 = {"Phytron port name", iocshA
|
|||||||
static const iocshArg PhytronCreateControllerArg2 = {"Phytron Selector", iocshArgString};
|
static const iocshArg PhytronCreateControllerArg2 = {"Phytron Selector", iocshArgString};
|
||||||
static const iocshArg PhytronCreateControllerArg3 = {"EncoderX", iocshArgInt};
|
static const iocshArg PhytronCreateControllerArg3 = {"EncoderX", iocshArgInt};
|
||||||
static const iocshArg PhytronCreateControllerArg4 = {"EncoderY", iocshArgInt};
|
static const iocshArg PhytronCreateControllerArg4 = {"EncoderY", iocshArgInt};
|
||||||
|
static const iocshArg PhytronCreateControllerArg5 = {"IgnoreLimitsX", iocshArgInt};
|
||||||
|
static const iocshArg PhytronCreateControllerArg6 = {"IgnoreLimitsY", iocshArgInt};
|
||||||
static const iocshArg * const PhytronCreateControllerArgs[] = {&PhytronCreateControllerArg0,
|
static const iocshArg * const PhytronCreateControllerArgs[] = {&PhytronCreateControllerArg0,
|
||||||
&PhytronCreateControllerArg1,
|
&PhytronCreateControllerArg1,
|
||||||
&PhytronCreateControllerArg2,
|
&PhytronCreateControllerArg2,
|
||||||
&PhytronCreateControllerArg3,
|
&PhytronCreateControllerArg3,
|
||||||
&PhytronCreateControllerArg4};
|
&PhytronCreateControllerArg4,
|
||||||
static const iocshFuncDef PhytronCreateControllerDef = {"PhytronCreateController", 5, PhytronCreateControllerArgs};
|
&PhytronCreateControllerArg5,
|
||||||
|
&PhytronCreateControllerArg6};
|
||||||
|
static const iocshFuncDef PhytronCreateControllerDef = {"PhytronCreateController", 7, PhytronCreateControllerArgs};
|
||||||
static void PhytronCreateContollerCallFunc(const iocshArgBuf *args)
|
static void PhytronCreateContollerCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
PhytronCreateController(args[0].sval, args[1].sval, args[2].sval, args[3].ival,args[4].ival);
|
PhytronCreateController(args[0].sval, args[1].sval, args[2].sval, args[3].ival,args[4].ival, args[5].ival, args[6].ival);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const iocshArg PhytronDoseCreateControllerArg0 = {"Port name", iocshArgString};
|
static const iocshArg PhytronDoseCreateControllerArg0 = {"Port name", iocshArgString};
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class PhytronAxis : public SINQAxis
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* These are the methods we override from the base class */
|
/* These are the methods we override from the base class */
|
||||||
PhytronAxis(class PhytronController *pC, int axis, int enc);
|
PhytronAxis(class PhytronController *pC, int axis, int enc, int ignoreLimits);
|
||||||
void report(FILE *fp, int level);
|
void report(FILE *fp, int level);
|
||||||
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);
|
||||||
@@ -50,6 +50,7 @@ protected:
|
|||||||
int homing_direction; /*1 forward, 0 backwards */
|
int homing_direction; /*1 forward, 0 backwards */
|
||||||
time_t next_poll;
|
time_t next_poll;
|
||||||
int encoder;
|
int encoder;
|
||||||
|
int ignore_limits;
|
||||||
int haveBrake;
|
int haveBrake;
|
||||||
int brakeIO;
|
int brakeIO;
|
||||||
|
|
||||||
@@ -74,7 +75,7 @@ PhytronDoseController *pC_;
|
|||||||
class PhytronController : public SINQController {
|
class PhytronController : public SINQController {
|
||||||
public:
|
public:
|
||||||
PhytronController(const char *portName, const char *PhytronPortName, const char *selector,
|
PhytronController(const char *portName, const char *PhytronPortName, const char *selector,
|
||||||
int encX, int encY);
|
int encX, int encY, int ignoreLimitsX, int ignoreLimitsY);
|
||||||
|
|
||||||
void report(FILE *fp, int level);
|
void report(FILE *fp, int level);
|
||||||
PhytronAxis* getAxis(asynUser *pasynUser);
|
PhytronAxis* getAxis(asynUser *pasynUser);
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ typedef struct {
|
|||||||
unsigned int dbInit;
|
unsigned int dbInit;
|
||||||
}EL737priv;
|
}EL737priv;
|
||||||
|
|
||||||
static void dummyAsynCallback([[maybe_unused]] asynUser *pasynUser)
|
static void dummyAsynCallback(asynUser *pasynUser)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
213
utils/decodeMasterMACStatusR10.py
Executable file
213
utils/decodeMasterMACStatusR10.py
Executable file
@@ -0,0 +1,213 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# List of tuples which encodes the states given in the file description.
|
||||||
|
# Index first with the bit index, then with the bit value
|
||||||
|
interpretation = [
|
||||||
|
("Not ready to be switched on", "Ready to be switched on"), # Bit 0
|
||||||
|
("Not switched on", "Switched on"), # Bit 1
|
||||||
|
("Disabled", "Enabled"), # Bit 2
|
||||||
|
("Ok", "Fault condition set"), # Bit 3
|
||||||
|
("Motor supply voltage absent ", "Motor supply voltage present"), # Bit 4
|
||||||
|
("Motor performs quick stop", "Ok"), # Bit 5
|
||||||
|
("Switch on enabled", "Switch on disabled"), # Bit 6
|
||||||
|
("Ok", "RWarning: Movement function was called while motor is still moving. The function call is ignored"), # Bit 7
|
||||||
|
("Motor is idle", "Motor is currently moving"), # Bit 8
|
||||||
|
("Motor does not execute command messages (local mode)", "Motor does execute command messages (remote mode)"), # Bit 9
|
||||||
|
("Target not reached", "Target reached"), # Bit 10
|
||||||
|
("Ok", "Internal limit active"), # Bit 11
|
||||||
|
("Not specified", "Not specified"), # Bit 12
|
||||||
|
("Not specified", "Not specified"), # Bit 13
|
||||||
|
("No event set or event has not occurred yet", "Set event has occurred"), # Bit 14
|
||||||
|
("Axis off (power disabled)", "Axis on (power enabled)"), # Bit 15
|
||||||
|
]
|
||||||
|
|
||||||
|
def decode(value, big_endian: bool = False):
|
||||||
|
|
||||||
|
interpreted = []
|
||||||
|
|
||||||
|
bit_list = [(value >> shift_ind) & 1
|
||||||
|
for shift_ind in range(value.bit_length())] # little endian
|
||||||
|
|
||||||
|
if big_endian:
|
||||||
|
bit_list.reverse() # big endian
|
||||||
|
|
||||||
|
for (bit, interpretations) in zip(bit_list, interpretation):
|
||||||
|
interpreted.append(interpretations[bit])
|
||||||
|
return (bit_list, interpreted)
|
||||||
|
|
||||||
|
def print_decoded(bit_list, interpreted):
|
||||||
|
for (idx, (bit_value, msg)) in enumerate(zip(bit_list, interpreted)):
|
||||||
|
print(f"Bit {idx} = {bit_value}: {msg}")
|
||||||
|
|
||||||
|
def interactive():
|
||||||
|
|
||||||
|
# Imported here, because curses is not available in Windows. Using the
|
||||||
|
# interactive mode therefore fails on Windows, but at least the single
|
||||||
|
# command mode can be used (which would not be possible if we would import
|
||||||
|
# curses at the top level)
|
||||||
|
import curses
|
||||||
|
|
||||||
|
stdscr = curses.initscr()
|
||||||
|
curses.noecho()
|
||||||
|
curses.cbreak()
|
||||||
|
stdscr.keypad(True)
|
||||||
|
stdscr.scrollok(True)
|
||||||
|
|
||||||
|
stdscr.addstr(">> ")
|
||||||
|
stdscr.refresh()
|
||||||
|
|
||||||
|
history = [""]
|
||||||
|
ptr = len(history) - 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
c = stdscr.getch()
|
||||||
|
if c == curses.KEY_RIGHT:
|
||||||
|
(y, x) = stdscr.getyx()
|
||||||
|
if x < len(history[ptr]) + 3:
|
||||||
|
stdscr.move(y, x+1)
|
||||||
|
stdscr.refresh()
|
||||||
|
elif c == curses.KEY_LEFT:
|
||||||
|
(y, x) = stdscr.getyx()
|
||||||
|
if x > 3:
|
||||||
|
stdscr.move(y, x-1)
|
||||||
|
stdscr.refresh()
|
||||||
|
elif c == curses.KEY_UP:
|
||||||
|
if ptr > 0:
|
||||||
|
ptr -= 1
|
||||||
|
stdscr.addch("\r")
|
||||||
|
stdscr.clrtoeol()
|
||||||
|
stdscr.addstr(">> " + history[ptr])
|
||||||
|
elif c == curses.KEY_DOWN:
|
||||||
|
if ptr < len(history) - 1:
|
||||||
|
ptr += 1
|
||||||
|
stdscr.addch("\r")
|
||||||
|
stdscr.clrtoeol()
|
||||||
|
stdscr.addstr(">> " + history[ptr])
|
||||||
|
elif c == curses.KEY_ENTER or c == ord('\n') or c == ord('\r'):
|
||||||
|
if history[ptr] == 'quit':
|
||||||
|
break
|
||||||
|
|
||||||
|
# because of arrow keys move back to the end of the line
|
||||||
|
(y, x) = stdscr.getyx()
|
||||||
|
stdscr.move(y, 3+len(history[ptr]))
|
||||||
|
|
||||||
|
if history[ptr]:
|
||||||
|
result = interpret_inputs(history[ptr].split())
|
||||||
|
if result is None:
|
||||||
|
stdscr.addstr(f"\nBAD INPUT: Expected input of 'value [big_endian]', where 'value' is an int or a float and 'big_endian' is an optional boolean argument.")
|
||||||
|
else:
|
||||||
|
(arg, big_endian) = result
|
||||||
|
(bit_list, interpreted) = decode(arg, big_endian)
|
||||||
|
for (idx, (bit_value, msg)) in enumerate(zip(bit_list, interpreted)):
|
||||||
|
stdscr.addstr(f"\nBit {idx} = {bit_value}: {msg}")
|
||||||
|
stdscr.refresh()
|
||||||
|
|
||||||
|
if ptr == len(history) - 1 and history[ptr] != "":
|
||||||
|
history += [""]
|
||||||
|
else:
|
||||||
|
history[-1] = ""
|
||||||
|
ptr = len(history) - 1
|
||||||
|
|
||||||
|
stdscr.addstr("\n>> ")
|
||||||
|
stdscr.refresh()
|
||||||
|
|
||||||
|
else:
|
||||||
|
if ptr < len(history) - 1: # Modifying previous input
|
||||||
|
if len(history[-1]) == 0:
|
||||||
|
history[-1] = history[ptr]
|
||||||
|
ptr = len(history) - 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
history += [history[ptr]]
|
||||||
|
ptr = len(history) - 1
|
||||||
|
|
||||||
|
if c == curses.KEY_BACKSPACE:
|
||||||
|
if len(history[ptr]) == 0:
|
||||||
|
continue
|
||||||
|
(y, x) = stdscr.getyx()
|
||||||
|
history[ptr] = history[ptr][0:x-4] + history[ptr][x-3:]
|
||||||
|
stdscr.addch("\r")
|
||||||
|
stdscr.clrtoeol()
|
||||||
|
stdscr.addstr(">> " + history[ptr])
|
||||||
|
stdscr.move(y, x-1)
|
||||||
|
stdscr.refresh()
|
||||||
|
|
||||||
|
else:
|
||||||
|
(y, x) = stdscr.getyx()
|
||||||
|
history[ptr] = history[ptr][0:x-3] + chr(c) + history[ptr][x-3:]
|
||||||
|
stdscr.addch("\r")
|
||||||
|
stdscr.clrtoeol()
|
||||||
|
stdscr.addstr(">> " + history[ptr])
|
||||||
|
stdscr.move(y, x+1)
|
||||||
|
stdscr.refresh()
|
||||||
|
|
||||||
|
# to quit
|
||||||
|
curses.nocbreak()
|
||||||
|
stdscr.keypad(False)
|
||||||
|
curses.echo()
|
||||||
|
curses.endwin()
|
||||||
|
|
||||||
|
def interpret_inputs(inputs):
|
||||||
|
|
||||||
|
number = None
|
||||||
|
big_endian = False
|
||||||
|
try:
|
||||||
|
number = int(float(inputs[0]))
|
||||||
|
if len(inputs) > 1:
|
||||||
|
second_arg = inputs[1]
|
||||||
|
if second_arg == "True" or second_arg == "true":
|
||||||
|
big_endian = True
|
||||||
|
elif second_arg == "False" or second_arg == "false":
|
||||||
|
big_endian = False
|
||||||
|
else:
|
||||||
|
big_endian = bool(int(second_arg))
|
||||||
|
return (number, big_endian)
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from sys import argv
|
||||||
|
|
||||||
|
if len(argv) == 1:
|
||||||
|
# Start interactive mode
|
||||||
|
interactive()
|
||||||
|
else:
|
||||||
|
|
||||||
|
result = interpret_inputs(argv[1:])
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
print("""
|
||||||
|
Decode R10 message of MasterMACs
|
||||||
|
------------------
|
||||||
|
|
||||||
|
MasterMACs returns its status message (R10) as a floating-point number.
|
||||||
|
The bits of this float encode different states. These states are stored
|
||||||
|
in the interpretation variable.
|
||||||
|
|
||||||
|
This script can be used in two different ways:
|
||||||
|
|
||||||
|
Option 1: Single Command
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Usage: decodeMasterMACStatusR10.py value [big_endian]
|
||||||
|
|
||||||
|
'value' is the return value of a R10 command. This value is interpreted
|
||||||
|
bit-wise and the result is printed out. The optional second argument can
|
||||||
|
be used to specify whether the input value needs to be interpreted as
|
||||||
|
little or big endian. Default is False.
|
||||||
|
|
||||||
|
Option 2: CLI Mode
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Usage: decodeMasterMACStatusR10.py
|
||||||
|
|
||||||
|
A prompt will be opened. Type in the return value of a R10 command, hit
|
||||||
|
enter and the interpretation will be printed in the prompt. After that,
|
||||||
|
the next value can be typed in. Type 'quit' to close the prompt.
|
||||||
|
""")
|
||||||
|
else:
|
||||||
|
print("Motor status")
|
||||||
|
print("============")
|
||||||
|
(arg, big_endian) = result
|
||||||
|
(bit_list, interpreted) = decode(arg, big_endian)
|
||||||
|
print_decoded(bit_list, interpreted)
|
||||||
@@ -64,6 +64,7 @@ if __name__ == "__main__":
|
|||||||
curses.noecho()
|
curses.noecho()
|
||||||
curses.cbreak()
|
curses.cbreak()
|
||||||
stdscr.keypad(True)
|
stdscr.keypad(True)
|
||||||
|
stdscr.scrollok(True)
|
||||||
|
|
||||||
stdscr.addstr(">> ")
|
stdscr.addstr(">> ")
|
||||||
stdscr.refresh()
|
stdscr.refresh()
|
||||||
|
|||||||
Reference in New Issue
Block a user